diff options
Diffstat (limited to 'src/devices/machine/mc68901.cpp')
-rw-r--r-- | src/devices/machine/mc68901.cpp | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/src/devices/machine/mc68901.cpp b/src/devices/machine/mc68901.cpp index 8da39d3a4bd..02011fe447f 100644 --- a/src/devices/machine/mc68901.cpp +++ b/src/devices/machine/mc68901.cpp @@ -211,10 +211,6 @@ inline void mc68901_device::rx_error() { take_interrupt(IR_RCV_ERROR); } - else - { - rx_buffer_full(); - } } inline void mc68901_device::timer_count(int index) @@ -414,7 +410,7 @@ void mc68901_device::device_start() save_item(NAME(m_transmit_buffer)); save_item(NAME(m_transmit_pending)); save_item(NAME(m_receive_buffer)); - save_item(NAME(m_receive_pending)); + save_item(NAME(m_overrun_pending)); save_item(NAME(m_gpio_input)); save_item(NAME(m_gpio_output)); save_item(NAME(m_rsr_read)); @@ -429,7 +425,8 @@ void mc68901_device::device_start() void mc68901_device::device_reset() { m_tsr = 0; - m_transmit_pending = 0; + m_transmit_pending = false; + m_overrun_pending = false; // Avoid read-before-write m_ipr = m_imr = 0; @@ -496,7 +493,7 @@ void mc68901_device::tra_complete() if (m_transmit_pending) { transmit_register_setup(m_transmit_buffer); - m_transmit_pending = 0; + m_transmit_pending = false; m_tsr |= TSR_BUFFER_EMPTY; if (m_ier & IR_XMIT_BUFFER_EMPTY) @@ -524,10 +521,16 @@ void mc68901_device::tra_complete() void mc68901_device::rcv_complete() { receive_register_extract(); - m_receive_buffer = get_received_char(); - //if (m_receive_pending) TODO: error? - - m_receive_pending = 1; + if (m_rsr & RSR_BUFFER_FULL) + { + m_overrun_pending = true; + } + else + { + m_receive_buffer = get_received_char(); + m_rsr |= RSR_BUFFER_FULL; + LOG("Received Character: %02x\n", m_receive_buffer); + } rx_buffer_full(); } @@ -565,19 +568,34 @@ READ8_MEMBER( mc68901_device::read ) case REGISTER_SCR: return m_scr; case REGISTER_UCR: return m_ucr; - case REGISTER_RSR: return m_rsr; + case REGISTER_RSR: + { + uint8_t rsr = m_rsr; + if (!machine().side_effect_disabled()) + m_rsr &= ~RSR_OVERRUN_ERROR; + return rsr; + } case REGISTER_TSR: { /* clear UE bit (in reality, this won't be cleared until one full clock cycle of the transmitter has passed since the bit was set) */ uint8_t tsr = m_tsr; - m_tsr &= ~TSR_UNDERRUN_ERROR; - + if (!machine().side_effect_disabled()) + m_tsr &= ~TSR_UNDERRUN_ERROR; return tsr; } case REGISTER_UDR: - m_receive_pending = 0; + if (!machine().side_effect_disabled()) + { + m_rsr &= ~RSR_BUFFER_FULL; + if (m_overrun_pending) + { + m_overrun_pending = false; + m_rsr |= RSR_OVERRUN_ERROR; + rx_error(); + } + } return m_receive_buffer; default: return 0; @@ -966,6 +984,7 @@ void mc68901_device::register_w(offs_t offset, uint8_t data) } set_data_frame(start_bits, data_bit_count, parity, stop_bits); + receive_register_reset(); m_ucr = data; } @@ -1052,22 +1071,23 @@ void mc68901_device::register_w(offs_t offset, uint8_t data) if (m_transmit_pending && is_transmit_register_empty()) { transmit_register_setup(m_transmit_buffer); - m_transmit_pending = 0; - m_tsr |= TSR_BUFFER_EMPTY; + m_transmit_pending = false; } + if (!m_transmit_pending) + m_tsr |= TSR_BUFFER_EMPTY; } break; case REGISTER_UDR: LOG("MC68901 UDR %x\n", data); m_transmit_buffer = data; - m_transmit_pending = 1; + m_transmit_pending = true; m_tsr &= ~TSR_BUFFER_EMPTY; if ((m_tsr & TSR_XMIT_ENABLE) && is_transmit_register_empty()) { transmit_register_setup(m_transmit_buffer); - m_transmit_pending = 0; + m_transmit_pending = false; m_tsr |= TSR_BUFFER_EMPTY; } break; |