diff options
-rw-r--r-- | src/devices/machine/mc68681.cpp | 93 | ||||
-rw-r--r-- | src/devices/machine/mc68681.h | 3 | ||||
-rw-r--r-- | src/devices/machine/mc68901.cpp | 16 |
3 files changed, 61 insertions, 51 deletions
diff --git a/src/devices/machine/mc68681.cpp b/src/devices/machine/mc68681.cpp index 29e252fa52a..b60567aa3f7 100644 --- a/src/devices/machine/mc68681.cpp +++ b/src/devices/machine/mc68681.cpp @@ -48,6 +48,8 @@ #include "emu.h" #include "mc68681.h" +#include <algorithm> + //#define VERBOSE 1 //#define LOG_OUTPUT_FUNC printf #include "logmacro.h" @@ -87,6 +89,7 @@ static const int baud_rate_ACR_1_X_1[] = { 50, 110, 134, 200, 3600, 14400, 28800 #define STATUS_RECEIVER_READY 0x01 #define MODE_RX_INT_SELECT_BIT 0x40 +#define MODE_BLOCK_ERROR 0x20 #define CHANA_TAG "cha" #define CHANB_TAG "chb" @@ -1062,6 +1065,7 @@ duart_channel::duart_channel(const machine_config &mconfig, const char *tag, dev , rx_fifo_num(0) , tx_enabled(0) { + std::fill_n(&rx_fifo[0], MC68681_RX_FIFO_SIZE, 0); } void duart_channel::device_start() @@ -1109,20 +1113,38 @@ void duart_channel::rcv_complete() if (rx_enabled) { - if (rx_fifo_num >= MC68681_RX_FIFO_SIZE) - { - logerror("68681: FIFO overflow\n"); - SR |= STATUS_OVERRUN_ERROR; - return; - } - rx_fifo[rx_fifo_write_ptr++] = get_received_char(); - if ( rx_fifo_write_ptr == MC68681_RX_FIFO_SIZE ) - { - rx_fifo_write_ptr = 0; - } - rx_fifo_num++; - update_interrupts(); + uint8_t errors = 0; + if (is_receive_framing_error()) + errors |= STATUS_FRAMING_ERROR; + if (is_receive_parity_error()) + errors |= STATUS_PARITY_ERROR; + rx_fifo_push(get_received_char(), errors); + } +} + +void duart_channel::rx_fifo_push(uint8_t data, uint8_t errors) +{ + if (rx_fifo_num >= MC68681_RX_FIFO_SIZE) + { + logerror("68681: FIFO overflow\n"); + SR |= STATUS_OVERRUN_ERROR; + return; } + + rx_fifo[rx_fifo_write_ptr++] = data | (errors << 8); + if (rx_fifo_write_ptr == MC68681_RX_FIFO_SIZE) + rx_fifo_write_ptr = 0; + + if (rx_fifo_num++ == 0) + { + SR |= STATUS_RECEIVER_READY; + if (!(MR1 & MODE_BLOCK_ERROR)) + SR &= ~(STATUS_RECEIVED_BREAK | STATUS_FRAMING_ERROR | STATUS_PARITY_ERROR); + SR |= errors; + } + if (rx_fifo_num == MC68681_RX_FIFO_SIZE) + SR |= STATUS_FIFO_FULL; + update_interrupts(); } void duart_channel::tra_complete() @@ -1138,22 +1160,7 @@ void duart_channel::tra_complete() // if local loopback is on, write the transmitted data as if a byte had been received if ((MR2 & 0xc0) == 0x80) - { - if (rx_fifo_num >= MC68681_RX_FIFO_SIZE) - { - LOG("68681: FIFO overflow\n"); - SR |= STATUS_OVERRUN_ERROR; - } - else - { - rx_fifo[rx_fifo_write_ptr++]= tx_data; - if (rx_fifo_write_ptr == MC68681_RX_FIFO_SIZE) - { - rx_fifo_write_ptr = 0; - } - rx_fifo_num++; - } - } + rx_fifo_push(tx_data, 0); update_interrupts(); } @@ -1190,26 +1197,6 @@ void duart_channel::tra_callback() void duart_channel::update_interrupts() { - if (rx_enabled) - { - if (rx_fifo_num > 0) - { - SR |= STATUS_RECEIVER_READY; - } - else - { - SR &= ~STATUS_RECEIVER_READY; - } - if (rx_fifo_num == MC68681_RX_FIFO_SIZE) - { - SR |= STATUS_FIFO_FULL; - } - else - { - SR &= ~STATUS_FIFO_FULL; - } - } - // Handle the TxEMT and TxRDY bits based on mode switch (MR2 & 0xc0) // what mode are we in? { @@ -1298,6 +1285,13 @@ uint8_t duart_channel::read_rx_fifo() } rx_fifo_num--; + SR &= ~STATUS_FIFO_FULL; + if (!(MR1 & MODE_BLOCK_ERROR)) + SR &= ~(STATUS_RECEIVED_BREAK | STATUS_FRAMING_ERROR | STATUS_PARITY_ERROR); + if (rx_fifo_num == 0) + SR &= ~STATUS_RECEIVER_READY; + else + SR |= rx_fifo[rx_fifo_read_ptr] >> 8; update_interrupts(); //printf("Rx read %02x\n", rv); @@ -1446,6 +1440,7 @@ void duart_channel::write_CR(uint8_t data) case 2: /* Reset channel receiver (disable receiver and flush fifo) */ rx_enabled = 0; SR &= ~STATUS_RECEIVER_READY; + SR &= ~(STATUS_RECEIVED_BREAK | STATUS_FRAMING_ERROR | STATUS_PARITY_ERROR); SR &= ~STATUS_OVERRUN_ERROR; // is this correct? rx_fifo_read_ptr = 0; rx_fifo_write_ptr = 0; diff --git a/src/devices/machine/mc68681.h b/src/devices/machine/mc68681.h index c8bfcedfb3d..ea4fd63e3af 100644 --- a/src/devices/machine/mc68681.h +++ b/src/devices/machine/mc68681.h @@ -57,6 +57,7 @@ public: void write_chan_reg(int reg, uint8_t data); void update_interrupts(); + void rx_fifo_push(uint8_t data, uint8_t errors); uint8_t read_rx_fifo(); void baud_updated(); @@ -83,7 +84,7 @@ private: /* Receiver */ uint8_t rx_enabled; - uint8_t rx_fifo[MC68681_RX_FIFO_SIZE]; + uint16_t rx_fifo[MC68681_RX_FIFO_SIZE]; int rx_fifo_read_ptr; int rx_fifo_write_ptr; int rx_fifo_num; diff --git a/src/devices/machine/mc68901.cpp b/src/devices/machine/mc68901.cpp index c3ba2a7bfaa..3a178089dfc 100644 --- a/src/devices/machine/mc68901.cpp +++ b/src/devices/machine/mc68901.cpp @@ -530,8 +530,22 @@ void mc68901_device::rcv_complete() m_receive_buffer = get_received_char(); m_rsr |= RSR_BUFFER_FULL; LOG("Received Character: %02x\n", m_receive_buffer); + + if (is_receive_framing_error()) + m_rsr |= RSR_FRAME_ERROR; + else + m_rsr &= ~RSR_FRAME_ERROR; + + if (is_receive_parity_error()) + m_rsr |= RSR_PARITY_ERROR; + else + m_rsr &= ~RSR_PARITY_ERROR; + + if ((m_rsr & (RSR_FRAME_ERROR | RSR_PARITY_ERROR)) && (m_ier & IR_RCV_ERROR)) + rx_error(); + else + rx_buffer_full(); } - rx_buffer_full(); } |