IMPORTANT: this code will render media unusable without formatting or recovery. Use unused, empty, or unneeded media.
It should be straightforward to replicate BIOS interrupt functions' behavior but the information about it online is lackluster on the real life use scenarios. So I wrote code to read 2.5" hdd drive identification info, which is a function of int 13h. I get a hang at the stage of checking for the DRQ (data ready for query?) bit of the 0x1f7 status register. When I comment out the check-DRQ loop the code proceeds but the data is all 0s, possibly because it was not read. I've tried varying slave and master bit, and the primary/secondary bus... The secondary bus goes through the DRQ check but the data seems to be all 1s. Importantly, int 13h on the same drive and the same machine works fine. Does anyone know if there's a way to: a) know ide location (primary/secondary, master/slave) of the hdd that is booting, and then b) test it's there without reading from it, and c) figure out how to get the DRQ bit to green? Will error register be meaningful before DRQ ones out?
Interestingly, BIOS shows me 3 HDDs aside from USB, DVD, and LAN entries, but I only have two slots for hard drives. And I can never plug-in my HDD so that it's HDD1. Bizarre. Could this be related?
Here's my bootable code to read from ATA HDD primary master using control registers and to print several bytes of it on screen as binary numbers:
[bits 16]
[org 0x7c00]
xor ax, ax
cli
mov dx, 0x1f7
m1:
in al, dx
test al, 010000000b
jnz m1
mov dx, 0x1f6
mov al, 0xE0 ; LBA mode - not needed for this?
out dx,al
mov dx, 0x1f7
m2:
in al, dx
test al, 010000000b ; wait for BSY to be 0
jnz m2
test al, 001000000b ; wait for DRDY to be 1
jz m2
mov dx, 0x1f7
mov al, 0xEC ; identify drive command
out dx, al
mov dx, 0x1f7
m3:
in al, dx
test al, 010000000b
jnz m3
mov dx, 0x1f7
m4:
in al, dx
test al, 000001000b ; this test for DRQ never turns 1
jz m4
mov ax, 0
mov es, ax
mov di, 0x7e00 ;save the identification to 0x7e00
mov dx, 0x1f0
mov cx, 256
rep insw
mov ax, 0xb800 ; display in table of binary bytes
mov es, ax
mov di, 0
mov ax, 0
mov ds, ax
mov si, 0x7e00 ;starting RAM address to read
mov cx, 0
mov dl, 20 ;how many lines to print
morelines:
mov bh, 7 ;how many bytes per line
morebytes:
mov ah, [ds:si]
mov bl, 8 ;counter for bits of each byte to print
morebits:
shl ah, 1
mov al, 48
jnc zero
mov al, 49
zero:
mov [es:di], al
inc di
inc di
dec bl
jnz morebits
mov al, 32
mov [es:di], al
inc di
inc di
inc si
dec bh
jnz morebytes
add cx, 80*2
mov di, cx
dec dl
jnz morelines
times 510 - ($ - $$) db 0
dw 0xaa55