mirror of
https://github.com/holub/mame
synced 2025-05-28 08:33:05 +03:00
mc68681: Detect framing and parity errors, storing flags with FIFO characters
mc68901: Detect framing and parity errors and signal Rx error interrupt if enabled
This commit is contained in:
parent
f1f0591f43
commit
82a8efd61f
@ -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,22 +1113,40 @@ 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()
|
||||
{
|
||||
//printf("%s ch %d Tx complete\n", tag(), m_ch);
|
||||
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user