--- xmil/z80c/z80dmap.c 2004/08/01 05:31:32 1.1 +++ xmil/z80c/z80dmap.c 2004/08/04 02:30:35 1.2 @@ -1,30 +1,170 @@ #include "compiler.h" +#include "z80core.h" #include "pccore.h" #include "iocore.h" #include "x1_io.h" -#include "x1_fdc.h" -void z80dmap(void) { #if 0 - UINT8 al; +static BOOL _iswork(void) { - al = dma.DMA_CMND; - if ((al & 3) == 0) return; - if (dma.DMA_ENBL == 0) return; - if (dma.ENDB_FLG != 0) return; - if (al & 2) { - if (dma.MACH_FLG != 0) return; + REG8 r; + + r = dma.DMA_CMND; + if ((r & 3) == 0) return(0); + if (dma.DMA_ENBL == 0) return(0); + if (dma.ENDB_FLG != 0) return(0); + if (r & 2) { + if (dma.MACH_FLG != 0) return(0); } if (dma.DMA_MODE != 1) { - al = dma.WR[5] ^ dma.DMA_REDY - if (al & 8) return; + if ((dma.WR[5] ^ dma.DMA_REDY) & 8) return(0); + } + return(1); +} + +static void _dmap(void) { + + UINT16 *off1; + UINT16 *off2; + REG8 flag1; + REG8 flag2; + UINT addr; + REG8 dat; + + 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 + if (dma.ENDB_FLG) { + break; + } + if ((dma.DMA_CMND & 2) && (dma.MACH_FLG)) { + break; + } + addr = *off1; + if (flag1 & 8) { + if (addr == 0x0ffb) { + fdcdummyread = 0; + } + dat = iocore_inp(addr); + } + else { + dat = Z80_RDMEM((REG16)addr); + } +TRACEOUT(("DMA IN -> %.4x %.2x", addr, dat)); + if (dma.DMA_CMND & 1) { + addr = *off2; + if (flag2 & 8) { + if ((addr == 0x0ffb) && (!ppi.IO_MODE)) { + fdcdummyread = 0; + } + iocore_out(addr, dat); + } + else { + Z80_WRMEM((REG16)addr, dat); + } +TRACEOUT(("DMA OUT -> %.4x %.2x", addr, dat)); + } + if (dma.DMA_CMND & 2) { + if (!((dat ^ dma.MACH_BYT) & (~dma.MASK_BYT))) { + dma.MACH_FLG = 1; + } + } + if (dma.DMA_MODE != 1) { + dma.DMA_STOP = (dma.WR[5] ^ dma.DMA_REDY) & 8; + if (dma.DMA_STOP) { + 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.ENDB_FLG = 1; + break; + } + if ((dma.BYT_L.w) && (dma.BYT_L.w != 0xffff) && (dma.BYT_N.w >= (dma.BYT_L.w + 1))) { + dma.ENDB_FLG = 1; + break; + } + } while(dma.DMA_MODE); +} +static void _intr(void) { -#if 0 -dmaintmain: push ebx + REG8 vect; + + if (dma.INT_ENBL) { + vect = 0; + if ((dma.INT_FLG & 1) && (dma.MACH_FLG)) { + vect = 2; + } + else if ((dma.INT_FLG & 2) && (dma.ENDB_FLG)) { + vect = 4; + } + if (vect) { + if (dma.INT_FLG & 0x20) { + vect += (dma.INT_VCT & 0xf9); + } + else { + vect = dma.INT_VCT; + } + z80c_interrupt(vect); + } + } +} + +LABEL void z80dmap(void) { + + __asm { +#if 1 + call _iswork + cmp al, 0 + jne short dmaintmain + ret +#else + 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 +#endif + +dmaintmain: +#if 1 + call _dmap +#else + push ebx mov ebx, offset dma.CNT_A mov ecx, offset dma.CNT_B @@ -45,7 +185,9 @@ dma_lpst: movzx ecx, word ptr [ebx] test dl, 8 jne dma_inport - call fast_RDMEM + push edx + call Z80_RDMEM + pop edx dmasrcend: pop ecx test dma.DMA_CMND, 1 @@ -58,7 +200,7 @@ dmasrcend: pop ecx mov dl, al test dh, 8 jne dma_outport - call fast_WRMEM + call Z80_WRMEM dmadstend: pop edx pop ecx pop eax @@ -112,6 +254,10 @@ dmplpedch: cmp dma.DMA_MODE, 0 jne dma_lp dmalpend: pop ebx +#endif +#if 1 + jmp _intr +#else cmp dma.INT_ENBL, 0 je dmaintrptend mov dl, 2 @@ -130,18 +276,18 @@ dmaintrptcall: movzx ecx, dma.INT_VCT je dma_intrpt and cl, 0f9h or cl, dl -dma_intrpt: jmp z80x_interrupt +dma_intrpt: jmp z80c_interrupt +#endif dmaintrptend: ret +#if 0 dma_inport: push edx push ebx cmp cx, 0ffbh jne Z80inport -// cmp s8255.IO_MODE, 0 -// jne Z80inport mov fdcdummyread, 0 -Z80inport: call Z80_In +Z80inport: call iocore_inp pop ebx pop edx jmp dmasrcend @@ -149,13 +295,128 @@ Z80inport: call Z80_In dma_outport: push ebx cmp cx, 0ffbh jne Z80outport - cmp s8255.IO_MODE, 0 + cmp ppi.IO_MODE, 0 jne Z80outport mov fdcdummyread, 0 -Z80outport: call Z80_Out +Z80outport: call iocore_out pop ebx jmp dmadstend #endif -#endif + } +} +#else +void z80dmap(void) { + + REG8 r; + UINT16 *off1; + UINT16 *off2; + REG8 flag1; + REG8 flag2; + UINT addr; + REG8 dat; + REG8 vect; + + r = dma.DMA_CMND; + if ((r & 3) == 0) return; + if (dma.DMA_ENBL == 0) return; + if (dma.ENDB_FLG != 0) return; + if (r & 2) { + if (dma.MACH_FLG != 0) return; + } + if (dma.DMA_MODE != 1) { + if ((dma.WR[5] ^ dma.DMA_REDY) & 8) 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 + if (dma.ENDB_FLG) { + break; + } + if ((dma.DMA_CMND & 2) && (dma.MACH_FLG)) { + break; + } + addr = *off1; + if (flag1 & 8) { + if (addr == 0x0ffb) { + fdcdummyread = 0; + } + dat = iocore_inp(addr); + } + else { + dat = Z80_RDMEM((REG16)addr); + } + if (dma.DMA_CMND & 1) { + addr = *off2; + if (flag2 & 8) { + if ((addr == 0x0ffb) && (!ppi.IO_MODE)) { + fdcdummyread = 0; + } + iocore_out(addr, dat); + } + else { + Z80_WRMEM((REG16)addr, dat); + } + } + if (dma.DMA_CMND & 2) { + if (!((dat ^ dma.MACH_BYT) & (~dma.MASK_BYT))) { + dma.MACH_FLG = 1; + } + } + if (dma.DMA_MODE != 1) { + dma.DMA_STOP = (dma.WR[5] ^ dma.DMA_REDY) & 8; + if (dma.DMA_STOP) { + 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.ENDB_FLG = 1; + break; + } + if ((dma.BYT_L.w) && (dma.BYT_L.w != 0xffff) && (dma.BYT_N.w >= (dma.BYT_L.w + 1))) { + dma.ENDB_FLG = 1; + break; + } + } while(dma.DMA_MODE); + + if (dma.INT_ENBL) { + vect = 0; + if ((dma.INT_FLG & 1) && (dma.MACH_FLG)) { + vect = 2; + } + else if ((dma.INT_FLG & 2) && (dma.ENDB_FLG)) { + vect = 4; + } + if (vect) { + if (dma.INT_FLG & 0x20) { + vect += (dma.INT_VCT & 0xf9); + } + else { + vect = dma.INT_VCT; + } + z80c_interrupt(vect); + } + } } +#endif