views:

171

answers:

3

I am using Bochs 2.4.5 to write a boot sector code. I use the INT 13H to read sectors from floppy. But I found that if the sector count to read > 72, the INT13 will fail. And the return code is AH=1. Below's the code and here is the INT13. The return code is AH=1.

Why can't the INT 13H read more than 72 sectors?

   xorb %ah, %ah
   xorb %dl, %dl
   int $0x13      # reset the floppy

   movw $0x8000, %ax
   movw %ax,%es        
   movw $0, %bx  # ES:BX is the buffer  
   movb $0x02, %ah
   movb $73, %al # how many sectors to read. 72 is ok, but >=73 is wrong.
   movb $0, %ch
   movb $1, %cl
   movb $0, %dh
   movb $0, %dl

   int $0x13

Thanks for any help.

Update

Following Matthew Slattery's instruction, I found the corresponding code. I listed it here for others as confused as me. The full code is located here.

7220       if ((drive > 1) || (head > 1) || (sector == 0) ||
7221           (num_sectors == 0) || (num_sectors > 72)) {
7222         BX_INFO("int13_diskette: read/write/verify: parameter out of range\n");
7223         SET_AH(1);
7224         set_diskette_ret_status(1);
7225         SET_AL(0); // no sectors read
7226         SET_CF(); // error occurred
7227         return;
7228       }
A: 

According to Standard Floppy Disks Supported by MS-DOS, the number of sectors per track on a 1.44 MB floppy disk is 18. Since 18*4 = 72, that might be a clue. It's possible that the BIOS doesn't want to read more than a certain number of tracks at once.

Greg Hewgill
Thanks for the clue. but why multiply by 4? I will keep on looking.
smwikipedia
+4  A: 

You're using Bochs, so the answer can be found in the Bochs BIOS source: the BIOS is performing an explicit range check on the number of sectors, and rejecting it if it is greater than 72 (or equal to 0).

Matthew Slattery
I am not quite a veteran of assembly language. Could you point out where the range check is?
smwikipedia
The link in my answer should take you to the right place, which is in C code: line 7211 of of `bios/rombios.c` (as of Bochs v2.4.5), which is actually the beginning of the relevant `case` statement inside `int13_diskette_function()` - the argument validation which includes the range check is the first `if (...)` within it, on lines 7220-7221.
Matthew Slattery
I found it as you instructed. Many thanks.
smwikipedia
A: 

The simple answer as pointed out by Matthew Slattery is that this is merely a range check performed by Bochs. This is based on a 2.88Mb floppy multi track floppy disk controller read which would be limited to 72 sectors.

The happy answer is that current BIOS due to backwards compatibility only support a single side read which for a 1.44Mb floppy is a maximum of 18 sectors. This depends on the starting sector so that the actual maximum would be up to the total remaining on the track. Booting and running from a USB flash drive is a simple alternative to the obsolete floppy disk for os dev. The same BIOS disk/diskette functions can be used depending on the boot drive identifier (dl register).

Mike Gonta