ATA IDE DRIVER
Posted: Fri Dec 31, 2004 12:00 pm
HELLO,
I AM DEVELOPING A IDE DEVICE DRIVER, AND MY HARD DISK IS ATTACH AT SECONDARY MASTER OF IDE.
THE BELOW CODE IS A PORTION OF BOOT SECTOR CODE OF MY DRIVER THAT READS A SINGLE SECTOR. MY PROBLEM WITH THIS CODE IS THAT IT IS EXECUTING IN ENDLESS LOOP, IN SHORT IT DOES NOT WORK. MY GUESS IS THAT THE VARIABLE "drive" is having wrong value.
In the upper part of my code I have this code
%define drive bp+40
and in the start of the code I have this
mov bp, 7C00H
mov [bp+40], dl ;THEY SAY BIOS PUT THE VALUE IN DL WHERE IT BOOTS.
I HAVE TRIED THIS VALUES TO PUT IN drive, 80H, 81H, 82H, 83H, 8EH, 8FH BUT TO NO AVAIL.
; Read one sector from disk, using LBA
; input: EAX - 32-bit DOS sector number
; ES:BX - destination buffer
; (will be filled with 1 sector of data)
; output: ES:BX points one byte after the last byte read.
; EAX - next sector
mov cx, 1 ;one sector to read
readDisk: push dx
push si
push di
read_next: push eax ; would ax be enough?
mov di, sp ; remember parameter block end
;--- db 0x66 ; operand size override (push dword)
push byte 0 ;XXX ; other half of the 32 bits at [C]
; (did not trust "o32 push byte 0" opcode)
push byte 0 ; [C] sector number high 32bit
push eax ; [8] sector number low 32bit
push es ; [6] buffer segment
push bx ; [4] buffer offset
push byte 1 ; [2] 1 sector (word)
push byte 16 ; [0] size of parameter block (word)
mov si, sp
mov dl, [drive]
mov ah, 42h ; disk read
int 0x13
mov sp, di ; remove parameter block from stack
; (without changing flags!)
pop eax ; would ax be enough?
jnc read_ok ; jump if no error
push ax ; !!
xor ah, ah ; else, reset and retry
int 0x13
pop ax ; !!
jmp read_next
read_ok: inc eax ; next sector
add bx, word [bsBytesPerSec]
jnc no_incr_es ; if overflow...
mov dx, es
add dh, 0x10 ; ...add 1000h to ES
mov es, dx
no_incr_es: pop di
pop si
pop dx
ret
THANK YOU VERY MUCH IN ADVANCE
I AM DEVELOPING A IDE DEVICE DRIVER, AND MY HARD DISK IS ATTACH AT SECONDARY MASTER OF IDE.
THE BELOW CODE IS A PORTION OF BOOT SECTOR CODE OF MY DRIVER THAT READS A SINGLE SECTOR. MY PROBLEM WITH THIS CODE IS THAT IT IS EXECUTING IN ENDLESS LOOP, IN SHORT IT DOES NOT WORK. MY GUESS IS THAT THE VARIABLE "drive" is having wrong value.
In the upper part of my code I have this code
%define drive bp+40
and in the start of the code I have this
mov bp, 7C00H
mov [bp+40], dl ;THEY SAY BIOS PUT THE VALUE IN DL WHERE IT BOOTS.
I HAVE TRIED THIS VALUES TO PUT IN drive, 80H, 81H, 82H, 83H, 8EH, 8FH BUT TO NO AVAIL.
; Read one sector from disk, using LBA
; input: EAX - 32-bit DOS sector number
; ES:BX - destination buffer
; (will be filled with 1 sector of data)
; output: ES:BX points one byte after the last byte read.
; EAX - next sector
mov cx, 1 ;one sector to read
readDisk: push dx
push si
push di
read_next: push eax ; would ax be enough?
mov di, sp ; remember parameter block end
;--- db 0x66 ; operand size override (push dword)
push byte 0 ;XXX ; other half of the 32 bits at [C]
; (did not trust "o32 push byte 0" opcode)
push byte 0 ; [C] sector number high 32bit
push eax ; [8] sector number low 32bit
push es ; [6] buffer segment
push bx ; [4] buffer offset
push byte 1 ; [2] 1 sector (word)
push byte 16 ; [0] size of parameter block (word)
mov si, sp
mov dl, [drive]
mov ah, 42h ; disk read
int 0x13
mov sp, di ; remove parameter block from stack
; (without changing flags!)
pop eax ; would ax be enough?
jnc read_ok ; jump if no error
push ax ; !!
xor ah, ah ; else, reset and retry
int 0x13
pop ax ; !!
jmp read_next
read_ok: inc eax ; next sector
add bx, word [bsBytesPerSec]
jnc no_incr_es ; if overflow...
mov dx, es
add dh, 0x10 ; ...add 1000h to ES
mov es, dx
no_incr_es: pop di
pop si
pop dx
ret
THANK YOU VERY MUCH IN ADVANCE