BIOS INT 0x13 partial reads
Posted: Sat Sep 20, 2025 7:59 am
Hello everyone!
I've been wondering whether it's necessary, practical or even possible to reliably handle partial reads with BIOS INT 0x13 functions AH=0x02 and AH=0x42.
According to the Ralph Brown Interrupt List (RBIL), if an error occurs (CF set), the number of sectors successfully transferred is stored in AL for function AH=0x02 and in the Disk Address Packet (DAP) for function AH=0x42. However, the BIOS interfaces have never been standardized and the various BIOS implementations tend to be buggy, often in the most unexpected ways. As such, I expect the reliability of the returned sector count to be questionable, especially in case it's not used by mainstream OSes and bootloaders.
Given that I have setup several virtual machines with real BIOS ROMs in PCem, I tried to conduct some tests to determine how various BIOS implementations handle partial reads. Specifically, I tried various reads that start near the end of the last head of the last cylinder and extend beyond the end of the disk (known CHS geometry: 243, 16, 63; tried CHS start values: 242, 15, <63), expecting the BIOS to return a partial read (CF set and AL containing a short sector count). However, all BIOSes that I tested in PCem returned a successful read. In constrast, QEMU returned a short read with AL set as expected. So I still haven't been able to determine how do BIOSes handle short reads.
As for the necessity of handling short reads, there are several conditions that can cause a partial read. Most of them are probably non-recoverable / non-resumable (e.g. bad sectors), but some probably allow for resuming from the next sector after the cut-off (e.g. possibly request exceeding track boundary or timing issues). That said, I already split read requests to track boundaries for CHS and at between 120 and 127 sectors for LBA (due to alignment for 512e devices).
So to recap, even I adhere to the most strict limits imposed by BIOS implementations, is it still necessary to handle short reads and is it possible to do it reliably? Alternatively, does anyone have any ideas how to induce a partial read in an emulated environment?
Thanks in advance!
I've been wondering whether it's necessary, practical or even possible to reliably handle partial reads with BIOS INT 0x13 functions AH=0x02 and AH=0x42.
According to the Ralph Brown Interrupt List (RBIL), if an error occurs (CF set), the number of sectors successfully transferred is stored in AL for function AH=0x02 and in the Disk Address Packet (DAP) for function AH=0x42. However, the BIOS interfaces have never been standardized and the various BIOS implementations tend to be buggy, often in the most unexpected ways. As such, I expect the reliability of the returned sector count to be questionable, especially in case it's not used by mainstream OSes and bootloaders.
Given that I have setup several virtual machines with real BIOS ROMs in PCem, I tried to conduct some tests to determine how various BIOS implementations handle partial reads. Specifically, I tried various reads that start near the end of the last head of the last cylinder and extend beyond the end of the disk (known CHS geometry: 243, 16, 63; tried CHS start values: 242, 15, <63), expecting the BIOS to return a partial read (CF set and AL containing a short sector count). However, all BIOSes that I tested in PCem returned a successful read. In constrast, QEMU returned a short read with AL set as expected. So I still haven't been able to determine how do BIOSes handle short reads.
As for the necessity of handling short reads, there are several conditions that can cause a partial read. Most of them are probably non-recoverable / non-resumable (e.g. bad sectors), but some probably allow for resuming from the next sector after the cut-off (e.g. possibly request exceeding track boundary or timing issues). That said, I already split read requests to track boundaries for CHS and at between 120 and 127 sectors for LBA (due to alignment for 512e devices).
So to recap, even I adhere to the most strict limits imposed by BIOS implementations, is it still necessary to handle short reads and is it possible to do it reliably? Alternatively, does anyone have any ideas how to induce a partial read in an emulated environment?
Thanks in advance!