From 2e9b62d4bd15690f3c75a8b6c434eb6826b80cb1 Mon Sep 17 00:00:00 2001 From: Joakim Larsson Edstrom Date: Mon, 20 Nov 2017 00:02:03 +0100 Subject: [PATCH] z80scc: general cleanup and backport of z80sio improvements part I --- src/devices/machine/z80scc.cpp | 200 ++++++++++++++------------------- src/devices/machine/z80scc.h | 79 ++++++------- 2 files changed, 119 insertions(+), 160 deletions(-) diff --git a/src/devices/machine/z80scc.cpp b/src/devices/machine/z80scc.cpp index ebdef5e346b..0bd4322ab7a 100644 --- a/src/devices/machine/z80scc.cpp +++ b/src/devices/machine/z80scc.cpp @@ -90,8 +90,9 @@ DONE (x) (p=partly) NMOS CMOS ESCC EMSCC #define LOG_DCD (1U << 8) #define LOG_SYNC (1U << 9) -//#define VERBOSE (LOG_INT|LOG_READ|LOG_SETUP|LOG_TX|LOG_CMD) -//#define LOG_OUTPUT_FUNC printf +//#define VERBOSE (LOG_TX) +//#define LOG_OUTPUT_STREAM std::cout + #include "logmacro.h" #define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__) @@ -111,10 +112,8 @@ DONE (x) (p=partly) NMOS CMOS ESCC EMSCC #ifdef _MSC_VER #define FUNCNAME __func__ -#define LLFORMAT "%I64d" #else #define FUNCNAME __PRETTY_FUNCTION__ -#define LLFORMAT "%lld" #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 */ @@ -157,10 +156,24 @@ MACHINE_CONFIG_END // 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::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_z80daisy_interface(mconfig, *this), @@ -170,21 +183,14 @@ z80scc_device::z80scc_device(const machine_config &mconfig, device_type type, co m_txca(0), m_rxcb(0), m_txcb(0), - m_out_txda_cb(*this), - m_out_dtra_cb(*this), - m_out_rtsa_cb(*this), - m_out_wreqa_cb(*this), - m_out_synca_cb(*this), - m_out_txdb_cb(*this), - m_out_dtrb_cb(*this), - m_out_rtsb_cb(*this), - m_out_wreqb_cb(*this), - m_out_syncb_cb(*this), + m_out_txd_cb{ { *this }, { *this } }, + m_out_dtr_cb{ { *this }, { *this } }, + m_out_rts_cb{ { *this }, { *this } }, + m_out_wreq_cb{ { *this }, { *this } }, + m_out_sync_cb{ { *this }, { *this } }, + m_out_rxdrq_cb{ { *this }, { *this } }, + m_out_txdrq_cb{ { *this }, { *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_wr0_ptrbits(0), 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 //------------------------------------------------- - void z80scc_device::device_start() { - LOGSETUP("%s\n", 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(); + LOG("%s", FUNCNAME); // state saving save_item(NAME(m_int_state)); @@ -274,16 +288,15 @@ void z80scc_device::device_start() //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- - void z80scc_device::device_reset() { - LOGSETUP("%s %s \n",tag(), FUNCNAME); + LOG("%s %s \n",tag(), FUNCNAME); // Do channel reset on both channels m_chanA->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 |= 0xc0; m_chanA->m_wr10 = 0x00; @@ -429,7 +442,6 @@ void z80scc_device::z80daisy_irq_reti() //------------------------------------------------- // check_interrupts - //------------------------------------------------- - void z80scc_device::check_interrupts() { int state = (z80daisy_irq_state() & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE; @@ -441,7 +453,6 @@ void z80scc_device::check_interrupts() //------------------------------------------------- // reset_interrupts - //------------------------------------------------- - void z80scc_device::reset_interrupts() { LOGINT("%s %s \n",tag(), FUNCNAME); @@ -597,7 +608,6 @@ int z80scc_device::update_extint(int index) //------------------------------------------------- // m1_r - interrupt acknowledge //------------------------------------------------- - int z80scc_device::m1_r() { return z80daisy_irq_ack(); @@ -760,7 +770,6 @@ WRITE8_MEMBER( z80scc_device::cd_ba_w ) //------------------------------------------------- // ba_cd_r - Universal Bus read //------------------------------------------------- - READ8_MEMBER( z80scc_device::ba_cd_r ) { int ba = BIT(offset, 1); @@ -782,7 +791,6 @@ READ8_MEMBER( z80scc_device::ba_cd_r ) //------------------------------------------------- // ba_cd_w - Universal Bus write //------------------------------------------------- - WRITE8_MEMBER( z80scc_device::ba_cd_w ) { int ba = BIT(offset, 1); @@ -807,7 +815,6 @@ WRITE8_MEMBER( z80scc_device::ba_cd_w ) //------------------------------------------------- // ba_cd_inv_r - Universal Bus read //------------------------------------------------- - READ8_MEMBER( z80scc_device::ba_cd_inv_r ) { int ba = BIT(offset, 1); @@ -829,7 +836,6 @@ READ8_MEMBER( z80scc_device::ba_cd_inv_r ) //------------------------------------------------- // ba_cd_inv_w - Universal Bus read //------------------------------------------------- - WRITE8_MEMBER( z80scc_device::ba_cd_inv_w ) { int ba = BIT(offset, 1); @@ -858,7 +864,6 @@ WRITE8_MEMBER( z80scc_device::ba_cd_inv_w ) //------------------------------------------------- // SCC_channel - constructor //------------------------------------------------- - 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_serial_interface(mconfig, *this), @@ -906,7 +911,6 @@ z80scc_channel::z80scc_channel(const machine_config &mconfig, const char *tag, d //------------------------------------------------- // start - channel startup //------------------------------------------------- - void z80scc_channel::device_start() { LOGSETUP("%s\n", FUNCNAME); @@ -987,7 +991,6 @@ void z80scc_channel::device_start() //------------------------------------------------- // reset - reset channel status //------------------------------------------------- - void z80scc_channel::device_reset() { LOGSETUP("%s\n", FUNCNAME); @@ -1003,7 +1006,7 @@ void z80scc_channel::device_reset() m_wr4 = 0x04; m_wr5 = 0x00; if (m_uart->m_variant & (z80scc_device::TYPE_SCC85C30 | z80scc_device::SET_ESCC)) - m_wr7 = 0x20; + m_wr7 = 0x20; // WR9,WR10,WR11 and WR14 has a different hard reset (see z80scc_device::device_reset()) values m_uart->m_wr9 &= 0xdf; m_wr10 &= 0x60; @@ -1020,9 +1023,8 @@ void z80scc_channel::device_reset() m_rr10 &= 0x40; // reset external lines - set_rts(m_wr5 & WR5_RTS ? 0 : 1); - set_dtr(m_wr14 & WR14_DTR_REQ_FUNC ? 0 : (m_wr5 & WR5_DTR ? 0 : 1)); - + out_rts_cb(m_rts = m_wr5 & WR5_RTS ? 0 : 1); + out_dtr_cb(m_dtr = m_wr14 & WR14_DTR_REQ_FUNC ? 0 : (m_wr5 & WR5_DTR ? 0 : 1)); // reset interrupts 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 - //------------------------------------------------- - void z80scc_channel::tra_callback() { 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 - if (m_index == z80scc_device::CHANNEL_A) - m_uart->m_out_txda_cb(1); - else - m_uart->m_out_txdb_cb(1); + out_txd_cb(1); } 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 - if (m_index == z80scc_device::CHANNEL_A) - m_uart->m_out_txda_cb(0); - else - m_uart->m_out_txdb_cb(0); + out_txd_cb(0); } else if (!is_transmit_register_empty()) { 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 - if (m_index == z80scc_device::CHANNEL_A) - m_uart->m_out_txda_cb(db); - else - m_uart->m_out_txdb_cb(db); + out_txd_cb(db); } 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); } } - //------------------------------------------------- // tra_complete - //------------------------------------------------- - void z80scc_channel::tra_complete() { // Delayed baudrate change according to SCC specs @@ -1118,7 +1108,7 @@ void z80scc_channel::tra_complete() { m_delayed_tx_brg_change = 0; 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)) @@ -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 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] : ' '); transmit_register_setup(m_tx_data_fifo[m_tx_fifo_rp]); // Reload the shift register m_tx_fifo_rp_step(); @@ -1134,7 +1124,7 @@ void z80scc_channel::tra_complete() } 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; // 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) { - 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 - if (m_index == z80scc_device::CHANNEL_A) - m_uart->m_out_txda_cb(0); - else - m_uart->m_out_txdb_cb(0); + out_txd_cb(0); } 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 - if (m_index == z80scc_device::CHANNEL_A) - m_uart->m_out_txda_cb(1); - else - m_uart->m_out_txdb_cb(1); + out_txd_cb(1); } } @@ -1185,18 +1169,17 @@ void z80scc_channel::tra_complete() //------------------------------------------------- // rcv_callback - //------------------------------------------------- - void z80scc_channel::rcv_callback() { 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); } #if 1 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); } #endif @@ -1206,14 +1189,13 @@ void z80scc_channel::rcv_callback() //------------------------------------------------- // rcv_complete - //------------------------------------------------- - void z80scc_channel::rcv_complete() { uint8_t data; receive_register_extract(); 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); #if START_BIT_HUNT m_rcv_mode = RCV_SEEKING; @@ -1224,7 +1206,6 @@ void z80scc_channel::rcv_complete() //------------------------------------------------- // get_clock_mode - get clock divisor //------------------------------------------------- - int z80scc_channel::get_clock_mode() { int clocks = 1; @@ -1254,10 +1235,7 @@ TODO: void z80scc_channel::set_rts(int state) { LOG("%s(%d) \"%s\": %c \n", FUNCNAME, state, owner()->tag(), 'A' + m_index); - if (m_index == z80scc_device::CHANNEL_A) - m_uart->m_out_rtsa_cb(state); - else - m_uart->m_out_rtsb_cb(state); + out_rts_cb(state); } void z80scc_channel::update_rts() @@ -1282,7 +1260,6 @@ void z80scc_channel::update_rts() //------------------------------------------------- // get_stop_bits - get number of stop bits //------------------------------------------------- - device_serial_interface::stop_bits_t z80scc_channel::get_stop_bits() { 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 //------------------------------------------------- - int z80scc_channel::get_rx_word_length() { int bits = 5; @@ -1319,7 +1295,6 @@ int z80scc_channel::get_rx_word_length() //------------------------------------------------- // get_tx_word_length - get transmit word length //------------------------------------------------- - int z80scc_channel::get_tx_word_length() { int bits = 5; @@ -1482,7 +1457,7 @@ uint8_t z80scc_channel::do_sccreg_rr7() LOGR("%s\n", FUNCNAME); 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 m_rr3; @@ -1513,7 +1488,7 @@ uint8_t z80scc_channel::do_sccreg_rr9() uint8_t z80scc_channel::do_sccreg_rr10() { LOGR("%s\n", FUNCNAME); - logerror("%s() not implemented feature\n", FUNCNAME); + logerror("%s not implemented feature\n", FUNCNAME); return m_rr10; } @@ -1623,7 +1598,7 @@ uint8_t z80scc_channel::scc_register_read( uint8_t reg) case REG_RR14_WR7_OR_R10: data = do_sccreg_rr14(); break; case REG_RR15_WR15_EXT_STAT: data = do_sccreg_rr15(); break; default: - logerror(" \"%s\" %s: %c : Unsupported RRx register:%02x\n", owner()->tag(), FUNCNAME, 'A' + m_index, reg); + logerror(" \"%s\"%s: %c : Unsupported RRx register:%02x\n", owner()->tag(), FUNCNAME, 'A' + m_index, reg); } return data; } @@ -1927,7 +1902,7 @@ void z80scc_channel::do_sccreg_wr7(uint8_t data) /* WR8 is the transmit buffer register */ 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); } @@ -2257,7 +2232,6 @@ with 0 before accessing WR0 or RR0.*/ //------------------------------------------------- // control_write - write control register //------------------------------------------------- - void z80scc_channel::control_write(uint8_t data) { 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 //------------------------------------------------- - uint8_t z80scc_channel::data_read() { 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) { /* 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 ( (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 //------------------------------------------------- - 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); @@ -2522,10 +2494,9 @@ void z80scc_channel::receive_data(uint8_t data) //------------------------------------------------- // cts_w - clear to send handler //------------------------------------------------- - 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); if ((m_rr0 & RR0_CTS) != (state ? RR0_CTS : 0)) // SCC change detection logic { @@ -2782,7 +2753,7 @@ void z80scc_channel::update_serial() 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); 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); m_dtr = state; - if (m_index == z80scc_device::CHANNEL_A) - m_uart->m_out_dtra_cb(m_dtr); - else - m_uart->m_out_dtrb_cb(m_dtr); + out_dtr_cb(m_dtr); } //------------------------------------------------- @@ -2893,8 +2861,6 @@ void z80scc_channel::check_waitrequest() if (m_wr1 & WR1_WREQ_FUNCTION) { // 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_index ? m_uart->m_out_wreqb_cb : m_uart->m_out_wreqa_cb)(state); + m_uart->m_out_wreq_cb[m_index]((m_rr0 & RR0_TX_BUFFER_EMPTY) ? ASSERT_LINE : CLEAR_LINE); } } diff --git a/src/devices/machine/z80scc.h b/src/devices/machine/z80scc.h index 33729f23efb..e409b301a1c 100644 --- a/src/devices/machine/z80scc.h +++ b/src/devices/machine/z80scc.h @@ -90,47 +90,47 @@ // Port A callbacks #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) \ - 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) \ - 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) \ - 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) \ - 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) \ - 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) \ - devcb = &z80scc_device::set_out_txdrqa_callback(*device, DEVCB_##_devcb); + devcb = &z80scc_device::set_out_txdrq_callback<0>(*device, DEVCB_##_devcb); // Port B callbacks #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) \ - 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) \ - 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) \ - 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) \ - 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) \ - 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) \ - 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 int m_ph; // Point high command to access regs 08-0f 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 z80scc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template static devcb_base &set_out_txda_callback(device_t &device, Object &&cb) { return downcast(device).m_out_txda_cb.set_callback(std::forward(cb)); } - template static devcb_base &set_out_dtra_callback(device_t &device, Object &&cb) { return downcast(device).m_out_dtra_cb.set_callback(std::forward(cb)); } - template static devcb_base &set_out_rtsa_callback(device_t &device, Object &&cb) { return downcast(device).m_out_rtsa_cb.set_callback(std::forward(cb)); } - template static devcb_base &set_out_wreqa_callback(device_t &device, Object &&cb) { return downcast(device).m_out_wreqa_cb.set_callback(std::forward(cb)); } - template static devcb_base &set_out_synca_callback(device_t &device, Object &&cb) { return downcast(device).m_out_synca_cb.set_callback(std::forward(cb)); } - template static devcb_base &set_out_txdb_callback(device_t &device, Object &&cb) { return downcast(device).m_out_txdb_cb.set_callback(std::forward(cb)); } - template static devcb_base &set_out_dtrb_callback(device_t &device, Object &&cb) { return downcast(device).m_out_dtrb_cb.set_callback(std::forward(cb)); } - template static devcb_base &set_out_rtsb_callback(device_t &device, Object &&cb) { return downcast(device).m_out_rtsb_cb.set_callback(std::forward(cb)); } - template static devcb_base &set_out_wreqb_callback(device_t &device, Object &&cb) { return downcast(device).m_out_wreqb_cb.set_callback(std::forward(cb)); } - template static devcb_base &set_out_syncb_callback(device_t &device, Object &&cb) { return downcast(device).m_out_syncb_cb.set_callback(std::forward(cb)); } + template static devcb_base &set_out_txd_callback(device_t &device, Object &&cb) { return downcast(device).m_out_txd_cb[N].set_callback(std::forward(cb)); } + template static devcb_base &set_out_dtr_callback(device_t &device, Object &&cb) { return downcast(device).m_out_dtr_cb[N].set_callback(std::forward(cb)); } + template static devcb_base &set_out_rts_callback(device_t &device, Object &&cb) { return downcast(device).m_out_rts_cb[N].set_callback(std::forward(cb)); } + template static devcb_base &set_out_wreq_callback(device_t &device, Object &&cb) { return downcast(device).m_out_wreq_cb[N].set_callback(std::forward(cb)); } + template static devcb_base &set_out_sync_callback(device_t &device, Object &&cb) { return downcast(device).m_out_sync_cb[N].set_callback(std::forward(cb)); } + template static devcb_base &set_out_rxdrq_callback(device_t &device, Object &&cb) { return downcast(device).m_out_rxdrq_cb[N].set_callback(std::forward(cb)); } + template static devcb_base &set_out_txdrq_callback(device_t &device, Object &&cb) { return downcast(device).m_out_txdrq_cb[N].set_callback(std::forward(cb)); } template static devcb_base &set_out_int_callback(device_t &device, Object &&cb) { return downcast(device).m_out_int_cb.set_callback(std::forward(cb)); } - template static devcb_base &set_out_rxdrqa_callback(device_t &device, Object &&cb) { return downcast(device).m_out_rxdrqa_cb.set_callback(std::forward(cb)); } - template static devcb_base &set_out_txdrqa_callback(device_t &device, Object &&cb) { return downcast(device).m_out_txdrqa_cb.set_callback(std::forward(cb)); } - template static devcb_base &set_out_rxdrqb_callback(device_t &device, Object &&cb) { return downcast(device).m_out_rxdrqb_cb.set_callback(std::forward(cb)); } - template static devcb_base &set_out_txdrqb_callback(device_t &device, Object &&cb) { return downcast(device).m_out_txdrqb_cb.set_callback(std::forward(cb)); } 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); // device-level overrides + virtual void device_resolve_objects() override; virtual void device_start() override; virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; @@ -781,23 +781,16 @@ protected: int m_rxcb; int m_txcb; - devcb_write_line m_out_txda_cb; - devcb_write_line m_out_dtra_cb; - devcb_write_line m_out_rtsa_cb; - devcb_write_line m_out_wreqa_cb; - devcb_write_line m_out_synca_cb; - - devcb_write_line m_out_txdb_cb; - devcb_write_line m_out_dtrb_cb; - devcb_write_line m_out_rtsb_cb; - devcb_write_line m_out_wreqb_cb; - devcb_write_line m_out_syncb_cb; + // internal state + devcb_write_line m_out_txd_cb[2]; + devcb_write_line m_out_dtr_cb[2]; + devcb_write_line m_out_rts_cb[2]; + devcb_write_line m_out_wreq_cb[2]; + devcb_write_line m_out_sync_cb[2]; + devcb_write_line m_out_rxdrq_cb[2]; + devcb_write_line m_out_txdrq_cb[2]; 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_source[6]; // interrupt source