summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2018-03-16 01:01:00 -0400
committer AJR <ajrhacker@users.noreply.github.com>2018-03-16 01:01:27 -0400
commitf715fc495c6b37c157dbebe594452c74b5adbb6e (patch)
treecacd8a737b140ee81ebbc80792f5395d22b91aa9
parent084d9a4ed3f47590fa02907ab45a11fe78adf2cb (diff)
ay31015: Fix receiver desync when next start bit arrives early
-rw-r--r--src/devices/machine/ay31015.cpp65
-rw-r--r--src/devices/machine/ay31015.h1
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;