
VAEG_EXT		equ		0		; added by Shinra

				struc	dmach_t
.adrs			resd	1		; 00
.leng			resw	1		; 04
.adrsorg		resw	1		; 06
.lengorg		resw	1		; 08
.action			resw	1		; 0a
.outproc		resd	1		; 0c
.inproc			resd	1		; 10
.extproc		resd	1		; 14
.mode			resb	1		; 18
.sreq			resb	1		; 19
.ready			resb	1		; 1a
.mask			resb	1		; 1b
.size			resb	1		; 1c
				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
%if VAEG_EXT
DMAEXT_DRQ			equ		3
%endif

DMA_INITSIGNALONLY	equ		1


section .bss

	extern	_dmac

section	.data

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
%if VAEG_EXT
				jz		short dmap_sea2
				push	eax
				push	ecx
				push	edi
				mov		ecx, DMAEXT_DRQ
				call	dword [eax + dmach_t.extproc]
				pop		edi
				pop		ecx
				or		al, al
				pop		eax
				jz		dmap_hit
dmap_sea2:
%else
				jne		short dmap_hit
%endif
				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
