📄 dma.asm
字号:
;/////////////////////////////////////////////////////////////////////////////
;// dma.asm
;//
;// DMA driver module
;//
;// 09/08/1999 fOSSiL Initial version
;// 23/10/1999 fOSSiL minor updates
;// 28/10/1999 fOSSiL 16bit DMA fix
;// 2000/01/14 The Owl nasm port
;// 2000/01/16 The Owl cosmetic changes ;-)
global DmaInit
bits 32
struc DmaType
.MaskReg resb 1 ; Mask reg
.ModeReg resb 1 ; Mode reg
.FFReg resb 1 ; Flip-Flop reg
.pad1 resb 1 ; 0 ; padding for 4-align
endstruc
struc DmaChan
.AddrReg resb 1
.CountReg resb 1
.PageReg resb 1
.WordType resb 1 ; 0 = 8bit, 1 = 16bit
endstruc
segment _LDATA
align 4
Types:
istruc DmaType ; 8bit DMA
at DmaType.MaskReg, db 00ah
at DmaType.ModeReg, db 00bh
at DmaType.FFReg, db 00ch
at DmaType.pad1, db 0
iend
istruc DmaType ; 16bit DMA
at DmaType.MaskReg, db 0d4h
at DmaType.ModeReg, db 0d6h
at DmaType.FFReg, db 0d8h
at DmaType.pad1, db 0
iend
Chans:
istruc DmaChan ; 0
at DmaChan.AddrReg, db 000h
at DmaChan.CountReg, db 001h
at DmaChan.PageReg, db 087h
at DmaChan.WordType, db 0
iend
istruc DmaChan ; 1
at DmaChan.AddrReg, db 002h
at DmaChan.CountReg, db 003h
at DmaChan.PageReg, db 083h
at DmaChan.WordType, db 0
iend
istruc DmaChan ; 2
at DmaChan.AddrReg, db 004h
at DmaChan.CountReg, db 005h
at DmaChan.PageReg, db 081h
at DmaChan.WordType, db 0
iend
istruc DmaChan ; 3
at DmaChan.AddrReg, db 006h
at DmaChan.CountReg, db 007h
at DmaChan.PageReg, db 082h
at DmaChan.WordType, db 0
iend
istruc DmaChan ; 4
at DmaChan.AddrReg, db 0c0h
at DmaChan.CountReg, db 0c2h
at DmaChan.PageReg, db 000h
at DmaChan.WordType, db 1
iend
istruc DmaChan ; 5
at DmaChan.AddrReg, db 0c4h
at DmaChan.CountReg, db 0c6h
at DmaChan.PageReg, db 08bh
at DmaChan.WordType, db 1
iend
istruc DmaChan ; 6
at DmaChan.AddrReg, db 0c8h
at DmaChan.CountReg, db 0cah
at DmaChan.PageReg, db 089h
at DmaChan.WordType, db 1
iend
istruc DmaChan ; 7
at DmaChan.AddrReg, db 0cch
at DmaChan.CountReg, db 0ceh
at DmaChan.PageReg, db 08ah
at DmaChan.WordType, db 1
iend
segment _LTEXT
DmaInit:
; EAX = chan#
; EBX = mem addr : page+offset
; ECX = block size
push esi
push edi
push ebx
; index into Chans array
lea edi, [Chans + eax * DmaChan_size]
; index into Types array
movzx edx, byte [edi + DmaChan.WordType]
ror ebx, 16
; if 16bit DMA we have to adjust Page/Offset and Count
or edx, edx
jz .NoAdjust
; offset gets the LSB of Page in its MSB
ror ebx, 1
rcl bx, 1
shr ecx, 1 ; adjust block size
sub eax, 4 ; adjust chan#
.NoAdjust:
push eax ; save it
push edi ; save it
lea edi, [Types + edx * DmaType_size]
; get Mask reg
xor edx, edx
mov dl, [edi + DmaType.MaskReg]
; mask DMA chan off
or al, 4
out dx, al
; jmp short $+2
call delay
mov dl, [edi + DmaType.FFReg]
xor eax, eax
out dx, al ; clear Flip-Flop
; jmp short $+2
call delay
mov dl, [edi + DmaType.ModeReg]
mov eax, [esp + 4] ; get saved EAX
or al, 058h ; Auto-Init mode
out dx, al
; jmp short $+2
call delay
xchg edi, [esp]
; set Count for channel
mov dl, [edi + DmaChan.CountReg]
dec ecx
mov al, cl
out dx, al
; jmp short $+2
call delay
mov al, ch
out dx, al
; jmp short $+2
call delay
; set Page
mov dl, [edi + DmaChan.PageReg]
mov al, bl
out dx, al
; jmp short $+2
call delay
; set Offset (Addr)
mov dl, [edi + DmaChan.AddrReg]
mov eax, ebx
shr eax, 16
out dx, al
; jmp short $+2
call delay
shr eax, 8
out dx, al
; jmp short $+2
call delay
; enable channel back
pop edi
mov dl, [edi + DmaType.MaskReg]
pop eax
out dx, al
; jmp short $+2
call delay
pop ebx
pop edi
pop esi
retn
delay:
push ecx
mov ecx,16
loop $
pop ecx
retn
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -