File:  [RetroPC.NET] / xmil / z80x / z80dmap.c
Revision 1.6: download - view: text, annotated - select for diffs
Thu Aug 12 01:09:04 2004 JST (21 years, 2 months ago) by yui
Branches: MAIN
CVS tags: HEAD
fix...

#include	"compiler.h"
#include	"z80core.h"
#include	"pccore.h"
#include	"iocore.h"
#include	"ievent.h"


void z80dmap(void) {

	UINT16	*off1;
	UINT16	*off2;
	REG8	flag1;
	REG8	flag2;
	UINT	addr;
	REG8	dat;

	if (!dma.working) {
		return;
	}

	if (dma.WR[0] & 4) {
		off1 = &dma.CNT_A.w;
		flag1 = dma.WR[1];
		off2 = &dma.CNT_B.w;
		flag2 = dma.WR[2];
	}
	else {
		off2 = &dma.CNT_A.w;
		flag2 = dma.WR[1];
		off1 = &dma.CNT_B.w;
		flag1 = dma.WR[2];
	}

	do {		// dma_lp
		addr = *off1;
		if (flag1 & 8) {
			dat = iocore_inp(addr);
		}
		else {
			dat = z80mem_read8(addr);
		}
		if (dma.cmd & 1) {
			addr = *off2;
			if (flag2 & 8) {
				iocore_out(addr, dat);
			}
			else {
				z80mem_write8(addr, dat);
			}
		}
		if (dma.cmd & 2) {
			if (!((dat ^ dma.MACH_BYT) & (~dma.MASK_BYT))) {
				dma.working = FALSE;
				dma.MACH_FLG = 1;
			}
		}
		if (dma.mode != 1) {
			dma.DMA_STOP = (dma.WR[5] ^ dma.ready) & 8;
			if (dma.DMA_STOP) {
				dma.working = FALSE;			// 既にセットされてる筈だが
				goto dma_stop;
			}
		}
		if (!(flag1 & 0x20)) {
			*off1 += (flag1 & 0x10)?1:-1;
		}
		if (!(flag2 & 0x20)) {
			*off2 += (flag2 & 0x10)?1:-1;
		}

dma_stop:
		dma.BYT_N.w++;
		if (dma.BYT_N.w == 0) {
			dma.working = FALSE;
			dma.ENDB_FLG = 1;
			goto intr;
		}
		if ((dma.BYT_L.w) && (dma.BYT_L.w != 0xffff) && (dma.BYT_N.w >= (dma.BYT_L.w + 1))) {
			dma.working = FALSE;
			dma.ENDB_FLG = 1;
			goto intr;
		}
		if (!dma.working) {
			goto intr;
		}
	} while(dma.mode);
	return;

intr:
	if (dma.INT_ENBL) {
		ievent_set(IEVENT_DMA);
	}
}





#if 0	// old
LABEL void z80dmap(void) {

	__asm {
				mov		al, dma.DMA_CMND
				test	al, 3
				je		dmaintend
				cmp		dma.DMA_ENBL, 0
				je		dmaintend
				cmp		dma.ENDB_FLG, 0
				jne		dmaintend
				test	al, 2
				je		ckcntmode
				cmp		dma.MACH_FLG, 0
				jne		short dmaintend
ckcntmode:		cmp		dma.DMA_MODE, 1
				je		dmaintmain
				mov		al, dma.WR[5]
				xor		al, dma.DMA_REDY
				test	al, 8
				je		dmaintmain
dmaintend:		ret

dmaintmain:		push	ebx
				mov		ebx, offset dma.CNT_A
				mov		ecx, offset dma.CNT_B

				mov		dx, word ptr (dma.WR[1])
				test	dma.WR[0], 4
				jne		dma_lp
				xchg	ebx, ecx
				xchg	dl, dh

dma_lp:			cmp		dma.ENDB_FLG, 0
				jne		dmalpend
				test	dma.DMA_CMND, 2
				je		dma_lpst
				cmp		dma.MACH_FLG, 0
				jne		dmalpend
dma_lpst:
				push	ecx
				push	edx
				movzx	ecx, word ptr [ebx]
				test	dl, 8
				jne		dma_inport
				call	memrd8_ecx_al
dmasrcend:		pop		edx
				pop		ecx

				test	dma.DMA_CMND, 1
				je		dmadstend

				push	eax
				push	ecx
				push	edx
				movzx	ecx, word ptr [ecx]
				mov		dl, al
				test	dh, 8
				jne		dma_outport
				call	memwr8_ecx_dl
dmadstend:		pop		edx
				pop		ecx
				pop		eax

				test	dma.DMA_CMND, 2
				je		dmamachcend
				xor		al, dma.MACH_BYT
				mov		ah,	dma.MASK_BYT
				not		ah
				and		al, ah
				jne		short dmamachcend
				mov		dma.MACH_FLG, 1
dmamachcend:
				cmp		dma.DMA_MODE, 1
				je		forcesrcaddr
				mov		al, dma.WR[5]
				xor		al, dma.DMA_REDY
				and		al, 8
				mov		dma.DMA_STOP, al
				jne		dmadststpend

forcesrcaddr:	test	dl, 20h
				jne		dmasrcstpend
				test	dl, 10h
				je		dmasrcdec
					inc		word ptr [ebx]
				jmp		dmasrcstpend
dmasrcdec:			dec		word ptr [ebx]
dmasrcstpend:
				test	dh, 20h
				jne		dmadststpend
				test	dh, 10h
				je		dmadstdec
					inc		word ptr [ecx]
				jmp		dmadststpend
dmadstdec:			dec		word ptr [ecx]
dmadststpend:
				inc		dma.BYT_N.w
				je		dmaforceend
				mov		ax, dma.BYT_L.w
				or		ax, ax
				je		dmplpedch				// BYT_L == 0なら無制限?
				inc		ax
				je		dmplpedch				// ver0.25
				cmp		ax, dma.BYT_N.w
				ja		dmplpedch
dmaforceend:	mov		dma.ENDB_FLG, 1
				jmp		dmalpend

dmplpedch:		cmp		dma.DMA_MODE, 0
				jne		dma_lp
dmalpend:
				pop		ebx
				cmp		dma.INT_ENBL, 0
				je		dmaintrptend
				mov		dl, 2
				mov		al, dma.INT_FLG
				test	al, 1
				je		dmaintrpt2ck
				cmp		dma.MACH_FLG, 0
				jne		dmaintrptcall
dmaintrpt2ck:	mov		dl, 4
				test	al, 2
				je		dmaintrptend
				cmp		dma.ENDB_FLG, 0
				je		dmaintrptend
dmaintrptcall:	movzx	ecx, dma.INT_VCT
				test	al, 20h
				je		dma_intrpt
				and		cl, 0f9h
				or		cl, dl
dma_intrpt:		jmp		z80x_interrupt
dmaintrptend:	ret


dma_inport:		call	iocore_inp
				jmp		dmasrcend

dma_outport:	call	iocore_out
				jmp		dmadstend
	}
}
#endif


RetroPC.NET-CVS <cvs@retropc.net>