BIOS Int 13h 08 DBT issue Bytes per sector code returns 0xF0 instead of 0x00 - 0x04
The code snippet in the question is wrong in the way it uses the segment registers. It's not possible to draw any conclusions about the F0-issue from it. However the same code on your GitHub repository seems OK.
The BIOS.ReturnDiskDriveParameters function 08h will only return in ES:DI
a far pointer to the DisketteParameterTable if the drive number that you specified in DL
on entry referred to a floppy drive (DL < 128
).
I have looked at your project on GitHub and believe that what happens here, is that this BIOS function did neither touch ES
nor DI
, and because both happen to contain 0 on entry (*), the code that follows will be using a NULL-pointer. An instruction like mov cl, [es:di+3]
(or similar) will therefore read the 4th byte of linear memory which so happens to hold F0. The first vector of the InterruptVectorTable is the DivideException and points to somewhere in the BIOS code. A typical value being F000:EF6F (6F, EF, 00, F0).
(*) In your boot.asm on GitHub, you setup the DS
and ES
segment registers via push cs
push cs
pop es
pop ds
. This is dangerous! There's absolutely no guarantee that the CS
segment register will hold the 0 that you need in accordance with your ORG 7C00h
directive. It would be perfectly allright for the BIOS to reach your bootloader with CS:IP = 07C0h:0000h
. The only valid way to setup is:
xor ax, ax
mov ds, ax
mov es, ax
What to do next?
-
Always check the status that was reported by the system functions. The BIOS.ReturnDiskDriveParameters function 08h sets the carry flag if something was wrong. Don't omit a check for this situation!
-
There exists a newer BIOS function that will report the drive parameters for hard drives exclusively.
Read about the BIOS.GetDriveParameters function 48h in this wikipedia article. -
It would be a very safe assumption to just consider BytesPerSector = 512. Many people have never seen anything else and for an hobby OS it might be the simplification you need...