From 83c82598e63c820e1df42d480194d63327eafb17 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Sat, 24 Feb 2024 03:28:33 +0100 Subject: Z80scc: Implement RTxC clock source (#12050) Fixes serial emulation at 115200 or 230400bps. Co-authored-by: Colin Leroy-Mira --- src/devices/machine/z80scc.cpp | 39 ++++++++++++++++++++++++++++++++------- src/devices/machine/z80scc.h | 1 + 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/devices/machine/z80scc.cpp b/src/devices/machine/z80scc.cpp index 83fd4f8c3e5..30b658e354b 100644 --- a/src/devices/machine/z80scc.cpp +++ b/src/devices/machine/z80scc.cpp @@ -2092,7 +2092,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 +2106,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 +2136,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 @@ -2795,18 +2797,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 +2907,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 diff --git a/src/devices/machine/z80scc.h b/src/devices/machine/z80scc.h index 1468b4d0726..7b28c4f036d 100644 --- a/src/devices/machine/z80scc.h +++ b/src/devices/machine/z80scc.h @@ -233,6 +233,7 @@ protected: virtual void device_reset() override; unsigned int get_brg_rate(); + unsigned int get_rtxc_rate(); void update_baudtimer(); void scc_register_write(uint8_t reg, uint8_t data); -- cgit v1.2.3