NASM: Disk read timeout

拈花ヽ惹草 提交于 2019-12-24 00:02:50

问题


Trying to read data from disk (from the same file), loading 2 additional 512-byte sectors into memory. Disk read function as is:

; read DH sectors to ES:BX from drive DL
disk_read:
    push dx 

    push bx  ; Tried to check if disk is ready first, this code runs without errors
    mov ah, 0x10
    int 0x13
    jc disk_not_ready
    mov bx , DISK_CURRENT_STATUS_MSG
    call print_string
    mov bx, 0
    mov bl , ah
    call print_hex
    pop bx

    mov ah , 0x42   ; BIOS read sector function
    mov al , dh     ; Read DH sectors
    mov ch , 0x00   ; Select cylinder 0
    mov dh , 0x00   ; Select head 0
    mov cl , 0x02   ; Start reading from second sector (i.e.
                    ; after the boot sector)

    int 0x13        ; BIOS interrupt to read from disk
    jc disk_read_error_general  ; Jump if error (i.e. carry flag set)
    pop dx                      ; Restore DX from the stack
    cmp dh , al                 ; if AL (sectors read) != DH (sectors expected)
    jne disk_read_error_number_of_sectors_read_differs  ; display error message
    cmp dh , al                 ; if AL (sectors read) != DH (sectors expected)
    je disk_read_success        ; display success message

    disk_read_exit:
        ret

disk_read_success:
    mov bx , DISK_READ_SUCCESS_MSG
    call print_string
    jmp disk_read_exit

disk_read_error_general:
    mov bx , DISK_READ_ERROR_GENERAL_FAIL_MSG
    call print_string
    mov bx , DISK_CURRENT_STATUS_MSG
    call print_string
    mov bx, 0
    mov bl , ah
    call print_hex
    jmp $

disk_not_ready:
    mov bx , DISK_NOT_READY_ERROR_MSG
    call print_string
    jmp $

disk_read_error_number_of_sectors_read_differs:
    mov bx , DISK_READ_ERROR_NUMBER_OF_SECTORS_DIFFERS_MSG
    call print_string
    jmp $

; Variables
DISK_READ_SUCCESS_MSG:
    db "Disk read were successful!" , 0

DISK_NOT_READY_ERROR_MSG:
    db "Disk is not ready for reading!" , 0

DISK_READ_ERROR_GENERAL_FAIL_MSG:
    db "Disk read error, carry in CF were not set!" , 0

DISK_READ_ERROR_NUMBER_OF_SECTORS_DIFFERS_MSG:
    db "Disk read error, number of sectors read differs from requested!" , 0

DISK_CURRENT_STATUS_MSG:
    db "Disk status:" , 0

The calling code:

; Read some sectors from the boot disk using our disk_read function
[org 0x7c00]


mov [BOOT_DRIVE] , dl

mov bp , 0x8000
mov sp , bp 
mov bx , 0x9000

mov dh , 3  ; Load 3 sectors to 0x0000 (ES):0x9000 (BX)
            ; from the boot disk.

mov dl , [BOOT_DRIVE]
call disk_read

mov dx , [0x9000]
call print_hex  ; Print out the first loaded word , which
                ; we expect to be 0xdada , stored
                ; at address 0x9000

mov dx , [0x9000+512]   ; Also , print the first word from the
call print_hex          ; 2 nd loaded sector : should be 0xface
jmp $

%include "print_string.asm" 
%include "print_hex.asm"    
%include "disk_read.asm"

; Global variables
BOOT_DRIVE: db 0

; Bootsector padding
times 510-($-$$) db 0
dw 0xaa55

times 256 dw 0xdada
times 256 dw 0xface

Why first disk status 0x0380 and how to fix this timeout error (error codes were checked from here: http://www.ctyme.com/intr/rb-0606.htm)? Hard drive is of SSD type, but probably it's not relevant here since addressing back-portable to regular drives (NASM: how to access ssd drive correctly?). Update print_string:

; Print string function, note that this code written after jmp $ instruction,
; otherwise the string were printed twice
print_string:
    push ax     ; pushing two registers that used onto a stack
    push bx

    mov ah , 0x0e       ; int 10/ ah = 0 eh -> scrolling teletype BIOS routine

    loop:
        mov al, [bx]    ; put ascii value in bx (lower bits) into al
        int 0x10        ; print what in al
        inc bx          ; increment bx through the string
        cmp al, 0       ; check if passed null-terminator
        jnz loop        ; loop until null terminator met

    mov al, 0x0a    ; line feed and carriage return added after line
    int 0x10
    mov al, 0x0d
    int 0x10

    pop bx ; popping two registers that used from stack
    pop ax
    ret

print_hex:

; Print hex function, note that this code written after jmp $ instruction,
; otherwise the string were printed twice
print_hex:
    push ax     ; pushing registers that used onto a stack
    push dx
    push bx
    push cx
    push si

    mov si, 4
    mov bx, dx

    print_hex_loop:
        dec si
        cmp si, -1
        je print_hex_loop_exit
        mov dx, 0
        mov ax, bx
        mov cx, 16
        div cx
        mov bx, ax
        mov ah, 0x0e    ; int 10/ ah = 0 eh -> scrolling teletype BIOS routine
        add dx, 0x0030
        cmp dx, 0x0039
        jg add_0x27_to_letter

    print_hex_loop_continue:
        mov al, dl
        ;int 0x10       ; print what in al
        mov [HEX_OUTPUT_STR+si+2], al
        jmp print_hex_loop

    add_0x27_to_letter:
        add dx, 0x0027
        jmp print_hex_loop_continue

    print_hex_loop_exit:
        mov bx, HEX_OUTPUT_STR
        call print_string

    pop si ; popping registers that used from stack
    pop cx  ; popping registers that used from stack
    pop bx
    pop dx
    pop ax
    ret

HEX_OUTPUT_STR:
    db "0x0000", 0

Update 2: After fixing print_hex function to print with dx and not bx (in disk_read.asm) (carefully pushed and popped from stack near use), and changing from int 13/ah=0x42 to int 13/ah=0x02 (otherwise I was getting status 01h="invalid function in AH or invalid parameter"), I've got disk status 0Ch which is "unsupported track or invalid media". Any thoughts why it can be?

来源:https://stackoverflow.com/questions/59338886/nasm-disk-read-timeout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!