summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/z180/z180.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/z180/z180.cpp')
-rw-r--r--src/devices/cpu/z180/z180.cpp809
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;
}