summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2018-12-28 14:58:14 -0500
committer AJR <ajrhacker@users.noreply.github.com>2018-12-28 15:00:02 -0500
commit82a8efd61f8c776a658ac83d936f27047b339a64 (patch)
tree86520d585312c793fbfd846f434705636f972a27
parentf1f0591f43f381123e8d9ec20c52eb7c0c332c79 (diff)
mc68681: Detect framing and parity errors, storing flags with FIFO characters
mc68901: Detect framing and parity errors and signal Rx error interrupt if enabled
-rw-r--r--src/devices/machine/mc68681.cpp93
-rw-r--r--src/devices/machine/mc68681.h3
-rw-r--r--src/devices/machine/mc68901.cpp16
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();
}