如何用DMA读写扇区?这个程序有什么错误?
INCLUDE Irvine16.inc
.data
sector db 512 dup(0)
msg1 db 'Starting DMA transfer...',0dh,0ah,0
msg2 db 'DMA transfer end',0dh,0ah,0
errmsg db 'error!',0dh,0ah,0
.code
InitDMA proc
pusha
cli
mov al,05
out 0ah,al ;屏蔽通道1
mov al,0
out 0ch,al ;清先后触发器
xor eax,eax
xor ebx,ebx
mov ebx,seg sector
lea eax,sector
shl ebx,4
add eax,ebx
out 02,al
shr eax,8
out 02,al
shr eax,8
out 83h,al
mov al,0ffh ;写字节计数器 512字节
out 03h,al
mov al,1
out 03h,al
mov al,01000101b ;写工作方式寄存器 通道1,写传送,单字节传送,地址加1
out 0bh,al
mov al,40h ;写命令字寄存器,DACK和DREQ低有效
out 08h,al
mov al,01
out 0ah,al
;初始化DMA完成
sti
popa
ret
InitDMA endp
ReadDMA proc
pusha
mov dx,1f7h ;开始向ATA接口发命令,DMA读
xor cx,cx
not cx
CheckReady:
in al,dx
and al,0c0h
.if al==40h ;IF(BSY=0&DRDY=1) GO
jmp GetData
.endif
;lea dx,msg1
;call WriteString
loop CheckReady
jmp Err
GetData: ;lea dx,msg1
;call WriteString
mov dx,1f2h
mov al,1
out dx,al
mov dx,1f3h
out dx,al
mov dx,1f4h
mov al,0
out dx,al
mov dx,1f5h
out dx,al
mov dx,1f6h
mov al,0a0h
out dx,al
mov dx,1f7h
mov al,0c8h
out dx,al
;lea dx,msg1
;call WriteString
;CheckRead:
; xor cx,cx
; not cx
; in al,dx
; and al,88h
; .if al==0
; jmp DMAEnd
; .endif
; loop CheckRead
; jmp Err
DMAWait:
in al,08
and al,02
jz DMAWait
DMAEnd:
mov al,05
out 0ah,al
jmp Quit
Err: lea dx,errmsg
call WriteString
Quit:
popa
ret
ReadDMA endp
.STARTUP
lea dx,msg1
call WriteString
call Crlf
call InitDMA
call ReadDMA
lea si,sector
add si,510
mov ax,[si]
call WriteHex
.EXIT
END
问题点数:100、回复次数:2Top
1 楼codesphere(codesphere)回复于 2005-11-29 21:53:21 得分 0
是不是初始化好DMA通道后就可以向ATA发命令了,我在程序里初始化了DMA通道1,然后向ATA发READ DMA命令,这样做对不对?Top
2 楼rockefeller8(洛克菲勒)回复于 2005-12-02 17:08:09 得分 0
太长了,支持一下,查一下DMA通道的初始化。Top




