Dex simple guild to FAT12.
First you need to load the fat in to memory and also the root dir
(as fat12 are not very big you we load them whole).We also load the boot sector, as we need
the info stored in the BPB. So let load a file from the disk. First the name of file needs
to be converted to a format the can be compared to the on stored in the root dir, which means
like this MYFILE EXE now as you can see its uppercase and packet out with space if less than
8 letters. So if you take user input for name of file to load, you will need to write some code
to convert the name as above.
Let for now say we want to find if "MYFILE EXE" is on the floppy, we would point say esi to the
Name in memory and edi to the start of the root dir in memory. The first thing we test for is edi
0, which means end of root dir and no file found, if not we can do a "repe cmpsb" (cx should = 11)
and if = we have found the file. if not = we add 32 to edi and try again.
But lets say it was =
, we than add 21 to edi and get what stored there (as this is the first
cluster number).
NOTE: when coding the "repe cmpsb" remember to pusha and popa before and after.
Now as we are talking fat12 1 cluster = 1 sector or 512bytes, Now our of all the fats, fat12 is
the biggest B**h, as it reprsents a pointer entry of 12bits or 1 1/2 bytes
, the first 2 entrys
in the fat, for fat12 contains FOF and FFn and reprsent cluster 0 and 1, so here how it would look:
FAT ENTRYS
*************************************************************************
*F0F*FF.*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*
*************************************************************************
0 1 2 3 4 5 and so on, these are relative cluster numbers
Now lets go back to our file "MYFILE EXE", lets say that it's the only file on the floppy, the
relative cluster number would be 0002h, it would look somthing like this
FAT ENTRYS
*************************************************************************
*F0F*FF.*003*004*FFF*...*...*...*...*...*...*...*...*...*...*...*...*...*
*************************************************************************
0 1 2 3 4 5 and so on, these are relative cluster numbers
NOTE: If you looked at them in a hex editor, the bytes would be reversed.
Now to help you to see what to do next, i will show you some simple code.
Code: Select all
;----------------------------------------------------;
; Load entire a program. ;
;----------------------------------------------------;
LoadImage:
mov ax,[cluster] ; In here is the cluster we saved
mov [FloppyTest],0 ; this is the nunmber of retrys
ReadNextClusterUP:
call ClusterLBA ; convert
call ReadSectors ; your read floppy function
jc ErrorFloppy ; error
;----------------------------------------------------;
; compute next cluster. ;
;----------------------------------------------------;
mov ax,word[cluster] ; here is the cluster number (2)
mov cx,ax
mov dx,ax
shr dx,0x0001 ; div it by 2 = (1)
add cx,dx ; = (3)
mov esi,BpbFat12 move the address of the the FAT into esi
add esi,ecx ; add (3) to the address
mov dx,word [ds:esi] ;load whats at that address, in to DX
test ax,0x0001 ; test if its odd or even ?
jnz OddCluster
EvenCluster:
and dx,0000111111111111b ; if even 0 out right most nibble
jmp Done
OddCluster:
shr dx,0x0004 ; if odd shift 4 right
Done:
mov word [cluster],dx ; Now test if its FF0H eg end of file
cmp dx,0x0FF0
jb LoadImage ; if not load some more as its not end of file.
;----------------------------------------------------;
; ExitSucsess. ;
;----------------------------------------------------;
ExitSucsess:
call Fdd_motor_off
mov [ErrorCode],0
pop ds
pop es
popad
mov ebx,dword[FddSectorsLoadedCount] ; Put number of sectors load, in ebx.
mov ah,0
clc
ret
;----------------------------------------------------;
; ErrorFloppy. ;
;----------------------------------------------------;
ErrorFloppy:
call Fdd_motor_off
pop ds
pop es
popad
mov ah,byte[ErrorCode]
stc
ret
;----------------------------------------------------;
; ReadSectors. ;
;----------------------------------------------------;
ReadSectors:
pushad
push es
push ds
call LBAcHs
TryReadFloppyAgain:
mov ch,byte [absoluteTrack]
mov cl,byte [absoluteSector]
mov dh,byte [absoluteHead]
mov dl,byte [bsDriveNumber]
call FddRead ; you call your floppy function here
jnc FloppyReadOK
;----------------------------------------------------;
; Try Reading floppy 3 time. ;
;----------------------------------------------------;
inc [FloppyTest]
cmp [FloppyTest],4
jae @f
call FddRecalibrate
jmp TryReadFloppyAgain
;----------------------------------------------------;
; Move data from DMA buffer, to image address. ;
;----------------------------------------------------;
FloppyReadOK:
mov cx,512
mov ax,sys_data
mov ds,ax
mov es,ax
mov esi,OffsetDma2Buffer ; this points to the DMAbuffer
mov edi,[LoadFileToAddress] ; this points to the file load address
add edi,[FileLoadCount]; each time we loop, we need to add 512 more bytes
rep movsb
add [FileLoadCount],512
add [FddSectorsLoadedCount],1 ; add 1 to number of sectors load count.
;----------------------------------------------------;
; ExitSucsess. ;
;----------------------------------------------------;
pop ds
pop es
popad
clc
ret
;----------------------------------------------------;
; Error. ;
;----------------------------------------------------;
@@:
pop ds
pop es
popad
stc
ret
;----------------------------------------------------;
; LBAcHs. ;
;----------------------------------------------------;
LBAcHs:
div word [bpbSectorsPerTrack]
inc dl
mov byte [absoluteSector],dl
xor dx,dx
div word [bpbHeadsPerCylinder]
mov byte [absoluteHead],dl
mov byte [absoluteTrack],al
ret
;----------------------------------------------------;
; ClusterLBA. ;
;----------------------------------------------------;
ClusterLBA:
sub ax,2 ;we sub the first 2 entrys
xor cx,cx
mov cl,byte[bpbSectorsPerCluster] ; in this case 1
mul cx
add ax, word [DataStart] ; here is the start of the data on the floppy
ret
; NOTE: You can get the DATA start address by Reserved_Sectors + FAT_Sectors + Root_Sectors
Now this code should be clear, but just in case, If we were using fat16 it would be much simpler
As we could go through the FAT by just adding 2bytes (eg:16bits or FAT16), But as we are using
FAT12 (or 12bits) we load 16 bits and test if even or odd, we then acording to this shift it right
4 bits or blank off 4 bits.
That's all folks
.