From 5a25c8887a5e9b859f10c0af1d389ad723144465 Mon Sep 17 00:00:00 2001 From: smf- Date: Fri, 25 Oct 2024 11:33:07 +0100 Subject: h8_sci: Disable logging by default & don't log debugger reads. Only start sending data via DMA if transmitter is enabled. Clear TEND when sending data via DMA. TDRE, RDRF, ORER, PER and FER flags can be cleared to 0 only if they have first been read while set to 1. Only set TEND when there is no more data to send. Receiver is started only on high to low rxd in asynchronous mode, when receiving and sending in synchronous mode when data is sent, or continuously when receiving without sending in synchronous mode. Set rx status to idle when stopping clock in rx_async_step(). Remove double invert when calculating parity in rx_async_step(). Remove redundant check for synchronous mode in rx_async_step(). --- src/devices/cpu/h8/h8_sci.cpp | 93 +++++++++++++++++++++++-------------------- src/devices/cpu/h8/h8_sci.h | 7 ++-- 2 files changed, 53 insertions(+), 47 deletions(-) diff --git a/src/devices/cpu/h8/h8_sci.cpp b/src/devices/cpu/h8/h8_sci.cpp index 5cdb3f2bdeb..d750d63c848 100644 --- a/src/devices/cpu/h8/h8_sci.cpp +++ b/src/devices/cpu/h8/h8_sci.cpp @@ -5,7 +5,6 @@ #include "h8_sci.h" #include "h8.h" -#include "h8_intc.h" #define LOG_REGS (1 << 1U) // Register writes #define LOG_RREGS (1 << 2U) // Register reads @@ -15,8 +14,8 @@ #define LOG_STATE (1 << 6U) // State machine states #define LOG_TICK (1 << 7U) // Clock ticks -#define VERBOSE (LOG_DATA) - +//#define VERBOSE (LOG_DATA) +//#define LOG_OUTPUT_FUNC osd_printf_info #include "logmacro.h" DEFINE_DEVICE_TYPE(H8_SCI, h8_sci_device, "h8_sci", "H8 Serial Communications Interface") @@ -70,7 +69,7 @@ h8_sci_device::h8_sci_device(const machine_config &mconfig, const char *tag, dev m_external_to_internal_ratio(0), m_internal_to_external_ratio(0), m_sync_timer(nullptr), m_id(0), m_eri_int(0), m_rxi_int(0), m_txi_int(0), m_tei_int(0), m_tx_state(0), m_rx_state(0), m_tx_bit(0), m_rx_bit(0), m_clock_state(0), m_tx_parity(0), m_rx_parity(0), m_tx_clock_counter(0), m_rx_clock_counter(0), m_clock_mode(INTERNAL_ASYNC), m_ext_clock_value(false), m_rx_value(true), - m_rdr(0), m_tdr(0), m_smr(0), m_scr(0), m_ssr(0), m_brr(0), m_rsr(0), m_tsr(0), m_clock_event(0), m_divider(0) + m_rdr(0), m_tdr(0), m_smr(0), m_scr(0), m_ssr(0), m_ssr_read(0), m_brr(0), m_rsr(0), m_tsr(0), m_clock_event(0), m_divider(0) { m_external_clock_period = attotime::never; } @@ -94,11 +93,14 @@ void h8_sci_device::smr_w(u8 data) m_cpu->pc()); clock_update(); + + sync_rx_start(); } u8 h8_sci_device::smr_r() { - LOGMASKED(LOG_RREGS, "smr_r %02x (%06x)\n", m_smr, m_cpu->pc()); + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_RREGS, "smr_r %02x (%06x)\n", m_smr, m_cpu->pc()); return m_smr; } @@ -111,13 +113,15 @@ void h8_sci_device::brr_w(u8 data) u8 h8_sci_device::brr_r() { - LOGMASKED(LOG_RREGS, "brr_r %02x (%06x)\n", m_brr, m_cpu->pc()); + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_RREGS, "brr_r %02x (%06x)\n", m_brr, m_cpu->pc()); return m_brr; } -bool h8_sci_device::is_sync_start() const +void h8_sci_device::sync_rx_start() { - return (m_smr & SMR_CA) && ((m_scr & (SCR_TE|SCR_RE)) == (SCR_TE|SCR_RE)); + if (m_rx_state == ST_IDLE && (m_smr & SMR_CA) && (m_scr & SCR_RE) && !(m_scr & SCR_TE) && !has_recv_error()) + rx_start(); } bool h8_sci_device::has_recv_error() const @@ -146,8 +150,8 @@ void h8_sci_device::scr_w(u8 data) clock_stop(CLK_RX); } - if((delta & SCR_RE) && (m_scr & SCR_RE) && m_rx_state == ST_IDLE && !has_recv_error() && !is_sync_start()) - rx_start(); + if((delta & (SCR_RE | SCR_TE))) + sync_rx_start(); if((delta & SCR_TIE) && (m_scr & SCR_TIE) && (m_ssr & SSR_TDRE)) m_intc->internal_interrupt(m_txi_int); if((delta & SCR_TEIE) && (m_scr & SCR_TEIE) && (m_ssr & SSR_TEND)) @@ -160,7 +164,8 @@ void h8_sci_device::scr_w(u8 data) u8 h8_sci_device::scr_r() { - LOGMASKED(LOG_RREGS, "scr_r %02x (%06x)\n", m_scr, m_cpu->pc()); + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_RREGS, "scr_r %02x (%06x)\n", m_scr, m_cpu->pc()); return m_scr; } @@ -168,8 +173,8 @@ void h8_sci_device::tdr_w(u8 data) { LOGMASKED(LOG_REGS, "tdr_w %02x (%06x)\n", data, m_cpu->pc()); m_tdr = data; - if(m_cpu->access_is_dma()) { - m_ssr &= ~SSR_TDRE; + if ((m_cpu->access_is_dma()) && (m_scr & SCR_TE)) { + m_ssr &= ~(SSR_TDRE | SSR_TEND); if(m_tx_state == ST_IDLE) tx_start(); } @@ -177,37 +182,38 @@ void h8_sci_device::tdr_w(u8 data) u8 h8_sci_device::tdr_r() { - LOGMASKED(LOG_RREGS, "tdr_r %02x (%06x)\n", m_tdr, m_cpu->pc()); + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_RREGS, "tdr_r %02x (%06x)\n", m_tdr, m_cpu->pc()); return m_tdr; } void h8_sci_device::ssr_w(u8 data) { - if(!(m_scr & SCR_TE)) { - data |= SSR_TDRE; - m_ssr |= SSR_TDRE; - } - if((m_ssr & SSR_TDRE) && !(data & SSR_TDRE)) - m_ssr &= ~SSR_TEND; - m_ssr = ((m_ssr & ~SSR_MPBT) | (data & SSR_MPBT)) & (data | (SSR_TEND|SSR_MPB|SSR_MPBT)); + if ((m_scr & SCR_TE) && (m_ssr & m_ssr_read & SSR_TDRE) && !(data & SSR_TDRE)) + m_ssr &= ~(SSR_TDRE | SSR_TEND); + m_ssr = (m_ssr & (~m_ssr_read | data | SSR_TDRE | SSR_TEND | SSR_MPB) & ~SSR_MPBT) | (data & SSR_MPBT); LOGMASKED(LOG_REGS, "ssr_w %02x -> %02x (%06x)\n", data, m_ssr, m_cpu->pc()); if(m_tx_state == ST_IDLE && !(m_ssr & SSR_TDRE)) tx_start(); - if((m_scr & SCR_RE) && m_rx_state == ST_IDLE && !has_recv_error() && !is_sync_start()) - rx_start(); + sync_rx_start(); } u8 h8_sci_device::ssr_r() { - LOGMASKED(LOG_RREGS, "ssr_r %02x (%06x)\n", m_ssr, m_cpu->pc()); + if (!machine().side_effects_disabled()) + { + LOGMASKED(LOG_RREGS, "ssr_r %02x (%06x)\n", m_ssr, m_cpu->pc()); + m_ssr_read = m_ssr; + } return m_ssr; } u8 h8_sci_device::rdr_r() { - LOGMASKED(LOG_RREGS, "rdr_r %02x (%06x)\n", m_rdr, m_cpu->pc()); + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_RREGS, "rdr_r %02x (%06x)\n", m_rdr, m_cpu->pc()); if(!machine().side_effects_disabled() && m_cpu->access_is_dma()) m_ssr &= ~SSR_RDRF; @@ -221,7 +227,8 @@ void h8_sci_device::scmr_w(u8 data) u8 h8_sci_device::scmr_r() { - LOGMASKED(LOG_RREGS, "scmr_r (%06x)\n", m_cpu->pc()); + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_RREGS, "scmr_r (%06x)\n", m_cpu->pc()); return 0x00; } @@ -360,9 +367,10 @@ void h8_sci_device::do_rx_w(int state) if(m_rx_clock_counter == 1 || m_rx_clock_counter == 15) m_rx_clock_counter = 0; + if(m_rx_state == ST_IDLE && !(m_smr & SMR_CA) && (m_scr & SCR_RE) && m_rx_value && !state) + rx_start(); + m_rx_value = state; - if(!m_rx_value && !(m_clock_state & CLK_RX) && m_rx_state != ST_IDLE) - clock_start(CLK_RX); } void h8_sci_device::do_clk_w(int state) @@ -507,7 +515,7 @@ void h8_sci_device::tx_start() m_tx_bit = 1; } clock_start(CLK_TX); - if(m_rx_state == ST_IDLE && !has_recv_error() && is_sync_start()) + if(m_rx_state == ST_IDLE && (m_smr & SMR_CA) && (m_scr & SCR_TE) && (m_scr & SCR_RE) && !has_recv_error()) rx_start(); } @@ -584,13 +592,14 @@ void h8_sci_device::tx_async_step() m_tx_bit = 0; clock_stop(CLK_TX); m_cpu->do_sci_tx(m_id, 1); - m_ssr |= SSR_TEND; if(m_scr & SCR_TEIE) m_intc->internal_interrupt(m_tei_int); // if there's more to send, start the transmitter if((m_scr & SCR_TE) && !(m_ssr & SSR_TDRE)) tx_start(); + else + m_ssr |= SSR_TEND; break; default: @@ -620,13 +629,14 @@ void h8_sci_device::tx_sync_step() m_tx_state = ST_IDLE; clock_stop(CLK_TX); m_cpu->do_sci_tx(m_id, 1); - m_ssr |= SSR_TEND; if(m_scr & SCR_TEIE) m_intc->internal_interrupt(m_tei_int); // if there's more to send, start the transmitter if((m_scr & SCR_TE) && !(m_ssr & SSR_TDRE)) tx_start(); + else + m_ssr |= SSR_TEND; } else { m_cpu->do_sci_tx(m_id, m_tsr & 1); m_tsr >>= 1; @@ -642,13 +652,11 @@ void h8_sci_device::rx_start() if(m_smr & SMR_CA) { m_rx_state = ST_BIT; m_rx_bit = 8; - clock_start(CLK_RX); } else { m_rx_state = ST_START; m_rx_bit = 1; - if(!m_rx_value) - clock_start(CLK_RX); } + clock_start(CLK_RX); } void h8_sci_device::rx_done() @@ -672,12 +680,11 @@ void h8_sci_device::rx_done() else m_intc->internal_interrupt(m_rxi_int); } - if((m_scr & SCR_RE) && !has_recv_error() && !is_sync_start()) - rx_start(); - else { - clock_stop(CLK_RX); - m_rx_state = ST_IDLE; - } + + m_rx_state = ST_IDLE; + clock_stop(CLK_RX); + + sync_rx_start(); } void h8_sci_device::rx_async_tick() @@ -694,6 +701,7 @@ void h8_sci_device::rx_async_step() switch(m_rx_state) { case ST_START: if(m_rx_value) { + m_rx_state = ST_IDLE; clock_stop(CLK_RX); break; } @@ -702,7 +710,6 @@ void h8_sci_device::rx_async_step() break; case ST_BIT: - m_rx_parity ^= m_rx_value; m_rsr >>= 1; if(m_rx_value) { m_rx_parity = !m_rx_parity; @@ -710,9 +717,7 @@ void h8_sci_device::rx_async_step() } m_rx_bit--; if(!m_rx_bit) { - if(m_smr & SMR_CA) - rx_done(); - else if(m_smr & SMR_PE) { + if(m_smr & SMR_PE) { m_rx_state = ST_PARITY; m_rx_bit = 1; } else { diff --git a/src/devices/cpu/h8/h8_sci.h b/src/devices/cpu/h8/h8_sci.h index 53a319ecefe..32fbfe0442e 100644 --- a/src/devices/cpu/h8/h8_sci.h +++ b/src/devices/cpu/h8/h8_sci.h @@ -14,8 +14,9 @@ #pragma once +#include "h8_intc.h" + class h8_device; -class h8_intc_device; class h8_sci_device : public device_t { public: @@ -117,7 +118,7 @@ protected: u32 m_clock_mode; bool m_ext_clock_value, m_rx_value; - u8 m_rdr, m_tdr, m_smr, m_scr, m_ssr, m_brr, m_rsr, m_tsr; + u8 m_rdr, m_tdr, m_smr, m_scr, m_ssr, m_ssr_read, m_brr, m_rsr, m_tsr; u64 m_clock_event, m_clock_step, m_divider; std::string m_last_clock_message; @@ -144,7 +145,7 @@ protected: void rx_sync_tick(); void rx_sync_step(); - bool is_sync_start() const; + void sync_rx_start(); bool has_recv_error() const; }; -- cgit v1.2.3