From f715fc495c6b37c157dbebe594452c74b5adbb6e Mon Sep 17 00:00:00 2001 From: AJR Date: Fri, 16 Mar 2018 01:01:00 -0400 Subject: ay31015: Fix receiver desync when next start bit arrives early --- src/devices/machine/ay31015.cpp | 65 +++++++++++++++++++++++++++++++---------- src/devices/machine/ay31015.h | 1 + 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/src/devices/machine/ay31015.cpp b/src/devices/machine/ay31015.cpp index a2954762953..df122a498a3 100644 --- a/src/devices/machine/ay31015.cpp +++ b/src/devices/machine/ay31015.cpp @@ -79,6 +79,8 @@ Start bit (low), Bit 0, Bit 1... highest bit, Parity bit (if enabled), 1-2 stop #include "emu.h" #include "ay31015.h" +//#define VERBOSE 1 +#include "logmacro.h" /* control reg */ @@ -147,10 +149,12 @@ ay51013_device::ay51013_device(const machine_config &mconfig, const char *tag, d } //------------------------------------------------- -// device_start - device-specific startup +// device_resolve_objects - resolve objects that +// may be needed for other devices to set +// initial conditions at start time //------------------------------------------------- -void ay31015_device::device_start() +void ay31015_device::device_resolve_objects() { m_read_si_cb.resolve(); m_write_so_cb.resolve(); @@ -161,7 +165,14 @@ void ay31015_device::device_start() m_write_fe_cb.resolve(); m_write_pe_cb.resolve(); m_write_eoc_cb.resolve(); +} +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void ay31015_device::device_start() +{ m_rx_timer = timer_alloc(TIMER_RX); m_rx_timer->adjust(attotime::never); update_rx_timer(); @@ -281,7 +292,10 @@ void ay31015_device::rx_process() case PREP_TIME: // assist sync by ensuring high bit occurs m_rx_pulses--; if (get_si()) + { + LOG("Receiver idle\n"); m_rx_state = IDLE; + } return; case IDLE: @@ -298,11 +312,15 @@ void ay31015_device::rx_process() if (m_rx_pulses == 8) // start bit must be low at sample time { if (get_si()) + { + LOG("Receive false start bit\n"); m_rx_state = IDLE; + } } else if (!m_rx_pulses) // end of start bit { + LOG("Receive start bit\n"); m_rx_state = PROCESSING; m_rx_pulses = m_total_pulses; m_rx_bit_count = 0; @@ -330,6 +348,7 @@ void ay31015_device::rx_process() m_internal_sample = get_si(); m_rx_parity ^= m_internal_sample; // calculate cumulative parity m_rx_data |= m_internal_sample << m_rx_bit_count; + LOG("Receive data bit #%d: %d\n", m_rx_bit_count + 1, m_internal_sample); } return; @@ -359,7 +378,10 @@ void ay31015_device::rx_process() case FIRST_STOP_BIT: m_rx_pulses--; if (m_rx_pulses == 8) // sample input stream + { m_internal_sample = get_si(); + LOG("Receive stop bit: %d\n", m_internal_sample); + } else if (m_rx_pulses == 7) // set error flags { @@ -393,20 +415,18 @@ void ay31015_device::rx_process() update_status_pins(); } else - if (m_rx_pulses == 4) + if (m_rx_pulses == 4 && m_second_stop_bit) { - if (m_second_stop_bit) - { - /* We should wait for the full first stop bit and - the beginning of the second stop bit */ - m_rx_state = SECOND_STOP_BIT; - m_rx_pulses += m_second_stop_bit - 7; - } - else - { - /* We have seen a STOP bit, go back to PREP_TIME */ - m_rx_state = PREP_TIME; - } + /* We should wait for the full first stop bit and + the beginning of the second stop bit */ + m_rx_state = SECOND_STOP_BIT; + m_rx_pulses += m_second_stop_bit - 7; + } + else + if (!m_rx_pulses) + { + /* We have seen a STOP bit, go back to IDLE */ + m_rx_state = IDLE; } return; @@ -458,6 +478,7 @@ void ay31015_device::tx_process() m_status_reg &= ~STATUS_EOC; // we are no longer idle m_tx_parity = 0; update_status_pins(); + LOG("Transmit start bit\n"); } m_tx_pulses--; @@ -478,6 +499,7 @@ void ay31015_device::tx_process() } else set_so(0); + LOG("Transmit data bit #%d: %d\n", 9 - (m_tx_pulses >> 4), m_tx_data & 1); m_tx_data >>= 1; // adjust the shift register } @@ -503,6 +525,7 @@ void ay31015_device::tx_process() set_so(1); /* extra bit to set the correct parity */ else set_so(0); /* it was already correct */ + LOG("Transmit parity bit: %d\n", t1); } m_tx_pulses--; @@ -515,7 +538,10 @@ void ay31015_device::tx_process() case FIRST_STOP_BIT: if (m_tx_pulses == 16) + { set_so(1); /* create a stop bit (marking and soon idle) */ + LOG("Transmit stop bit\n"); + } m_tx_pulses--; if (!m_tx_pulses) { @@ -524,10 +550,14 @@ void ay31015_device::tx_process() { m_tx_state = SECOND_STOP_BIT; m_tx_pulses = m_second_stop_bit; + LOG("Transmit second stop bit\n"); } else if (m_status_reg & STATUS_TBMT) + { m_tx_state = IDLE; // if nothing to send, go idle + LOG("Transmitter idle\n"); + } else { m_tx_pulses = 16; @@ -538,11 +568,16 @@ void ay31015_device::tx_process() return; case SECOND_STOP_BIT: + if (m_tx_pulses == 16) + LOG("Transmit second stop bit\n"); m_tx_pulses--; if (!m_tx_pulses) { if (m_status_reg & STATUS_TBMT) + { m_tx_state = IDLE; // if nothing to send, go idle + LOG("Transmitter idle\n"); + } else { m_tx_pulses = 16; diff --git a/src/devices/machine/ay31015.h b/src/devices/machine/ay31015.h index f76584d82bf..85206d673c3 100644 --- a/src/devices/machine/ay31015.h +++ b/src/devices/machine/ay31015.h @@ -119,6 +119,7 @@ protected: ay31015_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); // device-level overrides + virtual void device_resolve_objects() override; virtual void device_start() override; virtual void device_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; -- cgit v1.2.3