From d252e90bf3a18700a929c50526a36270b1b5b7ac Mon Sep 17 00:00:00 2001 From: AJR Date: Sun, 22 Mar 2020 12:03:31 -0400 Subject: z8s180: Internalize certain registers; make clock divider software-selectable --- src/devices/cpu/z180/z180.cpp | 321 ++++++++++++++++++++---------------------- src/devices/cpu/z180/z180.h | 26 +++- src/mame/drivers/20pacgal.cpp | 2 +- 3 files changed, 178 insertions(+), 171 deletions(-) diff --git a/src/devices/cpu/z180/z180.cpp b/src/devices/cpu/z180/z180.cpp index 7d7ea159d6c..824f24be6c9 100644 --- a/src/devices/cpu/z180/z180.cpp +++ b/src/devices/cpu/z180/z180.cpp @@ -102,7 +102,6 @@ z180_device::z180_device(const machine_config &mconfig, device_type type, const 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; @@ -130,13 +129,20 @@ hd64180rp_device::hd64180rp_device(const machine_config &mconfig, const char *ta 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()) +{ + // some arbitrary initial values + m_asci_tc[0].w = m_asci_tc[1].w = 0; +} + z8s180_device::z8s180_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : z180_device(mconfig, Z8S180, tag, owner, clock, false, address_map_constructor()) + : z8s180_device(mconfig, Z8S180, tag, owner, clock) { } z80182_device::z80182_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : z180_device(mconfig, Z80182, tag, owner, clock, false, address_map_constructor()) + : z8s180_device(mconfig, Z80182, tag, owner, clock) { } @@ -322,13 +328,13 @@ bool z180_device::get_tend1() #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 @@ -643,21 +649,6 @@ uint8_t z180_device::z180_internal_port_read(uint8_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); @@ -723,36 +714,6 @@ uint8_t z180_device::z180_internal_port_read(uint8_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); @@ -858,21 +819,11 @@ uint8_t z180_device::z180_internal_port_read(uint8_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); @@ -888,21 +839,6 @@ uint8_t z180_device::z180_internal_port_read(uint8_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); @@ -912,6 +848,11 @@ uint8_t z180_device::z180_internal_port_read(uint8_t port) 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; @@ -1027,21 +968,6 @@ void z180_device::z180_internal_port_write(uint8_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; @@ -1069,41 +995,6 @@ void z180_device::z180_internal_port_write(uint8_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; @@ -1217,21 +1108,11 @@ void z180_device::z180_internal_port_write(uint8_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; @@ -1250,21 +1131,6 @@ void z180_device::z180_internal_port_write(uint8_t port, uint8_t data) z180_mmu(); break; - case 0x3b: - LOG("Z180 IO3B wr $%02x\n", data); - // IO3B does not exist - break; - - case 0x3c: - LOG("Z180 IO3C wr $%02x\n", data); - // IO3C does not exist - break; - - case 0x3d: - LOG("Z180 IO3D wr $%02x\n", data); - // IO3D does not exist - break; - case 0x3e: LOG("Z180 OMCR wr $%02x ($%02x)\n", data, data & Z180_OMCR_MASK); m_omcr = data & Z180_OMCR_MASK; @@ -1274,6 +1140,117 @@ void z180_device::z180_internal_port_write(uint8_t port, uint8_t data) LOG("Z180 IOCR wr $%02x ($%02x)\n", data, data & (m_extended_io ? 0xa0 : 0xe0)); m_iocr = data & (m_extended_io ? 0xa0 : 0xe0); break; + + default: + LOG("Z180 IO%02X wr $%02x\n", port, data); + break; + + } +} + +uint8_t z8s180_device::z180_internal_port_read(uint8_t port) +{ + uint8_t data = 0xff; + + switch (port) + { + 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 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: + 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: + 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 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: + 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; } } @@ -1750,16 +1727,12 @@ void z180_device::device_start() 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); @@ -1771,8 +1744,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); @@ -1831,9 +1802,6 @@ void z180_device::device_start() 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)); @@ -1842,8 +1810,6 @@ void z180_device::device_start() 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)); @@ -1870,6 +1836,26 @@ void z180_device::device_start() set_icountptr(m_icount); } +void z8s180_device::device_start() +{ + z180_device::device_start(); + + 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_ASEXT1, "ASEXT1", m_asci_ext[1]).mask(Z180_ASEXT1_MASK); + state_add(Z180_ASTC1, "ASTC1", m_asci_tc[1].w); + + state_add(Z180_CMR, "CMR", m_cmr).mask(Z180_CMR_MASK); + state_add(Z180_CCR, "CCR", m_ccr); + + 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_cmr)); + save_item(NAME(m_ccr)); +} + /**************************************************************************** * Reset registers to their initial values ****************************************************************************/ @@ -1934,10 +1920,6 @@ void z180_device::device_reset() 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; @@ -1954,6 +1936,15 @@ void z180_device::device_reset() z180_mmu(); } +void z8s180_device::device_reset() +{ + m_asci_ext[0] = 0x00; + m_asci_ext[1] = 0x00; + m_cmr = 0x00; + m_ccr = 0x00; + notify_clock_changed(); +} + /* 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() { diff --git a/src/devices/cpu/z180/z180.h b/src/devices/cpu/z180/z180.h index ee75a43ca92..69663c73814 100644 --- a/src/devices/cpu/z180/z180.h +++ b/src/devices/cpu/z180/z180.h @@ -169,16 +169,12 @@ private: uint8_t m_asci_stat[2]; // ASCI status register 0-1 uint8_t m_asci_tdr[2]; // ASCI transmit data register 0-1 uint8_t m_asci_rdr[2]; // ASCI receive data register 0-1 - uint8_t m_asci_ext[2]; // (Z8S180/Z8L180) ASCI extension control register 0-1 - PAIR16 m_asci_tc[2]; // (Z8S180/Z8L180) ASCI time constant ch 0-1 uint8_t m_csio_cntr; // CSI/O control/status register uint8_t m_csio_trdr; // CSI/O transmit/receive register PAIR16 m_tmdr[2]; // TIMER data register ch 0-1 PAIR16 m_rldr[2]; // TIMER reload register ch 0-1 uint8_t m_tcr; // TIMER control register uint8_t m_frc; // free running counter - uint8_t m_cmr; // (Z8S180/Z8L180) clock multiplier - uint8_t m_ccr; // (Z8S180/Z8L180) chip control register PAIR m_dma_sar0; // DMA source address register ch 0 PAIR m_dma_dar0; // DMA destination address register ch 0 PAIR16 m_dma_bcr[2]; // DMA byte register ch 0-1 @@ -1817,9 +1813,29 @@ class z8s180_device : public z180_device public: // construction/destruction z8s180_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + z8s180_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // device_execute_interface overrides + virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override { return BIT(m_cmr, 7) ? (clocks * 2) : BIT(m_ccr, 7) ? clocks : (clocks + 2 - 1) / 2; } + virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override { return BIT(m_cmr, 7) ? (cycles + 2 - 1) / 2 : BIT(m_ccr, 7) ? cycles : (cycles * 2); } + + virtual uint8_t z180_internal_port_read(uint8_t port) override; + virtual void z180_internal_port_write(uint8_t port, uint8_t data) override; + +private: + uint8_t m_asci_ext[2]; // ASCI extension control register 0-1 + PAIR16 m_asci_tc[2]; // ASCI time constant ch 0-1 + uint8_t m_cmr; // clock multiplier + uint8_t m_ccr; // chip control register }; -class z80182_device : public z180_device +class z80182_device : public z8s180_device { public: // construction/destruction diff --git a/src/mame/drivers/20pacgal.cpp b/src/mame/drivers/20pacgal.cpp index f72bce8aa23..973f76e6632 100644 --- a/src/mame/drivers/20pacgal.cpp +++ b/src/mame/drivers/20pacgal.cpp @@ -101,7 +101,7 @@ Graphics: CY37256P160-83AC x 2 (Ultra37000 CPLD family - 160 pin TQFP, 256 Macro *************************************/ #define MASTER_CLOCK (XTAL(73'728'000)) -#define MAIN_CPU_CLOCK (MASTER_CLOCK / 2) // divided by 2 internally in the Z180 core +#define MAIN_CPU_CLOCK (MASTER_CLOCK / 4) #define NAMCO_AUDIO_CLOCK (MASTER_CLOCK / 4 / 6 / 32) -- cgit v1.2.3