Hi again,

I have tried to investigate this problem further by comparing 3 files:

> https://sourceforge.net/p/freedos/svn/HEAD/tree/kernel/trunk/boot/boot32lb.asm
> https://sourceforge.net/p/freedos/svn/HEAD/tree/kernel/trunk/boot/boot32.asm
> https://sourceforge.net/p/freedos/svn/HEAD/tree/kernel/trunk/boot/boot.asm

> Left-bound text is about LBA or FAT1x code, while
>         indented text is about FAT32 CHS in this email.

Some items are at different places but hopefully (?) do not get overwritten:

> boot32lb: fat_secshift [selfmodifying]
> fat_sector@+0x44 fat_start@+0x48 data_start@+0x4c
>         boot32: fat_secshift@+0x68, CHS boot sector
>         fat_sector@+0x48 fat_start@+0x5e data_start@+0x62 fat_secmask@+0x66

The initial calculations seem to achieve the same in different ways:

> fat_sector = dd 0
>         done much later in CHS case, but early enough as far as I can tell
> fat_start = data_start = dd nHidden + word bsResSectors
>         di:si and fat_start okay, check data_start
> data_start += dd (byte followed by 2 dw 0?) [bsFATs] *signed dd [xsectPerFat]
>         ax = db bsFATs cbw
>         di += ax * dw xsectPerFat HIGH, ignoring overflows
>         data_start = dx:ax = di:si + (ax * dw xsectPerFat LOW), 16x16=32 bit

However, the "secshift" calculations are rather different here...

Note that the FAT12 / FAT16 boot sector reads the entire FAT
into RAM first, so THAT does not have to know which sector of
the FAT contains info about which cluster.

> fat_secshift = 7 for 128 FAT items per 512 byte sector
> ax = 512
> while ax not bsBytesPerSec
>   ax <<= 1
>   fat_secshift++
> endwhile
>         cx = fat_secmask = (dw bsBytesPerSec >> 2) - 1
>         cx++, now (dw bsBytesPerSec >> 2) which is FAT items per sector
>         ax expected to be 0 after movsw
>         do
>           ax++
>           cx >>= 1
>         while cx not 1
>         fat_secshift = AL, low byte of ax
>         fat_sector LOW = fat_sector HIGH = cx-- (is 0 now)

Mixed other differences which might be relevant:

> only boot32lb uses 386+ code and calls print which modifies AX BX SI
> convert_cluster: cmp eax,fff fff8 jnc EOF
>         convert_cluster: cmp dx,fff jnz okay cmp ax,fff8 jnc EOF?
> 
> next_cluster uses shr dx,1 rcr ax,1 in a loop to shr DX:AX by fat_secshift
>         ... ((di and secmask) << 2) + fat_start ...

And from the comparison FAT32 CHS to FAT12 / FAT16 boot code:

> note: FAT12 / FAT16 boot sector readDisk changes CX, ADD COMMENT HERE!

> note: FAT1x boot does not retry in readDisk, plus used extra buffers
>         "inc ah or cl,ah" versus "or cl,ah inc cx" for 1-based sector

The next_cluster, convert_cluster and readDisk calls all juggle with
plenty of registers in strictly defined ways, I might have overlooked
some unintended register changes somewhere.

Cheers, Eric



------------------------------------------------------------------------------
_______________________________________________
Freedos-kernel mailing list
Freedos-kernel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freedos-kernel

Reply via email to