diff options
Diffstat (limited to 'src/devices/cpu/z180/z180.cpp')
-rw-r--r-- | src/devices/cpu/z180/z180.cpp | 809 |
1 files changed, 349 insertions, 460 deletions
diff --git a/src/devices/cpu/z180/z180.cpp b/src/devices/cpu/z180/z180.cpp index aede5f08a28..7d8f0c4c4f3 100644 --- a/src/devices/cpu/z180/z180.cpp +++ b/src/devices/cpu/z180/z180.cpp @@ -2,7 +2,6 @@ // copyright-holders:Juergen Buchmueller /***************************************************************************** * - * z180.c * Portable Z180 emulator V0.3 * *****************************************************************************/ @@ -13,22 +12,52 @@ - HALT processing is not yet perfect. The manual states that during HALT, all dma and internal i/o incl. timers continue to work. Currently, only timers are implemented. Ideally, the - burn_cycles routine would go away and halt processing be - implemented in cpu_execute. + (currently unused) burn_cycles routine would go away and halt + processing be implemented in execute_run. + + - Documentation for RXS/CTS1 pin is contradictory. + + From page 12: + "During RESET, this pin is initialized as RXS pin. If CTS1E + bit in ASCI status register ch1 (STAT1) is set to 1, CTS1 + function is selected. If CTS1E bit is set to 0, RXS function + is selected." + + However, there is no CTS1E bit in the ASCI status register. + + From pages 43-44: + "CTS/PS: Clear to Send/Prescale (bit 5)—If bit 5 of the System + Configuration Register is 0, the CTS0/RxS pin features the + CTS0 function, and the state of the pin can be read in bit 5 + of CNTLB0 in a real-time, positive-logic fashion (HIGH = 1 , + LOW = 0). If bit 5 in the System Configuration Register is 0 + to auto-enable CTS0, and the pin is negated (High), the TDRE + bit is inhibited (forced to 0). Bit 5 of CNTLB1 reads back as + 0." + + This contradicts everything else in the documentation as it + implies RXS shares a pin with CTS0 (rather than CTS1) + + For now, the input is always sent to both RXS and CTS1. + *****************************************************************************/ /***************************************************************************** Z180 Info: -Known clock speeds (from ZiLOG): 6, 8, 10, 20 & 33MHz +Known clock speeds (from ZiLOG): 6 (actually ~6.15), 8, 10, 20 & 33MHz + +Much like the 80186/188, the operating frequency is generated from the +XTAL/EXTAL clock by an internal divide-by-2 circuit. The maximum frequency of +the EXTAL input is therefore twice the speed rating for the specific part. ZiLOG Z180 codes: Speed: 10 = 10MHZ 20 = 20MHz 33 = 33MHz -Package: P = 60-Pin Plastic DIP +Package: P = 64-Pin Plastic SDIP V = 68-Pin PLCC F = 80-Pin QFP Temp: S = 0C to +70C @@ -37,7 +66,7 @@ Package: P = 60-Pin Plastic DIP Environmental Flow: C = Plastic Standard -Example from Ms.Pac-Man/Galaga - 20 year Reunion hardware (see src/mame/drivers/20pacgal.c): +Example from Ms.Pac-Man/Galaga - 20 year Reunion hardware (see src/mame/namco/20pacgal.cpp): CPU is Z8S18020VSC = Z180, 20MHz, 68-Pin PLCC, 0C to +70C, Plastic Standard @@ -53,7 +82,6 @@ Hitachi HD647180 series: #include "emu.h" #include "z180.h" #include "z180dasm.h" -#include "debugger.h" //#define VERBOSE 1 #include "logmacro.h" @@ -78,24 +106,25 @@ Hitachi HD647180 series: /* register is calculated as follows: refresh=(Regs.R&127)|(Regs.R2&128) */ /****************************************************************************/ -DEFINE_DEVICE_TYPE(Z180, z180_device, "z180", "Zilog Z180") +DEFINE_DEVICE_TYPE(Z80180, z80180_device, "z80180", "Zilog Z80180") // equivalent to Hitachi HD64180R or HD64180Z +DEFINE_DEVICE_TYPE(HD64180RP, hd64180rp_device, "hd64180rp", "Hitachi HD64180RP") // DIP64 version, identical to Zilog Z80180xxPSC +DEFINE_DEVICE_TYPE(Z8S180, z8s180_device, "z8s180", "Zilog Z8S180") // enhanced Z80180 +DEFINE_DEVICE_TYPE(Z80182, z80182_device, "z80182", "Zilog Z80182") // further enhanced Z8S180 -z180_device::z180_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : cpu_device(mconfig, Z180, tag, owner, clock) +z180_device::z180_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool extended_io, address_map_constructor internal_map) + : cpu_device(mconfig, type, tag, owner, clock) , z80_daisy_chain_interface(mconfig, *this) - , m_program_config("program", ENDIANNESS_LITTLE, 8, 20, 0) + , m_program_config("program", ENDIANNESS_LITTLE, 8, 20, 0, 16, 12, internal_map) , m_io_config("io", ENDIANNESS_LITTLE, 8, 16, 0) - , m_decrypted_opcodes_config("program", ENDIANNESS_LITTLE, 8, 20, 0) + , m_decrypted_opcodes_config("opcodes", ENDIANNESS_LITTLE, 8, 20, 0, 16, 12, internal_map) + , m_asci(*this, "asci_%u", 0U) + , m_csio(*this, "csio") + , m_extended_io(extended_io) + , m_tend0_cb(*this) + , m_tend1_cb(*this) { // some arbitrary initial values - m_asci_cntla[0] = m_asci_cntla[1] = 0; - m_asci_cntlb[0] = m_asci_cntlb[1] = 0; - m_asci_stat[0] = 0; - m_asci_tdr[0] = m_asci_tdr[1] = 0; - m_asci_rdr[0] = m_asci_rdr[1] = 0; - m_asci_tc[0].w = m_asci_tc[1].w = 0; - m_csio_trdr = 0; m_tmdr[0].w = m_tmdr[1].w = 0; m_rldr[0].w = m_rldr[1].w = 0xffff; m_dma_sar0.d = 0; @@ -110,6 +139,33 @@ std::unique_ptr<util::disasm_interface> z180_device::create_disassembler() return std::make_unique<z180_disassembler>(); } +z80180_device::z80180_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : z180_device(mconfig, Z80180, tag, owner, clock, false, address_map_constructor()) +{ +} + +hd64180rp_device::hd64180rp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : z180_device(mconfig, HD64180RP, tag, owner, clock, false, address_map_constructor()) +{ + // 64-pin DIP versions omit A19 + set_address_width(19); +} + +z8s180_device::z8s180_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : z180_device(mconfig, type, tag, owner, clock, false, address_map_constructor()) +{ +} + +z8s180_device::z8s180_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : z8s180_device(mconfig, Z8S180, tag, owner, clock) +{ +} + +z80182_device::z80182_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : z8s180_device(mconfig, Z80182, tag, owner, clock) +{ +} + #define CF 0x01 #define NF 0x02 #define PF 0x04 @@ -199,69 +255,6 @@ bool z180_device::get_tend1() #define _LY m_IY.b.l -/* 00 ASCI control register A ch 0 */ -#define Z180_CNTLA0_MPE 0x80 -#define Z180_CNTLA0_RE 0x40 -#define Z180_CNTLA0_TE 0x20 -#define Z180_CNTLA0_RTS0 0x10 -#define Z180_CNTLA0_MPBR_EFR 0x08 -#define Z180_CNTLA0_MODE_DATA 0x04 -#define Z180_CNTLA0_MODE_PARITY 0x02 -#define Z180_CNTLA0_MODE_STOPB 0x01 - -/* 01 ASCI control register A ch 1 */ -#define Z180_CNTLA1_MPE 0x80 -#define Z180_CNTLA1_RE 0x40 -#define Z180_CNTLA1_TE 0x20 -#define Z180_CNTLA1_CKA1D 0x10 -#define Z180_CNTLA1_MPBR_EFR 0x08 -#define Z180_CNTLA1_MODE 0x07 - -/* 02 ASCI control register B ch 0 */ -#define Z180_CNTLB0_MPBT 0x80 -#define Z180_CNTLB0_MP 0x40 -#define Z180_CNTLB0_CTS_PS 0x20 -#define Z180_CNTLB0_PEO 0x10 -#define Z180_CNTLB0_DR 0x08 -#define Z180_CNTLB0_SS 0x07 - -/* 03 ASCI control register B ch 1 */ -#define Z180_CNTLB1_MPBT 0x80 -#define Z180_CNTLB1_MP 0x40 -#define Z180_CNTLB1_CTS_PS 0x20 -#define Z180_CNTLB1_PEO 0x10 -#define Z180_CNTLB1_DR 0x08 -#define Z180_CNTLB1_SS 0x07 - -/* 04 ASCI status register 0 (all bits read-only except RIE and TIE) */ -#define Z180_STAT0_RDRF 0x80 -#define Z180_STAT0_OVRN 0x40 -#define Z180_STAT0_PE 0x20 -#define Z180_STAT0_FE 0x10 -#define Z180_STAT0_RIE 0x08 -#define Z180_STAT0_DCD0 0x04 -#define Z180_STAT0_TDRE 0x02 -#define Z180_STAT0_TIE 0x01 - -/* 05 ASCI status register 1 (all bits read-only except RIE, CTS1E and TIE) */ -#define Z180_STAT1_RDRF 0x80 -#define Z180_STAT1_OVRN 0x40 -#define Z180_STAT1_PE 0x20 -#define Z180_STAT1_FE 0x10 -#define Z180_STAT1_RIE 0x08 -#define Z180_STAT1_CTS1E 0x04 -#define Z180_STAT1_TDRE 0x02 -#define Z180_STAT1_TIE 0x01 - -/* 0a CSI/O control/status register (EF is read-only) */ -#define Z180_CNTR_EF 0x80 -#define Z180_CNTR_EIE 0x40 -#define Z180_CNTR_RE 0x20 -#define Z180_CNTR_TE 0x10 -#define Z180_CNTR_SS 0x07 - -#define Z180_CNTR_MASK 0xf7 - /* 10 TIMER control register (TIF1 and TIF0 are read-only) */ #define Z180_TCR_TIF1 0x80 #define Z180_TCR_TIF0 0x40 @@ -272,33 +265,13 @@ bool z180_device::get_tend1() #define Z180_TCR_TDE1 0x02 #define Z180_TCR_TDE0 0x01 -/* 12 (Z8S180/Z8L180) ASCI extension control register 0 (break detect is read-only) */ -#define Z180_ASEXT0_DCD0 0x40 -#define Z180_ASEXT0_CTS0 0x20 -#define Z180_ASEXT0_X1_BIT_CLK0 0x10 -#define Z180_ASEXT0_BRG0_MODE 0x08 -#define Z180_ASEXT0_BRK_EN 0x04 -#define Z180_ASEXT0_BRK_DET 0x02 -#define Z180_ASEXT0_BRK_SEND 0x01 - -#define Z180_ASEXT0_MASK 0x7f - -/* 13 (Z8S180/Z8L180) ASCI extension control register 1 (break detect is read-only) */ -#define Z180_ASEXT1_X1_BIT_CLK1 0x10 -#define Z180_ASEXT1_BRG1_MODE 0x08 -#define Z180_ASEXT1_BRK_EN 0x04 -#define Z180_ASEXT1_BRK_DET 0x02 -#define Z180_ASEXT1_BRK_SEND 0x01 - -#define Z180_ASEXT1_MASK 0x1f - -/* 1e clock multiplier */ +/* 1e (Z8S180/Z8L180) clock multiplier */ #define Z180_CMR_X2 0x80 #define Z180_CMR_LOW_NOISE 0x40 #define Z180_CMR_MASK 0xc0 -/* 1f chip control register */ +/* 1f (Z8S180/Z8L180) chip control register */ #define Z180_CCR_CLOCK_DIVIDE 0x80 #define Z180_CCR_STDBY_IDLE1 0x40 #define Z180_CCR_BREXT 0x20 @@ -388,8 +361,6 @@ bool z180_device::get_tend1() /* 3f I/O control register */ #define Z180_IOCR_IOSTP 0x20 -#define Z180_IOCR_MASK 0xe0 - /*************************************************************************** CPU PREFIXES @@ -427,6 +398,12 @@ static std::unique_ptr<uint8_t[]> SZHVC_sub; #include "z180op.hxx" +void z180_device::set_address_width(int bits) +{ + m_program_config.m_addr_width = bits; + m_decrypted_opcodes_config.m_addr_width = bits; +} + device_memory_interface::space_config_vector z180_device::memory_space_config() const { if(has_configured_map(AS_OPCODES)) @@ -444,75 +421,50 @@ device_memory_interface::space_config_vector z180_device::memory_space_config() uint8_t z180_device::z180_readcontrol(offs_t port) { - /* normal external readport */ - uint8_t data = m_iospace->read_byte(port); + // normal external readport (ignore the data) + (void)m_io.read_byte(port); - /* remap internal I/O registers */ - if((port & (m_iocr & 0xc0)) == (m_iocr & 0xc0)) - port = port - (m_iocr & 0xc0); + // read the internal register + return z180_internal_port_read(port & (m_extended_io ? 0x7f : 0x3f)); +} + +uint8_t z180_device::z180_internal_port_read(uint8_t port) +{ + uint8_t data = 0xff; - /* but ignore the data and read the internal register */ switch (port) { case 0x00: - data = m_asci_cntla[0]; - LOG("Z180 CNTLA0 rd $%02x\n", data); - break; - case 0x01: - data = m_asci_cntla[1]; - LOG("Z180 CNTLA1 rd $%02x\n", data); + data = m_asci[port & 1]->cntla_r(); break; case 0x02: - data = m_asci_cntlb[0]; - LOG("Z180 CNTLB0 rd $%02x\n", data); - break; - case 0x03: - data = m_asci_cntlb[1]; - LOG("Z180 CNTLB1 rd $%02x\n", data); + data = m_asci[port & 1]->cntlb_r(); break; case 0x04: - data = m_asci_stat[0]; - data |= 0x02; // kludge for 20pacgal - LOG("Z180 STAT0 rd $%02x\n", data); - break; - case 0x05: - data = m_asci_stat[1]; - LOG("Z180 STAT1 rd $%02x\n", data); + data = m_asci[port & 1]->stat_r(); break; case 0x06: - data = m_asci_tdr[0]; - LOG("Z180 TDR0 rd $%02x\n", data); - break; - case 0x07: - data = m_asci_tdr[1]; - LOG("Z180 TDR1 rd $%02x\n", data); + data = m_asci[port & 1]->tdr_r(); break; case 0x08: - data = m_asci_rdr[0]; - LOG("Z180 RDR0 rd $%02x\n", data); - break; - case 0x09: - data = m_asci_rdr[1]; - LOG("Z180 RDR1 rd $%02x\n", data); + data = m_asci[port & 1]->rdr_r(); break; case 0x0a: - data = m_csio_cntr | ~Z180_CNTR_MASK; - LOG("Z180 CNTR rd $%02x ($%02x)\n", data, m_csio_cntr); + data = m_csio->cntr_r(); break; case 0x0b: - data = m_csio_trdr; - logerror("Z180 TRDR rd $%02x\n", data); + data = m_csio->trdr_r(); break; case 0x0c: @@ -596,21 +548,6 @@ uint8_t z180_device::z180_readcontrol(offs_t port) LOG("Z180 TCR rd $%02x ($%02x)\n", data, m_tcr); break; - case 0x11: - data = 0xff; - LOG("Z180 IO11 rd $%02x\n", data); - break; - - case 0x12: - data = m_asci_ext[0]; - LOG("Z180 ASEXT0 rd $%02x ($%02x)\n", data, m_asci_ext[0]); - break; - - case 0x13: - data = m_asci_ext[1]; - LOG("Z180 ASEXT1 rd $%02x ($%02x)\n", data, m_asci_ext[1]); - break; - case 0x14: data = m_tmdr_value[1]; LOG("Z180 TMDR1L rd $%02x ($%02x)\n", data, m_tmdr[1].w); @@ -676,36 +613,6 @@ uint8_t z180_device::z180_readcontrol(offs_t port) LOG("Z180 IO19 rd $%02x\n", data); break; - case 0x1a: - data = m_asci_tc[0].b.l; - LOG("Z180 ASTC0L rd $%02x ($%04x)\n", data, m_asci_tc[0].w); - break; - - case 0x1b: - data = m_asci_tc[0].b.h; - LOG("Z180 ASTC0H rd $%02x ($%04x)\n", data, m_asci_tc[0].w); - break; - - case 0x1c: - data = m_asci_tc[1].b.l; - LOG("Z180 ASTC1L rd $%02x ($%04x)\n", data, m_asci_tc[1].w); - break; - - case 0x1d: - data = m_asci_tc[1].b.h; - LOG("Z180 ASTC1H rd $%02x ($%04x)\n", data, m_asci_tc[1].w); - break; - - case 0x1e: - data = m_cmr | ~Z180_CMR_MASK; - LOG("Z180 CMR rd $%02x ($%02x)\n", data, m_cmr); - break; - - case 0x1f: - data = m_ccr; - LOG("Z180 CCR rd $%02x\n", data); - break; - case 0x20: data = m_dma_sar0.b.l; LOG("Z180 SAR0L rd $%02x ($%05x)\n", data, m_dma_sar0.d); @@ -811,21 +718,11 @@ uint8_t z180_device::z180_readcontrol(offs_t port) LOG("Z180 ITC rd $%02x ($%02x)\n", data, m_itc); break; - case 0x35: - data = 0xff; - LOG("Z180 IO35 rd $%02x\n", data); - break; - case 0x36: data = m_rcr | ~Z180_RCR_MASK; LOG("Z180 RCR rd $%02x ($%02x)\n", data, m_rcr); break; - case 0x37: - data = 0xff; - LOG("Z180 IO37 rd $%02x\n", data); - break; - case 0x38: data = m_mmu_cbr; LOG("Z180 CBR rd $%02x\n", data); @@ -841,30 +738,20 @@ uint8_t z180_device::z180_readcontrol(offs_t port) LOG("Z180 CBAR rd $%02x\n", data); break; - case 0x3b: - data = 0xff; - LOG("Z180 IO3B rd $%02x\n", data); - break; - - case 0x3c: - data = 0xff; - LOG("Z180 IO3C rd $%02x\n", data); - break; - - case 0x3d: - data = 0xff; - LOG("Z180 IO3D rd $%02x\n", data); - break; - case 0x3e: data = m_omcr | Z180_OMCR_M1TE | ~Z180_OMCR_MASK; LOG("Z180 OMCR rd $%02x ($%02x)\n", data, m_omcr); break; case 0x3f: - data = m_iocr | ~Z180_IOCR_MASK; + data = m_iocr | ~(m_extended_io ? 0xa0 : 0xe0); LOG("Z180 IOCR rd $%02x ($%02x)\n", data, m_iocr); break; + + default: + data = 0xff; + LOG("Z180 IO%02X rd $%02x\n", port, data); + break; } return data; @@ -872,75 +759,48 @@ uint8_t z180_device::z180_readcontrol(offs_t port) void z180_device::z180_writecontrol(offs_t port, uint8_t data) { - /* normal external write port */ - m_iospace->write_byte(port, data); + // normal external write port + m_io.write_byte(port, data); - /* remap internal I/O registers */ - if((port & (m_iocr & 0xc0)) == (m_iocr & 0xc0)) - port = port - (m_iocr & 0xc0); + // store the data in the internal register + z180_internal_port_write(port & (m_extended_io ? 0x7f : 0x3f), data); +} - /* store the data in the internal register */ +void z180_device::z180_internal_port_write(uint8_t port, uint8_t data) +{ switch (port) { case 0x00: - LOG("Z180 CNTLA0 wr $%02x\n", data); - m_asci_cntla[0] = data; - break; - case 0x01: - LOG("Z180 CNTLA1 wr $%02x\n", data); - m_asci_cntla[1] = data; + m_asci[port & 1]->cntla_w(data); break; case 0x02: - LOG("Z180 CNTLB0 wr $%02x\n", data); - m_asci_cntlb[0] = data; - break; - case 0x03: - LOG("Z180 CNTLB1 wr $%02x\n", data); - m_asci_cntlb[1] = data; + m_asci[port & 1]->cntlb_w(data); break; case 0x04: - LOG("Z180 STAT0 wr $%02x ($%02x)\n", data, data & (Z180_STAT0_RIE | Z180_STAT0_TIE)); - m_asci_stat[0] = (m_asci_stat[0] & ~(Z180_STAT0_RIE | Z180_STAT0_TIE)) | (data & (Z180_STAT0_RIE | Z180_STAT0_TIE)); - break; - case 0x05: - LOG("Z180 STAT1 wr $%02x ($%02x)\n", data, data & (Z180_STAT1_RIE | Z180_STAT1_CTS1E | Z180_STAT1_TIE)); - m_asci_stat[1] = (m_asci_stat[1] & ~(Z180_STAT1_RIE | Z180_STAT1_CTS1E | Z180_STAT1_TIE)) | (data & (Z180_STAT1_RIE | Z180_STAT1_CTS1E | Z180_STAT1_TIE)); + m_asci[port & 1]->stat_w(data); break; case 0x06: - LOG("Z180 TDR0 wr $%02x\n", data); - m_asci_tdr[0] = data; - break; - case 0x07: - LOG("Z180 TDR1 wr $%02x\n", data); - m_asci_tdr[1] = data; + m_asci[port & 1]->tdr_w(data); break; case 0x08: - LOG("Z180 RDR0 wr $%02x\n", data); - m_asci_rdr[0] = data; - break; - case 0x09: - LOG("Z180 RDR1 wr $%02x\n", data); - m_asci_rdr[1] = data; + m_asci[port & 1]->rdr_w(data); break; case 0x0a: - // Inhibit setting up TE & RE flags due to the lack of CSIO implementation - LOG("Z180 CNTR wr $%02x ($%02x)\n", data, data & ~(Z180_CNTR_EF | Z180_CNTR_RE | Z180_CNTR_TE)); - m_csio_cntr = (m_csio_cntr & (Z180_CNTR_EF | Z180_CNTR_RE | Z180_CNTR_TE)) | (data & ~(Z180_CNTR_EF | Z180_CNTR_RE | Z180_CNTR_TE)); + m_csio->cntr_w(data); break; case 0x0b: - LOG("Z180 TRDR wr $%02x\n", data); - m_csio_trdr = data; + m_csio->trdr_w(data); break; case 0x0c: @@ -979,21 +839,6 @@ void z180_device::z180_writecontrol(offs_t port, uint8_t data) break; - case 0x11: - LOG("Z180 IO11 wr $%02x\n", data); - // IO11 does not exist - break; - - case 0x12: - LOG("Z180 ASEXT0 wr $%02x ($%02x)\n", data, data & Z180_ASEXT0_MASK & ~Z180_ASEXT0_BRK_DET); - m_asci_ext[0] = (m_asci_ext[0] & Z180_ASEXT0_BRK_DET) | (data & Z180_ASEXT0_MASK & ~Z180_ASEXT0_BRK_DET); - break; - - case 0x13: - LOG("Z180 ASEXT1 wr $%02x ($%02x)\n", data, data & Z180_ASEXT1_MASK & ~Z180_ASEXT1_BRK_DET); - m_asci_ext[1] = (m_asci_ext[1] & Z180_ASEXT1_BRK_DET) | (data & Z180_ASEXT1_MASK & ~Z180_ASEXT1_BRK_DET); - break; - case 0x14: LOG("Z180 TMDR1L wr $%02x\n", data); m_tmdr[1].b.l = data; @@ -1021,41 +866,6 @@ void z180_device::z180_writecontrol(offs_t port, uint8_t data) // FRC is read-only break; - case 0x19: - LOG("Z180 IO19 wr $%02x\n", data); - // IO19 does not exist - break; - - case 0x1a: - LOG("Z180 ASTC0L wr $%02x\n", data); - m_asci_tc[0].b.l = data; - break; - - case 0x1b: - LOG("Z180 ASTC0H wr $%02x\n", data); - m_asci_tc[0].b.h = data; - break; - - case 0x1c: - LOG("Z180 ASTC1L wr $%02x\n", data); - m_asci_tc[1].b.l = data; - break; - - case 0x1d: - LOG("Z180 ASTC1H wr $%02x\n", data); - m_asci_tc[1].b.h = data; - break; - - case 0x1e: - LOG("Z180 CMR wr $%02x ($%02x)\n", data, data & Z180_CMR_MASK); - m_cmr = data & Z180_CMR_MASK; - break; - - case 0x1f: - LOG("Z180 CCR wr $%02x\n", data); - m_ccr = data; - break; - case 0x20: LOG("Z180 SAR0L wr $%02x\n", data); m_dma_sar0.b.l = data; @@ -1169,21 +979,11 @@ void z180_device::z180_writecontrol(offs_t port, uint8_t data) m_itc = (m_itc & Z180_ITC_UFO) | (data & Z180_ITC_MASK & ~Z180_ITC_UFO); break; - case 0x35: - LOG("Z180 IO35 wr $%02x\n", data); - // IO35 does not exist - break; - case 0x36: LOG("Z180 RCR wr $%02x ($%02x)\n", data, data & Z180_RCR_MASK); m_rcr = data & Z180_RCR_MASK; break; - case 0x37: - LOG("Z180 IO37 wr $%02x\n", data); - // IO37 does not exist - break; - case 0x38: LOG("Z180 CBR wr $%02x\n", data); m_mmu_cbr = data; @@ -1202,29 +1002,95 @@ void z180_device::z180_writecontrol(offs_t port, uint8_t data) z180_mmu(); break; - case 0x3b: - LOG("Z180 IO3B wr $%02x\n", data); - // IO3B does not exist + case 0x3e: + LOG("Z180 OMCR wr $%02x ($%02x)\n", data, data & Z180_OMCR_MASK); + m_omcr = data & Z180_OMCR_MASK; break; - case 0x3c: - LOG("Z180 IO3C wr $%02x\n", data); - // IO3C does not exist + case 0x3f: + LOG("Z180 IOCR wr $%02x ($%02x)\n", data, data & (m_extended_io ? 0xa0 : 0xe0)); + m_iocr = data & (m_extended_io ? 0xa0 : 0xe0); break; - case 0x3d: - LOG("Z180 IO3D wr $%02x\n", data); - // IO3D does not exist + default: + LOG("Z180 IO%02X wr $%02x\n", port, data); break; - case 0x3e: - LOG("Z180 OMCR wr $%02x ($%02x)\n", data, data & Z180_OMCR_MASK); - m_omcr = data & Z180_OMCR_MASK; + } +} + +uint8_t z8s180_device::z180_internal_port_read(uint8_t port) +{ + uint8_t data = 0xff; + + switch (port) + { + case 0x12: + case 0x13: + data = m_asci[port & 1]->asext_r(); break; - case 0x3f: - LOG("Z180 IOCR wr $%02x ($%02x)\n", data, data & Z180_IOCR_MASK); - m_iocr = data & Z180_IOCR_MASK; + case 0x1a: + case 0x1b: + data = m_asci[port & 1]->astcl_r(); + break; + + case 0x1c: + case 0x1d: + data = m_asci[port & 1]->astcl_r(); + break; + + case 0x1e: + data = m_cmr | ~Z180_CMR_MASK; + LOG("Z180 CMR rd $%02x ($%02x)\n", data, m_cmr); + break; + + case 0x1f: + data = m_ccr; + LOG("Z180 CCR rd $%02x\n", data); + break; + + default: + data = z180_device::z180_internal_port_read(port); + break; + } + + return data; +} + +void z8s180_device::z180_internal_port_write(uint8_t port, uint8_t data) +{ + switch (port) + { + case 0x12: + case 0x13: + m_asci[port & 1]->asext_w(data); + break; + + case 0x1a: + case 0x1b: + m_asci[port & 1]->astcl_w(data); + break; + + case 0x1c: + case 0x1d: + m_asci[port & 1]->astch_w(data); + break; + + case 0x1e: + LOG("Z180 CMR wr $%02x ($%02x)\n", data, data & Z180_CMR_MASK); + m_cmr = data & Z180_CMR_MASK; + notify_clock_changed(); + break; + + case 0x1f: + LOG("Z180 CCR wr $%02x\n", data); + m_ccr = data; + notify_clock_changed(); + break; + + default: + z180_device::z180_internal_port_write(port, data); break; } } @@ -1255,28 +1121,29 @@ int z180_device::z180_dma0(int max_cycles) if (bcr0 == 1) { m_iol |= Z180_TEND0; + m_tend0_cb(ASSERT_LINE); } switch( m_dmode & (Z180_DMODE_SM | Z180_DMODE_DM) ) { case 0x00: /* memory SAR0+1 to memory DAR0+1 */ - m_program->write_byte(dar0++, m_program->read_byte(sar0++)); + z180_write_memory(dar0++, z180_read_memory(sar0++)); cycles += memory_wait_states() * 2; bcr0--; break; case 0x04: /* memory SAR0-1 to memory DAR0+1 */ - m_program->write_byte(dar0++, m_program->read_byte(sar0--)); + z180_write_memory(dar0++, z180_read_memory(sar0--)); cycles += memory_wait_states() * 2; bcr0--; break; case 0x08: /* memory SAR0 fixed to memory DAR0+1 */ - m_program->write_byte(dar0++, m_program->read_byte(sar0)); + z180_write_memory(dar0++, z180_read_memory(sar0)); cycles += memory_wait_states() * 2; bcr0--; break; case 0x0c: /* I/O SAR0 fixed to memory DAR0+1 */ if (m_iol & Z180_DREQ0) { - m_program->write_byte(dar0++, IN(sar0)); + z180_write_memory(dar0++, IN(sar0)); cycles += memory_wait_states(); bcr0--; /* edge sensitive DREQ0 ? */ @@ -1288,24 +1155,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++)); + z180_write_memory(dar0--, z180_read_memory(sar0++)); cycles += memory_wait_states() * 2; bcr0--; break; case 0x14: /* memory SAR0-1 to memory DAR0-1 */ - m_program->write_byte(dar0--, m_program->read_byte(sar0--)); + z180_write_memory(dar0--, z180_read_memory(sar0--)); cycles += memory_wait_states() * 2; bcr0--; break; case 0x18: /* memory SAR0 fixed to memory DAR0-1 */ - m_program->write_byte(dar0--, m_program->read_byte(sar0)); + z180_write_memory(dar0--, z180_read_memory(sar0)); cycles += memory_wait_states() * 2; bcr0--; break; case 0x1c: /* I/O SAR0 fixed to memory DAR0-1 */ if (m_iol & Z180_DREQ0) { - m_program->write_byte(dar0--, IN(sar0)); + z180_write_memory(dar0--, IN(sar0)); cycles += memory_wait_states(); bcr0--; /* edge sensitive DREQ0 ? */ @@ -1317,12 +1184,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++)); + z180_write_memory(dar0, z180_read_memory(sar0++)); cycles += memory_wait_states() * 2; bcr0--; break; case 0x24: /* memory SAR0-1 to memory DAR0 fixed */ - m_program->write_byte(dar0, m_program->read_byte(sar0--)); + z180_write_memory(dar0, z180_read_memory(sar0--)); cycles += memory_wait_states() * 2; bcr0--; break; @@ -1333,7 +1200,7 @@ int z180_device::z180_dma0(int max_cycles) case 0x30: /* memory SAR0+1 to I/O DAR0 fixed */ if (m_iol & Z180_DREQ0) { - OUT(dar0, m_program->read_byte(sar0++)); + OUT(dar0, z180_read_memory(sar0++)); cycles += memory_wait_states(); bcr0--; /* edge sensitive DREQ0 ? */ @@ -1347,7 +1214,7 @@ int z180_device::z180_dma0(int max_cycles) case 0x34: /* memory SAR0-1 to I/O DAR0 fixed */ if (m_iol & Z180_DREQ0) { - OUT(dar0, m_program->read_byte(sar0--)); + OUT(dar0, z180_read_memory(sar0--)); cycles += memory_wait_states(); bcr0--; /* edge sensitive DREQ0 ? */ @@ -1377,6 +1244,7 @@ int z180_device::z180_dma0(int max_cycles) if (bcr0 == 0) { m_iol &= ~Z180_TEND0; + m_tend0_cb(CLEAR_LINE); m_dstat &= ~Z180_DSTAT_DE0; /* terminal count interrupt enabled? */ if (m_dstat & Z180_DSTAT_DIE0 && m_IFF1) @@ -1410,6 +1278,7 @@ int z180_device::z180_dma1() if (bcr1 == 1) { m_iol |= Z180_TEND1; + m_tend1_cb(ASSERT_LINE); } m_extra_cycles = 0; @@ -1417,16 +1286,20 @@ int z180_device::z180_dma1() switch (m_dcntl & (Z180_DCNTL_DIM1 | Z180_DCNTL_DIM0)) { case 0x00: /* memory MAR1+1 to I/O IAR1 fixed */ - m_iospace->write_byte(iar1, m_program->read_byte(mar1++)); + m_io.write_byte(iar1, z180_read_memory(mar1++)); + bcr1--; break; case 0x01: /* memory MAR1-1 to I/O IAR1 fixed */ - m_iospace->write_byte(iar1, m_program->read_byte(mar1--)); + m_io.write_byte(iar1, z180_read_memory(mar1--)); + bcr1--; break; case 0x02: /* I/O IAR1 fixed to memory MAR1+1 */ - m_program->write_byte(mar1++, m_iospace->read_byte(iar1)); + z180_write_memory(mar1++, m_io.read_byte(iar1)); + bcr1--; break; case 0x03: /* I/O IAR1 fixed to memory MAR1-1 */ - m_program->write_byte(mar1--, m_iospace->read_byte(iar1)); + z180_write_memory(mar1--, m_io.read_byte(iar1)); + bcr1--; break; } @@ -1444,6 +1317,7 @@ int z180_device::z180_dma1() if (bcr1 == 0) { m_iol &= ~Z180_TEND1; + m_tend1_cb(CLEAR_LINE); m_dstat &= ~Z180_DSTAT_DE1; if (m_dstat & Z180_DSTAT_DIE1 && m_IFF1) m_int_pending[Z180_INT_DMA1] = 1; @@ -1657,11 +1531,10 @@ void z180_device::device_start() if( (i & 0x0f) == 0x0f ) SZHV_dec[i] |= HF; } - m_program = &space(AS_PROGRAM); - m_cache = m_program->cache<0, 0, ENDIANNESS_LITTLE>(); - m_oprogram = has_space(AS_OPCODES) ? &space(AS_OPCODES) : m_program; - m_ocache = m_oprogram->cache<0, 0, ENDIANNESS_LITTLE>(); - m_iospace = &space(AS_IO); + space(AS_PROGRAM).specific(m_program); + space(AS_PROGRAM).cache(m_cprogram); + space(has_space(AS_OPCODES) ? AS_OPCODES : AS_PROGRAM).cache(m_copcodes); + space(AS_IO).specific(m_io); /* set up the state table */ { @@ -1669,7 +1542,6 @@ void z180_device::device_start() state_add(STATE_GENPC, "GENPC", _PCD).noshow(); state_add(STATE_GENPCBASE, "CURPC", m_PREPC.w.l).noshow(); state_add(Z180_SP, "SP", m_SP.w.l); - state_add(STATE_GENSP, "GENSP", m_SP.w.l).noshow(); state_add(STATE_GENFLAGS, "GENFLAGS", m_AF.b.l).noshow().formatstr("%8s"); state_add(Z180_A, "A", _A).noshow(); state_add(Z180_B, "B", _B).noshow(); @@ -1697,24 +1569,9 @@ void z180_device::device_start() state_add(Z180_IOLINES, "IOLINES", m_ioltemp).mask(0xffffff).callimport(); - state_add(Z180_CNTLA0, "CNTLA0", m_asci_cntla[0]); - state_add(Z180_CNTLB0, "CNTLB0", m_asci_cntlb[0]); - state_add(Z180_STAT0, "STAT0", m_asci_stat[0]); - state_add(Z180_TDR0, "TDR0", m_asci_tdr[0]); - state_add(Z180_RDR0, "RDR0", m_asci_rdr[0]); - state_add(Z180_ASEXT0, "ASEXT0", m_asci_ext[0]).mask(Z180_ASEXT0_MASK); - state_add(Z180_ASTC0, "ASTC0", m_asci_tc[0].w); - - state_add(Z180_CNTLA1, "CNTLA1", m_asci_cntla[1]); - state_add(Z180_CNTLB1, "CNTLB1", m_asci_cntlb[1]); - state_add(Z180_STAT1, "STAT1", m_asci_stat[1]); - state_add(Z180_TDR1, "TDR1", m_asci_tdr[1]); - state_add(Z180_RDR1, "RDR1", m_asci_rdr[1]); - state_add(Z180_ASEXT1, "ASEXT1", m_asci_ext[1]).mask(Z180_ASEXT1_MASK); - state_add(Z180_ASTC1, "ASTC1", m_asci_tc[1].w); - - state_add(Z180_CNTR, "CNTR", m_csio_cntr).mask(Z180_CNTR_MASK); - state_add(Z180_TRDR, "TRDR", m_csio_trdr); + m_asci[0]->state_add(*this); + m_asci[1]->state_add(*this); + m_csio->state_add(*this); state_add(Z180_TMDR0, "TMDR0", m_tmdr_value[0]); state_add(Z180_RLDR0, "RLDR0", m_rldr[0].w); @@ -1723,8 +1580,6 @@ void z180_device::device_start() state_add(Z180_TCR, "TCR", m_tcr); state_add(Z180_FRC, "FRC", m_frc); - state_add(Z180_CMR, "CMR", m_cmr).mask(Z180_CMR_MASK); - state_add(Z180_CCR, "CCR", m_ccr); state_add(Z180_SAR0, "SAR0", m_dma_sar0.d).mask(Z180_SAR0_MASK); state_add(Z180_DAR0, "DAR0", m_dma_dar0.d).mask(Z180_DAR0_MASK); @@ -1742,7 +1597,7 @@ void z180_device::device_start() state_add(Z180_BBR, "BBR", m_mmu_bbr).callimport(); state_add(Z180_CBAR, "CBAR", m_mmu_cbar).callimport(); state_add(Z180_OMCR, "OMCR", m_omcr).mask(Z180_OMCR_MASK); - state_add(Z180_IOCR, "IOCR", m_iocr).mask(Z180_IOCR_MASK); + state_add(Z180_IOCR, "IOCR", m_iocr).mask(m_extended_io ? 0xa0 : 0xe0); } save_item(NAME(m_AF.w.l)); @@ -1768,9 +1623,7 @@ void z180_device::device_start() save_item(NAME(m_nmi_pending)); save_item(NAME(m_irq_state)); save_item(NAME(m_int_pending)); - save_item(NAME(m_timer_cnt)); - save_item(NAME(m_dma0_cnt)); - save_item(NAME(m_dma1_cnt)); + save_item(NAME(m_frc_prescale)); save_item(NAME(m_after_EI)); save_item(NAME(m_read_tcr_tmdr)); @@ -1778,24 +1631,12 @@ void z180_device::device_start() save_item(NAME(m_tmdrh)); save_item(NAME(m_tmdr_latch)); - save_item(NAME(m_asci_cntla)); - save_item(NAME(m_asci_cntlb)); - save_item(NAME(m_asci_stat)); - save_item(NAME(m_asci_tdr)); - save_item(NAME(m_asci_rdr)); - save_item(NAME(m_asci_ext)); - save_item(NAME(m_asci_tc[0].w)); - save_item(NAME(m_asci_tc[1].w)); - save_item(NAME(m_csio_cntr)); - save_item(NAME(m_csio_trdr)); save_item(NAME(m_tmdr[0].w)); save_item(NAME(m_tmdr[1].w)); save_item(NAME(m_rldr[0].w)); save_item(NAME(m_rldr[1].w)); save_item(NAME(m_tcr)); save_item(NAME(m_frc)); - save_item(NAME(m_cmr)); - save_item(NAME(m_ccr)); save_item(NAME(m_dma_sar0.d)); save_item(NAME(m_dma_dar0.d)); save_item(NAME(m_dma_bcr[0].w)); @@ -1822,6 +1663,17 @@ void z180_device::device_start() set_icountptr(m_icount); } +void z8s180_device::device_start() +{ + z180_device::device_start(); + + state_add(Z180_CMR, "CMR", m_cmr).mask(Z180_CMR_MASK); + state_add(Z180_CCR, "CCR", m_ccr); + + save_item(NAME(m_cmr)); + save_item(NAME(m_ccr)); +} + /**************************************************************************** * Reset registers to their initial values ****************************************************************************/ @@ -1873,23 +1725,11 @@ void z180_device::device_reset() m_int_pending[i] = 0; } - m_timer_cnt = 0; - m_dma0_cnt = 0; - m_dma1_cnt = 0; + m_frc = 0xff; + m_frc_prescale = 0; /* reset io registers */ - m_asci_cntla[0] = (m_asci_cntla[0] & Z180_CNTLA0_MPBR_EFR) | Z180_CNTLA0_RTS0; - m_asci_cntla[1] = (m_asci_cntla[1] & Z180_CNTLA1_MPBR_EFR) | Z180_CNTLA1_CKA1D; - m_asci_cntlb[0] = (m_asci_cntlb[0] & (Z180_CNTLB0_MPBT | Z180_CNTLB0_CTS_PS)) | 0x07; - m_asci_cntlb[1] = (m_asci_cntlb[1] & Z180_CNTLB1_MPBT) | 0x07; - m_asci_stat[0] = m_asci_stat[0] & (Z180_STAT0_DCD0 | Z180_STAT0_TDRE); - m_asci_stat[1] = Z180_STAT1_TDRE; - m_csio_cntr = 0x07; m_tcr = 0x00; - m_asci_ext[0] = 0x00; - m_asci_ext[1] = 0x00; - m_cmr = 0x00; - m_ccr = 0x00; m_dma_iar1.b.h2 = 0x00; m_dstat = Z180_DSTAT_DWE1 | Z180_DSTAT_DWE0; m_dmode = 0x00; @@ -1906,63 +1746,85 @@ void z180_device::device_reset() z180_mmu(); } +void z180_device::device_add_mconfig(machine_config &config) +{ + Z180ASCI_CHANNEL_0(config, m_asci[0], DERIVED_CLOCK(1,2)); + + Z180ASCI_CHANNEL_1(config, m_asci[1], DERIVED_CLOCK(1,2)); + + Z180CSIO(config, m_csio, DERIVED_CLOCK(1,2)); +} + +void z8s180_device::device_add_mconfig(machine_config &config) +{ + Z180ASCI_EXT_CHANNEL_0(config, m_asci[0], DERIVED_CLOCK(1,2)); + + Z180ASCI_EXT_CHANNEL_1(config, m_asci[1], DERIVED_CLOCK(1,2)); + + Z180CSIO(config, m_csio, DERIVED_CLOCK(1,2)); +} + +void z8s180_device::device_reset() +{ + z180_device::device_reset(); + + m_cmr = 0x00; + m_ccr = 0x00; + notify_clock_changed(); +} + +void z8s180_device::device_clock_changed() +{ + auto const rate = (m_cmr & 0x80) ? DERIVED_CLOCK(2,1) : (m_ccr & 0x80) ? DERIVED_CLOCK(1,1) : DERIVED_CLOCK(1,2); + m_asci[0]->set_clock(rate); + m_asci[1]->set_clock(rate); + m_csio->set_clock(rate); +} + /* Handle PRT timers, decreasing them after 20 clocks and returning the new icount base that needs to be used for the next check */ void z180_device::clock_timers() { - m_timer_cnt++; - if (m_timer_cnt >= 20) + /* Programmable Reload Timer 0 */ + if(m_tcr & Z180_TCR_TDE0) { - m_timer_cnt = 0; - /* Programmable Reload Timer 0 */ - if(m_tcr & Z180_TCR_TDE0) - { - if(m_tmdr_value[0] == 0) - { - m_tmdr_value[0] = m_rldr[0].w; - m_tcr |= Z180_TCR_TIF0; - } - else - m_tmdr_value[0]--; - } - - /* Programmable Reload Timer 1 */ - if(m_tcr & Z180_TCR_TDE1) + if(m_tmdr_value[0] == 0) { - if(m_tmdr_value[1] == 0) - { - m_tmdr_value[1] = m_rldr[1].w; - m_tcr |= Z180_TCR_TIF1; - } - else - m_tmdr_value[1]--; + m_tmdr_value[0] = m_rldr[0].w; + m_tcr |= Z180_TCR_TIF0; } + else + m_tmdr_value[0]--; + } - if((m_tcr & Z180_TCR_TIE0) && (m_tcr & Z180_TCR_TIF0)) + /* Programmable Reload Timer 1 */ + if(m_tcr & Z180_TCR_TDE1) + { + if(m_tmdr_value[1] == 0) { - // check if we can take the interrupt - if(m_IFF1 && !m_after_EI) - { - m_int_pending[Z180_INT_PRT0] = 1; - } + m_tmdr_value[1] = m_rldr[1].w; + m_tcr |= Z180_TCR_TIF1; } + else + m_tmdr_value[1]--; + } - if((m_tcr & Z180_TCR_TIE1) && (m_tcr & Z180_TCR_TIF1)) - { - // check if we can take the interrupt - if(m_IFF1 && !m_after_EI) - { - m_int_pending[Z180_INT_PRT1] = 1; - } - } + if((m_tcr & Z180_TCR_TIE0) && (m_tcr & Z180_TCR_TIF0)) + { + // check if we can take the interrupt + if(m_IFF1 && !m_after_EI) + m_int_pending[Z180_INT_PRT0] = 1; + } + if((m_tcr & Z180_TCR_TIE1) && (m_tcr & Z180_TCR_TIF1)) + { + // check if we can take the interrupt + if(m_IFF1 && !m_after_EI) + m_int_pending[Z180_INT_PRT1] = 1; } } int z180_device::check_interrupts() { - int i; - int cycles = 0; - /* check for IRQs before each instruction */ if (m_IFF1 && !m_after_EI) { @@ -1974,15 +1836,27 @@ int z180_device::check_interrupts() if (m_irq_state[2] != CLEAR_LINE && (m_itc & Z180_ITC_ITE2) == Z180_ITC_ITE2) m_int_pending[Z180_INT_IRQ2] = 1; + + m_int_pending[Z180_INT_CSIO] = m_csio->check_interrupt(); + m_int_pending[Z180_INT_ASCI0] = m_asci[0]->check_interrupt(); + m_int_pending[Z180_INT_ASCI1] = m_asci[1]->check_interrupt(); } - for (i = 0; i <= Z180_INT_MAX; i++) + int cycles = 0; + for (int i = 0; i <= Z180_INT_MAX; i++) + { if (m_int_pending[i]) { cycles += take_interrupt(i); m_int_pending[i] = 0; + switch (i) + { + case Z180_INT_ASCI0: m_asci[0]->clear_interrupt(); break; + case Z180_INT_ASCI1: m_asci[1]->clear_interrupt(); break; + } break; } + } return cycles; } @@ -1995,7 +1869,17 @@ void z180_device::handle_io_timers(int cycles) { while (cycles-- > 0) { - clock_timers(); + // FRC counts down by 1 every 10 cycles + m_frc_prescale++; + if (m_frc_prescale >= 10) + { + m_frc_prescale = 0; + m_frc--; + + // Programmable reload timers are clocked once every 20 cycles + if ((m_frc & 1) == 0) + clock_timers(); + } } } @@ -2034,7 +1918,7 @@ again: if ((m_dstat & Z180_DSTAT_DE0) == Z180_DSTAT_DE0 && (m_dmode & Z180_DMODE_MMOD) == Z180_DMODE_MMOD) { - debugger_instruction_hook(_PCD); + debugger_wait_hook(); /* FIXME z180_dma0 should be handled in handle_io_timers */ curcycles = z180_dma0(m_icount); @@ -2050,19 +1934,21 @@ again: handle_io_timers(curcycles); m_after_EI = 0; - _PPC = _PCD; - debugger_instruction_hook(_PCD); - if (!m_HALT) { + _PPC = _PCD; + debugger_instruction_hook(_PCD); + m_R++; - m_frc++; /* Added FRC counting, not implemented yet */ m_extra_cycles = 0; curcycles = exec_op(ROP()); curcycles += m_extra_cycles; } else + { + debugger_wait_hook(); curcycles = 3; + } m_icount -= curcycles; @@ -2109,19 +1995,21 @@ again: handle_io_timers(curcycles); m_after_EI = 0; - _PPC = _PCD; - debugger_instruction_hook(_PCD); - if (!m_HALT) { + _PPC = _PCD; + debugger_instruction_hook(_PCD); + m_R++; - m_frc++; /* Added FRC counting, not implemented yet */ m_extra_cycles = 0; curcycles = exec_op(ROP()); curcycles += m_extra_cycles; } else + { + debugger_wait_hook(); curcycles = 3; + } m_icount -= curcycles; handle_io_timers(curcycles); @@ -2132,7 +2020,7 @@ again: /**************************************************************************** * Burn 'cycles' T-states. Adjust R register for the lost time ****************************************************************************/ -void z180_device::execute_burn(int32_t cycles) +void z180_device::burn_cycles(int32_t cycles) { int extra_cycles = memory_wait_states(); @@ -2185,12 +2073,13 @@ void z180_device::execute_set_input(int irqline, int state) } /* logical to physical address translation */ -bool z180_device::memory_translate(int spacenum, int intention, offs_t &address) +bool z180_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) { if (spacenum == AS_PROGRAM) { address = MMU_REMAP_ADDR(address); } + target_space = &space(spacenum); return true; } |