mirror of
https://github.com/holub/mame
synced 2025-04-18 22:49:58 +03:00
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().
This commit is contained in:
parent
bae7420375
commit
5a25c8887a
@ -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 {
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user