--- xmil/io/dmac.c 2004/08/01 05:31:30 1.1 +++ xmil/io/dmac.c 2004/08/14 12:16:17 1.5 @@ -1,10 +1,77 @@ #include "compiler.h" +#include "z80core.h" #include "pccore.h" #include "iocore.h" -#include "x1_io.h" -#include "x1_fdc.h" +#include "nevent.h" +#include "ievent.h" +static REG8 iswork(const DMAC *d) { + + REG8 r; + + r = d->cmd; + if ((r & 3) == 0) return(FALSE); + if (d->enable == 0) return(FALSE); + if (d->ENDB_FLG != 0) return(FALSE); // mod + if (r & 2) { + if (d->MACH_FLG != 0) return(FALSE); // mod + } + if (d->mode != 1) { + if ((d->WR[5] ^ d->ready) & 8) return(FALSE); + } + return(TRUE); +} + +void dmac_sendready(BRESULT ready) { + + REG8 working; + + if (!ready) { + dma.working = FALSE; + dma.ready = 8; + } + else { + dma.ready = 0; + working = iswork(&dma); + if (dma.working != working) { + dma.working = working; + nevent_forceexit(); + } + } +} + + +BRESULT ieitem_dmac(UINT id) { + + 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; + } + Z80_INTERRUPT(vect); + return(TRUE); + } + } + (void)id; + return(FALSE); +} + + +// ---- + static void setdmareaddat(void) { UINT cnt; @@ -41,8 +108,9 @@ static void setdmareaddat(void) { void IOOUTCALL dmac_o(UINT port, REG8 value) { REG8 wr; + REG8 working; - dma.DMA_ENBL = 0; + dma.enable = 0; if (!dma.WR_CNT) { wr = 6; @@ -76,7 +144,7 @@ void IOOUTCALL dmac_o(UINT port, REG8 va dma.WR[wr] = value; switch(wr) { case 0: - dma.DMA_CMND = (UINT8)(value & 3); + dma.cmd = (UINT8)(value & 3); if (value & 0x08) { dma.WR_TBL[dma.WR_CNT++] = offsetof(DMAC, ADR_A.b.l); } @@ -106,11 +174,11 @@ void IOOUTCALL dmac_o(UINT port, REG8 va dma.WR_TBL[dma.WR_CNT++] = offsetof(DMAC, MACH_BYT); } dma.INT_ENBL = (UINT8)((value & 0x20)?1:0); - dma.DMA_ENBL = (UINT8)((value & 0x40)?1:0); + dma.enable = (UINT8)((value & 0x40)?1:0); break; case 4: - dma.DMA_MODE = (UINT8)((dma.WR[4] >> 5) & 3); + dma.mode = (UINT8)((dma.WR[4] >> 5) & 3); if (value & 0x04) { dma.WR_TBL[dma.WR_CNT++] = offsetof(DMAC, ADR_B.b.l); } @@ -125,15 +193,17 @@ void IOOUTCALL dmac_o(UINT port, REG8 va case 6: switch(value) { case 0x83: // dma disable - dma.DMA_ENBL = 0; + // dma.enable = 0; break; case 0x87: // dma enable - dma.DMA_ENBL = 1; + dma.increment = 0; + dma.enable = 1; break; case 0x8b: // re-init status byte - dma.MACH_FLG = dma.ENDB_FLG = 0; + dma.MACH_FLG = 0; + dma.ENDB_FLG = 0; break; case 0xa7: // イニシエイトリードシーケンス @@ -149,7 +219,7 @@ void IOOUTCALL dmac_o(UINT port, REG8 va break; case 0xb3: // force ready - dma.DMA_REDY = (dma.WR[5] & 0x08); + dma.ready = (dma.WR[5] & 0x08); break; case 0xbb: // read mask follows @@ -162,13 +232,11 @@ void IOOUTCALL dmac_o(UINT port, REG8 va break; case 0xc3: // reset -#if 1 // ローグアライアンス // ver0.25 - dma.DMA_CMND = 0; - dma.DMA_ENBL = 0; + // ローグアライアンス // ver0.25 + dma.cmd = 0; + // dma.enable = 0; dma.INT_ENBL = 0; -#else - init_dma(); -#endif + dma.increment = 0; break; case 0xc7: // リセットタイミングA @@ -176,42 +244,20 @@ void IOOUTCALL dmac_o(UINT port, REG8 va break; case 0xcf: // ロード - dma.DMA_MODE = (UINT8)((dma.WR[4] >> 5) & 3); + dma.mode = (UINT8)((dma.WR[4] >> 5) & 3); dma.CNT_A.w = dma.ADR_A.w; dma.CNT_B.w = dma.ADR_B.w; dma.BYT_N.w = 0; dma.ENDB_FLG = 0; dma.MACH_FLG = 0; // 0619 - dma.DMA_ENBL = 0; + // dma.enable = 0; break; case 0xd3: // コンティニュー - if (dma.DMA_STOP) { // 前回途中でNOT READY - dma.DMA_STOP = 0; - // ここでインクリメントするのはちょい無理が… - switch(dma.WR[1] & 0x30) { - case 0x00: - dma.CNT_A.w--; - break; - - case 0x10: - dma.CNT_A.w++; - break; - } - switch(dma.WR[2] & 0x30) { - case 0x00: - dma.CNT_B.w--; - break; - - case 0x10: - dma.CNT_B.w++; - break; - } - } dma.BYT_N.w = 0; // 0619 dma.MACH_FLG = 0; // 0619 dma.ENDB_FLG = 0; - dma.DMA_ENBL = 1; + dma.enable = 1; break; } break; @@ -235,6 +281,15 @@ void IOOUTCALL dmac_o(UINT port, REG8 va dma.WR_OFF++; dma.WR_CNT--; } + + working = iswork(&dma); + if (dma.working != working) { + dma.working = working; + if (working) { + nevent_forceexit(); + } + } + (void)port; } REG8 IOINPCALL dmac_i(UINT port) { @@ -242,10 +297,10 @@ REG8 IOINPCALL dmac_i(UINT port) { REG8 ret; ret = 0xcc; - if (dma.DMA_ENBL) { + if (dma.enable) { ret |= 0x01; } - if ((dma.DMA_MODE != 1) && ((dma.WR[5] ^ dma.DMA_REDY) & 8)) { + if ((dma.mode != 1) && ((dma.WR[5] ^ dma.ready) & 8)) { ret |= 0x02; } if (!dma.MACH_FLG) { @@ -261,6 +316,7 @@ REG8 IOINPCALL dmac_i(UINT port) { } ret = (*(((UINT8 *)&dma) + dma.RR_TBL[dma.RR_OFF++])); } + (void)port; return(ret); } @@ -270,7 +326,7 @@ REG8 IOINPCALL dmac_i(UINT port) { void dmac_reset(void) { ZeroMemory(&dma, sizeof(dma)); - dma.DMA_REDY = 8; + dma.ready = 8; dma.RR = 0x38; }