Merge pull request #1627 from JoakimLarsson/z80dart

DART: Refactored FIFO:s using new template based fifo class
This commit is contained in:
Joakim Larsson Edström 2016-11-04 14:20:17 +01:00 committed by GitHub
commit f7d09823aa
3 changed files with 39 additions and 34 deletions

View File

@ -31,21 +31,21 @@
#include "z80dart.h" #include "z80dart.h"
//************************************************************************** //**************************************************************************
// MACROS / CONSTANTS // MACROS / CONSTANTS
//************************************************************************** //**************************************************************************
#define VERBOSE 0 #define VERBOSE 0
#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 CHANA_TAG "cha"
#define CHANB_TAG "chb" #define CHANB_TAG "chb"
//************************************************************************** //**************************************************************************
// DEVICE DEFINITIONS // DEVICE DEFINITIONS
//************************************************************************** //**************************************************************************
@ -503,7 +503,6 @@ 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_t(mconfig, Z80DART_CHANNEL, "Z80 DART channel", tag, owner, clock, "z80dart_channel", __FILE__),
device_serial_interface(mconfig, *this), device_serial_interface(mconfig, *this),
m_rx_error(0), m_rx_error(0),
m_rx_fifo(-1),
m_rx_clock(0), m_rx_clock(0),
m_rx_first(0), m_rx_first(0),
m_rx_break(0), m_rx_break(0),
@ -523,12 +522,6 @@ z80dart_channel::z80dart_channel(const machine_config &mconfig, const char *tag,
for (auto & elem : m_wr) for (auto & elem : m_wr)
elem = 0; elem = 0;
for (int i = 0; i < 3; i++)
{
m_rx_data_fifo[i] = 0;
m_rx_error_fifo[i] = 0;
}
} }
@ -544,10 +537,8 @@ void z80dart_channel::device_start()
// state saving // state saving
save_item(NAME(m_rr)); save_item(NAME(m_rr));
save_item(NAME(m_wr)); save_item(NAME(m_wr));
save_item(NAME(m_rx_data_fifo)); // save_item(NAME(m_rx_data_fifo));
save_item(NAME(m_rx_error_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_clock)); save_item(NAME(m_rx_clock));
save_item(NAME(m_rx_first)); save_item(NAME(m_rx_first));
save_item(NAME(m_rx_break)); save_item(NAME(m_rx_break));
@ -1001,18 +992,15 @@ uint8_t z80dart_channel::data_read()
{ {
uint8_t data = 0; uint8_t data = 0;
if (m_rx_fifo >= 0) if (!m_rx_data_fifo.empty())
{ {
// load data from the FIFO // load data from the FIFO
data = m_rx_data_fifo[m_rx_fifo]; data = m_rx_data_fifo.dequeue();
// load error status from the FIFO // 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.dequeue();
// decrease FIFO pointer if (m_rx_data_fifo.empty())
m_rx_fifo--;
if (m_rx_fifo < 0)
{ {
// no more characters available in the FIFO // no more characters available in the FIFO
m_rr[0] &= ~ RR0_RX_CHAR_AVAILABLE; m_rr[0] &= ~ RR0_RX_CHAR_AVAILABLE;
@ -1064,7 +1052,7 @@ 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)); 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_data_fifo.full())
{ {
// receive overrun error detected // receive overrun error detected
m_rx_error |= RR1_RX_OVERRUN_ERROR; m_rx_error |= RR1_RX_OVERRUN_ERROR;
@ -1083,15 +1071,16 @@ void z80dart_channel::receive_data(uint8_t data)
m_uart->trigger_interrupt(m_index, INT_SPECIAL); m_uart->trigger_interrupt(m_index, INT_SPECIAL);
break; break;
} }
// overwrite last character/error with received character and error status into FIFO
m_rx_data_fifo.poke(data);
m_rx_error_fifo.poke(m_rx_error);
} }
else else
{ {
m_rx_fifo++;
}
// store received character and error status into FIFO // store received character and error status into FIFO
m_rx_data_fifo[m_rx_fifo] = data; m_rx_data_fifo.enqueue(data);
m_rx_error_fifo[m_rx_fifo] = m_rx_error; m_rx_error_fifo.enqueue(m_rx_error);
}
m_rr[0] |= RR0_RX_CHAR_AVAILABLE; m_rr[0] |= RR0_RX_CHAR_AVAILABLE;

View File

@ -428,11 +428,10 @@ protected:
int get_tx_word_length(); int get_tx_word_length();
// receiver state // receiver state
uint8_t m_rx_data_fifo[3]; // receive data FIFO util::fifo<uint8_t, 3> m_rx_data_fifo;
uint8_t m_rx_error_fifo[3]; // receive error FIFO util::fifo<uint8_t, 3> m_rx_error_fifo;
uint8_t m_rx_error; // current receive error
int m_rx_fifo; // receive FIFO pointer
uint8_t m_rx_error; // current receive error
int m_rx_clock; // receive clock pulse count int m_rx_clock; // receive clock pulse count
int m_rx_first; // first character received int m_rx_first; // first character received
int m_rx_break; // receive break condition int m_rx_break; // receive break condition

View File

@ -428,7 +428,7 @@ public:
fifo() fifo()
: std::array<T, N>() : std::array<T, N>()
, m_head(this->begin()) , m_head(this->begin())
, m_tail(this->end()) , m_tail(this->begin())
, m_empty(true) , m_empty(true)
{ {
static_assert(0U < N, "FIFO must have at least one element"); static_assert(0U < N, "FIFO must have at least one element");
@ -513,11 +513,28 @@ public:
return result; return result;
} }
void poke(T &v)
{
*m_tail = v;
}
void poke(T &&v)
{
*m_tail = std::move(v);
}
T const &peek() const T const &peek() const
{ {
return *m_head; return *m_head;
} }
void clear() const
{
m_head = m_tail = this->begin();
m_empty = true;
return *m_head;
}
private: private:
typename fifo::iterator m_head, m_tail; typename fifo::iterator m_head, m_tail;
bool m_empty; bool m_empty;