A question that I've wondered for a long time and nothing that I've read has addressed:
Does the BIOS fill in the real values in the drive info area (from what it auto-detects assuming a newish BIOS) once the boot sector is loaded into memory, or do you have to figure out the values yourself? It seems a bit pointless for the BIOS to do the auto-detection and then not bother telling you what it found, but I'm quite used to that sort of thing by now
Just in case someone thinks I'm talking about the floppy drive parameter block (offset found at int 1e location), I'm talking about the one that starts at offset 3 in your boot sector.
Boot Sector Drive Parameter Block (Edit: Int13/08 not workin
Re:Boot Sector Drive Parameter Block
Hi,
The "BIOS Parameter Block" (BPB) that starts at offset 0x0B in the first sector is not used by the BIOS at all. Instead it contains values that DOS uses, and is entirely optional if you don't need compatibility with Microsoft OSs.
From my experience, without a correct BPB Windows 98 and earlier Microsoft OS's won't even format the disk, while Windows XP (and Linux, etc) will.
For floppies, the BIOS itself doesn't need to know how many sectors per track, total number of sectors, etc as it uses "number of sectors from starting CHS" only. If you ask the BIOS to read or write more sectors than exists, it'll try to transfer them until the floppy hardware returns a "sector not found" error (which the BIOS returns to it's caller).
The only values that the BIOS does need is timing data (head settle time, step rate time, etc) at the "int 0x1E" vector, which are set to default values at boot (and usually updated by the OS soon after).
For this reason the BIOS is more flexible than DOS or DOS's BPB as it will work with non-standard floppy formats, including non-sequential sector numbering and/or a non-constant sectors per track (these techniques were used once upon a time for copy protection). In general DOS supports a standardized subset of what the BIOS supports, and the BIOS supports a standardized subset of what the hardware itself supports. By writing software that uses the floppy disk controller directly incredibly strange arrangements are possible - the only problem is that you need to know what's going on before you can read it.
Cheers,
Brendan
The "BIOS Parameter Block" (BPB) that starts at offset 0x0B in the first sector is not used by the BIOS at all. Instead it contains values that DOS uses, and is entirely optional if you don't need compatibility with Microsoft OSs.
From my experience, without a correct BPB Windows 98 and earlier Microsoft OS's won't even format the disk, while Windows XP (and Linux, etc) will.
For floppies, the BIOS itself doesn't need to know how many sectors per track, total number of sectors, etc as it uses "number of sectors from starting CHS" only. If you ask the BIOS to read or write more sectors than exists, it'll try to transfer them until the floppy hardware returns a "sector not found" error (which the BIOS returns to it's caller).
The only values that the BIOS does need is timing data (head settle time, step rate time, etc) at the "int 0x1E" vector, which are set to default values at boot (and usually updated by the OS soon after).
For this reason the BIOS is more flexible than DOS or DOS's BPB as it will work with non-standard floppy formats, including non-sequential sector numbering and/or a non-constant sectors per track (these techniques were used once upon a time for copy protection). In general DOS supports a standardized subset of what the BIOS supports, and the BIOS supports a standardized subset of what the hardware itself supports. By writing software that uses the floppy disk controller directly incredibly strange arrangements are possible - the only problem is that you need to know what's going on before you can read it.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:Boot Sector Drive Parameter Block
Yeah, like I said, I know about the floppy block (though thanks still for confirming that stuff). So basically with the hard drives it's up to me to figure out how the drive is laid out? Also, is it safe to use Int 13 with AH = 42h (Extended Read), which allows me to just give the sector number, or did that never make it into the current standard (standard in the sense that most BIOSes implement it)?
Ref: http://lrs.fmi.uni-passau.de/support/doc/interrupt-57/RB-0670.HTM
The main reason I'm asking about this is that since I switched to loading my second stage by assuming head 0 / cylinder 0 / sector 8 for where sector 8 actually is my code has been failing (the hard drive controller returns an error), so I may have to go back to calculating it to be safe.
Ref: http://lrs.fmi.uni-passau.de/support/doc/interrupt-57/RB-0670.HTM
The main reason I'm asking about this is that since I switched to loading my second stage by assuming head 0 / cylinder 0 / sector 8 for where sector 8 actually is my code has been failing (the hard drive controller returns an error), so I may have to go back to calculating it to be safe.
Re:Boot Sector Drive Parameter Block
The Linear Block Address Extended BIOS Disk Functions are supposedly mainstream since 1997, systems before or around then may not support them however.
There is a more important reason to use them on harddrives then simply having linear addressing though, that being that the old CHS functions can't read more than 8GB, if you have a drive larger than that then anything beyond 8GB is off limits, the LBA extensions shatter it with support for thousands of terabytes.
If you want to support older computers, or at least fail gracefully, you should make sure the extensions are supported first (There is a function to verify support) then optionally fall back to CHS if they aren't.
In regards to drive data, both the extended and CHS functions provide "Get Drive Parameters" functions which will tell you the geometry/block-count. As for determining the number of drives in the system, the CHS "Get Drive Parameters" function tells you but I'll have to get back to you when I've learned how the value it gives works .
There is a more important reason to use them on harddrives then simply having linear addressing though, that being that the old CHS functions can't read more than 8GB, if you have a drive larger than that then anything beyond 8GB is off limits, the LBA extensions shatter it with support for thousands of terabytes.
If you want to support older computers, or at least fail gracefully, you should make sure the extensions are supported first (There is a function to verify support) then optionally fall back to CHS if they aren't.
In regards to drive data, both the extended and CHS functions provide "Get Drive Parameters" functions which will tell you the geometry/block-count. As for determining the number of drives in the system, the CHS "Get Drive Parameters" function tells you but I'll have to get back to you when I've learned how the value it gives works .
Re:Boot Sector Drive Parameter Block
Oh, ok, I missed the function to get those details, thanks for that one. I'll use the extended functions for now (while testing is confined to my own PC) and probably sort out a fall-back position later, though I doubt my OS will be run on a PC older than 1997 (mainly as ones a bit newer are dirt cheap ).
Edit:
I appear to have found my problem... Virtual PC is apparently reporting a sectors per track number less than 8 (just about to run a quick boot sector I wrote that'll dump all the info out for me). I'm guessing my old CHS conversion using what I assumed would be good values was just coming up with a freak result that happened to be a valid place on the disk, hence loading the wrong data.
Progress report soon.
Edit:
I appear to have found my problem... Virtual PC is apparently reporting a sectors per track number less than 8 (just about to run a quick boot sector I wrote that'll dump all the info out for me). I'm guessing my old CHS conversion using what I assumed would be good values was just coming up with a freak result that happened to be a valid place on the disk, hence loading the wrong data.
Progress report soon.
Re:Boot Sector Drive Parameter Block
Well great, function AH=08h reports that there are 0 sectors per track. *mumbles about dodgy BIOS calls* Gonna see what other ones say.
My code tells me that the function returns the following:
Number of drives : 16
Heads (selected drive) : 0
Sectors per track (selected drive) : 0
So my assumption now is that there is something wrong with my test code, but the only part I can see having a problem is my code to convert an 8-bit binary number to a two character text version of the hex equivalent (so that 00010111 would be printed as 17). I went through this code on paper and it all worked fine, and the fact that I'm getting real numbers out of it rather than random characters seems to indicate it's ok, though I did write it on the fly.
It basically takes the number in AL and returns the text version of the hex in AX.
So that's where I am, either the BIOS is giving me stupid values back or my code is broke.
Edit: That procedure gives the two characters the wrong way round, so I've fixed that, obviously not getting the right values still though
Edit 2: Ok, I think that's enough for today. It has know started giving me an error when it calls the function. God knows what's going on. Error 1: Invalid function or parameter. AH is 08h and DL is the drive number (80h), what could possibly be wrong with that? >:(
My code tells me that the function returns the following:
Number of drives : 16
Heads (selected drive) : 0
Sectors per track (selected drive) : 0
So my assumption now is that there is something wrong with my test code, but the only part I can see having a problem is my code to convert an 8-bit binary number to a two character text version of the hex equivalent (so that 00010111 would be printed as 17). I went through this code on paper and it all worked fine, and the fact that I'm getting real numbers out of it rather than random characters seems to indicate it's ok, though I did write it on the fly.
Code: Select all
bin2hex:
MOV AH, AL
AND AL, 00001111b ; Lower digit
AND AH, 11110000b ; Higher digit
SHR AH, 4 ; Make upper digit correct
ADD AL, 48 ; Turn into ASCII character
ADD AH, 48 ; And again
RETN
So that's where I am, either the BIOS is giving me stupid values back or my code is broke.
Edit: That procedure gives the two characters the wrong way round, so I've fixed that, obviously not getting the right values still though
Edit 2: Ok, I think that's enough for today. It has know started giving me an error when it calls the function. God knows what's going on. Error 1: Invalid function or parameter. AH is 08h and DL is the drive number (80h), what could possibly be wrong with that? >:(
Re:Boot Sector Drive Parameter Block
Ok, this is really annoying me now. I have this:
And I get back error 1 (invalid function or parameter). Those two parameters are the only ones required by function 08h (get disk params), so I can't see what could possibly be wrong. Any thoughts on this? :-\
As a sidenote, my bin2hex routine got severely shortened by not dealing with AH and AL as seperate things.
Edit:
When tried with the floppy drive (DL = 00 rather than 80h), it returns that there is 1 drive and that the selected drive (which is apparently the only one) has 0 heads and 0 sectors per track. I would assume it is virtual pc screwing with me, but if OSes can boot under it then it must work somehow.
Code: Select all
XOR AX, AX
MOV AH, 08h
MOV DL, 80h
INT 13h
As a sidenote, my bin2hex routine got severely shortened by not dealing with AH and AL as seperate things.
Edit:
When tried with the floppy drive (DL = 00 rather than 80h), it returns that there is 1 drive and that the selected drive (which is apparently the only one) has 0 heads and 0 sectors per track. I would assume it is virtual pc screwing with me, but if OSes can boot under it then it must work somehow.
Re:Boot Sector Drive Parameter Block (Edit: Int13/08 not wor
Have you actually attached a hard drive to the emulator? I think I recall having a similar problem where the values I was getting were 0 but it was caused by other operations manipulating the values accidentally setting them to 0.
You can also simply read 0040:0075 (byte) [0x475 Linear] to get the number of hard drives, I'm reasonably sure it is a standard for the layout of the BIOS Data Segment but for reliability Int 0x13 may be better.
You can also simply read 0040:0075 (byte) [0x475 Linear] to get the number of hard drives, I'm reasonably sure it is a standard for the layout of the BIOS Data Segment but for reliability Int 0x13 may be better.
Re:Boot Sector Drive Parameter Block (Edit: Int13/08 not wor
Yeah, a hard drive is attached, it's what it's booting from. I really should probably try it on real hardware, but my spare drive is at home right now, and I'm at uni, could always ask my gf to pick it up I suppose.