diff --git a/src/devices/machine/z80dart.cpp b/src/devices/machine/z80dart.cpp index 72086d5e00f..70d321909c5 100644 --- a/src/devices/machine/z80dart.cpp +++ b/src/devices/machine/z80dart.cpp @@ -37,15 +37,17 @@ // MACROS / CONSTANTS //************************************************************************** -#define VERBOSE 0 +#define VERBOSE 2 +#define LOGPRINT(x) do { if (VERBOSE) logerror x; } while (0) +#define LOG(x) {} LOGPRINT(x) -#define LOG(x) do { if (VERBOSE) logerror x; } while (0) +#if VERBOSE == 2 +#define logerror printf +#endif #define CHANA_TAG "cha" #define CHANB_TAG "chb" - - //************************************************************************** // DEVICE DEFINITIONS //************************************************************************** @@ -503,7 +505,7 @@ z80dart_channel::z80dart_channel(const machine_config &mconfig, const char *tag, : device_t(mconfig, Z80DART_CHANNEL, "Z80 DART channel", tag, owner, clock, "z80dart_channel", __FILE__), device_serial_interface(mconfig, *this), m_rx_error(0), - m_rx_fifo(-1), + // m_rx_fifo(-1), m_rx_clock(0), m_rx_first(0), m_rx_break(0), @@ -523,12 +525,13 @@ z80dart_channel::z80dart_channel(const machine_config &mconfig, const char *tag, for (auto & elem : m_wr) elem = 0; - +#if 0 for (int i = 0; i < 3; i++) { m_rx_data_fifo[i] = 0; m_rx_error_fifo[i] = 0; } +#endif } @@ -544,10 +547,15 @@ void z80dart_channel::device_start() // state saving save_item(NAME(m_rr)); save_item(NAME(m_wr)); +#if 0 save_item(NAME(m_rx_data_fifo)); save_item(NAME(m_rx_error_fifo)); - save_item(NAME(m_rx_error)); save_item(NAME(m_rx_fifo)); + save_item(NAME(m_rx_error)); +#else + // save_item(NAME(m_rx_data_fifot)); + // save_item(NAME(m_rx_error_fifot)); +#endif save_item(NAME(m_rx_clock)); save_item(NAME(m_rx_first)); save_item(NAME(m_rx_break)); @@ -1001,18 +1009,22 @@ uint8_t z80dart_channel::data_read() { uint8_t data = 0; - if (m_rx_fifo >= 0) +// if (m_rx_fifo >= 0) + if (!m_rx_data_fifot.empty()) { // load data from the FIFO - data = m_rx_data_fifo[m_rx_fifo]; +// data = m_rx_data_fifo[m_rx_fifo]; + data = m_rx_data_fifot.dequeue(); // load error status from the FIFO - m_rr[1] = (m_rr[1] & ~(RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR | RR1_PARITY_ERROR)) | m_rx_error_fifo[m_rx_fifo]; +// m_rr[1] = (m_rr[1] & ~(RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR | RR1_PARITY_ERROR)) | m_rx_error_fifo[m_rx_fifo]; + m_rr[1] = (m_rr[1] & ~(RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR | RR1_PARITY_ERROR)) | m_rx_error_fifot.dequeue(); // decrease FIFO pointer - m_rx_fifo--; +// m_rx_fifo--; - if (m_rx_fifo < 0) +// if (m_rx_fifo < 0) + if (m_rx_data_fifot.empty()) { // no more characters available in the FIFO m_rr[0] &= ~ RR0_RX_CHAR_AVAILABLE; @@ -1064,7 +1076,8 @@ void z80dart_channel::receive_data(uint8_t data) { LOG(("Z80DART \"%s\" Channel %c : Receive Data Byte '%02x'\n", m_owner->tag(), 'A' + m_index, data)); - if (m_rx_fifo == 2) +// if (m_rx_fifo == 2) + if (m_rx_data_fifot.full()) { // receive overrun error detected m_rx_error |= RR1_RX_OVERRUN_ERROR; @@ -1083,15 +1096,19 @@ void z80dart_channel::receive_data(uint8_t data) m_uart->trigger_interrupt(m_index, INT_SPECIAL); break; } + m_rx_data_fifot.poke(data); + m_rx_error_fifot.poke(m_rx_error); } else { - m_rx_fifo++; +// m_rx_fifo++; + m_rx_data_fifot.enqueue(data); + m_rx_error_fifot.enqueue(m_rx_error); } - // store received character and error status into FIFO - m_rx_data_fifo[m_rx_fifo] = data; - m_rx_error_fifo[m_rx_fifo] = m_rx_error; +// store received character and error status into FIFO +// m_rx_data_fifo[m_rx_fifo] = data; +// m_rx_error_fifo[m_rx_fifo] = m_rx_error; m_rr[0] |= RR0_RX_CHAR_AVAILABLE; diff --git a/src/devices/machine/z80dart.h b/src/devices/machine/z80dart.h index a7eba9f8ac1..8d4bedc8d01 100644 --- a/src/devices/machine/z80dart.h +++ b/src/devices/machine/z80dart.h @@ -241,6 +241,61 @@ // ======================> z80dart_channel +template +class fifo +{ + T m_arr[N]; + int m_wp; + int m_rp; + bool m_empty; +public: + fifo() + : m_arr() + , m_wp(0) + , m_rp(0) + , m_empty(true) + { + static_assert(0U < N, "FIFO must have at least one element"); + } + + bool full() const { return !m_empty && (m_wp == m_rp); } + bool empty() const { return m_empty; } + + void enqueue(T v) + { + if (m_empty || (m_wp != m_rp)) + { + m_arr[m_wp] = v; + if (++m_wp == N) + m_wp = 0; + m_empty = false; + } + } + + T dequeue() + { + T result = -1; + if (!m_empty) + { + result = m_arr[m_rp]; + if (++m_rp == N) + m_rp = 0; + m_empty = (m_rp == m_wp); + } + return result; + } + + T const peek() const + { + return m_arr[m_rp]; + } + + void poke(T v) + { + m_arr[m_wp] = v; + } +}; + class z80dart_device; class z80dart_channel : public device_t, @@ -428,11 +483,15 @@ protected: int get_tx_word_length(); // receiver state +//#if 0 uint8_t m_rx_data_fifo[3]; // receive data FIFO uint8_t m_rx_error_fifo[3]; // receive error FIFO - uint8_t m_rx_error; // current receive error int m_rx_fifo; // receive FIFO pointer - +//#else + fifo m_rx_data_fifot; + fifo m_rx_error_fifot; +//#endif + uint8_t m_rx_error; // current receive error int m_rx_clock; // receive clock pulse count int m_rx_first; // first character received int m_rx_break; // receive break condition