mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
ay31015: Fix receiver desync when next start bit arrives early
This commit is contained in:
parent
084d9a4ed3
commit
f715fc495c
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user