summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/z80sio.cpp
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2020-02-29 22:45:20 -0500
committer AJR <ajrhacker@users.noreply.github.com>2020-02-29 22:49:10 -0500
commit8e52be5c1ec4b6e2f5800c722bcd66b26558cd26 (patch)
tree2897519335ee21669f6a064bfe61f595d68393a3 /src/devices/machine/z80sio.cpp
parentd502c5a880006e70ebbd90db367bbf2e52087b8e (diff)
z80dart: Replace old device with new variant of modern SIO emulation
z80sio: Make LOGBIT less spammy; booleanize a few members (nw) machine/mtx.cpp: Remove unnecessary includes (nw)
Diffstat (limited to 'src/devices/machine/z80sio.cpp')
-rw-r--r--src/devices/machine/z80sio.cpp113
1 files changed, 85 insertions, 28 deletions
diff --git a/src/devices/machine/z80sio.cpp b/src/devices/machine/z80sio.cpp
index 767ef2e6e1e..6b3b511cb12 100644
--- a/src/devices/machine/z80sio.cpp
+++ b/src/devices/machine/z80sio.cpp
@@ -3,6 +3,7 @@
/***************************************************************************
Z80-SIO Serial Input/Output emulation
+ Z80-DART Dual Asynchronous Receiver/Transmitter emulation
Intel 8274 Multi-Protocol Serial Controller emulation
NEC µPD7201 Multiprotocol Serial Communications Controller emulation
@@ -119,7 +120,7 @@ enum : uint8_t
RR0_INTERRUPT_PENDING = 0x02,
RR0_TX_BUFFER_EMPTY = 0x04,
RR0_DCD = 0x08,
- RR0_SYNC_HUNT = 0x10,
+ RR0_SYNC_HUNT = 0x10, // RI on DART
RR0_CTS = 0x20,
RR0_TX_UNDERRUN = 0x40,
RR0_BREAK_ABORT = 0x80
@@ -254,9 +255,11 @@ constexpr uint16_t SDLC_RESIDUAL = 0x1d0f;
// device type definition
DEFINE_DEVICE_TYPE(Z80SIO_CHANNEL, z80sio_channel, "z80sio_channel", "Z80 SIO channel")
+DEFINE_DEVICE_TYPE(Z80DART_CHANNEL, z80dart_channel, "z80dart_channel", "Z80 DART channel")
DEFINE_DEVICE_TYPE(I8274_CHANNEL, i8274_channel, "i8274_channel", "Intel 8274 MPSC channel")
DEFINE_DEVICE_TYPE(MK68564_CHANNEL, mk68564_channel, "mk68564_channel", "Mostek MK68564 SIO channel")
DEFINE_DEVICE_TYPE(Z80SIO, z80sio_device, "z80sio", "Z80 SIO")
+DEFINE_DEVICE_TYPE(Z80DART, z80dart_device, "z80dart", "Z80 DART")
DEFINE_DEVICE_TYPE(I8274, i8274_device, "i8274", "Intel 8274 MPSC")
DEFINE_DEVICE_TYPE(UPD7201, upd7201_device, "upd7201", "NEC uPD7201 MPSC")
DEFINE_DEVICE_TYPE(MK68564, mk68564_device, "mk68564", "Mostek MK68564 SIO")
@@ -270,6 +273,12 @@ void z80sio_device::device_add_mconfig(machine_config &config)
Z80SIO_CHANNEL(config, CHANB_TAG, 0);
}
+void z80dart_device::device_add_mconfig(machine_config &config)
+{
+ Z80DART_CHANNEL(config, CHANA_TAG, 0);
+ Z80DART_CHANNEL(config, CHANB_TAG, 0);
+}
+
void i8274_device::device_add_mconfig(machine_config &config)
{
I8274_CHANNEL(config, CHANA_TAG, 0);
@@ -358,7 +367,7 @@ inline void z80sio_channel::tx_setup(uint16_t data, int bits, bool framing, bool
LOGBIT("%.6f TX_SR %05x data %04x flags %x\n" , machine().time().as_double() , m_tx_sr & TX_SR_MASK , data , m_tx_flags);
}
-inline void z80sio_channel::tx_setup_idle()
+void z80sio_channel::tx_setup_idle()
{
switch (m_wr4 & WR4_SYNC_MODE_MASK)
{
@@ -380,6 +389,11 @@ inline void z80sio_channel::tx_setup_idle()
m_tx_in_pkt = false;
}
+void z80dart_channel::tx_setup_idle()
+{
+ logerror("%s (sync mode not supported by DART)\n", FUNCNAME);
+}
+
//-------------------------------------------------
// z80sio_device - constructor
//-------------------------------------------------
@@ -407,6 +421,11 @@ z80sio_device::z80sio_device(const machine_config &mconfig, const char *tag, dev
{
}
+z80dart_device::z80dart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ z80sio_device(mconfig, Z80DART, tag, owner, clock)
+{
+}
+
i8274_device::i8274_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
z80sio_device(mconfig, type, tag, owner, clock)
{
@@ -943,12 +962,13 @@ z80sio_channel::z80sio_channel(
, m_rx_count(0)
, m_rx_bit(0)
, m_rx_sr(0)
- , m_rx_first(0)
+ , m_rx_first(false)
, m_rxd(1)
, m_tx_data(0)
, m_tx_clock(0), m_tx_count(0), m_tx_parity(0), m_tx_sr(0), m_tx_crc(0), m_tx_hist(0), m_tx_flags(0)
, m_txd(1), m_dtr(0), m_rts(0)
- , m_ext_latched(0), m_brk_latched(0), m_cts(0), m_dcd(0), m_sync(0)
+ , m_ext_latched(false), m_brk_latched(false)
+ , m_cts(0), m_dcd(0), m_sync(0)
, m_rr1_auto_reset(rr1_auto_reset)
{
LOG("%s\n",FUNCNAME);
@@ -963,6 +983,11 @@ z80sio_channel::z80sio_channel(const machine_config &mconfig, const char *tag, d
{
}
+z80dart_channel::z80dart_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : z80sio_channel(mconfig, Z80DART_CHANNEL, tag, owner, clock, RR1_END_OF_FRAME | RR1_CRC_FRAMING_ERROR | RR1_RESIDUE_CODE_MASK)
+{
+}
+
i8274_channel::i8274_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: z80sio_channel(mconfig, I8274_CHANNEL, tag, owner, clock, RR1_RX_OVERRUN_ERROR)
{
@@ -1005,23 +1030,13 @@ void z80sio_channel::device_start()
save_item(NAME(m_wr3));
save_item(NAME(m_wr4));
save_item(NAME(m_wr5));
- save_item(NAME(m_wr6));
- save_item(NAME(m_wr7));
save_item(NAME(m_rx_fifo_depth));
save_item(NAME(m_rx_data_fifo));
save_item(NAME(m_rx_error_fifo));
save_item(NAME(m_rx_clock));
save_item(NAME(m_rx_count));
- save_item(NAME(m_dlyd_rxd));
save_item(NAME(m_rx_bit));
- save_item(NAME(m_rx_bit_limit));
- save_item(NAME(m_rx_sync_fsm));
- save_item(NAME(m_rx_one_cnt));
save_item(NAME(m_rx_sr));
- save_item(NAME(m_rx_sync_sr));
- save_item(NAME(m_rx_crc_delay));
- save_item(NAME(m_rx_crc));
- save_item(NAME(m_rx_crc_en));
save_item(NAME(m_rx_parity));
save_item(NAME(m_rx_first));
save_item(NAME(m_tx_data));
@@ -1029,10 +1044,8 @@ void z80sio_channel::device_start()
save_item(NAME(m_tx_count));
save_item(NAME(m_tx_phase));
save_item(NAME(m_tx_parity));
- save_item(NAME(m_tx_in_pkt));
- save_item(NAME(m_tx_forced_sync));
+ save_item(NAME(m_tx_in_pkt)); // TODO: does this actually function in async mode?
save_item(NAME(m_tx_sr));
- save_item(NAME(m_tx_crc));
save_item(NAME(m_tx_hist));
save_item(NAME(m_tx_flags));
save_item(NAME(m_tx_delay));
@@ -1045,6 +1058,29 @@ void z80sio_channel::device_start()
save_item(NAME(m_dcd));
save_item(NAME(m_sync));
save_item(NAME(m_cts));
+ sync_save_state();
+}
+
+void z80sio_channel::sync_save_state()
+{
+ save_item(NAME(m_wr6));
+ save_item(NAME(m_wr7));
+ save_item(NAME(m_dlyd_rxd));
+ save_item(NAME(m_rx_bit_limit));
+ save_item(NAME(m_rx_sync_fsm));
+ save_item(NAME(m_rx_one_cnt));
+ save_item(NAME(m_rx_sync_sr));
+ save_item(NAME(m_rx_crc_delay));
+ save_item(NAME(m_rx_crc));
+ save_item(NAME(m_rx_crc_en));
+ //save_item(NAME(m_tx_in_pkt));
+ save_item(NAME(m_tx_forced_sync));
+ save_item(NAME(m_tx_crc));
+}
+
+void z80dart_channel::sync_save_state()
+{
+ // no need to save the above members
}
void mk68564_channel::device_start()
@@ -1104,7 +1140,7 @@ void z80sio_channel::device_reset()
m_uart->clear_interrupt(m_index, INT_TRANSMIT);
m_uart->clear_interrupt(m_index, INT_RECEIVE);
reset_ext_status();
- // FIXME: should this actually reset all the interrtupts, or just the prioritisation (daisy chain) logic?
+ // FIXME: should this actually reset all the interrupts, or just the prioritisation (daisy chain) logic?
if (m_index == z80sio_device::CHANNEL_A)
m_uart->reset_interrupts();
}
@@ -1258,6 +1294,11 @@ void z80sio_channel::sync_tx_sr_empty()
}
}
+void z80dart_channel::sync_tx_sr_empty()
+{
+ LOG("%s (sync mode not supported by DART)\n", FUNCNAME);
+}
+
bool z80sio_channel::get_tx_empty() const
{
// During CRC transmission, tx buffer is shown as full
@@ -1335,8 +1376,8 @@ void z80sio_channel::async_tx_setup()
void z80sio_channel::reset_ext_status()
{
// this will clear latched external pin state
- m_ext_latched = 0;
- m_brk_latched = 0;
+ m_ext_latched = false;
+ m_brk_latched = false;
read_ext();
// Clear any pending External interrupt
@@ -1380,7 +1421,7 @@ void z80sio_channel::trigger_ext_int()
// update line
if (!m_ext_latched)
read_ext();
- m_ext_latched = 1;
+ m_ext_latched = true;
// trigger interrupt if enabled
if (m_wr1 & WR1_EXT_INT_ENABLE)
@@ -1625,7 +1666,7 @@ void z80sio_channel::do_sioreg_wr0(uint8_t data)
case WR0_ENABLE_INT_NEXT_RX:
// enable interrupt on next receive character
LOGINT("%s Ch:%c : Enable Interrupt on Next Received Character\n", FUNCNAME, 'A' + m_index);
- m_rx_first = 1;
+ m_rx_first = true;
break;
case WR0_RESET_TX_INT:
LOGCMD("%s Ch:%c : Reset Transmitter Interrupt Pending\n", FUNCNAME, 'A' + m_index);
@@ -1925,6 +1966,11 @@ void z80sio_channel::enter_hunt_mode()
}
}
+void z80dart_channel::enter_hunt_mode()
+{
+ LOG("%s (sync mode not supported by DART)\n", FUNCNAME);
+}
+
//-------------------------------------------------
// sync_receive - synchronous reception handler
//-------------------------------------------------
@@ -2042,6 +2088,11 @@ void z80sio_channel::sync_receive()
m_dlyd_rxd = m_rxd;
}
+void z80dart_channel::sync_receive()
+{
+ LOG("%s (sync mode not supported by DART)\n", FUNCNAME);
+}
+
//-------------------------------------------------
// sdlc_receive - SDLC reception handler
//-------------------------------------------------
@@ -2068,7 +2119,7 @@ void z80sio_channel::sdlc_receive()
LOGRCV("SDLC Abort detected\n");
m_rr0 |= RR0_BREAK_ABORT;
if (!m_brk_latched) {
- m_brk_latched = 1;
+ m_brk_latched = true;
trigger_ext_int();
}
enter_hunt_mode();
@@ -2088,7 +2139,7 @@ void z80sio_channel::sdlc_receive()
{
m_rr0 &= ~RR0_BREAK_ABORT;
if (!m_brk_latched) {
- m_brk_latched = 1;
+ m_brk_latched = true;
trigger_ext_int();
}
}
@@ -2189,6 +2240,11 @@ void z80sio_channel::sdlc_receive()
}
}
+void z80dart_channel::sdlc_receive()
+{
+ logerror("%s (sync mode not supported by DART)\n", FUNCNAME);
+}
+
//-------------------------------------------------
// receive_data - receive data word
//-------------------------------------------------
@@ -2234,7 +2290,7 @@ void z80sio_channel::queue_received(uint16_t data, uint32_t error)
case WR1_RX_INT_FIRST:
if (m_rx_first || (error & get_special_rx_mask()))
m_uart->trigger_interrupt(m_index, INT_RECEIVE);
- m_rx_first = 0;
+ m_rx_first = false;
break;
case WR1_RX_INT_ALL_PARITY:
@@ -2340,7 +2396,7 @@ WRITE_LINE_MEMBER( z80sio_channel::rxc_w )
LOGRCV("Break termination detected\n");
m_rr0 &= ~RR0_BREAK_ABORT;
if (!m_brk_latched) {
- m_brk_latched = 1;
+ m_brk_latched = true;
trigger_ext_int();
}
}
@@ -2407,7 +2463,7 @@ WRITE_LINE_MEMBER( z80sio_channel::rxc_w )
{
LOGRCV("Break detected\n");
m_rr0 |= RR0_BREAK_ABORT;
- m_brk_latched = 1;
+ m_brk_latched = true;
trigger_ext_int();
}
}
@@ -2454,7 +2510,8 @@ WRITE_LINE_MEMBER( z80sio_channel::txc_w )
m_tx_count = get_clock_mode() / 2;
// Send out a delayed half bit
bool new_txd = BIT(m_tx_delay , 3);
- LOGBIT("%.6f TX %d DLY %x\n" , machine().time().as_double() , new_txd , m_tx_delay & 0xf);
+ if ((m_wr4 & WR4_STOP_BITS_MASK) == WR4_STOP_BITS_SYNC || !(m_rr1 & RR1_ALL_SENT))
+ LOGBIT("%.6f TX %d DLY %x\n" , machine().time().as_double() , new_txd , m_tx_delay & 0xf);
if (new_txd != m_txd && !(m_wr5 & WR5_SEND_BREAK))
{
out_txd_cb(new_txd);