summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/z80scc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/z80scc.cpp')
-rw-r--r--src/devices/machine/z80scc.cpp56
1 files changed, 37 insertions, 19 deletions
diff --git a/src/devices/machine/z80scc.cpp b/src/devices/machine/z80scc.cpp
index 209202b4bde..66c3e0b1af6 100644
--- a/src/devices/machine/z80scc.cpp
+++ b/src/devices/machine/z80scc.cpp
@@ -1459,13 +1459,15 @@ void z80scc_channel::update_rts()
if (m_wr5 & WR5_RTS)
{
// when the RTS bit is set, the _RTS output goes low
- set_rts(0);
m_rts = 1;
+ set_rts(!m_rts);
}
else
{
// when the RTS bit is reset, the _RTS output goes high after the transmitter empties
m_rts = 0;
+ if (!(m_wr3 & WR3_AUTO_ENABLES) || (m_rr1 & RR1_ALL_SENT))
+ set_rts(!m_rts);
}
// data terminal ready output follows the state programmed into the DTR bit*/
@@ -2621,8 +2623,6 @@ void z80scc_channel::data_write(uint8_t data)
LOGTX("- TX FIFO has more room, setting TBE bit\n");
m_rr0 |= RR0_TX_BUFFER_EMPTY; // or there is a slot in the FIFO available
}
- LOGTX("- TX FIFO now has data to send, clearing ALL_SENT bit\n");
- m_rr1 &= ~RR1_ALL_SENT; // All is definitelly not sent anymore
}
check_waitrequest();
@@ -2636,7 +2636,8 @@ void z80scc_channel::data_write(uint8_t data)
LOGTX("- Setting up transmitter\n");
transmit_register_setup(m_tx_data_fifo[m_tx_fifo_rp]); // Load the shift register, reload is done in tra_complete()
m_tx_fifo_rp_step();
- m_rr1 |= RR1_ALL_SENT; // Now stuff is on its way again
+ LOGTX("- TX shift register loaded, clearing ALL_SENT bit\n");
+ m_rr1 &= ~RR1_ALL_SENT; // All is definitely not sent anymore
m_rr0 |= RR0_TX_BUFFER_EMPTY; // And there is a slot in the FIFO available
}
else
@@ -2730,7 +2731,7 @@ WRITE_LINE_MEMBER( z80scc_channel::cts_w )
{
LOG("\"%s\"%s: %c : CTS %u\n", owner()->tag(), FUNCNAME, 'A' + m_index, state);
- if ((m_rr0 & RR0_CTS) != (state ? RR0_CTS : 0)) // SCC change detection logic
+ if ((m_rr0 & RR0_CTS) != (state ? 0 : RR0_CTS)) // SCC change detection logic
{
// enable transmitter if in auto enables mode
if (!state)
@@ -2743,7 +2744,7 @@ WRITE_LINE_MEMBER( z80scc_channel::cts_w )
}
}
- if (state) m_rr0 |= RR0_CTS; else m_rr0 &= ~RR0_CTS; // Raw pin/status value
+ if (state) m_rr0 &= ~RR0_CTS; else m_rr0 |= RR0_CTS; // Raw pin/status value
if (m_extint_latch == 0 && (m_wr1 & WR1_EXT_INT_ENABLE) && (m_wr15 & WR15_CTS))
{
@@ -2767,7 +2768,7 @@ WRITE_LINE_MEMBER( z80scc_channel::dcd_w )
{
LOGDCD("\"%s\": %c : DCD %u\n", owner()->tag(), 'A' + m_index, state);
- if ((m_rr0 & RR0_DCD) != (state ? RR0_DCD : 0)) // SCC change detection logic
+ if ((m_rr0 & RR0_DCD) != (state ? 0 : RR0_DCD)) // SCC change detection logic
{
// enable transmitter if in auto enables mode
if (!state)
@@ -2783,7 +2784,7 @@ WRITE_LINE_MEMBER( z80scc_channel::dcd_w )
}
}
- if (state) m_rr0 |= RR0_DCD; else m_rr0 &= ~RR0_DCD; // Raw pin/status value
+ if (state) m_rr0 &= ~RR0_DCD; else m_rr0 |= RR0_DCD; // Raw pin/status value
if (m_extint_latch == 0 && (m_wr1 & WR1_EXT_INT_ENABLE) && (m_wr15 & WR15_DCD))
{
@@ -2799,25 +2800,42 @@ WRITE_LINE_MEMBER( z80scc_channel::dcd_w )
}
}
-
-//-------------------------------------------------
-// ri_w - ring indicator handler
-//-------------------------------------------------
-WRITE_LINE_MEMBER( z80scc_channel::ri_w )
-{
- LOGINT("\"%s\": %c : RI %u - not implemented\n", owner()->tag(), 'A' + m_index, state);
-}
-
//-------------------------------------------------
// sync_w - sync handler for external sync mode
//-------------------------------------------------
WRITE_LINE_MEMBER( z80scc_channel::sync_w )
{
LOGSYNC("\"%s\": %c : SYNC %u\n", owner()->tag(), 'A' + m_index, state);
- if ((m_rr0 & RR0_SYNC_HUNT) != (state ? RR0_SYNC_HUNT : 0)) // SCC change detection logic
+
+ /*
+ * The /SYNC pin is a general purpose input whose state is reported in the
+ * Sync/Hunt bit in RR0. If the crystal oscillator is enabled, this pin is
+ * not available and the Sync/Hunt bit is forced to 0. Otherwise, the /SYNC
+ * pin may be used to carry the Ring Indicator signal.
+ */
+ if (!(m_wr11 & WR11_RCVCLK_TYPE))
{
- if (state) m_rr0 |= RR0_SYNC_HUNT; else m_rr0 &= ~RR0_SYNC_HUNT; // Raw pin/status value
+ // check for state change
+ if ((m_rr0 & RR0_SYNC_HUNT) != (state ? 0 : RR0_SYNC_HUNT))
+ {
+ // record pin state (inverted)
+ if (state)
+ m_rr0 &= ~RR0_SYNC_HUNT;
+ else
+ m_rr0 |= RR0_SYNC_HUNT;
+
+ // trigger an external interrupt if enabled
+ if (m_extint_latch == 0 && (m_wr1 & WR1_EXT_INT_ENABLE) && (m_wr15 & WR15_SYNC))
+ {
+ m_extint_latch = 1;
+ m_extint_states = m_rr0;
+
+ m_uart->trigger_interrupt(m_index, INT_EXTERNAL);
+ }
+ }
}
+ else
+ fatalerror("/SYNC cannot be used as an input in RTxC-XTAL clock mode.");
}
//-------------------------------------------------