|
|
| version 1.7, 2004/08/11 12:08:17 | version 1.11, 2005/02/04 06:42:14 |
|---|---|
| Line 2 | Line 2 |
| #include "z80core.h" | #include "z80core.h" |
| #include "pccore.h" | #include "pccore.h" |
| #include "iocore.h" | #include "iocore.h" |
| #include "ievent.h" | |
| void z80dmap(void) { | void z80dmap(void) { |
| REG8 r; | DMACNT *cnt1; |
| UINT16 *off1; | DMACNT *cnt2; |
| UINT16 *off2; | |
| REG8 flag1; | |
| REG8 flag2; | |
| UINT addr; | UINT addr; |
| REG8 dat; | REG8 dat; |
| REG8 vect; | REG8 flag1; |
| REG8 flag2; | |
| r = dma.DMA_CMND; | #if !defined(DMAS_STOIC) |
| if ((r & 3) == 0) return; | if (!dma.working) |
| if (dma.DMA_ENBL == 0) return; | #else |
| if (dma.ENDB_FLG != 0) return; // mod | if (!(dma.flag & DMAF_WORKING)) |
| if (r & 2) { | #endif |
| if (dma.MACH_FLG != 0) return; // mod | { |
| } | return; |
| if (dma.DMA_MODE != 1) { | |
| if ((dma.WR[5] ^ dma.DMA_REDY) & 8) return; | |
| } | } |
| if (dma.WR[0] & 4) { | if (dma.WR0 & 4) { |
| off1 = &dma.CNT_A.w; | cnt1 = &dma.cnt_a; |
| flag1 = dma.WR[1]; | cnt2 = &dma.cnt_b; |
| off2 = &dma.CNT_B.w; | |
| flag2 = dma.WR[2]; | |
| } | } |
| else { | else { |
| off2 = &dma.CNT_A.w; | cnt2 = &dma.cnt_a; |
| flag2 = dma.WR[1]; | cnt1 = &dma.cnt_b; |
| off1 = &dma.CNT_B.w; | |
| flag1 = dma.WR[2]; | |
| } | } |
| flag1 = cnt1->b.flag; | |
| flag2 = cnt2->b.flag; | |
| do { // dma_lp | do { // dma_lp |
| if (dma.ENDB_FLG) { | CPU_REMCLOCK -= 6; |
| break; | #if !defined(DMAS_STOIC) |
| if (dma.increment) | |
| #else | |
| if (dma.flag & DMAF_INCREMENT) | |
| #endif | |
| { | |
| if (!(flag1 & 0x20)) { | |
| cnt1->w.addr += (flag1 & 0x10)?1:-1; | |
| } | |
| if (!(flag2 & 0x20)) { | |
| cnt2->w.addr += (flag2 & 0x10)?1:-1; | |
| } | |
| } | } |
| if ((dma.DMA_CMND & 2) && (dma.MACH_FLG)) { | else { |
| break; | #if !defined(DMAS_STOIC) |
| dma.increment = 1; | |
| #else | |
| dma.flag |= DMAF_INCREMENT; | |
| #endif | |
| } | } |
| addr = *off1; | addr = cnt1->w.addr; |
| if (flag1 & 8) { | if (flag1 & 8) { |
| dat = iocore_inp(addr); | dat = iocore_inp(addr); |
| TRACEOUT(("dma r %.4x - %.2x", addr, dat)); | |
| } | } |
| else { | else { |
| dat = mem_read8(addr); | dat = z80mem_read8(addr); |
| } | } |
| if (dma.DMA_CMND & 1) { | if (dma.WR0 & 2) { |
| addr = *off2; | |
| if (flag2 & 8) { | |
| iocore_out(addr, dat); | |
| } | |
| else { | |
| mem_write8(addr, dat); | |
| } | |
| } | |
| if (dma.DMA_CMND & 2) { | |
| if (!((dat ^ dma.MACH_BYT) & (~dma.MASK_BYT))) { | if (!((dat ^ dma.MACH_BYT) & (~dma.MASK_BYT))) { |
| #if !defined(DMAS_STOIC) | |
| dma.working = FALSE; | |
| dma.MACH_FLG = 1; | dma.MACH_FLG = 1; |
| #else | |
| dma.flag &= ~(DMAF_WORKING | DMAF_MACH); | |
| #endif | |
| } | } |
| } | } |
| if (dma.DMA_MODE != 1) { | if (dma.WR0 & 1) { |
| dma.DMA_STOP = (dma.WR[5] ^ dma.DMA_REDY) & 8; | addr = cnt2->w.addr; |
| if (dma.DMA_STOP) { | if (flag2 & 8) { |
| goto dma_stop; | iocore_out(addr, dat); |
| } | |
| else { | |
| z80mem_write8(addr, dat); | |
| TRACEOUT(("dma w %.4x - %.2x", addr, dat)); | |
| } | } |
| } | |
| if (!(flag1 & 0x20)) { | |
| *off1 += (flag1 & 0x10)?1:-1; | |
| } | |
| if (!(flag2 & 0x20)) { | |
| *off2 += (flag2 & 0x10)?1:-1; | |
| } | } |
| dma_stop: | dma.leng.w.n++; |
| dma.BYT_N.w++; | if (dma.leng.w.n == 0) { |
| if (dma.BYT_N.w == 0) { | #if !defined(DMAS_STOIC) |
| dma.working = FALSE; | |
| dma.ENDB_FLG = 1; | dma.ENDB_FLG = 1; |
| break; | #else |
| } | dma.flag &= ~(DMAF_WORKING | DMAF_ENDB); |
| if ((dma.BYT_L.w) && (dma.BYT_L.w != 0xffff) && (dma.BYT_N.w >= (dma.BYT_L.w + 1))) { | #endif |
| } | |
| else if ((dma.leng.w.l) && ((dma.leng.w.n - 1) >= dma.leng.w.l)) { | |
| #if !defined(DMAS_STOIC) | |
| dma.working = FALSE; | |
| dma.ENDB_FLG = 1; | dma.ENDB_FLG = 1; |
| break; | #else |
| dma.flag &= ~(DMAF_WORKING | DMAF_ENDB); | |
| #endif | |
| } | |
| #if !defined(DMAS_STOIC) | |
| if (!dma.working) | |
| #else | |
| if (!(dma.flag & DMAF_WORKING)) | |
| #endif | |
| { | |
| goto intr; | |
| } | } |
| } while(dma.DMA_MODE); | } while(dma.mode); |
| return; | |
| intr: | |
| if (dma.INT_ENBL) { | if (dma.INT_ENBL) { |
| vect = 0; | ievent_set(IEVENT_DMA); |
| 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); | |
| } | |
| } | } |
| } | } |