diff options
Diffstat (limited to 'src/devices/machine/z80scc.cpp')
-rw-r--r-- | src/devices/machine/z80scc.cpp | 83 |
1 files changed, 58 insertions, 25 deletions
diff --git a/src/devices/machine/z80scc.cpp b/src/devices/machine/z80scc.cpp index 83fd4f8c3e5..7c999df4ac9 100644 --- a/src/devices/machine/z80scc.cpp +++ b/src/devices/machine/z80scc.cpp @@ -374,7 +374,7 @@ DEFINE_DEVICE_TYPE(Z80SCC_CHANNEL, z80scc_channel, "z80scc_channel", "Z80 SCC C DEFINE_DEVICE_TYPE(SCC8030, scc8030_device, "scc8030", "Zilog Z8030 SCC") DEFINE_DEVICE_TYPE(SCC80C30, scc80c30_device, "scc80c30", "Zilog Z80C30 SCC") DEFINE_DEVICE_TYPE(SCC80230, scc80230_device, "scc80230", "Zilog Z80230 ESCC") -DEFINE_DEVICE_TYPE(SCC8530N, scc8530_device, "scc8530", "Zilog Z8530 SCC") // remove trailing N when 8530scc.c is fully replaced and removed +DEFINE_DEVICE_TYPE(SCC8530, scc8530_device, "scc8530", "Zilog Z8530 SCC") DEFINE_DEVICE_TYPE(SCC85C30, scc85c30_device, "scc85c30", "Zilog Z85C30 SCC") DEFINE_DEVICE_TYPE(SCC85230, scc85230_device, "scc85230", "Zilog Z85230 ESCC") DEFINE_DEVICE_TYPE(SCC85233, scc85233_device, "scc85233", "Zilog Z85233 EMSCC") @@ -455,7 +455,7 @@ scc80230_device::scc80230_device(const machine_config &mconfig, const char *tag, } scc8530_device::scc8530_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : z80scc_device(mconfig, SCC8530N, tag, owner, clock, TYPE_SCC8530) + : z80scc_device(mconfig, SCC8530, tag, owner, clock, TYPE_SCC8530) { } @@ -1796,6 +1796,8 @@ void z80scc_channel::do_sccreg_wr0(uint8_t data) break; } } + // re-assert interrupt if conditions are still present + check_receive_interrupt(); break; case WR0_ERROR_RESET: /*Error Reset Command (110). This command resets the error bits in RR1. If interrupt on first Rx @@ -2092,7 +2094,7 @@ void z80scc_channel::do_sccreg_wr11(uint8_t data) /RTxC pin.*/ switch (data & WR11_RCVCLK_SRC_MASK) { - case WR11_RCVCLK_SRC_RTXC: LOG("Receive clock source is RTxC - not implemented\n"); break; + case WR11_RCVCLK_SRC_RTXC: LOG("Receive clock source is RTxC\n"); break; case WR11_RCVCLK_SRC_TRXC: LOG("Receive clock source is TRxC - not implemented\n"); break; case WR11_RCVCLK_SRC_BR: LOG("Receive clock source is Baudrate Generator\n"); break; case WR11_RCVCLK_SRC_DPLL: LOG("Receive clock source is DPLL - not implemented\n"); break; @@ -2106,7 +2108,7 @@ void z80scc_channel::do_sccreg_wr11(uint8_t data) source of the transmit clocks.*/ switch (data & WR11_TRACLK_SRC_MASK) { - case WR11_TRACLK_SRC_RTXC: LOG("Transmit clock source is RTxC - not implemented\n"); break; + case WR11_TRACLK_SRC_RTXC: LOG("Transmit clock source is RTxC\n"); break; case WR11_TRACLK_SRC_TRXC: LOG("Transmit clock source is TRxC - not implemented\n"); break; case WR11_TRACLK_SRC_BR: LOG("Transmit clock source is Baudrate Generator\n"); break; case WR11_TRACLK_SRC_DPLL: LOG("Transmit clock source is DPLL - not implemented\n"); break; @@ -2136,6 +2138,8 @@ void z80scc_channel::do_sccreg_wr11(uint8_t data) } else LOG("TRxC pin is Input\n"); + + update_serial(); } /*WR12 contains the lower byte of the time constant for the baud rate generator. The time constant @@ -2582,22 +2586,7 @@ void z80scc_channel::receive_data(uint8_t data) m_rr0 |= RR0_RX_CHAR_AVAILABLE; check_dma_request(); - // receive interrupt on FIRST and ALL character - switch (m_wr1 & WR1_RX_INT_MODE_MASK) - { - case WR1_RX_INT_FIRST: - if (m_rx_first) - { - m_uart->trigger_interrupt(m_index, INT_RECEIVE); - - m_rx_first = 0; - } - break; - - case WR1_RX_INT_ALL: - m_uart->trigger_interrupt(m_index, INT_RECEIVE); - break; - } + check_receive_interrupt(); } @@ -2795,18 +2784,30 @@ unsigned int z80scc_channel::get_brg_rate() if (m_wr14 & WR14_BRG_SOURCE) // Do we use the PCLK as baudrate source { rate = owner()->clock() / (brg_const == 0 ? 1 : brg_const); - LOG(" - Source bit rate (%d) = PCLK (%d) / (%d)\n", rate, owner()->clock(), brg_const); + LOG(" - BRG Source bit rate (%d) = PCLK (%d) / (%d)\n", rate, owner()->clock(), brg_const); } else // Else we use the RTxC as BRG source { unsigned int source = (m_index == z80scc_device::CHANNEL_A) ? m_uart->m_rxca : m_uart->m_rxcb; rate = source / (brg_const == 0 ? 1 : brg_const); - LOG(" - Source bit rate (%d) = RTxC (%d) / (%d)\n", rate, source, brg_const); + LOG(" - BRG Source bit rate (%d) = RTxC (%d) / (%d)\n", rate, source, brg_const); } return (rate / (2 * get_clock_mode())); } +//------------------------------------------------- +// get_rtxc_rate +//------------------------------------------------- +unsigned int z80scc_channel::get_rtxc_rate() +{ + unsigned int rate; + unsigned int source = (m_index == z80scc_device::CHANNEL_A) ? m_uart->m_rxca : m_uart->m_rxcb; + rate = source / get_clock_mode(); + LOG(" - RTxC Source bit rate (%d) = RTxC (%d) / (%d)\n", rate, source, get_clock_mode()); + return rate; +} + void z80scc_channel::update_baudtimer() { unsigned int rate; @@ -2893,9 +2894,20 @@ void z80scc_channel::update_serial() } else { - LOG("- BRG disabled\n"); - set_rcv_rate(0); - set_tra_rate(0); + if ((m_wr11 & WR11_RCVCLK_SRC_MASK) == WR11_RCVCLK_SRC_RTXC && + (m_wr11 & WR11_TRACLK_SRC_MASK) == WR11_TRACLK_SRC_RTXC) + { + m_brg_rate = get_rtxc_rate(); + LOG("- BRG disabled, clock source RTxC (rate %d, clock %d)\n", m_brg_rate, get_clock_mode()); + set_rcv_rate(m_brg_rate); + set_tra_rate(m_brg_rate); + } + else + { + LOG("- BRG disabled and RX/TX clock sources differ, unimplemented: stopping\n"); + set_rcv_rate(0); + set_tra_rate(0); + } } // TODO: Check registers for use of RTxC and TRxC, if used as direct Tx and/or Rx clocks set them to value as programmed // in m_uart->txca/txcb and rxca/rxcb respectivelly @@ -2980,3 +2992,24 @@ void z80scc_channel::check_dma_request() } } } + +void z80scc_channel::check_receive_interrupt() +{ + if (m_rr0 & RR0_RX_CHAR_AVAILABLE) + { + switch (m_wr1 & WR1_RX_INT_MODE_MASK) + { + case WR1_RX_INT_FIRST: + if (m_rx_first) + { + m_uart->trigger_interrupt(m_index, INT_RECEIVE); + m_rx_first = 0; + } + break; + + case WR1_RX_INT_ALL: + m_uart->trigger_interrupt(m_index, INT_RECEIVE); + break; + } + } +} |