Floppy controller failure during real mode int 13h (ah=02h)
Posted: Mon Aug 11, 2008 4:23 am
Hi there,
while trying to write my own bootloader, I've failed to fix a problem reading from the floppy disk I'm booting from.
Some background info at first:
I'm using VirtualBox OSE to test my OS. But I've tried my code on Qemu, too, but it works neither on VirtualBox nor on Qemu.
My bootloader is only meant to copy data from the booting floppy disk to memory. It is using int 0x13 (with ah=0x02) for this task. But whenever I start reading from the 19th (0x13th) or any higher block inside a cylinder, the interrupt returns status code 0x20 - "controller failure".
Here is some example code
This code prints , "@" is the 0x40th ASCII character, therefore the return status code is 0x20. According to Ralf Brown's Interrupt List this indicates a controller failure (whatever that means exactly).
Some more testing later, I knew that my code failed, whenever cl (the number of the sector I start reading from) is greater than 0x12 (18).
I do not have an explanation for this. The only relevant meaning of the number 18 I know is the number of blocks per head on floppies. But no matter what I alter the head number (dh) it either returns 0x20 or 0x01 (invalid function number or invalid params).
Any help would be appreciated.
Greetings
Out Of The Stream
Edit: I'm really wondering if the block number I'm starting to read from is interpreted from the start of that cylinder or from the start of the head
while trying to write my own bootloader, I've failed to fix a problem reading from the floppy disk I'm booting from.
Some background info at first:
I'm using VirtualBox OSE to test my OS. But I've tried my code on Qemu, too, but it works neither on VirtualBox nor on Qemu.
My bootloader is only meant to copy data from the booting floppy disk to memory. It is using int 0x13 (with ah=0x02) for this task. But whenever I start reading from the 19th (0x13th) or any higher block inside a cylinder, the interrupt returns status code 0x20 - "controller failure".
Here is some example code
Code: Select all
[BITS 16]
global _start
_start:
mov ax,0x2000
mov ss,ax
mov ax,0xFFFF
mov sp,ax
mov bp,ax
;demo output to see how far we get
mov bx,0x0007
mov ax,0x0E76
int 0x10
mov al,0x77
int 0x10
;read first 18 blocks
mov ax,0x0212
mov bx,0x1000
mov es,bx
mov bx,0x0000
mov cx,0x0101
mov dx,0x0000
int 0x13
jc error
;another demo output
mov ax,0x0E78
mov bx,0x0007
int 0x10
;read the remaining 18 blocks from the same track
mov ax,0x0212
mov bx,0x1240
mov es,bx
mov bx,0x0000
mov cx,0x0113
mov dx,0x0000
int 0x13
jc error
;more demo output
mov ax,0x0E79
mov bx,0x0007
int 0x10
mov al,0x7A
int 0x10
;infinite loop
rpt:
nop
jmp rpt
error:
;store status code
mov cl,ah
;output a space
mov ah,0x0E
mov bx,0x0007
mov al,0x20
int 0x10
;output the error code. It is increased by 0x20 to assure that it is a printable character.
mov al,cl
add al,0x20
int 0x10
jmp rpt
Code: Select all
vwx @
Some more testing later, I knew that my code failed, whenever cl (the number of the sector I start reading from) is greater than 0x12 (18).
I do not have an explanation for this. The only relevant meaning of the number 18 I know is the number of blocks per head on floppies. But no matter what I alter the head number (dh) it either returns 0x20 or 0x01 (invalid function number or invalid params).
Any help would be appreciated.
Greetings
Out Of The Stream
Edit: I'm really wondering if the block number I'm starting to read from is interpreted from the start of that cylinder or from the start of the head