diff --git a/src/devices/cpu/z180/z180.cpp b/src/devices/cpu/z180/z180.cpp index a1dda238c60..91d240e6142 100644 --- a/src/devices/cpu/z180/z180.cpp +++ b/src/devices/cpu/z180/z180.cpp @@ -34,7 +34,7 @@ Package: P = 60-Pin Plastic DIP Temp: S = 0C to +70C E = -40C to +85C -Environmanetal Flow: C = Plastic Standard +Environmental Flow: C = Plastic Standard Example from Ms.Pac-Man/Galaga - 20 year Reunion hardare (see src/mame/drivers/20pacgal.c): @@ -683,7 +683,7 @@ bool z180_device::get_tend1() /* 36 refresh control register */ #define Z180_RCR_REFE 0x80 -#define Z180_RCR_REFW 0x80 +#define Z180_RCR_REFW 0x40 #define Z180_RCR_CYC 0x03 #define Z180_RCR_RESET 0xc0 @@ -1602,6 +1602,7 @@ int z180_device::z180_dma0(int max_cycles) while (count > 0) { + m_extra_cycles = 0; /* last transfer happening now? */ if (bcr0 == 1) { @@ -1611,20 +1612,24 @@ int z180_device::z180_dma0(int max_cycles) { case 0x00: /* memory SAR0+1 to memory DAR0+1 */ m_program->write_byte(dar0++, m_program->read_byte(sar0++)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x04: /* memory SAR0-1 to memory DAR0+1 */ m_program->write_byte(dar0++, m_program->read_byte(sar0--)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x08: /* memory SAR0 fixed to memory DAR0+1 */ m_program->write_byte(dar0++, m_program->read_byte(sar0)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x0c: /* I/O SAR0 fixed to memory DAR0+1 */ if (m_iol & Z180_DREQ0) { m_program->write_byte(dar0++, IN(sar0)); + cycles += IO_DCNTL >> 6; // memory wait states bcr0--; /* edge sensitive DREQ0 ? */ if (IO_DCNTL & Z180_DCNTL_DMS0) @@ -1636,20 +1641,24 @@ int z180_device::z180_dma0(int max_cycles) break; case 0x10: /* memory SAR0+1 to memory DAR0-1 */ m_program->write_byte(dar0--, m_program->read_byte(sar0++)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x14: /* memory SAR0-1 to memory DAR0-1 */ m_program->write_byte(dar0--, m_program->read_byte(sar0--)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x18: /* memory SAR0 fixed to memory DAR0-1 */ m_program->write_byte(dar0--, m_program->read_byte(sar0)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x1c: /* I/O SAR0 fixed to memory DAR0-1 */ if (m_iol & Z180_DREQ0) { m_program->write_byte(dar0--, IN(sar0)); + cycles += IO_DCNTL >> 6; // memory wait states bcr0--; /* edge sensitive DREQ0 ? */ if (IO_DCNTL & Z180_DCNTL_DMS0) @@ -1661,10 +1670,12 @@ int z180_device::z180_dma0(int max_cycles) break; case 0x20: /* memory SAR0+1 to memory DAR0 fixed */ m_program->write_byte(dar0, m_program->read_byte(sar0++)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x24: /* memory SAR0-1 to memory DAR0 fixed */ m_program->write_byte(dar0, m_program->read_byte(sar0--)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x28: /* reserved */ @@ -1675,6 +1686,7 @@ int z180_device::z180_dma0(int max_cycles) if (m_iol & Z180_DREQ0) { OUT(dar0, m_program->read_byte(sar0++)); + cycles += IO_DCNTL >> 6; // memory wait states bcr0--; /* edge sensitive DREQ0 ? */ if (IO_DCNTL & Z180_DCNTL_DMS0) @@ -1688,6 +1700,7 @@ int z180_device::z180_dma0(int max_cycles) if (m_iol & Z180_DREQ0) { OUT(dar0, m_program->read_byte(sar0--)); + cycles += IO_DCNTL >> 6; // memory wait states bcr0--; /* edge sensitive DREQ0 ? */ if (IO_DCNTL & Z180_DCNTL_DMS0) @@ -1703,7 +1716,7 @@ int z180_device::z180_dma0(int max_cycles) break; } count--; - cycles += 6; + cycles += 6 + m_extra_cycles; // use extra_cycles for I/O wait states if (cycles > max_cycles) break; } @@ -1756,6 +1769,8 @@ int z180_device::z180_dma1() m_iol |= Z180_TEND1; } + m_extra_cycles = 0; + switch (IO_DCNTL & (Z180_DCNTL_DIM1 | Z180_DCNTL_DIM0)) { case 0x00: /* memory MAR1+1 to I/O IAR1 fixed */ @@ -1772,6 +1787,9 @@ int z180_device::z180_dma1() break; } + cycles += IO_DCNTL >> 6; // memory wait states + cycles += m_extra_cycles; // use extra_cycles for I/O wait states + /* edge sensitive DREQ1 ? */ if (IO_DCNTL & Z180_DCNTL_DIM1) m_iol &= ~Z180_DREQ1; @@ -1919,7 +1937,6 @@ void z180_device::z180_write_iolines(uint32_t data) } } - void z180_device::device_start() { int i, p; @@ -2503,14 +2520,16 @@ again: ****************************************************************************/ void z180_device::execute_burn(int32_t cycles) { + int extra_cycles = IO_DCNTL >> 6; // memory wait states + /* FIXME: This is not appropriate for dma */ while ( (cycles > 0) ) { - handle_io_timers(3); + handle_io_timers(3 + extra_cycles); /* NOP takes 3 cycles per instruction */ m_R += 1; - m_icount -= 3; - cycles -= 3; + m_icount -= 3 + extra_cycles; + cycles -= 3 + extra_cycles; } } diff --git a/src/devices/cpu/z180/z180.h b/src/devices/cpu/z180/z180.h index dca5c963539..624c07b0bb5 100644 --- a/src/devices/cpu/z180/z180.h +++ b/src/devices/cpu/z180/z180.h @@ -202,6 +202,9 @@ private: static const opcode_func s_z180ops[6][0x100]; inline void z180_mmu(); + inline u8 RM(offs_t addr); + inline u8 IN(u16 port); + inline void OUT(u16 port, u8 value); inline void RM16( offs_t addr, PAIR *r ); inline void WM16( offs_t addr, PAIR *r ); inline uint8_t ROP(); diff --git a/src/devices/cpu/z180/z180ops.h b/src/devices/cpu/z180/z180ops.h index 9ffe45cc42d..1c1fa8322f6 100644 --- a/src/devices/cpu/z180/z180ops.h +++ b/src/devices/cpu/z180/z180ops.h @@ -22,17 +22,27 @@ /*************************************************************** * Input a byte from given I/O port ***************************************************************/ -#define IN(port) \ - (((port ^ IO_IOCR) & 0xffc0) == 0) ? \ - z180_readcontrol(port) : m_iospace->read_byte(port) +inline u8 z180_device::IN(u16 port) +{ + if(((port ^ IO_IOCR) & 0xffc0) == 0) + return z180_readcontrol(port); + m_extra_cycles += ((IO_DCNTL & (Z180_DCNTL_IWI1 | Z180_DCNTL_IWI0)) >> 4) + 1; // external I/O wait states + return m_iospace->read_byte(port); +} /*************************************************************** * Output a byte to given I/O port ***************************************************************/ -#define OUT(port,value) \ - if (((port ^ IO_IOCR) & 0xffc0) == 0) \ - z180_writecontrol(port,value); \ - else m_iospace->write_byte(port,value) +inline void z180_device::OUT(u16 port, u8 value) +{ + if (((port ^ IO_IOCR) & 0xffc0) == 0) { + z180_writecontrol(port,value); + } else + { + m_extra_cycles += ((IO_DCNTL & (Z180_DCNTL_IWI1 | Z180_DCNTL_IWI0)) >> 4) + 1; // external I/O wait states + m_iospace->write_byte(port, value); + } +} /*************************************************************** * MMU calculate the memory management lookup table @@ -68,12 +78,16 @@ void z180_device::z180_mmu() /*************************************************************** * Read a byte from given memory location ***************************************************************/ -#define RM(addr) m_program->read_byte(MMU_REMAP_ADDR(addr)) +inline u8 z180_device::RM(offs_t addr) +{ + m_extra_cycles += IO_DCNTL >> 6; // memory wait states + return m_program->read_byte(MMU_REMAP_ADDR(addr)); +} /*************************************************************** * Write a byte to given memory location ***************************************************************/ -#define WM(addr,value) m_program->write_byte(MMU_REMAP_ADDR(addr),value) +#define WM(addr,value) m_extra_cycles += IO_DCNTL >> 6; /* memory wait states */ m_program->write_byte(MMU_REMAP_ADDR(addr),value) /*************************************************************** * Read a word from given memory location @@ -102,6 +116,7 @@ uint8_t z180_device::ROP() { offs_t addr = _PCD; _PC++; + m_extra_cycles += IO_DCNTL >> 6; // memory wait states return m_odirect->read_byte(MMU_REMAP_ADDR(addr)); } @@ -115,6 +130,7 @@ uint8_t z180_device::ARG() { offs_t addr = _PCD; _PC++; + m_extra_cycles += IO_DCNTL >> 6; // memory wait states return m_direct->read_byte(MMU_REMAP_ADDR(addr)); } @@ -122,6 +138,7 @@ uint32_t z180_device::ARG16() { offs_t addr = _PCD; _PC += 2; + m_extra_cycles += (IO_DCNTL >> 6) * 2; // memory wait states return m_direct->read_byte(MMU_REMAP_ADDR(addr)) | (m_direct->read_byte(MMU_REMAP_ADDR(addr+1)) << 8); }