; FAT12 driver. ;
; ;
;----------------------------------------------------------;
- struc disk
- {
- .disk_number db 0 ; which disk?
- .root_dir dw 0 ; position of rootdir
- .fat_1 dd 0 ; position of fat1
- .fat_2 dd 0 ; position of fat2
- .data_area dw 0 ; position of dataarea
- .disk_size dd 0
- .free_space dd 0
- .boot bootsector
- ; ..... some other values
- }
- struc bootsector ; 512 bytes
- {
- .jumper db 0,0,0
- .oem db 0,0,0,0,0,0,0,0
- .sectorsize dw 0
- .sect_per_clust db 0
- ;.... more values here
- }
-
- virtual at 0
- bootsector bootsector
- sizeof.bootsector = $
- end virtual
-
- virtual at 0
- disk disk
- sizeof.disk = $
- end virtual
-
-
-fd0 disk ; define fd0 data..
-
-;drv dd 0
-;mov edi, drv+disk.boot
- ;-----------------------------;
- ; calculate root location ;
- ;-----------------------------;
- xor eax, eax
- mov al, byte [fd0.boot.fats_per_drive]
- mul word [fd0.boot.sectors_per_fat]
- add ax, word [fd0.boot.reserved_sect]
- mov [fd0.root_dir], ax
+ ;---------------------------------------------;
+ ; main FAT12 info structure ;
+ ;---------------------------------------------;
+ struc fat12
+ {
+ .disk_number db 0 ; which VFS disk number
+ .root_dir dw 0 ; position of rootdir
+ .fat_1 dd 0 ; position of fat1
+ .fat_2 dd 0 ; position of fat2
+ .data_area dw 0 ; position of dataarea
+ .disk_size dd 0 ; total storage size
+ .free_space dd 0 ; free space available
+ .boot bootsector
+ .dir_entries:
+ times 16 * sizeof.dir_entry db 0 ; 512b dir entry buffer
+ .fat_buffer: times 512 db 0 ; 512b FAT cluster info buffer
+ }
+
+ ;---------------------------------------------;
+ ; FAT12 bootsector structure ;
+ ;---------------------------------------------;
+ struc bootsector ; 512 bytes
+ {
+ .jumper db 0,0,0
+ .oem db 0,0,0,0,0,0,0,0
+ .sectorsize dw 0
+ .sect_per_clust db 0
+ .reserved_sect dw 0 ; reserved sectors, 1 for bootsector.
+ .fats_per_drive db 0
+ .root_entries dw 0
+ .small_sectors dw 0 ; total sectors on small disk
+ .media_describtor db 0 ; 240 / 0xF0 = 1.44MB, 3.5"
+ .sectors_per_fat dw 0 ; 9 on 1.44MB, 3,5"
+ .sect_per_track dw 0 ; 18 on 1.44MB, 3,5"
+ .heads dw 0 ; 2 on 1.44MB, 3,5"
+ .hidden_sectors dd 0 ; sectors before bootsector
+ .large_sectors dd 0 ; total sectors if large disk
+ .drive_no db 0
+ .reserved_field db 0
+ .bpb_signature db 0 ; 41=3 more (win NT req.), 0=end.
+ .disk_id dd 0 ; random ident number on format.
+ .volume_label db 0,0,0,0,0,0,0,0,0,0,0
+ .filesystem db 0,0,0,0,0,0,0,0 ; "FAT12 " or "FAT16 "
+ .code: times 448 db 0
+ .boot_signature db 0,0 ; 0x55,0xAA
+ }
+
+ ;---------------------------------------------;
+ ; FAT12 directory entry structure ;
+ ;---------------------------------------------;
+ struct dir_entry
+ {
+ .filename db 0,0,0,0,0,0,0,0
+ .extension db 0,0,0
+ .attributes db 0 ; 0x10 = dir for example.
+ .reserved db 0,0,0,0,0,0,0,0,0,0
+ .changed_time dw 0
+ .changed_date dw 0
+ .start_cluster dw 0
+ .filesize dd 0
+ }
+
+ ;---------------------------------------------;
+ ; FAT12 directory entry for LFN ;
+ ;---------------------------------------------;
+ struct lnf_entry
+ {
+ .order db 0 ; LFN entry in sequence, never 0x00 or 0xE5.
+ .namefirst dw 0,0,0,0,0 ; 5 first unicode (2byte) chars
+ .attribute db 0 ; 0x0F for Long File Name identification.
+ .reserved db 0
+ .checksum db 0 ; 8.3 name checksum
+ .namemiddle dw 0,0,0,0,0,0 ; middle 6 unicode (2byte) chars
+ .zero_cluster dw 0 ; always zero on LNF entries
+ .namelast dw 0,0 ; last 2 unicode (2byte) characters.
+ }
+
+ virtual at 0
+ lfn_entry lfn_entry
+ sizeof.lfn_entry = $
+ end virtual
+
+ virtual at 0
+ dir_entry dir_entry
+ sizeof.dir_entry = $
+ end virtual
+
+ virtual at 0
+ bootsector bootsector
+ sizeof.bootsector = $
+ end virtual
+
+ virtual at 0
+ disk disk
+ sizeof.disk = $
+ end virtual
+
+ ;------------------------------------------;
+ ; FAT cluster constants used ;
+ ;------------------------------------------;
+ cluster_free = 0x000 ; up for grabs.
+ cluster_reserved = 0xFF0 ; 0xFF0-0xFF6. 0xFF7=bad.
+ cluster_last = 0xFF8 ; 0xFF8-0xFFF last cluster.
+
+ ;------------------------------------------;
+ ; Directory entry first char constants ;
+ ;------------------------------------------;
+ entry_free = 0xE5 ; up for grabs.
+ entry_last = 0x00 ; this and remaining is free
+ entry_japan_kludge = 0x0E ; should be outputed as 0xE5.
+ entry_dot = 0x2E ; ASCII dot, check for "." or ".." dirs
+
+ ;------------------------------------------;
+ ; Directory entry attribute masks ;
+ ;------------------------------------------;
+ mask_readonly = 0x01
+ mask_hidden = 0x02
+ mask_system = 0x04
+ mask_volume_label = 0x08
+ mask_subdirectory = 0x10
+ mask_archive = 0x20
+
+ ;------------------------------------------;
+ ; Long File Name entry constants ;
+ ;------------------------------------------;
+ lfn_last_entry_mask = 0x40 ; LFN sequence-order mask for last
+ attribute_lfn = 0x0F ; attrb. byte value for LFN dir entry
+
-;mov si, [dsk]
-;mov ax, [si+disk.boot.sectorssize]
+
+fd0: fat12 ; define fd0 data.. tmp example.
+
+; TODO, alloc memory for struct and keep pointer only.
+; ---------------
+;drive dd 0
+;mov edi, drive+fat12into.boot
+
+;--------------------------------------------------------------;
+; init_fat12 - detect if drive fs is fat12 and init ;
+;--------------------------------------------------------------;
+; ;
+; in: reg = pointer to VFS drive info ;
+; ;
+; out: reg = pointer to struct(s) if FAT12 found ;
+; ;
+;--------------------------------------------------------------;
init_fat12:
push eax
+ ;...
+
+ ;-----------------------------;
+ ; calculate root location ;
+ ;-----------------------------;
+ xor eax, eax
+ mov al, byte [fd0.boot.fats_per_drive]
+ mul word [fd0.boot.sectors_per_fat]
+ add ax, word [fd0.boot.reserved_sect]
+ mov [fd0.root_dir], ax
+
+; working with
+;mov si, [drive]
+;mov ax, [si+fat12.boot.sectorssize]
+
; a bit more code here
pop eax
+ ret
+
+;--------------------------------------------------------------;
+; calc_lfn_chksum - get long file name checksum ;
+;--------------------------------------------------------------;
+; ;
+; in: esi = pointer to 11 byte 8.3 filename ;
+; ;
+; out: ax = checksum ;
+; ;
+;--------------------------------------------------------------;
+calc_lfn_chksum:
+ push cx
+ push esi
+
+ mov cx, 11
+ xor ax, ax ; return value start with null
+ .l1:
+ add ax, byte [esi] ; add next char to sum
+ shr ax, 1 ; shift sum right by 1
+ inc esi ; prepare for next character
+ loop .l1
+
+ pop esi
+ pop cx
+ ret
+
+;--------------------------------------------------------------;
+; get_dir_entry - get a directory entry or amount ;
+;--------------------------------------------------------------;
+; ;
+; in: esi = pointer to prev dir entry or 0 for root ;
+; cx = entry no. to extract or 0 for none ;
+; ;
+; out: cx = number of entries or unchanged if set ;
+; edi = pointer to dir entry or unchanged if cx=0 ;
+;--------------------------------------------------------------;
+get_dir_entry:
+ ;......
+ ret
+
+;--------------------------------------------------------------;
+; get_fat_entry - get a fat entry/cluster number ;
+;--------------------------------------------------------------;
+; ;
+; in: cx = fat entry/cluster number ;
+; ;
+; out: cx = next fat entry/cluster no. or 0 if none ;
+;--------------------------------------------------------------;
+get_fat_entry:
+ ;...
+ ret
+
+;--------------------------------------------------------------;
+; get_cluster - get a cluster ;
+;--------------------------------------------------------------;
+; ;
+; in: cx = fat entry/cluster number ;
+; ;
+; out: edi = pointer to cluster or zero if none ;
+;--------------------------------------------------------------;
+get_cluster:
+ ;...
ret
\ No newline at end of file