2023-03-18

Solved BIOS doesn't read the sectors

Answer: After investigating I found out that the drive given as input was the wrong one. The memory cell containing it was overwritten by another function. To anyone in the future having the same problem check ALL inputs, even when they seem to be guaranteed right.

Problem: The BIOS function ah = 2, int 0x13 raises an carry flag and reads 0 segments on the second read. After the faulty read ax is set to 0x2000, so 0 segments were read and it doesn't tell if the BIOS function isn't supported or something. My Image/disk has 2 heads and 36 Sectors per track (tells me a BIOS function). Is there a way to fix this?

If needed the function code:

param_loadlba_sectors: db 1
param_loadlba: dw 0
param_loadlbabuffer: dw 0
load_with_lba:
    ;
    ;   Convert lba to chs
    ;
    pusha
    mov ax, [param_loadlba]
    div BYTE[self_sectperside]
    ; temp, sector = lba / sect per side, lba % sect per side + 1
    mov BYTE[LODAWITHLBATEMP], al
    inc ah
    mov BYTE[LOADWITLBASECTOR], ah

    mov ah, 0
    mov al, BYTE[LODAWITHLBATEMP]
    div BYTE[self_heads]
    ; cylinder, head = temp / heads, temp % heads
    mov BYTE[LOADWITHLBACYLINDER], al
    mov BYTE[LOADWITHLBAHEAD], ah
    ;
    ;   Load
    ;
    ; drive
    mov dl, [start_drive]
    ; cylinder
    mov cl, BYTE[LOADWITHLBACYLINDER]
    ; diskside
    mov dh, BYTE[LOADWITHLBAHEAD]
    ; sector
    mov cl, [LOADWITLBASECTOR]
    ; number of sectors
    mov al, BYTE[param_loadlba_sectors]
    ; es = 0
    mov bx, 0
    mov es, bx
    ; bx = *param_loadlbabuffer
    mov bx, WORD[param_loadlbabuffer]
    mov ah, 0x2
    clc
    int 0x13
    ; check if error
    jnc NOERROR
    mov BYTE[error], FILEERROR
    NOERROR:
    mov BYTE[param_loadlba_sectors], 1
    popa
    ret
LODAWITHLBATEMP: db 0
LOADWITLBASECTOR: db 0
LOADWITHLBAHEAD: db 0
LOADWITHLBACYLINDER: db 0

After the faulty call I checked the state of 'local variables' and it calculated that the cylinder 0, head 0 and sector 4 was read (The labels at the bottom).

If it's important I load on the first call some code into the address 0x500 and jump to it (I verified the code there is executed) even if I read the function call a second time before the jump it raises the carry flag.

I use qemu and nasm.

For



No comments:

Post a Comment