struc dmach_t
.adrs resd 1 ; 00
.leng resw 1 ; 04
.adrsorg resw 1 ; 06
.lengorg resw 1 ; 08
.action resw 1 ; 18
.outproc resd 1 ; 0c
.inproc resd 1 ; 10
.extproc resd 1 ; 14
.mode resb 1 ; 1a
.sreq resb 1 ; 1b
.ready resb 1 ; 1c
.mask resb 1 ; 1d
.size ; 20
endstruc
struc dmac_t
.dmach resb (dmach_t.size * 4)
.lh resd 1
.work resb 1
.working resb 1
.mask resb 1
.stat resb 1
endstruc
DMAEXT_START equ 0
DMAEXT_END equ 1
DMAEXT_BREAK equ 2
DMA_INITSIGNALONLY equ 1
section .bss
extern _dmac
section .text
global _dmap_i286
extern @i286_memoryread@4
extern @i286_memorywrite@8
align 16
_dmap_i286: cmp byte [_dmac + dmac_t.working], byte 0
je short dmap_nowork
mov eax, _dmac + dmac_t.dmach
mov cl, 1
dmap_sea: test [_dmac + dmac_t.working], cl
jne short dmap_hit
add cl, cl
add eax, dmach_t.size
and cl, 15
jne short dmap_sea
dmap_nowork: ret
dmap_hit: push edi
sub word [eax + dmach_t.leng], byte 1
mov edi, eax
jnc short dmap_exec
or [_dmac + dmac_t.stat], cl
not cl
and [_dmac + dmac_t.working], cl
mov ecx, DMAEXT_END
call dword [edi + dmach_t.extproc]
dmap_exec: mov al, [edi + dmach_t.mode]
and al, 0ch
je short dmap_verify
cmp al, 04h
je short dmap_port2mem
mov ecx, [edi + dmach_t.adrs]
call @i286_memoryread@4
mov cl, al
call dword [edi + dmach_t.outproc]
jmp short dmap_inccnt
dmap_verify: call dword [edi + dmach_t.inproc]
jmp short dmap_inccnt
dmap_port2mem: call dword [edi + dmach_t.inproc]
mov ecx, [edi + dmach_t.adrs]
mov dl, al
call @i286_memorywrite@8
dmap_inccnt: test byte [edi + dmach_t.mode], 20h
jne short dmap_adrsdec
inc dword [edi + dmach_t.adrs]
pop edi
ret
dmap_adrsdec: dec dword [edi + dmach_t.adrs]
pop edi
ret
ends
RetroPC.NET-CVS <cvs@retropc.net>