@@ -3217,7 +3217,7 @@ hd_bpb20: ; cluster size determined
32173217 sub ax , 1 + ( 512 * 32 /SECSIZE) ; subtract reserved+root directory
32183218 sbb dx , 0 ; (note: 32 bytes per entry)
32193219 xor cx , cx
3220- mov ch , BPB.ALLOCSIZ [ bx ] ; CX = (256 * # of clusters on drive )
3220+ mov ch , BPB.ALLOCSIZ [ bx ] ; CX = (256 * sectors per cluster )
32213221 dec cx
32223222 add ax , cx ; add in for rounding error
32233223 adc dx , 0
@@ -3265,27 +3265,36 @@ hd_bpb30: ; build BPB for FAT32
32653265
32663266 ; Now follows the calculation of the sector count per FAT.
32673267 ; It is calculated after the formula
3268- ; (total_sec + (sec_per_clust-1) - reserved) /
3269- ; (sect_per_clust * entries_per_FAT_sector)
3270- ; This is somewhat inefficient, because the FATs are unnecessarily
3271- ; treated as data area.
3272- hd_bpb40: ; DX:AX = total sectors
3273- sub ax , BPB.FATADD [ bx ] ; subtract reserved
3268+ ; ((ts-res+1)/2+spc) / (64*spc+1) + 1
3269+ ; where ts = total sectors, spc = sectors per cluster and
3270+ ; res = reserved sectors
3271+ ; See https://github.com/boeckmann/fatdocs on how the formula was
3272+ ; derived.
3273+ hd_bpb40: ; DX:AX = ts
3274+ sub ax , BPB.FATADD [ bx ] ; DX:AX = ts - res
32743275 sbb dx , 0
3276+ add ax , 1
3277+ adc dx , 0 ; DX:AX = ts - res + 1
3278+ shr dx , 1
3279+ rcr ax , 1 ; DX:AX = (ts - res + 1) / 2
32753280 xor cx , cx
3276- mov ch , BPB.ALLOCSIZ [ bx ]
3277- shr cx , 1 ; CX = sectors per cluster * 128
3278- ; If CX is now zero this means that we are dealing with
3279- ; 256 sectors per cluster. We set CX to:
3280- ; 256 sectors per cluster * 128 FAT entries per sector = 8000h
3281- jnz hd_bpb41
3282- mov ch , 80h
3281+ mov cl , BPB.ALLOCSIZ [ bx ] ; CX = spc
3282+ test cl , cl ; CL = zero means spc=256
3283+ jnz hd_bpb41
3284+ mov ch , 1
32833285hd_bpb41:
3284- dec cx
3285- add ax , cx ; add in for rounding error
3286- adc dx , 0
3287- inc cx
3288- ; div cx ; AX = # of fat sectors
3286+ add ax , cx
3287+ adc dx , 0 ; DX:AX = (ts - res + 1) / 2 + spc
3288+ xchg ch , cl
3289+ shr cx , 1
3290+ shr cx , 1 ; CX = spc * 64
3291+ ; If CX is zero this means that we are dealing with 256 sectors per
3292+ ; cluster. We set CX to = 256 * 64 = 4000h
3293+ test cx , cx
3294+ jnz hd_bpb42
3295+ mov ch , 40h
3296+ hd_bpb42:
3297+ add cx , 1 ; CX = 64 * spc + 1
32893298 push bp
32903299 push dx
32913300 push ax
@@ -3299,6 +3308,8 @@ hd_bpb41:
32993308 pop dx
33003309 add sp , 8
33013310 pop bp
3311+ add ax , 1
3312+ adc dx , 0 ; DX:AX = FAT size in sectors
33023313 mov word ptr BPB.BFATSEC [ bx ], ax ; remember FAT size
33033314 mov word ptr BPB.BFATSEC + 2 [ bx ], dx
33043315 and word ptr BPB.FATSEC [ bx ], 0 ; clear small FAT size field
0 commit comments