Ok so I wrote a test program that I was using to see if my LBA2CHS function worked correctly.
1. I read the disk parameters using INT 0x13, AH = 0x08
2. I convert the LBA address to CHS using the disk parameters
3. I read the sector from the disk using INT 0x13, AH = 0x02 (it fails here)
4. I search the sector for the signature (dw 0xDEAD, 0xBEEF)
The LBA Address im converting is 0x00200000 (1GB) on a 2GB disk
The conversion function does everything as expected
The function fails during the INT 0x13 call where AH = 0x02
Upon return from the Interrupt, Carry is set, AX = 0x0220; According to Ralph Brown's Interrupt List, When AH = 0x02 it means 'address mark not found'
Code: Select all
getDriveParams:
mov si, errDisk ; precuationary load, incase we cannot get disk parameters
push dx ; save boot drive
mov ah, 0x08 ; get drive paramters
xor di, di ; some BIOS crash if ES:DI is not 0000:0000
int 0x13 ; BIOS disk interrupt
jc printMsg ; if error, print message
convLBA2CHS:
and cx, 0x3F ; get Sectors Per Track
movzx si, cl ; save Sectors Per Track
movzx di, dh ; save Heads Per Cylinder
.getCylinder: ; Cylinder = LBA / (SPT * HPC)
mov ax, si ; set ax to SPT
mul di ; multiply SPT by HPS
mov cx, ax ; set CX to the result
mov dx, 0x0020 ; make (dx << 10) + ax = 0x00200000
xor ax, ax ; clear ax
div cx ; divide by (SPT * HPC)
mov cx, ax ; set CX to the result
shl cx, 6 ; this is the cylinder, so shift left 6 bits
.getSector: ; Sector = (LBA % SPT) + 1
mov dx, 0x0020 ; make (dx << 10) + ax = 0x00200000
xor ax, ax ; clear AX
div si ; divide by SPT
add cx, dx ; add result to CX
inc cx ; increment so we get a correct sector number
.getHead: ; Head = (LBA / SPT) % HPC
xor dx, dx ; ax already holds quotient of (LBA / SPT), so clear dx
div di ; divide by HPC
xchg dh, dl ; set DH to Head Number
pop ax ; get drive number into AX
mov dl, al ; restore drive number
readBeef:
mov di, 0x0005 ; try at least 5 times
mov bx, 0x9000 ; into memory location 0000:9000
.loop1:
mov ax, 0x0201 ; read 1 sector from disk
int 0x13 ; BIOS disk interrupt
jnc findBeef ; if no error, ensure sector is valid
xor ax, ax ; otherwise, reset disk
int 0x13 ; BIOS disk interrupt
dec di ; remove 1 remaining attempt
jnz .loop1 ; try again
mov si, errDisk ; otherwise, load error message and print