The code below is of a program which tries to list files located in as FAT12 formatted disk.
From my basic understanding I know that in order to find a file you need to look first in the root directory which is located at 19th sector in a physical disk. This root directory is 14 sectors in size.
There is a certain routine I've taken to list files in a FAT12:
Step 1: preparing a memory location to load each sector of the root directory which is location 0x0:0x1000
Step 2: Determining the size of root directory - formular i've used *Root_Directory_Size = (size of each entry * total number of entries) / size of sector*
Step 3: Figuring out the starting sector number of the root directory using the following formular = *(Number of fat * Size of each fat) + Reserved sectors + hidden sectors*
Step 4: After calculating the above offset, the program then starts to load each sector into location 0x0:0x1000, in each entry the program checks for the following first bytes in each entry the empty entry(0xe5) and the 0x00 this bytes indicates either root entry is empty or contains a deleted file
So here the challenge is after doing all this stuff I'm not getting a even character of a existing file on my screen.
;This is a basic program which reads files on FAT12 and displays their names on the screen:
;This program is loaded into RAM by a bootloader not
;bios which I have managed to accomplish
[org 0x00]
[bits 16]
mov ax, 0x2000
mov ds, ax
mov es, ax
;since we ve been loaded by bootloader into memory obviously the value of dl which normally contains
;drive letter has been altered by bootloader program will skip this routine
;and assume that our first boot drive is byte 0x80
;mov [drive_letter], dl
mov bx, file_name
mov si, bx ; since bx points to the first entry of the root directory which contains the name of the file
mov di, buffer ; the location of root directory entry
add di, [next_section]
mov cx, 11 ; string length
cld
rep movsb
mov dx, buffer
mov cx, 14
call print_string
mov ah, 8 ; read disk parameter
mov dl, [drive_letter]
int 13h
jc read_error
and cx, 3fh
mov [SectorsPerTrack], cx
movzx dx, dh ; high word has been zeroed out
add dx, 1
mov [Head], dx
xor ax, ax
mov dl, [drive_letter]
int 13h
jc read_error
;#calculating the root start
mov ax, 19 ; root directory logical block begins at 19th sector
mov [root_start], ax ; now we have the starting sector of the root directory
;#load root director entry into memory sector by sector
mov cx, 14
mov ax, [root_start]
mov bx, 0x3000
mov es, bx
xor bx, bx
read_next_sector:
push cx
push ax ; store lba address in the stack
xor bx, bx
call read_sectors
read_next_entry:
mov si, bx ; since bx points to the first entry of the root directory which contains the name of the file
mov di, buffer ; the location of root directory entry
add di, [next_section]
mov cx, 11 ; string length
cld
rep movsb
push bx
mov bx, [next_section]
add bx, 11
mov [next_section], bx
pop bx
add bx, 32 ; point to the next entry
cmp bx, 512 ; have we exceeded the sector size if yes excute the code below
jne read_next_entry
pop ax ; retrive the current logical address from the stack
pop cx ; retrive count from the stack
inc ax ; load next sector when we loop back again
loop read_next_sector
mov ah, 0x0e
xor bh, bh
mov al, 'L'
int 10h
mov dx, buffer
mov cx, 1000
call print_string
jmp $
print_string:
push cx
out_char:
mov ah, 0x0e
mov bx, dx
mov al, [bx]
xor bh, bh
int 10h
inc dx
pop cx
loop print_string
ret
file_found:
mov ah, 0x0e
xor bh, bh
mov al, 'Z'
int 10h
hlt
jmp $
read_error:
mov ah, 0x0e
xor bh, bh
mov al, 'R'
int 10h
xor ah, ah
int 16h
int 19h
hlt
jmp $
read_sectors:
push ax
push bx
xor dx, dx
mov bx, [SectorsPerTrack]; sectors per track
div bx
inc dx
mov cl, dl
xor dx, dx
mov bx, [Head] ; number of heads
div bx
mov ch, al
xchg dl, dh
;call other function routines
mov ah, 2
mov al, 1
pop bx
mov dl, [drive_letter]
int 13h
jc read_error
pop ax ; restore logical block address before exiting the read_sector routine
ret
drive_letter db 0x80
SectorsPerTrack dw 0
Head dw 0
root_size dw 14
root_start dw 0
next_section dw 0
file_name db 'KERNEL BIN', 0
buffer db 'No file found', 0
buffer1 times 1000 db 0
times 1024 db 0