I’m trying to develop a bootloader that simply scans the root directory of its own boot medium (Floppy with FAT16) for a file and jumps to it. I finally ran into a problem that I found nowhere online and I feel like I’ve done something wrong: At the start of my code, when I read the root directory of the drive using INT 0x13, the carry flag is being set and after I made it print out the error code that comes in AH, I got 0x80 which seems to correspond to a disk timeout. I already tried hardcoding DL to 0x00 (Floppy #1 ‒ same as before), 0x01 (Floppy #2 ‒ AH=0x01 Illegal function) and 0x80 (Hard disk #1 ‒ there actually was data, but as expected, not the one from the floppy image). I also tried hardcoding the calculating of parameters and I tried only reading one sector. Below is the code that the error seems to be happening in:
BITS 16
jmp short bootload
nop
; Drive parameters
bootload:
; Segment registers
mov ax, 0x07C0+544
cli
mov ss, ax
mov sp, 4096
sti
mov ax, 0x07C0
mov ds, ax
mov es, ax
; Boot device
mov [bootdev], dl
; Calculations (I just hardcoded them in this example to make it easier to understand)
mov byte [rootdirsize], 14
mov byte [rootdirchssec], 1
mov word [rootdirchstrack], 1
; Read sectors
mov ah, 0x02 ; Read sectors
mov al, byte [rootdirsize] ; The amount of sectors needed by the root dir entries
; (RootDirEntries / 16)
mov dl, byte [bootdev]
mov dh, 0 ; Heads are ignored... yet
mov cl, byte [rootdirchssec] ; Sector number of the root dir in CHS
and cx, 0b0000_0000_0011_1111 ; Sector only uses bits 0-5 of CX
mov bx, word [rootdirchstrack] ; Track number of the root dir in CHS
shl bx, 6 ; Track uses bits 6-15 of CX
or cx, bx ; Transfer to CX
mov bx, 0x0100 ; Segment where it is loaded
mov es, bx
mov bx, 0 ; Offset = 0
int 0x13
jc disk_error ; CF = error
jmp $ ; the rest of the bootloader
disk_error:
mov al, ah ; AH is the error code
mov ah, 0x0E ; print it
int 0x10 ; returns 'Ç' = 0x80 = timeout
jmp $
data:
bootdev db 0
rootdirsec dw 0
rootdirchssec db 0
rootdirchstrack dw 0
rootdirsize db 0
times 510-($-$$) db 0
dw 0xAA55
The real code is of course much longer, I tried to write only the parts essential to the problem. Other details that may help:
- I’m using NASM
- I’m testing on VMWare Workstation with a virtual floppy
- Other code works fine (for example, printing stuff or interacting with the keyboard)
- I did multiple snapshots to inspect the virtual memory with a hex editor, the disk data (apart from the bootcode) was never loaded into memory