summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/68561mpcc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/68561mpcc.cpp')
-rw-r--r--src/devices/machine/68561mpcc.cpp48
1 files changed, 37 insertions, 11 deletions
diff --git a/src/devices/machine/68561mpcc.cpp b/src/devices/machine/68561mpcc.cpp
index 8b93885ffc2..4e0221e712c 100644
--- a/src/devices/machine/68561mpcc.cpp
+++ b/src/devices/machine/68561mpcc.cpp
@@ -609,6 +609,12 @@ void mpcc_device::rcv_complete()
data = get_received_char();
LOGRX("%s %02x [%c]\n", FUNCNAME, isascii(data) ? data : ' ', data);
+ uint8_t errors = 0;
+ if (is_receive_parity_error())
+ errors |= REG_RSR_CPERR;
+ if (is_receive_framing_error())
+ errors |= REG_RSR_FRERR;
+
// receive_data(data);
if (m_rx_data_fifo.full())
{
@@ -622,7 +628,12 @@ void mpcc_device::rcv_complete()
}
else
{
- m_rx_data_fifo.enqueue(data);
+ if (m_rx_data_fifo.empty())
+ {
+ m_rsr |= errors;
+ update_interrupts(INT_RX);
+ }
+ m_rx_data_fifo.enqueue(data | errors << 8);
m_rsr |= REG_RSR_RDA;
// interrupt if rx data availble is enabled
if (m_rier & REG_RIER_RDA)
@@ -747,13 +758,14 @@ void mpcc_device::update_interrupts(int source)
switch(source)
{
+ case INT_TX:
case INT_TX_TDRA:
case INT_TX_TFC:
case INT_TX_TUNRN:
case INT_TX_TFERR:
- if ( m_tsr & (REG_TSR_TDRA | REG_TSR_TFC | REG_TSR_TUNRN | REG_TSR_TFERR) )
+ if (m_tsr & m_tier & (REG_TSR_TDRA | REG_TSR_TFC | REG_TSR_TUNRN | REG_TSR_TFERR))
{
- LOGINT(" - Found unserved TX interrupt %02x\n", m_tsr);
+ LOGINT(" - Found unserved TX interrupt %02x\n", m_tsr & m_tier);
m_int_state[TX_INT_PRIO] = INT_REQ; // Still TX interrupts to serve
}
else
@@ -761,15 +773,16 @@ void mpcc_device::update_interrupts(int source)
m_int_state[TX_INT_PRIO] = INT_NONE; // No more TX interrupts to serve
}
break;
+ case INT_RX:
case INT_RX_RDA:
case INT_RX_EOF:
case INT_RX_CPERR:
case INT_RX_FRERR:
case INT_RX_ROVRN:
case INT_RX_RAB:
- if ( m_rsr & (REG_RSR_RDA | REG_RSR_EOF | REG_RSR_CPERR | REG_RSR_FRERR | REG_RSR_ROVRN | REG_RSR_RAB))
+ if (m_rsr & m_rier & (REG_RSR_RDA | REG_RSR_EOF | REG_RSR_CPERR | REG_RSR_FRERR | REG_RSR_ROVRN | REG_RSR_RAB))
{
- LOGINT(" - Found unserved RX interrupt %02x\n", m_rsr);
+ LOGINT(" - Found unserved RX interrupt %02x\n", m_rsr & m_rier);
m_int_state[RX_INT_PRIO] = INT_REQ; // Still RX interrupts to serve
}
else
@@ -777,12 +790,13 @@ void mpcc_device::update_interrupts(int source)
m_int_state[RX_INT_PRIO] = INT_NONE; // No more RX interrupts to serve
}
break;
+ case INT_SR:
case INT_SR_CTS:
case INT_SR_DSR:
case INT_SR_DCD:
- if ( m_sisr & (REG_SISR_CTST | REG_SISR_DSRT | REG_SISR_DCDT ) )
+ if (m_sisr & m_sier & (REG_SISR_CTST | REG_SISR_DSRT | REG_SISR_DCDT))
{
- LOGINT(" - Found unserved SR interrupt %02x\n", m_sisr);
+ LOGINT(" - Found unserved SR interrupt %02x\n", m_sisr & m_sier);
m_int_state[SR_INT_PRIO] = INT_REQ; // Still SR interrupts to serve
}
else
@@ -865,12 +879,15 @@ WRITE8_MEMBER( mpcc_device::write )
}
}
-// TODO: Sync clear of error bits with readout from fifo
// TODO: implement Idle bit
void mpcc_device::do_rsr(uint8_t data)
{
LOG("%s -> %02x\n", FUNCNAME, data);
- m_rsr = data;
+ // writing 1 resets status bits except for RDA which is read-only
+ m_rsr &= ~data | REG_RSR_RDA;
+ // status belonging to data at the head of the FIFO cannot be cleared
+ if (!m_rx_data_fifo.empty())
+ m_rsr |= m_rx_data_fifo.peek() >> 8;
update_interrupts(INT_RX);
}
@@ -909,7 +926,7 @@ uint8_t mpcc_device::do_rdr()
if (!m_rx_data_fifo.empty())
{
// load data from the FIFO
- data = m_rx_data_fifo.dequeue();
+ data = m_rx_data_fifo.dequeue() & 0xff;
// Check if this was the last data and reset the interrupt and status register accordingly
if (m_rx_data_fifo.empty())
@@ -917,6 +934,11 @@ uint8_t mpcc_device::do_rdr()
m_rsr &= ~REG_RSR_RDA;
update_interrupts(INT_RX_RDA);
}
+ else
+ {
+ m_rsr |= m_rx_data_fifo.peek() >> 8;
+ update_interrupts(INT_RX);
+ }
}
else
{
@@ -952,6 +974,7 @@ void mpcc_device::do_rier(uint8_t data)
LOGSETUP(" - Rx INT on Frame error : %s\n", (m_rier & REG_RIER_FRERR) ? "enabled" : "disabled");
LOGSETUP(" - Rx INT on Receiver overrun : %s\n", (m_rier & REG_RIER_ROVRN) ? "enabled" : "disabled");
LOGSETUP(" - Rx INT on Abort/Break : %s\n", (m_rier & REG_RIER_RAB) ? "enabled" : "disabled");
+ update_interrupts(INT_RX);
}
uint8_t mpcc_device::do_rier()
@@ -1004,7 +1027,8 @@ void mpcc_device::do_tdr(uint8_t data)
void mpcc_device::do_tsr(uint8_t data)
{
LOGINT("%s -> %02x\n", FUNCNAME, data);
- m_tsr = data;
+ // writing 1 resets status bits except for TDRA which is read-only
+ m_tsr &= ~data | REG_TSR_TDRA;
update_interrupts(INT_TX);
}
@@ -1060,6 +1084,7 @@ void mpcc_device::do_tier(uint8_t data)
LOGSETUP(" - Tx INT on Frame complete : %s\n", (m_tier & REG_TIER_TFC ) ? "enabled" : "disabled");
LOGSETUP(" - Tx INT on Underrun : %s\n", (m_tier & REG_TIER_TUNRN) ? "enabled" : "disabled");
LOGSETUP(" - Tx INT on Frame error : %s\n", (m_tier & REG_TIER_TFERR) ? "enabled" : "disabled");
+ update_interrupts(INT_TX);
}
uint8_t mpcc_device::do_tier()
@@ -1131,6 +1156,7 @@ void mpcc_device::do_sier(uint8_t data)
LOGSETUP(" - Serial interface INT on CTS: %s\n", (m_sier & REG_SIER_CTS) ? "enabled" : "disabled");
LOGSETUP(" - Serial interface INT on DSR: %s\n", (m_sier & REG_SIER_DSR) ? "enabled" : "disabled");
LOGSETUP(" - Serial interface INT on DCD: %s\n", (m_sier & REG_SIER_DCD) ? "enabled" : "disabled");
+ update_interrupts(INT_SR);
}
uint8_t mpcc_device::do_sier()