summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/mc68901.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/mc68901.cpp')
-rw-r--r--src/devices/machine/mc68901.cpp58
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;