z80scc: general cleanup and backport of z80sio improvements part I

This commit is contained in:
Joakim Larsson Edstrom 2017-11-20 00:02:03 +01:00
parent 8ff47b6ec3
commit 2e9b62d4bd
2 changed files with 119 additions and 160 deletions

View File

@ -90,8 +90,9 @@ DONE (x) (p=partly) NMOS CMOS ESCC EMSCC
#define LOG_DCD (1U << 8) #define LOG_DCD (1U << 8)
#define LOG_SYNC (1U << 9) #define LOG_SYNC (1U << 9)
//#define VERBOSE (LOG_INT|LOG_READ|LOG_SETUP|LOG_TX|LOG_CMD) //#define VERBOSE (LOG_TX)
//#define LOG_OUTPUT_FUNC printf //#define LOG_OUTPUT_STREAM std::cout
#include "logmacro.h" #include "logmacro.h"
#define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__) #define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__)
@ -111,10 +112,8 @@ DONE (x) (p=partly) NMOS CMOS ESCC EMSCC
#ifdef _MSC_VER #ifdef _MSC_VER
#define FUNCNAME __func__ #define FUNCNAME __func__
#define LLFORMAT "%I64d"
#else #else
#define FUNCNAME __PRETTY_FUNCTION__ #define FUNCNAME __PRETTY_FUNCTION__
#define LLFORMAT "%lld"
#endif #endif
/* LOCAL _BRG is set in z80scc.h, local timer based BRG is not complete and will be removed if not needed for synchrounous mode */ /* LOCAL _BRG is set in z80scc.h, local timer based BRG is not complete and will be removed if not needed for synchrounous mode */
@ -157,10 +156,24 @@ MACHINE_CONFIG_END
// LIVE DEVICE // LIVE DEVICE
//************************************************************************** //**************************************************************************
inline void z80scc_channel::out_txd_cb(int state)
{
m_uart->m_out_txd_cb[m_index](state);
}
inline void z80scc_channel::out_rts_cb(int state)
{
m_uart->m_out_rts_cb[m_index](state);
}
inline void z80scc_channel::out_dtr_cb(int state)
{
m_uart->m_out_dtr_cb[m_index](state);
}
//------------------------------------------------- //-------------------------------------------------
// z80scc_device - constructor // z80scc_device - constructor
//------------------------------------------------- //-------------------------------------------------
z80scc_device::z80scc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t variant) z80scc_device::z80scc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t variant)
: device_t(mconfig, type, tag, owner, clock), : device_t(mconfig, type, tag, owner, clock),
device_z80daisy_interface(mconfig, *this), device_z80daisy_interface(mconfig, *this),
@ -170,21 +183,14 @@ z80scc_device::z80scc_device(const machine_config &mconfig, device_type type, co
m_txca(0), m_txca(0),
m_rxcb(0), m_rxcb(0),
m_txcb(0), m_txcb(0),
m_out_txda_cb(*this), m_out_txd_cb{ { *this }, { *this } },
m_out_dtra_cb(*this), m_out_dtr_cb{ { *this }, { *this } },
m_out_rtsa_cb(*this), m_out_rts_cb{ { *this }, { *this } },
m_out_wreqa_cb(*this), m_out_wreq_cb{ { *this }, { *this } },
m_out_synca_cb(*this), m_out_sync_cb{ { *this }, { *this } },
m_out_txdb_cb(*this), m_out_rxdrq_cb{ { *this }, { *this } },
m_out_dtrb_cb(*this), m_out_txdrq_cb{ { *this }, { *this } },
m_out_rtsb_cb(*this),
m_out_wreqb_cb(*this),
m_out_syncb_cb(*this),
m_out_int_cb(*this), m_out_int_cb(*this),
m_out_rxdrqa_cb(*this),
m_out_txdrqa_cb(*this),
m_out_rxdrqb_cb(*this),
m_out_txdrqb_cb(*this),
m_variant(variant), m_variant(variant),
m_wr0_ptrbits(0), m_wr0_ptrbits(0),
m_cputag(nullptr) m_cputag(nullptr)
@ -238,29 +244,37 @@ scc8523l_device::scc8523l_device(const machine_config &mconfig, const char *tag,
{ {
} }
//-------------------------------------------------
// device_resolve_objects - device-specific setup
//-------------------------------------------------
void z80scc_device::device_resolve_objects()
{
LOG("%s\n", FUNCNAME);
// resolve callbacks
m_out_txd_cb[CHANNEL_A].resolve_safe();
m_out_dtr_cb[CHANNEL_A].resolve_safe();
m_out_rts_cb[CHANNEL_A].resolve_safe();
m_out_wreq_cb[CHANNEL_A].resolve_safe();
m_out_sync_cb[CHANNEL_A].resolve_safe();
m_out_txd_cb[CHANNEL_B].resolve_safe();
m_out_dtr_cb[CHANNEL_B].resolve_safe();
m_out_rts_cb[CHANNEL_B].resolve_safe();
m_out_wreq_cb[CHANNEL_B].resolve_safe();
m_out_sync_cb[CHANNEL_B].resolve_safe();
m_out_rxdrq_cb[CHANNEL_A].resolve_safe();
m_out_txdrq_cb[CHANNEL_A].resolve_safe();
m_out_rxdrq_cb[CHANNEL_B].resolve_safe();
m_out_txdrq_cb[CHANNEL_B].resolve_safe();
m_out_int_cb.resolve_safe();
}
//------------------------------------------------- //-------------------------------------------------
// device_start - device-specific startup // device_start - device-specific startup
//------------------------------------------------- //-------------------------------------------------
void z80scc_device::device_start() void z80scc_device::device_start()
{ {
LOGSETUP("%s\n", FUNCNAME); LOG("%s", FUNCNAME);
// resolve callbacks
m_out_txda_cb.resolve_safe();
m_out_dtra_cb.resolve_safe();
m_out_rtsa_cb.resolve_safe();
m_out_wreqa_cb.resolve_safe();
m_out_synca_cb.resolve_safe();
m_out_txdb_cb.resolve_safe();
m_out_dtrb_cb.resolve_safe();
m_out_rtsb_cb.resolve_safe();
m_out_wreqb_cb.resolve_safe();
m_out_syncb_cb.resolve_safe();
m_out_int_cb.resolve_safe();
m_out_rxdrqa_cb.resolve_safe();
m_out_txdrqa_cb.resolve_safe();
m_out_rxdrqb_cb.resolve_safe();
m_out_txdrqb_cb.resolve_safe();
// state saving // state saving
save_item(NAME(m_int_state)); save_item(NAME(m_int_state));
@ -274,16 +288,15 @@ void z80scc_device::device_start()
//------------------------------------------------- //-------------------------------------------------
// device_reset - device-specific reset // device_reset - device-specific reset
//------------------------------------------------- //-------------------------------------------------
void z80scc_device::device_reset() void z80scc_device::device_reset()
{ {
LOGSETUP("%s %s \n",tag(), FUNCNAME); LOG("%s %s \n",tag(), FUNCNAME);
// Do channel reset on both channels // Do channel reset on both channels
m_chanA->reset(); m_chanA->reset();
m_chanB->reset(); m_chanB->reset();
// Fix hardware reset values for registers where it differs from channel reset values // Hardware reset values for registers where it differs from channel reset values
m_wr9 &= 0x3c; m_wr9 &= 0x3c;
m_wr9 |= 0xc0; m_wr9 |= 0xc0;
m_chanA->m_wr10 = 0x00; m_chanA->m_wr10 = 0x00;
@ -429,7 +442,6 @@ void z80scc_device::z80daisy_irq_reti()
//------------------------------------------------- //-------------------------------------------------
// check_interrupts - // check_interrupts -
//------------------------------------------------- //-------------------------------------------------
void z80scc_device::check_interrupts() void z80scc_device::check_interrupts()
{ {
int state = (z80daisy_irq_state() & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE; int state = (z80daisy_irq_state() & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE;
@ -441,7 +453,6 @@ void z80scc_device::check_interrupts()
//------------------------------------------------- //-------------------------------------------------
// reset_interrupts - // reset_interrupts -
//------------------------------------------------- //-------------------------------------------------
void z80scc_device::reset_interrupts() void z80scc_device::reset_interrupts()
{ {
LOGINT("%s %s \n",tag(), FUNCNAME); LOGINT("%s %s \n",tag(), FUNCNAME);
@ -597,7 +608,6 @@ int z80scc_device::update_extint(int index)
//------------------------------------------------- //-------------------------------------------------
// m1_r - interrupt acknowledge // m1_r - interrupt acknowledge
//------------------------------------------------- //-------------------------------------------------
int z80scc_device::m1_r() int z80scc_device::m1_r()
{ {
return z80daisy_irq_ack(); return z80daisy_irq_ack();
@ -760,7 +770,6 @@ WRITE8_MEMBER( z80scc_device::cd_ba_w )
//------------------------------------------------- //-------------------------------------------------
// ba_cd_r - Universal Bus read // ba_cd_r - Universal Bus read
//------------------------------------------------- //-------------------------------------------------
READ8_MEMBER( z80scc_device::ba_cd_r ) READ8_MEMBER( z80scc_device::ba_cd_r )
{ {
int ba = BIT(offset, 1); int ba = BIT(offset, 1);
@ -782,7 +791,6 @@ READ8_MEMBER( z80scc_device::ba_cd_r )
//------------------------------------------------- //-------------------------------------------------
// ba_cd_w - Universal Bus write // ba_cd_w - Universal Bus write
//------------------------------------------------- //-------------------------------------------------
WRITE8_MEMBER( z80scc_device::ba_cd_w ) WRITE8_MEMBER( z80scc_device::ba_cd_w )
{ {
int ba = BIT(offset, 1); int ba = BIT(offset, 1);
@ -807,7 +815,6 @@ WRITE8_MEMBER( z80scc_device::ba_cd_w )
//------------------------------------------------- //-------------------------------------------------
// ba_cd_inv_r - Universal Bus read // ba_cd_inv_r - Universal Bus read
//------------------------------------------------- //-------------------------------------------------
READ8_MEMBER( z80scc_device::ba_cd_inv_r ) READ8_MEMBER( z80scc_device::ba_cd_inv_r )
{ {
int ba = BIT(offset, 1); int ba = BIT(offset, 1);
@ -829,7 +836,6 @@ READ8_MEMBER( z80scc_device::ba_cd_inv_r )
//------------------------------------------------- //-------------------------------------------------
// ba_cd_inv_w - Universal Bus read // ba_cd_inv_w - Universal Bus read
//------------------------------------------------- //-------------------------------------------------
WRITE8_MEMBER( z80scc_device::ba_cd_inv_w ) WRITE8_MEMBER( z80scc_device::ba_cd_inv_w )
{ {
int ba = BIT(offset, 1); int ba = BIT(offset, 1);
@ -858,7 +864,6 @@ WRITE8_MEMBER( z80scc_device::ba_cd_inv_w )
//------------------------------------------------- //-------------------------------------------------
// SCC_channel - constructor // SCC_channel - constructor
//------------------------------------------------- //-------------------------------------------------
z80scc_channel::z80scc_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) z80scc_channel::z80scc_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, Z80SCC_CHANNEL, tag, owner, clock), : device_t(mconfig, Z80SCC_CHANNEL, tag, owner, clock),
device_serial_interface(mconfig, *this), device_serial_interface(mconfig, *this),
@ -906,7 +911,6 @@ z80scc_channel::z80scc_channel(const machine_config &mconfig, const char *tag, d
//------------------------------------------------- //-------------------------------------------------
// start - channel startup // start - channel startup
//------------------------------------------------- //-------------------------------------------------
void z80scc_channel::device_start() void z80scc_channel::device_start()
{ {
LOGSETUP("%s\n", FUNCNAME); LOGSETUP("%s\n", FUNCNAME);
@ -987,7 +991,6 @@ void z80scc_channel::device_start()
//------------------------------------------------- //-------------------------------------------------
// reset - reset channel status // reset - reset channel status
//------------------------------------------------- //-------------------------------------------------
void z80scc_channel::device_reset() void z80scc_channel::device_reset()
{ {
LOGSETUP("%s\n", FUNCNAME); LOGSETUP("%s\n", FUNCNAME);
@ -1020,9 +1023,8 @@ void z80scc_channel::device_reset()
m_rr10 &= 0x40; m_rr10 &= 0x40;
// reset external lines // reset external lines
set_rts(m_wr5 & WR5_RTS ? 0 : 1); out_rts_cb(m_rts = m_wr5 & WR5_RTS ? 0 : 1);
set_dtr(m_wr14 & WR14_DTR_REQ_FUNC ? 0 : (m_wr5 & WR5_DTR ? 0 : 1)); out_dtr_cb(m_dtr = m_wr14 & WR14_DTR_REQ_FUNC ? 0 : (m_wr5 & WR5_DTR ? 0 : 1));
// reset interrupts // reset interrupts
if (m_index == z80scc_device::CHANNEL_A) if (m_index == z80scc_device::CHANNEL_A)
{ {
@ -1067,50 +1069,38 @@ void z80scc_channel::device_timer(emu_timer &timer, device_timer_id id, int para
//------------------------------------------------- //-------------------------------------------------
// tra_callback - // tra_callback -
//------------------------------------------------- //-------------------------------------------------
void z80scc_channel::tra_callback() void z80scc_channel::tra_callback()
{ {
if (!(m_wr5 & WR5_TX_ENABLE)) if (!(m_wr5 & WR5_TX_ENABLE))
{ {
LOG(LLFORMAT " %s() \"%s \"Channel %c transmit mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); LOGTX("%s \"%s \"Channel %c transmit mark 1 m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5);
// transmit mark // transmit mark
if (m_index == z80scc_device::CHANNEL_A) out_txd_cb(1);
m_uart->m_out_txda_cb(1);
else
m_uart->m_out_txdb_cb(1);
} }
else if (m_wr5 & WR5_SEND_BREAK) else if (m_wr5 & WR5_SEND_BREAK)
{ {
LOG(LLFORMAT " %s() \"%s \"Channel %c send break 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); LOGTX("%s \"%s \"Channel %c send break 1 m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5);
// transmit break // transmit break
if (m_index == z80scc_device::CHANNEL_A) out_txd_cb(0);
m_uart->m_out_txda_cb(0);
else
m_uart->m_out_txdb_cb(0);
} }
else if (!is_transmit_register_empty()) else if (!is_transmit_register_empty())
{ {
int db = transmit_register_get_data_bit(); int db = transmit_register_get_data_bit();
LOG(LLFORMAT " %s() \"%s \"Channel %c transmit data bit %d m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index, db, m_wr5); LOGTX("%s \"%s \"Channel %c transmit data bit %d m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, db, m_wr5);
// transmit data // transmit data
if (m_index == z80scc_device::CHANNEL_A) out_txd_cb(db);
m_uart->m_out_txda_cb(db);
else
m_uart->m_out_txdb_cb(db);
} }
else else
{ {
LOG(LLFORMAT " %s() \"%s \"Channel %c Failed to transmit m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); LOGTX("%s \"%s \"Channel %c Failed to transmit m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5);
logerror("%s \"%s \"Channel %c Failed to transmit\n", FUNCNAME, owner()->tag(), 'A' + m_index); logerror("%s \"%s \"Channel %c Failed to transmit\n", FUNCNAME, owner()->tag(), 'A' + m_index);
} }
} }
//------------------------------------------------- //-------------------------------------------------
// tra_complete - // tra_complete -
//------------------------------------------------- //-------------------------------------------------
void z80scc_channel::tra_complete() void z80scc_channel::tra_complete()
{ {
// Delayed baudrate change according to SCC specs // Delayed baudrate change according to SCC specs
@ -1118,7 +1108,7 @@ void z80scc_channel::tra_complete()
{ {
m_delayed_tx_brg_change = 0; m_delayed_tx_brg_change = 0;
set_tra_rate(m_brg_rate); set_tra_rate(m_brg_rate);
LOG("Delayed Init - Baud Rate Generator: %d mode: %dx\n", m_brg_rate, get_clock_mode() ); LOGTX("Delayed Init - Baud Rate Generator: %d mode: %dx\n", m_brg_rate, get_clock_mode() );
} }
if ((m_wr5 & WR5_TX_ENABLE) && !(m_wr5 & WR5_SEND_BREAK)) if ((m_wr5 & WR5_TX_ENABLE) && !(m_wr5 & WR5_SEND_BREAK))
@ -1126,7 +1116,7 @@ void z80scc_channel::tra_complete()
if ( (m_rr0 & RR0_TX_BUFFER_EMPTY) == 0 || // Takes care of the NMOS/CMOS 1 slot TX FIFO if ( (m_rr0 & RR0_TX_BUFFER_EMPTY) == 0 || // Takes care of the NMOS/CMOS 1 slot TX FIFO
m_tx_fifo_rp != m_tx_fifo_wp) // or there are more characters to send in a longer FIFO. m_tx_fifo_rp != m_tx_fifo_wp) // or there are more characters to send in a longer FIFO.
{ {
LOGTX(" %s() %s %c done sending, loading data from fifo:%02x '%c'\n", FUNCNAME, owner()->tag(), 'A' + m_index, LOGTX("%s %s %c done sending, loading data from fifo:%02x '%c'\n", FUNCNAME, owner()->tag(), 'A' + m_index,
m_tx_data_fifo[m_tx_fifo_rp], isascii(m_tx_data_fifo[m_tx_fifo_rp]) ? m_tx_data_fifo[m_tx_fifo_rp] : ' '); m_tx_data_fifo[m_tx_fifo_rp], isascii(m_tx_data_fifo[m_tx_fifo_rp]) ? m_tx_data_fifo[m_tx_fifo_rp] : ' ');
transmit_register_setup(m_tx_data_fifo[m_tx_fifo_rp]); // Reload the shift register transmit_register_setup(m_tx_data_fifo[m_tx_fifo_rp]); // Reload the shift register
m_tx_fifo_rp_step(); m_tx_fifo_rp_step();
@ -1134,7 +1124,7 @@ void z80scc_channel::tra_complete()
} }
else else
{ {
LOGTX(" %s() %s %c done sending, setting all sent bit\n", FUNCNAME, owner()->tag(), 'A' + m_index); LOGTX("%s %s %c done sending, setting all sent bit\n", FUNCNAME, owner()->tag(), 'A' + m_index);
m_rr1 |= RR1_ALL_SENT; m_rr1 |= RR1_ALL_SENT;
// when the RTS bit is reset, the _RTS output goes high after the transmitter empties // when the RTS bit is reset, the _RTS output goes high after the transmitter empties
@ -1163,21 +1153,15 @@ void z80scc_channel::tra_complete()
} }
else if (m_wr5 & WR5_SEND_BREAK) else if (m_wr5 & WR5_SEND_BREAK)
{ {
LOG(LLFORMAT " %s() \"%s \"Channel %c Transmit Break 0 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); LOG("%s \"%s \"Channel %c Transmit Break 0 m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5);
// transmit break // transmit break
if (m_index == z80scc_device::CHANNEL_A) out_txd_cb(0);
m_uart->m_out_txda_cb(0);
else
m_uart->m_out_txdb_cb(0);
} }
else else
{ {
LOG(LLFORMAT " %s() \"%s \"Channel %c Transmit Mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); LOG("%s \"%s \"Channel %c Transmit Mark 1 m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5);
// transmit mark // transmit mark
if (m_index == z80scc_device::CHANNEL_A) out_txd_cb(1);
m_uart->m_out_txda_cb(1);
else
m_uart->m_out_txdb_cb(1);
} }
} }
@ -1185,18 +1169,17 @@ void z80scc_channel::tra_complete()
//------------------------------------------------- //-------------------------------------------------
// rcv_callback - // rcv_callback -
//------------------------------------------------- //-------------------------------------------------
void z80scc_channel::rcv_callback() void z80scc_channel::rcv_callback()
{ {
if (m_wr3 & WR3_RX_ENABLE) if (m_wr3 & WR3_RX_ENABLE)
{ {
LOG(LLFORMAT " %s() \"%s \"Channel %c receive data bit %d m_wr3:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index, m_rxd, m_wr3); LOG("%s \"%s \"Channel %c receive data bit %d m_wr3:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_rxd, m_wr3);
receive_register_update_bit(m_rxd); receive_register_update_bit(m_rxd);
} }
#if 1 #if 1
else else
{ {
LOG(LLFORMAT " %s() \"%s \"Channel %c Received Data Bit but receiver is disabled\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index); LOG("%s \"%s \"Channel %c Received Data Bit but receiver is disabled\n", FUNCNAME, owner()->tag(), 'A' + m_index);
logerror("%s \"%s \"Channel %c Received data dit but receiver is disabled\n", FUNCNAME, owner()->tag(), 'A' + m_index); logerror("%s \"%s \"Channel %c Received data dit but receiver is disabled\n", FUNCNAME, owner()->tag(), 'A' + m_index);
} }
#endif #endif
@ -1206,14 +1189,13 @@ void z80scc_channel::rcv_callback()
//------------------------------------------------- //-------------------------------------------------
// rcv_complete - // rcv_complete -
//------------------------------------------------- //-------------------------------------------------
void z80scc_channel::rcv_complete() void z80scc_channel::rcv_complete()
{ {
uint8_t data; uint8_t data;
receive_register_extract(); receive_register_extract();
data = get_received_char(); data = get_received_char();
LOG(LLFORMAT " %s() \"%s \"Channel %c Received Data %c\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index, data); LOG("%s \"%s \"Channel %c Received Data %c\n", FUNCNAME, owner()->tag(), 'A' + m_index, data);
receive_data(data); receive_data(data);
#if START_BIT_HUNT #if START_BIT_HUNT
m_rcv_mode = RCV_SEEKING; m_rcv_mode = RCV_SEEKING;
@ -1224,7 +1206,6 @@ void z80scc_channel::rcv_complete()
//------------------------------------------------- //-------------------------------------------------
// get_clock_mode - get clock divisor // get_clock_mode - get clock divisor
//------------------------------------------------- //-------------------------------------------------
int z80scc_channel::get_clock_mode() int z80scc_channel::get_clock_mode()
{ {
int clocks = 1; int clocks = 1;
@ -1254,10 +1235,7 @@ TODO:
void z80scc_channel::set_rts(int state) void z80scc_channel::set_rts(int state)
{ {
LOG("%s(%d) \"%s\": %c \n", FUNCNAME, state, owner()->tag(), 'A' + m_index); LOG("%s(%d) \"%s\": %c \n", FUNCNAME, state, owner()->tag(), 'A' + m_index);
if (m_index == z80scc_device::CHANNEL_A) out_rts_cb(state);
m_uart->m_out_rtsa_cb(state);
else
m_uart->m_out_rtsb_cb(state);
} }
void z80scc_channel::update_rts() void z80scc_channel::update_rts()
@ -1282,7 +1260,6 @@ void z80scc_channel::update_rts()
//------------------------------------------------- //-------------------------------------------------
// get_stop_bits - get number of stop bits // get_stop_bits - get number of stop bits
//------------------------------------------------- //-------------------------------------------------
device_serial_interface::stop_bits_t z80scc_channel::get_stop_bits() device_serial_interface::stop_bits_t z80scc_channel::get_stop_bits()
{ {
switch (m_wr4 & WR4_STOP_BITS_MASK) switch (m_wr4 & WR4_STOP_BITS_MASK)
@ -1299,7 +1276,6 @@ device_serial_interface::stop_bits_t z80scc_channel::get_stop_bits()
//------------------------------------------------- //-------------------------------------------------
// get_rx_word_length - get receive word length // get_rx_word_length - get receive word length
//------------------------------------------------- //-------------------------------------------------
int z80scc_channel::get_rx_word_length() int z80scc_channel::get_rx_word_length()
{ {
int bits = 5; int bits = 5;
@ -1319,7 +1295,6 @@ int z80scc_channel::get_rx_word_length()
//------------------------------------------------- //-------------------------------------------------
// get_tx_word_length - get transmit word length // get_tx_word_length - get transmit word length
//------------------------------------------------- //-------------------------------------------------
int z80scc_channel::get_tx_word_length() int z80scc_channel::get_tx_word_length()
{ {
int bits = 5; int bits = 5;
@ -1482,7 +1457,7 @@ uint8_t z80scc_channel::do_sccreg_rr7()
LOGR("%s\n", FUNCNAME); LOGR("%s\n", FUNCNAME);
if (!(m_uart->m_variant & (z80scc_device::SET_NMOS))) if (!(m_uart->m_variant & (z80scc_device::SET_NMOS)))
{ {
logerror(" %s() not implemented feature\n", FUNCNAME); logerror("%s not implemented feature\n", FUNCNAME);
return 0; return 0;
} }
return m_rr3; return m_rr3;
@ -1513,7 +1488,7 @@ uint8_t z80scc_channel::do_sccreg_rr9()
uint8_t z80scc_channel::do_sccreg_rr10() uint8_t z80scc_channel::do_sccreg_rr10()
{ {
LOGR("%s\n", FUNCNAME); LOGR("%s\n", FUNCNAME);
logerror("%s() not implemented feature\n", FUNCNAME); logerror("%s not implemented feature\n", FUNCNAME);
return m_rr10; return m_rr10;
} }
@ -1927,7 +1902,7 @@ void z80scc_channel::do_sccreg_wr7(uint8_t data)
/* WR8 is the transmit buffer register */ /* WR8 is the transmit buffer register */
void z80scc_channel::do_sccreg_wr8(uint8_t data) void z80scc_channel::do_sccreg_wr8(uint8_t data)
{ {
LOG("%s(%02x) \"%s\": %c : Transmit Buffer write %02x\n", FUNCNAME, data, owner()->tag(), 'A' + m_index, data); LOGTX("%s(%02x) \"%s\": %c : Transmit Buffer write %02x\n", FUNCNAME, data, owner()->tag(), 'A' + m_index, data);
data_write(data); data_write(data);
} }
@ -2257,7 +2232,6 @@ with 0 before accessing WR0 or RR0.*/
//------------------------------------------------- //-------------------------------------------------
// control_write - write control register // control_write - write control register
//------------------------------------------------- //-------------------------------------------------
void z80scc_channel::control_write(uint8_t data) void z80scc_channel::control_write(uint8_t data)
{ {
uint8_t reg = m_uart->m_wr0_ptrbits; //m_wr0; uint8_t reg = m_uart->m_wr0_ptrbits; //m_wr0;
@ -2286,7 +2260,6 @@ void z80scc_channel::control_write(uint8_t data)
//------------------------------------------------- //-------------------------------------------------
// data_read - read data register from fifo // data_read - read data register from fifo
//------------------------------------------------- //-------------------------------------------------
uint8_t z80scc_channel::data_read() uint8_t z80scc_channel::data_read()
{ {
uint8_t data = 0; uint8_t data = 0;
@ -2383,7 +2356,7 @@ WRITE8_MEMBER (z80scc_device::db_w) { m_chanB->data_write(data); }
void z80scc_channel::data_write(uint8_t data) void z80scc_channel::data_write(uint8_t data)
{ {
/* Tx FIFO is full or...? */ /* Tx FIFO is full or...? */
LOGTX("%s \"%s\": %c : Data Register Write: %02d '%c'\n", FUNCNAME, owner()->tag(), 'A' + m_index, data, isprint(data) ? data : ' '); LOG("%s \"%s\": %c : Data Register Write: %02d '%c'\n", FUNCNAME, owner()->tag(), 'A' + m_index, data, isprint(data) ? data : ' ');
if ( !(m_rr0 & RR0_TX_BUFFER_EMPTY) && // NMOS/CMOS 1 slot "FIFO" is controlled by the TBE bit instead of fifo logic if ( !(m_rr0 & RR0_TX_BUFFER_EMPTY) && // NMOS/CMOS 1 slot "FIFO" is controlled by the TBE bit instead of fifo logic
( (m_tx_fifo_wp + 1 == m_tx_fifo_rp) || ( (m_tx_fifo_wp + 1 == m_tx_fifo_sz) && (m_tx_fifo_rp == 0) ))) ( (m_tx_fifo_wp + 1 == m_tx_fifo_rp) || ( (m_tx_fifo_wp + 1 == m_tx_fifo_sz) && (m_tx_fifo_rp == 0) )))
@ -2469,7 +2442,6 @@ void z80scc_channel::data_write(uint8_t data)
//------------------------------------------------- //-------------------------------------------------
// receive_data - put received data word into fifo // receive_data - put received data word into fifo
//------------------------------------------------- //-------------------------------------------------
void z80scc_channel::receive_data(uint8_t data) void z80scc_channel::receive_data(uint8_t data)
{ {
LOGRCV("\"%s\": %c : Received Data Byte '%c'/%02x put into FIFO\n", owner()->tag(), 'A' + m_index, isprint(data) ? data : ' ', data); LOGRCV("\"%s\": %c : Received Data Byte '%c'/%02x put into FIFO\n", owner()->tag(), 'A' + m_index, isprint(data) ? data : ' ', data);
@ -2522,7 +2494,6 @@ void z80scc_channel::receive_data(uint8_t data)
//------------------------------------------------- //-------------------------------------------------
// cts_w - clear to send handler // cts_w - clear to send handler
//------------------------------------------------- //-------------------------------------------------
WRITE_LINE_MEMBER( z80scc_channel::cts_w ) WRITE_LINE_MEMBER( z80scc_channel::cts_w )
{ {
LOG("\"%s\"%s: %c : CTS %u\n", owner()->tag(), FUNCNAME, 'A' + m_index, state); LOG("\"%s\"%s: %c : CTS %u\n", owner()->tag(), FUNCNAME, 'A' + m_index, state);
@ -2782,7 +2753,7 @@ void z80scc_channel::update_serial()
parity = PARITY_NONE; parity = PARITY_NONE;
} }
LOG(" %s() \"%s \"Channel %c setting data frame %d+%d%c%d\n", FUNCNAME, owner()->tag(), 'A' + m_index, 1, LOG("%s \"%s \"Channel %c setting data frame %d+%d%c%d\n", FUNCNAME, owner()->tag(), 'A' + m_index, 1,
data_bit_count, parity == PARITY_NONE ? 'N' : parity == PARITY_EVEN ? 'E' : 'O', (stop_bits + 1) / 2); data_bit_count, parity == PARITY_NONE ? 'N' : parity == PARITY_EVEN ? 'E' : 'O', (stop_bits + 1) / 2);
set_data_frame(1, data_bit_count, parity, stop_bits); set_data_frame(1, data_bit_count, parity, stop_bits);
@ -2841,10 +2812,7 @@ void z80scc_channel::set_dtr(int state)
LOG("%s(%d)\n", FUNCNAME, state); LOG("%s(%d)\n", FUNCNAME, state);
m_dtr = state; m_dtr = state;
if (m_index == z80scc_device::CHANNEL_A) out_dtr_cb(m_dtr);
m_uart->m_out_dtra_cb(m_dtr);
else
m_uart->m_out_dtrb_cb(m_dtr);
} }
//------------------------------------------------- //-------------------------------------------------
@ -2893,8 +2861,6 @@ void z80scc_channel::check_waitrequest()
if (m_wr1 & WR1_WREQ_FUNCTION) if (m_wr1 & WR1_WREQ_FUNCTION)
{ {
// assert /W//REQ if transmit buffer is empty, clear if it's not // assert /W//REQ if transmit buffer is empty, clear if it's not
int state = (m_rr0 & RR0_TX_BUFFER_EMPTY) ? ASSERT_LINE : CLEAR_LINE; m_uart->m_out_wreq_cb[m_index]((m_rr0 & RR0_TX_BUFFER_EMPTY) ? ASSERT_LINE : CLEAR_LINE);
(m_index ? m_uart->m_out_wreqb_cb : m_uart->m_out_wreqa_cb)(state);
} }
} }

View File

@ -90,47 +90,47 @@
// Port A callbacks // Port A callbacks
#define MCFG_Z80SCC_OUT_TXDA_CB(_devcb) \ #define MCFG_Z80SCC_OUT_TXDA_CB(_devcb) \
devcb = &z80scc_device::set_out_txda_callback(*device, DEVCB_##_devcb); devcb = &z80scc_device::set_out_txd_callback<0>(*device, DEVCB_##_devcb);
#define MCFG_Z80SCC_OUT_DTRA_CB(_devcb) \ #define MCFG_Z80SCC_OUT_DTRA_CB(_devcb) \
devcb = &z80scc_device::set_out_dtra_callback(*device, DEVCB_##_devcb); devcb = &z80scc_device::set_out_dtr_callback<0>(*device, DEVCB_##_devcb);
#define MCFG_Z80SCC_OUT_RTSA_CB(_devcb) \ #define MCFG_Z80SCC_OUT_RTSA_CB(_devcb) \
devcb = &z80scc_device::set_out_rtsa_callback(*device, DEVCB_##_devcb); devcb = &z80scc_device::set_out_rts_callback<0>(*device, DEVCB_##_devcb);
#define MCFG_Z80SCC_OUT_WREQA_CB(_devcb) \ #define MCFG_Z80SCC_OUT_WREQA_CB(_devcb) \
devcb = &z80scc_device::set_out_wreqa_callback(*device, DEVCB_##_devcb); devcb = &z80scc_device::set_out_wreq_callback<0>(*device, DEVCB_##_devcb);
#define MCFG_Z80SCC_OUT_SYNCA_CB(_devcb) \ #define MCFG_Z80SCC_OUT_SYNCA_CB(_devcb) \
devcb = &z80scc_device::set_out_synca_callback(*device, DEVCB_##_devcb); devcb = &z80scc_device::set_out_sync_callback<0>(*device, DEVCB_##_devcb);
#define MCFG_Z80SCC_OUT_RXDRQA_CB(_devcb) \ #define MCFG_Z80SCC_OUT_RXDRQA_CB(_devcb) \
devcb = &z80scc_device::set_out_rxdrqa_callback(*device, DEVCB_##_devcb); devcb = &z80scc_device::set_out_rxdrq_callback<0>(*device, DEVCB_##_devcb);
#define MCFG_Z80SCC_OUT_TXDRQA_CB(_devcb) \ #define MCFG_Z80SCC_OUT_TXDRQA_CB(_devcb) \
devcb = &z80scc_device::set_out_txdrqa_callback(*device, DEVCB_##_devcb); devcb = &z80scc_device::set_out_txdrq_callback<0>(*device, DEVCB_##_devcb);
// Port B callbacks // Port B callbacks
#define MCFG_Z80SCC_OUT_TXDB_CB(_devcb) \ #define MCFG_Z80SCC_OUT_TXDB_CB(_devcb) \
devcb = &z80scc_device::set_out_txdb_callback(*device, DEVCB_##_devcb); devcb = &z80scc_device::set_out_txd_callback<1>(*device, DEVCB_##_devcb);
#define MCFG_Z80SCC_OUT_DTRB_CB(_devcb) \ #define MCFG_Z80SCC_OUT_DTRB_CB(_devcb) \
devcb = &z80scc_device::set_out_dtrb_callback(*device, DEVCB_##_devcb); devcb = &z80scc_device::set_out_dtr_callback<1>(*device, DEVCB_##_devcb);
#define MCFG_Z80SCC_OUT_RTSB_CB(_devcb) \ #define MCFG_Z80SCC_OUT_RTSB_CB(_devcb) \
devcb = &z80scc_device::set_out_rtsb_callback(*device, DEVCB_##_devcb); devcb = &z80scc_device::set_out_rts_callback<1>(*device, DEVCB_##_devcb);
#define MCFG_Z80SCC_OUT_WREQB_CB(_devcb) \ #define MCFG_Z80SCC_OUT_WREQB_CB(_devcb) \
devcb = &z80scc_device::set_out_wreqb_callback(*device, DEVCB_##_devcb); devcb = &z80scc_device::set_out_wreq_callback<1>(*device, DEVCB_##_devcb);
#define MCFG_Z80SCC_OUT_SYNCB_CB(_devcb) \ #define MCFG_Z80SCC_OUT_SYNCB_CB(_devcb) \
devcb = &z80scc_device::set_out_syncb_callback(*device, DEVCB_##_devcb); devcb = &z80scc_device::set_out_sync_callback<1>(*device, DEVCB_##_devcb);
#define MCFG_Z80SCC_OUT_RXDRQB_CB(_devcb) \ #define MCFG_Z80SCC_OUT_RXDRQB_CB(_devcb) \
devcb = &z80scc_device::set_out_rxdrqb_callback(*device, DEVCB_##_devcb); devcb = &z80scc_device::set_out_rxdrq_callback<1>(*device, DEVCB_##_devcb);
#define MCFG_Z80SCC_OUT_TXDRQB_CB(_devcb) \ #define MCFG_Z80SCC_OUT_TXDRQB_CB(_devcb) \
devcb = &z80scc_device::set_out_txdrqb_callback(*device, DEVCB_##_devcb); devcb = &z80scc_device::set_out_txdrq_callback<1>(*device, DEVCB_##_devcb);
//************************************************************************** //**************************************************************************
@ -632,6 +632,12 @@ protected:
// SCC specifics // SCC specifics
int m_ph; // Point high command to access regs 08-0f int m_ph; // Point high command to access regs 08-0f
uint8_t m_zc; uint8_t m_zc;
private:
// helpers
void out_txd_cb(int state);
void out_rts_cb(int state);
void out_dtr_cb(int state);
}; };
@ -645,21 +651,14 @@ public:
// construction/destruction // construction/destruction
z80scc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); z80scc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template <class Object> static devcb_base &set_out_txda_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_txda_cb.set_callback(std::forward<Object>(cb)); } template <unsigned N, class Object> static devcb_base &set_out_txd_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_txd_cb[N].set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_out_dtra_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_dtra_cb.set_callback(std::forward<Object>(cb)); } template <unsigned N, class Object> static devcb_base &set_out_dtr_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_dtr_cb[N].set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_out_rtsa_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_rtsa_cb.set_callback(std::forward<Object>(cb)); } template <unsigned N, class Object> static devcb_base &set_out_rts_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_rts_cb[N].set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_out_wreqa_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_wreqa_cb.set_callback(std::forward<Object>(cb)); } template <unsigned N, class Object> static devcb_base &set_out_wreq_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_wreq_cb[N].set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_out_synca_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_synca_cb.set_callback(std::forward<Object>(cb)); } template <unsigned N, class Object> static devcb_base &set_out_sync_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_sync_cb[N].set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_out_txdb_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_txdb_cb.set_callback(std::forward<Object>(cb)); } template <unsigned N, class Object> static devcb_base &set_out_rxdrq_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_rxdrq_cb[N].set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_out_dtrb_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_dtrb_cb.set_callback(std::forward<Object>(cb)); } template <unsigned N, class Object> static devcb_base &set_out_txdrq_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_txdrq_cb[N].set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_out_rtsb_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_rtsb_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_out_wreqb_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_wreqb_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_out_syncb_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_syncb_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_out_int_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_int_cb.set_callback(std::forward<Object>(cb)); } template <class Object> static devcb_base &set_out_int_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_int_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_out_rxdrqa_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_rxdrqa_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_out_txdrqa_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_txdrqa_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_out_rxdrqb_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_rxdrqb_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_out_txdrqb_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_txdrqb_cb.set_callback(std::forward<Object>(cb)); }
static void static_set_cputag(device_t &device, const char *tag) static void static_set_cputag(device_t &device, const char *tag)
{ {
@ -727,6 +726,7 @@ protected:
z80scc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t variant); z80scc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t variant);
// device-level overrides // device-level overrides
virtual void device_resolve_objects() override;
virtual void device_start() override; virtual void device_start() override;
virtual void device_reset() override; virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override; virtual void device_add_mconfig(machine_config &config) override;
@ -781,23 +781,16 @@ protected:
int m_rxcb; int m_rxcb;
int m_txcb; int m_txcb;
devcb_write_line m_out_txda_cb; // internal state
devcb_write_line m_out_dtra_cb; devcb_write_line m_out_txd_cb[2];
devcb_write_line m_out_rtsa_cb; devcb_write_line m_out_dtr_cb[2];
devcb_write_line m_out_wreqa_cb; devcb_write_line m_out_rts_cb[2];
devcb_write_line m_out_synca_cb; devcb_write_line m_out_wreq_cb[2];
devcb_write_line m_out_sync_cb[2];
devcb_write_line m_out_txdb_cb; devcb_write_line m_out_rxdrq_cb[2];
devcb_write_line m_out_dtrb_cb; devcb_write_line m_out_txdrq_cb[2];
devcb_write_line m_out_rtsb_cb;
devcb_write_line m_out_wreqb_cb;
devcb_write_line m_out_syncb_cb;
devcb_write_line m_out_int_cb; devcb_write_line m_out_int_cb;
devcb_write_line m_out_rxdrqa_cb;
devcb_write_line m_out_txdrqa_cb;
devcb_write_line m_out_rxdrqb_cb;
devcb_write_line m_out_txdrqb_cb;
int m_int_state[6]; // interrupt state int m_int_state[6]; // interrupt state
int m_int_source[6]; // interrupt source int m_int_source[6]; // interrupt source