diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index a9a03c0d069..9dfc6e94627 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -3335,18 +3335,6 @@ if (MACHINES["Z80CTC"]~=null) then } end ---------------------------------------------------- --- ---@src/devices/machine/z80dart.h,MACHINES["Z80DART"] = true ---------------------------------------------------- - -if (MACHINES["Z80DART"]~=null) then - files { - MAME_DIR .. "src/devices/machine/z80dart.cpp", - MAME_DIR .. "src/devices/machine/z80dart.h", - } -end - --------------------------------------------------- -- --@src/devices/machine/z80sio.h,MACHINES["Z80SIO"] = true diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index c71b8c45816..b72c86cc295 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -650,7 +650,6 @@ MACHINES["X2212"] = true MACHINES["X76F041"] = true MACHINES["X76F100"] = true MACHINES["Z80CTC"] = true -MACHINES["Z80DART"] = true MACHINES["Z80SIO"] = true MACHINES["Z80SCC"] = true MACHINES["Z80DMA"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 71d1d2a426b..e6a0df3eb59 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -691,7 +691,6 @@ MACHINES["X76F100"] = true MACHINES["YM2148"] = true MACHINES["YM3802"] = true MACHINES["Z80CTC"] = true -MACHINES["Z80DART"] = true MACHINES["Z80SIO"] = true MACHINES["Z80SCC"] = true MACHINES["Z80DMA"] = true diff --git a/src/devices/bus/abcbus/sio.h b/src/devices/bus/abcbus/sio.h index 6cb86d9fc76..156939808df 100644 --- a/src/devices/bus/abcbus/sio.h +++ b/src/devices/bus/abcbus/sio.h @@ -7,7 +7,7 @@ #include "abcbus.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" diff --git a/src/devices/bus/cpc/cpc_rs232.h b/src/devices/bus/cpc/cpc_rs232.h index 56e7ccd8b4f..2b1319158e9 100644 --- a/src/devices/bus/cpc/cpc_rs232.h +++ b/src/devices/bus/cpc/cpc_rs232.h @@ -12,7 +12,7 @@ #pragma once #include "cpcexp.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/pit8253.h" #include "bus/rs232/rs232.h" diff --git a/src/devices/bus/wangpc/mcc.h b/src/devices/bus/wangpc/mcc.h index 3f08991d785..9aa0d4adee1 100644 --- a/src/devices/bus/wangpc/mcc.h +++ b/src/devices/bus/wangpc/mcc.h @@ -12,7 +12,6 @@ #pragma once #include "wangpc.h" -#include "machine/z80dart.h" #include "machine/z80sio.h" diff --git a/src/devices/machine/z80dart.cpp b/src/devices/machine/z80dart.cpp deleted file mode 100644 index a5f80551712..00000000000 --- a/src/devices/machine/z80dart.cpp +++ /dev/null @@ -1,1270 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Curt Coder -/*************************************************************************** - - Z80-DART Dual Asynchronous Receiver/Transmitter emulation - - The z80dart/z80sio itself is based on an older intel serial chip, the i8274 MPSC - (see http://doc.chipfind.ru/pdf/intel/8274.pdf), which also has almost identical - behavior, except lacks the interrupt daisy chaining and has its own interrupt/dma - scheme which uses write register 2 on channel A, that register which is unused on - the z80dart and z80sio. - -***************************************************************************/ - -/* - - TODO: - - - i8274 DMA scheme - - break detection - - wr0 reset tx interrupt pending - - wait/ready - - 1.5 stop bits - -*/ - -#include "emu.h" -#include "z80dart.h" - -//#define VERBOSE 1 -//#define LOG_OUTPUT_FUNC printf -#include "logmacro.h" - -#define CHANA_TAG "cha" -#define CHANB_TAG "chb" - -//************************************************************************** -// DEVICE DEFINITIONS -//************************************************************************** - -// device type definition -DEFINE_DEVICE_TYPE(Z80DART, z80dart_device, "z80dart", "Z80 DART") -DEFINE_DEVICE_TYPE(Z80DART_CHANNEL, z80dart_channel, "z80dart_channel", "Z80 DART channel") - - -//------------------------------------------------- -// device_add_mconfig - add device configuration -//------------------------------------------------- - -void z80dart_device::device_add_mconfig(machine_config &config) -{ - Z80DART_CHANNEL(config, m_chanA, 0); - Z80DART_CHANNEL(config, m_chanB, 0); -} - - -//************************************************************************** -// LIVE DEVICE -//************************************************************************** - -//------------------------------------------------- -// z80dart_device - constructor -//------------------------------------------------- - -z80dart_device::z80dart_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) - , m_chanA(*this, CHANA_TAG) - , m_chanB(*this, CHANB_TAG) - , m_rxca(0) - , 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_wrdya_cb(*this) - , m_out_synca_cb(*this) - , m_out_txdb_cb(*this) - , m_out_dtrb_cb(*this) - , m_out_rtsb_cb(*this) - , m_out_wrdyb_cb(*this) - , m_out_syncb_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) -{ - for (auto & elem : m_int_state) - elem = 0; -} - -z80dart_device::z80dart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : z80dart_device(mconfig, Z80DART, tag, owner, clock, TYPE_DART) -{ -} - - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void z80dart_device::device_start() -{ - // resolve callbacks - m_out_txda_cb.resolve_safe(); - m_out_dtra_cb.resolve_safe(); - m_out_rtsa_cb.resolve_safe(); - m_out_wrdya_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_wrdyb_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(); - - // configure channel A - m_chanA->set_rxc(m_rxca); - m_chanA->set_txc(m_txca); - - // configure channel B - m_chanB->set_rxc(m_rxcb); - m_chanB->set_txc(m_txcb); - - // state saving - save_item(NAME(m_int_state)); -} - - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void z80dart_device::device_reset() -{ - LOG("Z80DART \"%s\" Reset\n", tag()); -} - -//------------------------------------------------- -// z80daisy_irq_state - get interrupt status -//------------------------------------------------- - -int z80dart_device::z80daisy_irq_state() -{ - int state = 0; - int i; - - LOG("Z80DART \"%s\" : Interrupt State A:%d%d%d%d B:%d%d%d%d\n", tag(), - m_int_state[0], m_int_state[1], m_int_state[2], m_int_state[3], - m_int_state[4], m_int_state[5], m_int_state[6], m_int_state[7]); - - // loop over all interrupt sources - for (i = 0; i < 8; i++) - { - // if we're servicing a request, don't indicate more interrupts - if (m_int_state[i] & Z80_DAISY_IEO) - { - state |= Z80_DAISY_IEO; - break; - } - state |= m_int_state[i]; - } - - LOG("Z80DART \"%s\" : Interrupt State %u\n", tag(), state); - - return state; -} - - -//------------------------------------------------- -// z80daisy_irq_ack - interrupt acknowledge -//------------------------------------------------- - -int z80dart_device::z80daisy_irq_ack() -{ - int i; - - LOG("Z80DART \"%s\" Interrupt Acknowledge\n", tag()); - - // loop over all interrupt sources - for (i = 0; i < 8; i++) - { - // find the first channel with an interrupt requested - if (m_int_state[i] & Z80_DAISY_INT) - { - // clear interrupt, switch to the IEO state, and update the IRQs - m_int_state[i] = Z80_DAISY_IEO; - m_chanA->clr_interrupt_pending(); - check_interrupts(); - - LOG("Z80DART \"%s\" : Interrupt Acknowledge Vector %02x\n", tag(), m_chanB->get_vector()); - - return m_chanB->get_vector(); - } - } - - //logerror("z80dart_irq_ack: failed to find an interrupt to ack!\n"); - - return m_chanB->get_vector(); -} - - -//------------------------------------------------- -// z80daisy_irq_reti - return from interrupt -//------------------------------------------------- - -void z80dart_device::z80daisy_irq_reti() -{ - int i; - - LOG("Z80DART \"%s\" Return from Interrupt\n", tag()); - - // loop over all interrupt sources - for (i = 0; i < 8; i++) - { - // find the first channel with an IEO pending - if (m_int_state[i] & Z80_DAISY_IEO) - { - // clear the IEO state and update the IRQs - m_int_state[i] &= ~Z80_DAISY_IEO; - check_interrupts(); - return; - } - } - - //logerror("z80dart_irq_reti: failed to find an interrupt to clear IEO on!\n"); -} - - -//------------------------------------------------- -// check_interrupts - -//------------------------------------------------- - -void z80dart_device::check_interrupts() -{ - int state = (z80daisy_irq_state() & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE; - m_out_int_cb(state); -} - - -//------------------------------------------------- -// reset_interrupts - -//------------------------------------------------- - -void z80dart_device::reset_interrupts() -{ - for (auto & elem : m_int_state) - { - elem = 0; - } - - check_interrupts(); -} - - -//------------------------------------------------- -// trigger_interrupt - -//------------------------------------------------- - -void z80dart_device::trigger_interrupt(int index, int state) -{ - uint8_t vector = m_chanB->m_wr[2]; - int priority; - - if((m_variant == TYPE_I8274) || (m_variant == TYPE_UPD7201)) - { - int prio_level = 0; - switch(state) - { - case z80dart_channel::INT_TRANSMIT: - prio_level = 1; - break; - case z80dart_channel::INT_RECEIVE: - case z80dart_channel::INT_SPECIAL: - prio_level = 0; - break; - case z80dart_channel::INT_EXTERNAL: - prio_level = 2; - break; - } - - if(m_chanA->get_priority()) - { - priority = (prio_level * 2) + index; - } - else - { - priority = (prio_level == 2) ? index + 4 : ((index * 2) + prio_level); - } - if (m_chanB->get_status_vector()) - { - vector = (!index << 2) | state; - if((m_chanA->m_wr[1] & 0x18) == z80dart_channel::WR2_MODE_8086_8088) - { - vector = (m_chanB->m_wr[2] & 0xf8) | vector; - } - else - { - vector = (m_chanB->m_wr[2] & 0xe3) | (vector << 2); - } - } - } - else - { - priority = (index << 2) | state; - if (m_chanB->get_status_vector()) - { - // status affects vector - vector = (m_chanB->m_wr[2] & 0xf1) | (!index << 3) | (state << 1); - } - } - - LOG("Z80DART \"%s\" Channel %c : Interrupt Request %u\n", tag(), 'A' + index, state); - - // update vector register - m_chanB->set_vector(vector); - - // trigger interrupt - m_int_state[priority] |= Z80_DAISY_INT; - m_chanA->set_interrupt_pending(); - - // check for interrupt - check_interrupts(); -} - - -//------------------------------------------------- -// m1_r - interrupt acknowledge -//------------------------------------------------- - -int z80dart_device::m1_r() -{ - return z80daisy_irq_ack(); -} - - -//------------------------------------------------- -// cd_ba_r - -//------------------------------------------------- - -uint8_t z80dart_device::cd_ba_r(offs_t offset) -{ - int ba = BIT(offset, 0); - int cd = BIT(offset, 1); - z80dart_channel *channel = ba ? m_chanB : m_chanA; - - return cd ? channel->control_read() : channel->data_read(); -} - - -//------------------------------------------------- -// cd_ba_w - -//------------------------------------------------- - -void z80dart_device::cd_ba_w(offs_t offset, uint8_t data) -{ - int ba = BIT(offset, 0); - int cd = BIT(offset, 1); - z80dart_channel *channel = ba ? m_chanB : m_chanA; - - if (cd) - channel->control_write(data); - else - channel->data_write(data); -} - - -//------------------------------------------------- -// ba_cd_r - -//------------------------------------------------- - -uint8_t z80dart_device::ba_cd_r(offs_t offset) -{ - int ba = BIT(offset, 1); - int cd = BIT(offset, 0); - z80dart_channel *channel = ba ? m_chanB : m_chanA; - - return cd ? channel->control_read() : channel->data_read(); -} - - -//------------------------------------------------- -// ba_cd_w - -//------------------------------------------------- - -void z80dart_device::ba_cd_w(offs_t offset, uint8_t data) -{ - int ba = BIT(offset, 1); - int cd = BIT(offset, 0); - z80dart_channel *channel = ba ? m_chanB : m_chanA; - - if (cd) - channel->control_write(data); - else - channel->data_write(data); -} - - - -//************************************************************************** -// DART CHANNEL -//************************************************************************** - -//------------------------------------------------- -// dart_channel - constructor -//------------------------------------------------- - -z80dart_channel::z80dart_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, Z80DART_CHANNEL, tag, owner, clock) - , device_serial_interface(mconfig, *this) - , m_rx_error(0) - , m_rx_clock(0) - , m_rx_first(0) - , m_rx_break(0) - , m_rx_rr0_latch(0) - , m_rxd(1) - , m_ri(0) - , m_cts(0) - , m_dcd(0) - , m_tx_data(0) - , m_tx_clock(0) - , m_dtr(0) - , m_rts(0) - , m_sync(0) -{ - for (auto & elem : m_rr) - elem = 0; - - for (auto & elem : m_wr) - elem = 0; -} - - -//------------------------------------------------- -// start - channel startup -//------------------------------------------------- - -void z80dart_channel::device_start() -{ - m_uart = downcast(owner()); - m_index = m_uart->get_channel_index(this); - - // state saving - save_item(NAME(m_rr)); - save_item(NAME(m_wr)); - // save_item(NAME(m_rx_data_fifo)); - // save_item(NAME(m_rx_error_fifo)); - save_item(NAME(m_rx_clock)); - save_item(NAME(m_rx_first)); - save_item(NAME(m_rx_break)); - save_item(NAME(m_rx_rr0_latch)); - save_item(NAME(m_ri)); - save_item(NAME(m_cts)); - save_item(NAME(m_dcd)); - save_item(NAME(m_tx_data)); - save_item(NAME(m_tx_clock)); - save_item(NAME(m_dtr)); - save_item(NAME(m_rts)); - save_item(NAME(m_sync)); -} - - -//------------------------------------------------- -// reset - reset channel status -//------------------------------------------------- - -void z80dart_channel::device_reset() -{ - receive_register_reset(); - transmit_register_reset(); - - // disable receiver - m_wr[3] &= ~WR3_RX_ENABLE; - - // disable transmitter - m_wr[5] &= ~WR5_TX_ENABLE; - m_rr[0] |= RR0_TX_BUFFER_EMPTY; - m_rr[1] |= RR1_ALL_SENT; - - // reset external lines - set_rts(1); - set_dtr(1); - - // reset interrupts - if (m_index == z80dart_device::CHANNEL_A) - { - m_uart->reset_interrupts(); - } -} - - -//------------------------------------------------- -// tra_callback - -//------------------------------------------------- - -void z80dart_channel::tra_callback() -{ - if (!(m_wr[5] & WR5_TX_ENABLE)) - { - // transmit mark - if (m_index == z80dart_device::CHANNEL_A) - m_uart->m_out_txda_cb(1); - else - m_uart->m_out_txdb_cb(1); - } - else if (m_wr[5] & WR5_SEND_BREAK) - { - // transmit break - if (m_index == z80dart_device::CHANNEL_A) - m_uart->m_out_txda_cb(0); - else - m_uart->m_out_txdb_cb(0); - } - else if (!is_transmit_register_empty()) - { - // transmit data - if (m_index == z80dart_device::CHANNEL_A) - m_uart->m_out_txda_cb(transmit_register_get_data_bit()); - else - m_uart->m_out_txdb_cb(transmit_register_get_data_bit()); - } -} - - -//------------------------------------------------- -// tra_complete - -//------------------------------------------------- - -void z80dart_channel::tra_complete() -{ - if ((m_wr[5] & WR5_TX_ENABLE) && !(m_wr[5] & WR5_SEND_BREAK) && !(m_rr[0] & RR0_TX_BUFFER_EMPTY)) - { - LOG("Z80DART \"%s\" Channel %c : Transmit Data Byte '%02x'\n", owner()->tag(), 'A' + m_index, m_tx_data); - - transmit_register_setup(m_tx_data); - - // empty transmit buffer - m_rr[0] |= RR0_TX_BUFFER_EMPTY; - - if (m_wr[1] & WR1_TX_INT_ENABLE) - m_uart->trigger_interrupt(m_index, INT_TRANSMIT); - } - else if (m_wr[5] & WR5_SEND_BREAK) - { - // transmit break - if (m_index == z80dart_device::CHANNEL_A) - m_uart->m_out_txda_cb(0); - else - m_uart->m_out_txdb_cb(0); - } - else - { - // transmit mark - if (m_index == z80dart_device::CHANNEL_A) - m_uart->m_out_txda_cb(1); - else - m_uart->m_out_txdb_cb(1); - } - - // if transmit buffer is empty - if (m_rr[0] & RR0_TX_BUFFER_EMPTY) - { - // then all characters have been sent - m_rr[1] |= RR1_ALL_SENT; - - // when the RTS bit is reset, the _RTS output goes high after the transmitter empties - if (!m_rts) - set_rts(1); - } -} - - -//------------------------------------------------- -// rcv_callback - -//------------------------------------------------- - -void z80dart_channel::rcv_callback() -{ - if (m_wr[3] & WR3_RX_ENABLE) - { - receive_register_update_bit(m_rxd); - } -} - - -//------------------------------------------------- -// rcv_complete - -//------------------------------------------------- - -void z80dart_channel::rcv_complete() -{ - receive_register_extract(); - receive_data(get_received_char()); -} - - -//------------------------------------------------- -// get_clock_mode - get clock divisor -//------------------------------------------------- - -int z80dart_channel::get_clock_mode() -{ - int clocks = 1; - - switch (m_wr[4] & WR4_CLOCK_RATE_MASK) - { - case WR4_CLOCK_RATE_X1: clocks = 1; break; - case WR4_CLOCK_RATE_X16: clocks = 16; break; - case WR4_CLOCK_RATE_X32: clocks = 32; break; - case WR4_CLOCK_RATE_X64: clocks = 64; break; - } - - return clocks; -} - - -//------------------------------------------------- -// get_stop_bits - get number of stop bits -//------------------------------------------------- - -device_serial_interface::stop_bits_t z80dart_channel::get_stop_bits() -{ - switch (m_wr[4] & WR4_STOP_BITS_MASK) - { - case WR4_STOP_BITS_1: return STOP_BITS_1; - case WR4_STOP_BITS_1_5: return STOP_BITS_1_5; - case WR4_STOP_BITS_2: return STOP_BITS_2; - } - - return STOP_BITS_0; -} - - -//------------------------------------------------- -// get_rx_word_length - get receive word length -//------------------------------------------------- - -int z80dart_channel::get_rx_word_length() -{ - int bits = 5; - - switch (m_wr[3] & WR3_RX_WORD_LENGTH_MASK) - { - case WR3_RX_WORD_LENGTH_5: bits = 5; break; - case WR3_RX_WORD_LENGTH_6: bits = 6; break; - case WR3_RX_WORD_LENGTH_7: bits = 7; break; - case WR3_RX_WORD_LENGTH_8: bits = 8; break; - } - - return bits; -} - - -//------------------------------------------------- -// get_tx_word_length - get transmit word length -//------------------------------------------------- - -int z80dart_channel::get_tx_word_length() -{ - int bits = 5; - - switch (m_wr[5] & WR5_TX_WORD_LENGTH_MASK) - { - case WR5_TX_WORD_LENGTH_5: bits = 5; break; - case WR5_TX_WORD_LENGTH_6: bits = 6; break; - case WR5_TX_WORD_LENGTH_7: bits = 7; break; - case WR5_TX_WORD_LENGTH_8: bits = 8; break; - } - - return bits; -} - - -//------------------------------------------------- -// control_read - read control register -//------------------------------------------------- - -uint8_t z80dart_channel::control_read() -{ - uint8_t data = 0; - - int reg = m_wr[0] & WR0_REGISTER_MASK; - - if (reg != 0) - { - // mask out register index - m_wr[0] &= ~WR0_REGISTER_MASK; - } - - switch (reg) - { - case 0: - case 1: - data = m_rr[reg]; - break; - - case 2: - // channel B only - if (m_index == z80dart_device::CHANNEL_B) - data = m_rr[reg]; - break; - } - - //LOG("Z80DART \"%s\" Channel %c : Control Register Read '%02x'\n", owner()->tag(), 'A' + m_index, data); - - return data; -} - - -//------------------------------------------------- -// control_write - write control register -//------------------------------------------------- - -void z80dart_channel::control_write(uint8_t data) -{ - int reg = m_wr[0] & WR0_REGISTER_MASK; - uint8_t prev = m_wr[reg]; - - LOG("Z80DART \"%s\" Channel %c : Control Register Write '%02x'\n", owner()->tag(), 'A' + m_index, data); - - // write data to selected register - if (reg < 6) - m_wr[reg] = data; - - if (reg != 0) - { - // mask out register index - m_wr[0] &= ~WR0_REGISTER_MASK; - } - - switch (reg) - { - case 0: - switch (data & WR0_COMMAND_MASK) - { - case WR0_NULL: - LOG("Z80DART \"%s\" Channel %c : Null\n", owner()->tag(), 'A' + m_index); - break; - - case WR0_SEND_ABORT: - LOG("Z80DART \"%s\" Channel %c : Send Abort\n", owner()->tag(), 'A' + m_index); - logerror("Z80DART \"%s\" Channel %c : unsupported command: Send Abort\n", owner()->tag(), 'A' + m_index); - break; - - case WR0_RESET_EXT_STATUS: - // reset external/status interrupt - m_rr[0] &= ~(RR0_DCD | RR0_RI | RR0_CTS | RR0_BREAK_ABORT); - - if (!m_dcd) m_rr[0] |= RR0_DCD; - if (m_ri) m_rr[0] |= RR0_RI; - if (!m_cts) m_rr[0] |= RR0_CTS; - - m_rx_rr0_latch = 0; - - LOG("Z80DART \"%s\" Channel %c : Reset External/Status Interrupt\n", owner()->tag(), 'A' + m_index); - break; - - case WR0_CHANNEL_RESET: - // channel reset - LOG("Z80DART \"%s\" Channel %c : Channel Reset\n", owner()->tag(), 'A' + m_index); - device_reset(); - break; - - case WR0_ENABLE_INT_NEXT_RX: - // enable interrupt on next receive character - LOG("Z80DART \"%s\" Channel %c : Enable Interrupt on Next Received Character\n", owner()->tag(), 'A' + m_index); - m_rx_first = 1; - break; - - case WR0_RESET_TX_INT: - // reset transmitter interrupt pending - LOG("Z80DART \"%s\" Channel %c : Reset Transmitter Interrupt Pending\n", owner()->tag(), 'A' + m_index); - logerror("Z80DART \"%s\" Channel %c : unsupported command: Reset Transmitter Interrupt Pending\n", owner()->tag(), 'A' + m_index); - break; - - case WR0_ERROR_RESET: - // error reset - LOG("Z80DART \"%s\" Channel %c : Error Reset\n", owner()->tag(), 'A' + m_index); - m_rr[1] &= ~(RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR | RR1_PARITY_ERROR); - break; - - case WR0_RETURN_FROM_INT: - // return from interrupt - LOG("Z80DART \"%s\" Channel %c : Return from Interrupt\n", owner()->tag(), 'A' + m_index); - m_uart->z80daisy_irq_reti(); - if((m_uart->m_variant == z80dart_device::TYPE_I8274) || (m_uart->m_variant == z80dart_device::TYPE_UPD7201)) - { - if (m_uart->m_chanB->get_status_vector()) - { - if((m_uart->m_chanA->m_wr[1] & 0x18) == z80dart_channel::WR2_MODE_8086_8088) - m_uart->m_chanB->m_rr[2] = (m_uart->m_chanB->m_wr[2] & 0xf8) | 0x07; - else - m_uart->m_chanB->m_rr[2] = (m_uart->m_chanB->m_wr[2] & 0xe3) | 0x1c; - } - } - break; - } - break; - - case 1: - LOG("Z80DART \"%s\" Channel %c : External Interrupt Enable %u\n", owner()->tag(), 'A' + m_index, (data & WR1_EXT_INT_ENABLE) ? 1 : 0); - LOG("Z80DART \"%s\" Channel %c : Transmit Interrupt Enable %u\n", owner()->tag(), 'A' + m_index, (data & WR1_TX_INT_ENABLE) ? 1 : 0); - LOG("Z80DART \"%s\" Channel %c : Status Affects Vector %u\n", owner()->tag(), 'A' + m_index, (data & WR1_STATUS_VECTOR) ? 1 : 0); - LOG("Z80DART \"%s\" Channel %c : Wait/Ready Enable %u\n", owner()->tag(), 'A' + m_index, (data & WR1_WRDY_ENABLE) ? 1 : 0); - LOG("Z80DART \"%s\" Channel %c : Wait/Ready Function %s\n", owner()->tag(), 'A' + m_index, (data & WR1_WRDY_FUNCTION) ? "Ready" : "Wait"); - LOG("Z80DART \"%s\" Channel %c : Wait/Ready on %s\n", owner()->tag(), 'A' + m_index, (data & WR1_WRDY_ON_RX_TX) ? "Receive" : "Transmit"); - - switch (data & WR1_RX_INT_MODE_MASK) - { - case WR1_RX_INT_DISABLE: - LOG("Z80DART \"%s\" Channel %c : Receiver Interrupt Disabled\n", owner()->tag(), 'A' + m_index); - break; - - case WR1_RX_INT_FIRST: - LOG("Z80DART \"%s\" Channel %c : Receiver Interrupt on First Character\n", owner()->tag(), 'A' + m_index); - break; - - case WR1_RX_INT_ALL_PARITY: - LOG("Z80DART \"%s\" Channel %c : Receiver Interrupt on All Characters, Parity Affects Vector\n", owner()->tag(), 'A' + m_index); - break; - - case WR1_RX_INT_ALL: - LOG("Z80DART \"%s\" Channel %c : Receiver Interrupt on All Characters\n", owner()->tag(), 'A' + m_index); - break; - } - - m_uart->check_interrupts(); - break; - - case 2: - // interrupt vector - if (m_index == z80dart_device::CHANNEL_B) - { - if(get_status_vector()) - m_rr[2] = ( m_rr[2] & 0x0e ) | ( m_wr[2] & 0xF1); - else - m_rr[2] = m_wr[2]; - } - m_uart->check_interrupts(); - LOG("Z80DART \"%s\" Channel %c : Interrupt Vector %02x\n", owner()->tag(), 'A' + m_index, data); - break; - - case 3: - LOG("Z80DART \"%s\" Channel %c : Receiver Enable %u\n", owner()->tag(), 'A' + m_index, (data & WR3_RX_ENABLE) ? 1 : 0); - LOG("Z80DART \"%s\" Channel %c : Auto Enables %u\n", owner()->tag(), 'A' + m_index, (data & WR3_AUTO_ENABLES) ? 1 : 0); - LOG("Z80DART \"%s\" Channel %c : Receiver Bits/Character %u\n", owner()->tag(), 'A' + m_index, get_rx_word_length()); - - if (data != prev) - update_serial(); - break; - - case 4: - LOG("Z80DART \"%s\" Channel %c : Parity Enable %u\n", owner()->tag(), 'A' + m_index, (data & WR4_PARITY_ENABLE) ? 1 : 0); - LOG("Z80DART \"%s\" Channel %c : Parity %s\n", owner()->tag(), 'A' + m_index, (data & WR4_PARITY_EVEN) ? "Even" : "Odd"); - LOG("Z80DART \"%s\" Channel %c : Stop Bits %s\n", owner()->tag(), 'A' + m_index, stop_bits_tostring(get_stop_bits())); - LOG("Z80DART \"%s\" Channel %c : Clock Mode %uX\n", owner()->tag(), 'A' + m_index, get_clock_mode()); - - if (data != prev) - update_serial(); - break; - - case 5: - LOG("Z80DART \"%s\" Channel %c : Transmitter Enable %u\n", owner()->tag(), 'A' + m_index, (data & WR5_TX_ENABLE) ? 1 : 0); - LOG("Z80DART \"%s\" Channel %c : Transmitter Bits/Character %u\n", owner()->tag(), 'A' + m_index, get_tx_word_length()); - LOG("Z80DART \"%s\" Channel %c : Send Break %u\n", owner()->tag(), 'A' + m_index, (data & WR5_SEND_BREAK) ? 1 : 0); - LOG("Z80DART \"%s\" Channel %c : Request to Send %u\n", owner()->tag(), 'A' + m_index, (data & WR5_RTS) ? 1 : 0); - LOG("Z80DART \"%s\" Channel %c : Data Terminal Ready %u\n", owner()->tag(), 'A' + m_index, (data & WR5_DTR) ? 1 : 0); - - // don't update if parameters haven't changed; in fact, don't update at all since these ones are currently unused - if (0 && (data & WR5_TX_WORD_LENGTH_MASK) != (prev & WR5_TX_WORD_LENGTH_MASK)) - update_serial(); - - if (data & WR5_RTS) - { - // when the RTS bit is set, the _RTS output goes low - set_rts(0); - m_rts = 1; - } - else - { - // when the RTS bit is reset, the _RTS output goes high after the transmitter empties - if (m_rr[1] & RR1_ALL_SENT) - set_rts(1); - m_rts = 0; - } - - // data terminal ready output follows the state programmed into the DTR bit*/ - set_dtr((data & WR5_DTR) ? 0 : 1); - break; - - case 6: - LOG("Z80DART \"%s\" Channel %c : Transmit Sync %02x\n", owner()->tag(), 'A' + m_index, data); - m_sync = (m_sync & 0xff00) | data; - break; - - case 7: - LOG("Z80DART \"%s\" Channel %c : Receive Sync %02x\n", owner()->tag(), 'A' + m_index, data); - m_sync = (data << 8) | (m_sync & 0xff); - break; - } -} - - -//------------------------------------------------- -// data_read - read data register -//------------------------------------------------- - -uint8_t z80dart_channel::data_read() -{ - uint8_t data = 0; - - if (!m_rx_data_fifo.empty()) - { - // load data from the FIFO - data = m_rx_data_fifo.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.dequeue(); - - if (m_rx_data_fifo.empty()) - { - // no more characters available in the FIFO - m_rr[0] &= ~ RR0_RX_CHAR_AVAILABLE; - } - } - - LOG("Z80DART \"%s\" Channel %c : Data Register Read '%02x'\n", owner()->tag(), 'A' + m_index, data); - - return data; -} - - -//------------------------------------------------- -// data_write - write data register -//------------------------------------------------- - -void z80dart_channel::data_write(uint8_t data) -{ - m_tx_data = data; - - if ((m_wr[5] & WR5_TX_ENABLE) && is_transmit_register_empty()) - { - LOG("Z80DART \"%s\" Channel %c : Transmit Data Byte '%02x'\n", owner()->tag(), 'A' + m_index, m_tx_data); - - transmit_register_setup(m_tx_data); - - // empty transmit buffer - m_rr[0] |= RR0_TX_BUFFER_EMPTY; - - if (m_wr[1] & WR1_TX_INT_ENABLE) - m_uart->trigger_interrupt(m_index, INT_TRANSMIT); - } - else - { - m_rr[0] &= ~RR0_TX_BUFFER_EMPTY; - } - - m_rr[1] &= ~RR1_ALL_SENT; - - LOG("Z80DART \"%s\" Channel %c : Data Register Write '%02x'\n", owner()->tag(), 'A' + m_index, data); -} - - -//------------------------------------------------- -// receive_data - receive data word -//------------------------------------------------- - -void z80dart_channel::receive_data(uint8_t data) -{ - LOG("Z80DART \"%s\" Channel %c : Receive Data Byte '%02x'\n", owner()->tag(), 'A' + m_index, data); - - if (m_rx_data_fifo.full()) - { - // receive overrun error detected - m_rx_error |= RR1_RX_OVERRUN_ERROR; - - switch (m_wr[1] & WR1_RX_INT_MODE_MASK) - { - case WR1_RX_INT_FIRST: - if (!m_rx_first) - { - m_uart->trigger_interrupt(m_index, INT_SPECIAL); - } - break; - - case WR1_RX_INT_ALL_PARITY: - case WR1_RX_INT_ALL: - m_uart->trigger_interrupt(m_index, INT_SPECIAL); - 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 - { - // store received character and error status into FIFO - m_rx_data_fifo.enqueue(data); - m_rx_error_fifo.enqueue(m_rx_error); - } - - m_rr[0] |= RR0_RX_CHAR_AVAILABLE; - - // receive interrupt - switch (m_wr[1] & WR1_RX_INT_MODE_MASK) - { - case WR1_RX_INT_FIRST: - if (m_rx_first) - { - m_uart->trigger_interrupt(m_index, INT_RECEIVE); - - m_rx_first = 0; - } - break; - - case WR1_RX_INT_ALL_PARITY: - case WR1_RX_INT_ALL: - m_uart->trigger_interrupt(m_index, INT_RECEIVE); - break; - } -} - - -//------------------------------------------------- -// cts_w - clear to send handler -//------------------------------------------------- - -WRITE_LINE_MEMBER( z80dart_channel::cts_w ) -{ - LOG("Z80DART \"%s\" Channel %c : CTS %u\n", owner()->tag(), 'A' + m_index, state); - - if (m_cts != state) - { - // enable transmitter if in auto enables mode - if (!state) - if (m_wr[3] & WR3_AUTO_ENABLES) - m_wr[5] |= WR5_TX_ENABLE; - - // set clear to send - m_cts = state; - - if (!m_rx_rr0_latch) - { - if (!m_cts) - m_rr[0] |= RR0_CTS; - else - m_rr[0] &= ~RR0_CTS; - - // trigger interrupt - if (m_wr[1] & WR1_EXT_INT_ENABLE) - { - // trigger interrupt - m_uart->trigger_interrupt(m_index, INT_EXTERNAL); - - // latch read register 0 - m_rx_rr0_latch = 1; - } - } - } -} - - -//------------------------------------------------- -// dcd_w - data carrier detected handler -//------------------------------------------------- - -WRITE_LINE_MEMBER( z80dart_channel::dcd_w ) -{ - LOG("Z80DART \"%s\" Channel %c : DCD %u\n", owner()->tag(), 'A' + m_index, state); - - if (m_dcd != state) - { - // enable receiver if in auto enables mode - if (!state) - if (m_wr[3] & WR3_AUTO_ENABLES) - m_wr[3] |= WR3_RX_ENABLE; - - // set data carrier detect - m_dcd = state; - - if (!m_rx_rr0_latch) - { - if (m_dcd) - m_rr[0] |= RR0_DCD; - else - m_rr[0] &= ~RR0_DCD; - - if (m_wr[1] & WR1_EXT_INT_ENABLE) - { - // trigger interrupt - m_uart->trigger_interrupt(m_index, INT_EXTERNAL); - - // latch read register 0 - m_rx_rr0_latch = 1; - } - } - } -} - - -//------------------------------------------------- -// ri_w - ring indicator handler -//------------------------------------------------- - -WRITE_LINE_MEMBER( z80dart_channel::ri_w ) -{ - LOG("Z80DART \"%s\" Channel %c : RI %u\n", owner()->tag(), 'A' + m_index, state); - - if (m_ri != state) - { - // set ring indicator state - m_ri = state; - - if (!m_rx_rr0_latch) - { - if (m_ri) - m_rr[0] |= RR0_RI; - else - m_rr[0] &= ~RR0_RI; - - if (m_wr[1] & WR1_EXT_INT_ENABLE) - { - // trigger interrupt - m_uart->trigger_interrupt(m_index, INT_EXTERNAL); - - // latch read register 0 - m_rx_rr0_latch = 1; - } - } - } -} - - -//------------------------------------------------- -// sync_w - sync handler -//------------------------------------------------- - -WRITE_LINE_MEMBER( z80dart_channel::sync_w ) -{ - LOG("Z80DART \"%s\" Channel %c : SYNC %u\n", owner()->tag(), 'A' + m_index, state); -} - - -//------------------------------------------------- -// rxc_w - receive clock -//------------------------------------------------- - -WRITE_LINE_MEMBER( z80dart_channel::rxc_w ) -{ - //LOG("Z80DART \"%s\" Channel %c : Receiver Clock Pulse\n", owner()->tag(), m_index + 'A'); - int clocks = get_clock_mode(); - if (clocks == 1) - rx_clock_w(state); - else if(state) - { - rx_clock_w(m_rx_clock < clocks/2); - - m_rx_clock++; - if (m_rx_clock == clocks) - m_rx_clock = 0; - - } -} - - -//------------------------------------------------- -// txc_w - transmit clock -//------------------------------------------------- - -WRITE_LINE_MEMBER( z80dart_channel::txc_w ) -{ - //LOG("Z80DART \"%s\" Channel %c : Transmitter Clock Pulse\n", owner()->tag(), m_index + 'A'); - int clocks = get_clock_mode(); - if (clocks == 1) - tx_clock_w(state); - else if(state) - { - tx_clock_w(m_tx_clock < clocks/2); - - m_tx_clock++; - if (m_tx_clock == clocks) - m_tx_clock = 0; - - } -} - - -//------------------------------------------------- -// update_serial - -//------------------------------------------------- - -void z80dart_channel::update_serial() -{ - int data_bit_count = get_rx_word_length(); - stop_bits_t stop_bits = get_stop_bits(); - - parity_t parity; - if (m_wr[4] & WR4_PARITY_ENABLE) - { - if (m_wr[4] & WR4_PARITY_EVEN) - parity = PARITY_EVEN; - else - parity = PARITY_ODD; - } - else - parity = PARITY_NONE; - - set_data_frame(1, data_bit_count, parity, stop_bits); - - int clocks = get_clock_mode(); - - if (m_rxc > 0) - { - set_rcv_rate(m_rxc / clocks); - } - - if (m_txc > 0) - { - set_tra_rate(m_txc / clocks); - } - receive_register_reset(); // if stop bits is changed from 0, receive register has to be reset (FIXME: doing this without checking is stupid) -} - - -//------------------------------------------------- -// set_dtr - -//------------------------------------------------- - -void z80dart_channel::set_dtr(int state) -{ - m_dtr = state; - - if (m_index == z80dart_device::CHANNEL_A) - m_uart->m_out_dtra_cb(m_dtr); - else - m_uart->m_out_dtrb_cb(m_dtr); -} - - -//------------------------------------------------- -// set_rts - -//------------------------------------------------- - -void z80dart_channel::set_rts(int state) -{ - if (m_index == z80dart_device::CHANNEL_A) - m_uart->m_out_rtsa_cb(state); - else - m_uart->m_out_rtsb_cb(state); -} - - -//------------------------------------------------- -// write_rx - -//------------------------------------------------- - -WRITE_LINE_MEMBER(z80dart_channel::write_rx) -{ - m_rxd = state; - //only use rx_w when self-clocked - if(m_rxc) - device_serial_interface::rx_w(state); -} diff --git a/src/devices/machine/z80dart.h b/src/devices/machine/z80dart.h deleted file mode 100644 index 69a5b8caf26..00000000000 --- a/src/devices/machine/z80dart.h +++ /dev/null @@ -1,416 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Curt Coder -/*************************************************************************** - - Z80-DART Dual Asynchronous Receiver/Transmitter emulation - -**************************************************************************** - _____ _____ - D1 1 |* \_/ | 40 D0 - D3 2 | | 39 D2 - D5 3 | | 38 D4 - D7 4 | | 37 D6 - _INT 5 | | 36 _IORQ - IEI 6 | | 35 _CE - IEO 7 | | 34 B/_A - _M1 8 | | 33 C/_D - Vdd 9 | | 32 _RD - _W/RDYA 10 | Z80-DART | 31 GND - _RIA 11 | Z8470 | 30 _W/RDYB - RxDA 12 | | 29 _RIB - _RxCA 13 | | 28 RxDB - _TxCA 14 | | 27 _RxTxCB - TxDA 15 | | 26 TxDB - _DTRA 16 | | 25 _DTRB - _RTSA 17 | | 24 _RTSB - _CTSA 18 | | 23 _CTSB - _DCDA 19 | | 22 _DCDB - CLK 20 |_____________| 21 _RESET - -***************************************************************************/ - -#ifndef MAME_MACHINE_Z80DART_H -#define MAME_MACHINE_Z80DART_H - -#pragma once - -#include "machine/z80daisy.h" -#include "diserial.h" - - -//************************************************************************** -// TYPE DEFINITIONS -//************************************************************************** - -// ======================> z80dart_channel - -class z80dart_device; - -class z80dart_channel : public device_t, - public device_serial_interface -{ - friend class z80dart_device; // FIXME: still accesses m_rr and m_wr directly in a couple of places -public: - enum - { - INT_TRANSMIT = 0, - INT_EXTERNAL, - INT_RECEIVE, - INT_SPECIAL - }; - - z80dart_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - DECLARE_WRITE_LINE_MEMBER( write_rx ); - DECLARE_WRITE_LINE_MEMBER( cts_w ); - DECLARE_WRITE_LINE_MEMBER( dcd_w ); - DECLARE_WRITE_LINE_MEMBER( ri_w ); - DECLARE_WRITE_LINE_MEMBER( rxc_w ); - DECLARE_WRITE_LINE_MEMBER( txc_w ); - DECLARE_WRITE_LINE_MEMBER( sync_w ); - - uint8_t control_read(); - void control_write(uint8_t data); - - uint8_t data_read(); - void data_write(uint8_t data); - - void set_rxc(int rxc) { m_rxc = rxc; } - void set_txc(int txc) { m_txc = txc; } - - void clr_interrupt_pending() { m_rr[0] &= ~RR0_INTERRUPT_PENDING; } - void set_interrupt_pending() { m_rr[0] |= RR0_INTERRUPT_PENDING; } - - uint8_t get_vector() const { return m_rr[2]; } - void set_vector(uint8_t vector) { m_rr[2] = vector; } - - bool get_status_vector() const { return m_wr[1] & WR1_STATUS_VECTOR; } - bool get_priority() const { return m_wr[2] & WR2_PRIORITY; } - -protected: - // device-level overrides - virtual void device_start() override; - virtual void device_reset() override; - - // device_serial_interface overrides - virtual void tra_callback() override; - virtual void tra_complete() override; - virtual void rcv_callback() override; - virtual void rcv_complete() override; - - void receive_data(uint8_t data); - - int m_rxc; - int m_txc; - - // register state - uint8_t m_rr[3]; // read register - uint8_t m_wr[6]; // write register - - enum - { - RR0_RX_CHAR_AVAILABLE = 0x01, - RR0_INTERRUPT_PENDING = 0x02, - RR0_TX_BUFFER_EMPTY = 0x04, - RR0_DCD = 0x08, - RR0_RI = 0x10, - RR0_SYNC_HUNT = 0x10, // not supported - RR0_CTS = 0x20, - RR0_TX_UNDERRUN = 0x40, // not supported - RR0_BREAK_ABORT = 0x80 // not supported - }; - - enum - { - RR1_ALL_SENT = 0x01, - RR1_RESIDUE_CODE_MASK = 0x0e, // not supported - RR1_PARITY_ERROR = 0x10, - RR1_RX_OVERRUN_ERROR = 0x20, - RR1_CRC_FRAMING_ERROR = 0x40, - RR1_END_OF_FRAME = 0x80 // not supported - }; - - enum - { - WR0_REGISTER_MASK = 0x07, - WR0_COMMAND_MASK = 0x38, - WR0_NULL = 0x00, - WR0_SEND_ABORT = 0x08, // not supported - WR0_RESET_EXT_STATUS = 0x10, - WR0_CHANNEL_RESET = 0x18, - WR0_ENABLE_INT_NEXT_RX = 0x20, - WR0_RESET_TX_INT = 0x28, // not supported - WR0_ERROR_RESET = 0x30, - WR0_RETURN_FROM_INT = 0x38, // not supported - WR0_CRC_RESET_CODE_MASK = 0xc0, // not supported - WR0_CRC_RESET_NULL = 0x00, // not supported - WR0_CRC_RESET_RX = 0x40, // not supported - WR0_CRC_RESET_TX = 0x80, // not supported - WR0_CRC_RESET_TX_UNDERRUN = 0xc0 // not supported - }; - - enum - { - WR1_EXT_INT_ENABLE = 0x01, - WR1_TX_INT_ENABLE = 0x02, - WR1_STATUS_VECTOR = 0x04, - WR1_RX_INT_MODE_MASK = 0x18, - WR1_RX_INT_DISABLE = 0x00, - WR1_RX_INT_FIRST = 0x08, - WR1_RX_INT_ALL_PARITY = 0x10, // not supported - WR1_RX_INT_ALL = 0x18, - WR1_WRDY_ON_RX_TX = 0x20, // not supported - WR1_WRDY_FUNCTION = 0x40, // not supported - WR1_WRDY_ENABLE = 0x80 // not supported - }; - - enum - { - WR2_DATA_XFER_INT = 0x00, // not supported - WR2_DATA_XFER_DMA_INT = 0x01, // not supported - WR2_DATA_XFER_DMA = 0x02, // not supported - WR2_DATA_XFER_ILLEGAL = 0x03, // not supported - WR2_DATA_XFER_MASK = 0x03, // not supported - WR2_PRIORITY = 0x04, // not supported - WR2_MODE_8085_1 = 0x00, // not supported - WR2_MODE_8085_2 = 0x08, // not supported - WR2_MODE_8086_8088 = 0x10, // not supported - WR2_MODE_ILLEGAL = 0x18, // not supported - WR2_MODE_MASK = 0x18, // not supported - WR2_VECTORED_INT = 0x20, // not supported - WR2_PIN10_SYNDETB_RTSB = 0x80 // not supported - }; - - enum - { - WR3_RX_ENABLE = 0x01, - WR3_SYNC_CHAR_LOAD_INHIBIT= 0x02, // not supported - WR3_ADDRESS_SEARCH_MODE = 0x04, // not supported - WR3_RX_CRC_ENABLE = 0x08, // not supported - WR3_ENTER_HUNT_PHASE = 0x10, // not supported - WR3_AUTO_ENABLES = 0x20, - WR3_RX_WORD_LENGTH_MASK = 0xc0, - WR3_RX_WORD_LENGTH_5 = 0x00, - WR3_RX_WORD_LENGTH_7 = 0x40, - WR3_RX_WORD_LENGTH_6 = 0x80, - WR3_RX_WORD_LENGTH_8 = 0xc0 - }; - - enum - { - WR4_PARITY_ENABLE = 0x01, - WR4_PARITY_EVEN = 0x02, - WR4_STOP_BITS_MASK = 0x0c, - WR4_STOP_BITS_1 = 0x04, - WR4_STOP_BITS_1_5 = 0x08, // not supported - WR4_STOP_BITS_2 = 0x0c, - WR4_SYNC_MODE_MASK = 0x30, // not supported - WR4_SYNC_MODE_8_BIT = 0x00, // not supported - WR4_SYNC_MODE_16_BIT = 0x10, // not supported - WR4_SYNC_MODE_SDLC = 0x20, // not supported - WR4_SYNC_MODE_EXT = 0x30, // not supported - WR4_CLOCK_RATE_MASK = 0xc0, - WR4_CLOCK_RATE_X1 = 0x00, - WR4_CLOCK_RATE_X16 = 0x40, - WR4_CLOCK_RATE_X32 = 0x80, - WR4_CLOCK_RATE_X64 = 0xc0 - }; - - enum - { - WR5_TX_CRC_ENABLE = 0x01, // not supported - WR5_RTS = 0x02, - WR5_CRC16 = 0x04, // not supported - WR5_TX_ENABLE = 0x08, - WR5_SEND_BREAK = 0x10, - WR5_TX_WORD_LENGTH_MASK = 0x60, - WR5_TX_WORD_LENGTH_5 = 0x00, - WR5_TX_WORD_LENGTH_6 = 0x40, - WR5_TX_WORD_LENGTH_7 = 0x20, - WR5_TX_WORD_LENGTH_8 = 0x60, - WR5_DTR = 0x80 - }; - - void update_serial(); - void set_dtr(int state); - void set_rts(int state); - - int get_clock_mode(); - stop_bits_t get_stop_bits(); - int get_rx_word_length(); - int get_tx_word_length(); - - // receiver state - util::fifo m_rx_data_fifo; - util::fifo m_rx_error_fifo; - - 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 - uint8_t m_rx_rr0_latch; // read register 0 latched - - int m_rxd; - int m_ri; // ring indicator latch - int m_cts; // clear to send latch - int m_dcd; // data carrier detect latch - - // transmitter state - uint8_t m_tx_data; // transmit data register - int m_tx_clock; // transmit clock pulse count - - int m_dtr; // data terminal ready - int m_rts; // request to send - - // synchronous state - uint16_t m_sync; // sync character - - int m_index; - z80dart_device *m_uart; -}; - - -// ======================> z80dart_device - -class z80dart_device : public device_t, - public device_z80daisy_interface -{ - friend class z80dart_channel; - -public: - // construction/destruction - z80dart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - auto out_txda_callback() { return m_out_txda_cb.bind(); } - auto out_dtra_callback() { return m_out_dtra_cb.bind(); } - auto out_rtsa_callback() { return m_out_rtsa_cb.bind(); } - auto out_wrdya_callback() { return m_out_wrdya_cb.bind(); } - auto out_synca_callback() { return m_out_synca_cb.bind(); } - auto out_txdb_callback() { return m_out_txdb_cb.bind(); } - auto out_dtrb_callback() { return m_out_dtrb_cb.bind(); } - auto out_rtsb_callback() { return m_out_rtsb_cb.bind(); } - auto out_wrdyb_callback() { return m_out_wrdyb_cb.bind(); } - auto out_syncb_callback() { return m_out_syncb_cb.bind(); } - auto out_int_callback() { return m_out_int_cb.bind(); } - auto out_rxdrqa_callback() { return m_out_rxdrqa_cb.bind(); } - auto out_txdrqa_callback() { return m_out_txdrqa_cb.bind(); } - auto out_rxdrqb_callback() { return m_out_rxdrqb_cb.bind(); } - auto out_txdrqb_callback() { return m_out_txdrqb_cb.bind(); } - - void configure_channels(int rxa, int txa, int rxb, int txb) - { - m_rxca = rxa; - m_txca = txa; - m_rxcb = rxb; - m_txcb = txb; - } - - uint8_t cd_ba_r(offs_t offset); - void cd_ba_w(offs_t offset, uint8_t data); - uint8_t ba_cd_r(offs_t offset); - void ba_cd_w(offs_t offset, uint8_t data); - - uint8_t da_r() { return m_chanA->data_read(); } - void da_w(uint8_t data) { m_chanA->data_write(data); } - uint8_t db_r() { return m_chanB->data_read(); } - void db_w(uint8_t data) { m_chanB->data_write(data); } - - uint8_t ca_r() { return m_chanA->control_read(); } - void ca_w(uint8_t data) { m_chanA->control_write(data); } - uint8_t cb_r() { return m_chanB->control_read(); } - void cb_w(uint8_t data) { m_chanB->control_write(data); } - - // interrupt acknowledge - int m1_r(); - - DECLARE_WRITE_LINE_MEMBER( rxa_w ) { m_chanA->write_rx(state); } - DECLARE_WRITE_LINE_MEMBER( rxb_w ) { m_chanB->write_rx(state); } - DECLARE_WRITE_LINE_MEMBER( ctsa_w ) { m_chanA->cts_w(state); } - DECLARE_WRITE_LINE_MEMBER( ctsb_w ) { m_chanB->cts_w(state); } - DECLARE_WRITE_LINE_MEMBER( dcda_w ) { m_chanA->dcd_w(state); } - DECLARE_WRITE_LINE_MEMBER( dcdb_w ) { m_chanB->dcd_w(state); } - DECLARE_WRITE_LINE_MEMBER( ria_w ) { m_chanA->ri_w(state); } - DECLARE_WRITE_LINE_MEMBER( rib_w ) { m_chanB->ri_w(state); } - DECLARE_WRITE_LINE_MEMBER( rxca_w ) { m_chanA->rxc_w(state); } - DECLARE_WRITE_LINE_MEMBER( rxcb_w ) { m_chanB->rxc_w(state); } - DECLARE_WRITE_LINE_MEMBER( txca_w ) { m_chanA->txc_w(state); } - DECLARE_WRITE_LINE_MEMBER( txcb_w ) { m_chanB->txc_w(state); } - DECLARE_WRITE_LINE_MEMBER( rxtxcb_w ) { m_chanB->rxc_w(state); m_chanB->txc_w(state); } - DECLARE_WRITE_LINE_MEMBER( synca_w ) { m_chanA->sync_w(state); } - DECLARE_WRITE_LINE_MEMBER( syncb_w ) { m_chanB->sync_w(state); } - -protected: - z80dart_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_start() override; - virtual void device_reset() override; - virtual void device_add_mconfig(machine_config &config) override; - - // device_z80daisy_interface overrides - virtual int z80daisy_irq_state() override; - virtual int z80daisy_irq_ack() override; - virtual void z80daisy_irq_reti() override; - - // internal interrupt management - void check_interrupts(); - void reset_interrupts(); - void trigger_interrupt(int index, int state); - int get_channel_index(z80dart_channel *ch) { return (ch == m_chanA) ? 0 : 1; } - - enum - { - TYPE_DART, - TYPE_SIO0, - TYPE_SIO1, - TYPE_SIO2, - TYPE_SIO3, - TYPE_SIO4, - TYPE_I8274, - TYPE_UPD7201 - }; - - enum - { - CHANNEL_A = 0, - CHANNEL_B - }; - - required_device m_chanA; - required_device m_chanB; - - // internal state - int m_rxca; - int m_txca; - 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_wrdya_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_wrdyb_cb; - devcb_write_line m_out_syncb_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[8]; // interrupt state - - int const m_variant; -}; - - -// device type definition -DECLARE_DEVICE_TYPE(Z80DART_CHANNEL, z80dart_channel) -DECLARE_DEVICE_TYPE(Z80DART, z80dart_device) - -#endif // MAME_MACHINE_Z80DART_H diff --git a/src/devices/machine/z80sio.cpp b/src/devices/machine/z80sio.cpp index 767ef2e6e1e..6b3b511cb12 100644 --- a/src/devices/machine/z80sio.cpp +++ b/src/devices/machine/z80sio.cpp @@ -3,6 +3,7 @@ /*************************************************************************** Z80-SIO Serial Input/Output emulation + Z80-DART Dual Asynchronous Receiver/Transmitter emulation Intel 8274 Multi-Protocol Serial Controller emulation NEC µPD7201 Multiprotocol Serial Communications Controller emulation @@ -119,7 +120,7 @@ enum : uint8_t RR0_INTERRUPT_PENDING = 0x02, RR0_TX_BUFFER_EMPTY = 0x04, RR0_DCD = 0x08, - RR0_SYNC_HUNT = 0x10, + RR0_SYNC_HUNT = 0x10, // RI on DART RR0_CTS = 0x20, RR0_TX_UNDERRUN = 0x40, RR0_BREAK_ABORT = 0x80 @@ -254,9 +255,11 @@ constexpr uint16_t SDLC_RESIDUAL = 0x1d0f; // device type definition DEFINE_DEVICE_TYPE(Z80SIO_CHANNEL, z80sio_channel, "z80sio_channel", "Z80 SIO channel") +DEFINE_DEVICE_TYPE(Z80DART_CHANNEL, z80dart_channel, "z80dart_channel", "Z80 DART channel") DEFINE_DEVICE_TYPE(I8274_CHANNEL, i8274_channel, "i8274_channel", "Intel 8274 MPSC channel") DEFINE_DEVICE_TYPE(MK68564_CHANNEL, mk68564_channel, "mk68564_channel", "Mostek MK68564 SIO channel") DEFINE_DEVICE_TYPE(Z80SIO, z80sio_device, "z80sio", "Z80 SIO") +DEFINE_DEVICE_TYPE(Z80DART, z80dart_device, "z80dart", "Z80 DART") DEFINE_DEVICE_TYPE(I8274, i8274_device, "i8274", "Intel 8274 MPSC") DEFINE_DEVICE_TYPE(UPD7201, upd7201_device, "upd7201", "NEC uPD7201 MPSC") DEFINE_DEVICE_TYPE(MK68564, mk68564_device, "mk68564", "Mostek MK68564 SIO") @@ -270,6 +273,12 @@ void z80sio_device::device_add_mconfig(machine_config &config) Z80SIO_CHANNEL(config, CHANB_TAG, 0); } +void z80dart_device::device_add_mconfig(machine_config &config) +{ + Z80DART_CHANNEL(config, CHANA_TAG, 0); + Z80DART_CHANNEL(config, CHANB_TAG, 0); +} + void i8274_device::device_add_mconfig(machine_config &config) { I8274_CHANNEL(config, CHANA_TAG, 0); @@ -358,7 +367,7 @@ inline void z80sio_channel::tx_setup(uint16_t data, int bits, bool framing, bool LOGBIT("%.6f TX_SR %05x data %04x flags %x\n" , machine().time().as_double() , m_tx_sr & TX_SR_MASK , data , m_tx_flags); } -inline void z80sio_channel::tx_setup_idle() +void z80sio_channel::tx_setup_idle() { switch (m_wr4 & WR4_SYNC_MODE_MASK) { @@ -380,6 +389,11 @@ inline void z80sio_channel::tx_setup_idle() m_tx_in_pkt = false; } +void z80dart_channel::tx_setup_idle() +{ + logerror("%s (sync mode not supported by DART)\n", FUNCNAME); +} + //------------------------------------------------- // z80sio_device - constructor //------------------------------------------------- @@ -407,6 +421,11 @@ z80sio_device::z80sio_device(const machine_config &mconfig, const char *tag, dev { } +z80dart_device::z80dart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + z80sio_device(mconfig, Z80DART, tag, owner, clock) +{ +} + i8274_device::i8274_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : z80sio_device(mconfig, type, tag, owner, clock) { @@ -943,12 +962,13 @@ z80sio_channel::z80sio_channel( , m_rx_count(0) , m_rx_bit(0) , m_rx_sr(0) - , m_rx_first(0) + , m_rx_first(false) , m_rxd(1) , m_tx_data(0) , m_tx_clock(0), m_tx_count(0), m_tx_parity(0), m_tx_sr(0), m_tx_crc(0), m_tx_hist(0), m_tx_flags(0) , m_txd(1), m_dtr(0), m_rts(0) - , m_ext_latched(0), m_brk_latched(0), m_cts(0), m_dcd(0), m_sync(0) + , m_ext_latched(false), m_brk_latched(false) + , m_cts(0), m_dcd(0), m_sync(0) , m_rr1_auto_reset(rr1_auto_reset) { LOG("%s\n",FUNCNAME); @@ -963,6 +983,11 @@ z80sio_channel::z80sio_channel(const machine_config &mconfig, const char *tag, d { } +z80dart_channel::z80dart_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : z80sio_channel(mconfig, Z80DART_CHANNEL, tag, owner, clock, RR1_END_OF_FRAME | RR1_CRC_FRAMING_ERROR | RR1_RESIDUE_CODE_MASK) +{ +} + i8274_channel::i8274_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : z80sio_channel(mconfig, I8274_CHANNEL, tag, owner, clock, RR1_RX_OVERRUN_ERROR) { @@ -1005,23 +1030,13 @@ void z80sio_channel::device_start() save_item(NAME(m_wr3)); save_item(NAME(m_wr4)); save_item(NAME(m_wr5)); - save_item(NAME(m_wr6)); - save_item(NAME(m_wr7)); save_item(NAME(m_rx_fifo_depth)); save_item(NAME(m_rx_data_fifo)); save_item(NAME(m_rx_error_fifo)); save_item(NAME(m_rx_clock)); save_item(NAME(m_rx_count)); - save_item(NAME(m_dlyd_rxd)); save_item(NAME(m_rx_bit)); - save_item(NAME(m_rx_bit_limit)); - save_item(NAME(m_rx_sync_fsm)); - save_item(NAME(m_rx_one_cnt)); save_item(NAME(m_rx_sr)); - save_item(NAME(m_rx_sync_sr)); - save_item(NAME(m_rx_crc_delay)); - save_item(NAME(m_rx_crc)); - save_item(NAME(m_rx_crc_en)); save_item(NAME(m_rx_parity)); save_item(NAME(m_rx_first)); save_item(NAME(m_tx_data)); @@ -1029,10 +1044,8 @@ void z80sio_channel::device_start() save_item(NAME(m_tx_count)); save_item(NAME(m_tx_phase)); save_item(NAME(m_tx_parity)); - save_item(NAME(m_tx_in_pkt)); - save_item(NAME(m_tx_forced_sync)); + save_item(NAME(m_tx_in_pkt)); // TODO: does this actually function in async mode? save_item(NAME(m_tx_sr)); - save_item(NAME(m_tx_crc)); save_item(NAME(m_tx_hist)); save_item(NAME(m_tx_flags)); save_item(NAME(m_tx_delay)); @@ -1045,6 +1058,29 @@ void z80sio_channel::device_start() save_item(NAME(m_dcd)); save_item(NAME(m_sync)); save_item(NAME(m_cts)); + sync_save_state(); +} + +void z80sio_channel::sync_save_state() +{ + save_item(NAME(m_wr6)); + save_item(NAME(m_wr7)); + save_item(NAME(m_dlyd_rxd)); + save_item(NAME(m_rx_bit_limit)); + save_item(NAME(m_rx_sync_fsm)); + save_item(NAME(m_rx_one_cnt)); + save_item(NAME(m_rx_sync_sr)); + save_item(NAME(m_rx_crc_delay)); + save_item(NAME(m_rx_crc)); + save_item(NAME(m_rx_crc_en)); + //save_item(NAME(m_tx_in_pkt)); + save_item(NAME(m_tx_forced_sync)); + save_item(NAME(m_tx_crc)); +} + +void z80dart_channel::sync_save_state() +{ + // no need to save the above members } void mk68564_channel::device_start() @@ -1104,7 +1140,7 @@ void z80sio_channel::device_reset() m_uart->clear_interrupt(m_index, INT_TRANSMIT); m_uart->clear_interrupt(m_index, INT_RECEIVE); reset_ext_status(); - // FIXME: should this actually reset all the interrtupts, or just the prioritisation (daisy chain) logic? + // FIXME: should this actually reset all the interrupts, or just the prioritisation (daisy chain) logic? if (m_index == z80sio_device::CHANNEL_A) m_uart->reset_interrupts(); } @@ -1258,6 +1294,11 @@ void z80sio_channel::sync_tx_sr_empty() } } +void z80dart_channel::sync_tx_sr_empty() +{ + LOG("%s (sync mode not supported by DART)\n", FUNCNAME); +} + bool z80sio_channel::get_tx_empty() const { // During CRC transmission, tx buffer is shown as full @@ -1335,8 +1376,8 @@ void z80sio_channel::async_tx_setup() void z80sio_channel::reset_ext_status() { // this will clear latched external pin state - m_ext_latched = 0; - m_brk_latched = 0; + m_ext_latched = false; + m_brk_latched = false; read_ext(); // Clear any pending External interrupt @@ -1380,7 +1421,7 @@ void z80sio_channel::trigger_ext_int() // update line if (!m_ext_latched) read_ext(); - m_ext_latched = 1; + m_ext_latched = true; // trigger interrupt if enabled if (m_wr1 & WR1_EXT_INT_ENABLE) @@ -1625,7 +1666,7 @@ void z80sio_channel::do_sioreg_wr0(uint8_t data) case WR0_ENABLE_INT_NEXT_RX: // enable interrupt on next receive character LOGINT("%s Ch:%c : Enable Interrupt on Next Received Character\n", FUNCNAME, 'A' + m_index); - m_rx_first = 1; + m_rx_first = true; break; case WR0_RESET_TX_INT: LOGCMD("%s Ch:%c : Reset Transmitter Interrupt Pending\n", FUNCNAME, 'A' + m_index); @@ -1925,6 +1966,11 @@ void z80sio_channel::enter_hunt_mode() } } +void z80dart_channel::enter_hunt_mode() +{ + LOG("%s (sync mode not supported by DART)\n", FUNCNAME); +} + //------------------------------------------------- // sync_receive - synchronous reception handler //------------------------------------------------- @@ -2042,6 +2088,11 @@ void z80sio_channel::sync_receive() m_dlyd_rxd = m_rxd; } +void z80dart_channel::sync_receive() +{ + LOG("%s (sync mode not supported by DART)\n", FUNCNAME); +} + //------------------------------------------------- // sdlc_receive - SDLC reception handler //------------------------------------------------- @@ -2068,7 +2119,7 @@ void z80sio_channel::sdlc_receive() LOGRCV("SDLC Abort detected\n"); m_rr0 |= RR0_BREAK_ABORT; if (!m_brk_latched) { - m_brk_latched = 1; + m_brk_latched = true; trigger_ext_int(); } enter_hunt_mode(); @@ -2088,7 +2139,7 @@ void z80sio_channel::sdlc_receive() { m_rr0 &= ~RR0_BREAK_ABORT; if (!m_brk_latched) { - m_brk_latched = 1; + m_brk_latched = true; trigger_ext_int(); } } @@ -2189,6 +2240,11 @@ void z80sio_channel::sdlc_receive() } } +void z80dart_channel::sdlc_receive() +{ + logerror("%s (sync mode not supported by DART)\n", FUNCNAME); +} + //------------------------------------------------- // receive_data - receive data word //------------------------------------------------- @@ -2234,7 +2290,7 @@ void z80sio_channel::queue_received(uint16_t data, uint32_t error) case WR1_RX_INT_FIRST: if (m_rx_first || (error & get_special_rx_mask())) m_uart->trigger_interrupt(m_index, INT_RECEIVE); - m_rx_first = 0; + m_rx_first = false; break; case WR1_RX_INT_ALL_PARITY: @@ -2340,7 +2396,7 @@ WRITE_LINE_MEMBER( z80sio_channel::rxc_w ) LOGRCV("Break termination detected\n"); m_rr0 &= ~RR0_BREAK_ABORT; if (!m_brk_latched) { - m_brk_latched = 1; + m_brk_latched = true; trigger_ext_int(); } } @@ -2407,7 +2463,7 @@ WRITE_LINE_MEMBER( z80sio_channel::rxc_w ) { LOGRCV("Break detected\n"); m_rr0 |= RR0_BREAK_ABORT; - m_brk_latched = 1; + m_brk_latched = true; trigger_ext_int(); } } @@ -2454,7 +2510,8 @@ WRITE_LINE_MEMBER( z80sio_channel::txc_w ) m_tx_count = get_clock_mode() / 2; // Send out a delayed half bit bool new_txd = BIT(m_tx_delay , 3); - LOGBIT("%.6f TX %d DLY %x\n" , machine().time().as_double() , new_txd , m_tx_delay & 0xf); + if ((m_wr4 & WR4_STOP_BITS_MASK) == WR4_STOP_BITS_SYNC || !(m_rr1 & RR1_ALL_SENT)) + LOGBIT("%.6f TX %d DLY %x\n" , machine().time().as_double() , new_txd , m_tx_delay & 0xf); if (new_txd != m_txd && !(m_wr5 & WR5_SEND_BREAK)) { out_txd_cb(new_txd); diff --git a/src/devices/machine/z80sio.h b/src/devices/machine/z80sio.h index 8d0875e418b..f8fbc1522c9 100644 --- a/src/devices/machine/z80sio.h +++ b/src/devices/machine/z80sio.h @@ -3,6 +3,7 @@ /*************************************************************************** Z80-SIO Serial Input/Output + Z80-DART Dual Asynchronous Receiver/Transmitter Intel 8274 Multi-Protocol Serial Controller NEC µPD7201 Multiprotocol Serial Communications Controller @@ -51,6 +52,28 @@ R S S D K S D S S R D R S S D K S D S S R C A A A A E B B B B B A A A A E B B B B T T + _____ _____ + D1 1 |* \_/ | 40 D0 + D3 2 | | 39 D2 + D5 3 | | 38 D4 + D7 4 | | 37 D6 + _INT 5 | | 36 _IORQ + IEI 6 | | 35 _CE + IEO 7 | | 34 B/_A + _M1 8 | | 33 C/_D + Vdd 9 | | 32 _RD + _W/RDYA 10 | Z80-DART | 31 GND + _RIA 11 | Z8470 | 30 _W/RDYB + RxDA 12 | | 29 _RIB + _RxCA 13 | | 28 RxDB + _TxCA 14 | | 27 _RxTxCB + TxDA 15 | | 26 TxDB + _DTRA 16 | | 25 _DTRB + _RTSA 17 | | 24 _RTSB + _CTSA 18 | | 23 _CTSB + _DCDA 19 | | 22 _DCDB + CLK 20 |_____________| 21 _RESET + _____ _____ CLK 1 |* \_/ | 40 Vcc _RESET 2 | | 39 _CTSA @@ -149,6 +172,7 @@ class z80sio_device; class z80sio_channel : public device_t { friend class z80sio_device; + friend class z80dart_device; friend class i8274_device; friend class upd7201_device; friend class mk68564_device; @@ -294,7 +318,7 @@ protected: bool m_rx_crc_en; // rx CRC enabled bool m_rx_parity; // accumulated parity - int m_rx_first; // first character received + bool m_rx_first; // first character received int m_rxd; @@ -319,8 +343,8 @@ protected: int m_rts; // request to send // external/status monitoring - int m_ext_latched; // changed data lines - int m_brk_latched; // break status latched + bool m_ext_latched; // changed data lines + bool m_brk_latched; // break status latched int m_cts; // clear to send line state int m_dcd; // data carrier detect line state int m_sync; // sync line state @@ -340,9 +364,9 @@ protected: virtual bool transmit_allowed() const; void receive_enabled(); - void enter_hunt_mode(); - void sync_receive(); - void sdlc_receive(); + virtual void enter_hunt_mode(); + virtual void sync_receive(); + virtual void sdlc_receive(); void receive_data(); void queue_received(uint16_t data, uint32_t error); void advance_rx_fifo(); @@ -352,13 +376,14 @@ protected: void transmit_enable(); void transmit_complete(); void async_tx_setup(); - void sync_tx_sr_empty(); + virtual void sync_tx_sr_empty(); void tx_setup(uint16_t data, int bits, bool framing, bool crc_tx, bool abort_tx); - void tx_setup_idle(); + virtual void tx_setup_idle(); bool get_tx_empty() const; void set_tx_empty(bool prev_state, bool new_state); void update_crc(uint16_t& crc , bool bit); + virtual void sync_save_state(); void reset_ext_status(); void read_ext(); void trigger_ext_int(); @@ -367,6 +392,23 @@ protected: }; +// ======================> z80dart_channel + +class z80dart_channel : public z80sio_channel +{ +public: + z80dart_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual void enter_hunt_mode() override; + virtual void sync_receive() override; + virtual void sdlc_receive() override; + virtual void sync_tx_sr_empty() override; + virtual void tx_setup_idle() override; + virtual void sync_save_state() override; +}; + + // ======================> i8274_channel class i8274_channel : public z80sio_channel @@ -534,6 +576,19 @@ protected: int m_int_source[8]; // interrupt source }; +class z80dart_device : public z80sio_device +{ +public: + z80dart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_WRITE_LINE_MEMBER( ria_w ) { m_chanA->sync_w(state); } + DECLARE_WRITE_LINE_MEMBER( rib_w ) { m_chanB->sync_w(state); } + +protected: + // device_t overrides + virtual void device_add_mconfig(machine_config &config) override; +}; + class i8274_device : public z80sio_device { public: @@ -582,6 +637,7 @@ private: // device type declaration DECLARE_DEVICE_TYPE(Z80SIO, z80sio_device) +DECLARE_DEVICE_TYPE(Z80DART, z80dart_device) DECLARE_DEVICE_TYPE(I8274, i8274_device) DECLARE_DEVICE_TYPE(UPD7201, upd7201_device) DECLARE_DEVICE_TYPE(MK68564, mk68564_device) diff --git a/src/mame/drivers/alphatpc16.cpp b/src/mame/drivers/alphatpc16.cpp index 0a7e43caf4e..57581525a35 100644 --- a/src/mame/drivers/alphatpc16.cpp +++ b/src/mame/drivers/alphatpc16.cpp @@ -51,7 +51,7 @@ via the PC 16 Terminal, operates independently after programming), connects to t #include "imagedev/floppy.h" #include "machine/wd_fdc.h" #include "video/ef9345.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/pic8259.h" #include "machine/timer.h" #include "machine/ram.h" diff --git a/src/mame/drivers/altos2.cpp b/src/mame/drivers/altos2.cpp index 0cf4ee4165c..53ce989ed0b 100644 --- a/src/mame/drivers/altos2.cpp +++ b/src/mame/drivers/altos2.cpp @@ -18,7 +18,7 @@ Keyboard: P8035L CPU, undumped 2716 labelled "358_2758", XTAL marked "4608-300-1 #include "cpu/z80/z80.h" #include "machine/z80daisy.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/x2212.h" #include "sound/beep.h" //#include "video/crt9006.h" diff --git a/src/mame/drivers/altos5.cpp b/src/mame/drivers/altos5.cpp index 85dbc36eeba..affbec19858 100644 --- a/src/mame/drivers/altos5.cpp +++ b/src/mame/drivers/altos5.cpp @@ -17,7 +17,6 @@ #include "machine/z80ctc.h" #include "machine/z80pio.h" #include "machine/z80sio.h" -#include "machine/z80dart.h" #include "machine/z80dma.h" #include "machine/wd_fdc.h" #include "machine/clock.h" diff --git a/src/mame/drivers/ampex210.cpp b/src/mame/drivers/ampex210.cpp index aff3b4abeec..ebcd0debc9b 100644 --- a/src/mame/drivers/ampex210.cpp +++ b/src/mame/drivers/ampex210.cpp @@ -12,7 +12,7 @@ #include "machine/mos6551.h" #include "machine/nvram.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "video/scn2674.h" #include "screen.h" diff --git a/src/mame/drivers/ampro.cpp b/src/mame/drivers/ampro.cpp index 013192e6699..97ccf1ce7d7 100644 --- a/src/mame/drivers/ampro.cpp +++ b/src/mame/drivers/ampro.cpp @@ -27,7 +27,7 @@ of a hard drive of up to 88MB. #include "machine/output_latch.h" #include "machine/z80daisy.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/wd_fdc.h" #include "machine/timer.h" #include "softlist.h" diff --git a/src/mame/drivers/czk80.cpp b/src/mame/drivers/czk80.cpp index 6eeca07ca68..67d12684f2a 100644 --- a/src/mame/drivers/czk80.cpp +++ b/src/mame/drivers/czk80.cpp @@ -44,7 +44,7 @@ I/O ports: These ranges are what is guessed #include "machine/upd765.h" #include "machine/z80daisy.h" #include "machine/z80pio.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/z80ctc.h" #include "machine/terminal.h" diff --git a/src/mame/drivers/dmax8000.cpp b/src/mame/drivers/dmax8000.cpp index 564b3685bd1..50162dbdef8 100644 --- a/src/mame/drivers/dmax8000.cpp +++ b/src/mame/drivers/dmax8000.cpp @@ -29,7 +29,7 @@ What there is of the schematic shows no sign of a daisy chain or associated inte #include "machine/wd_fdc.h" #include "machine/z80daisy.h" #include "machine/z80pio.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/z80ctc.h" #include "machine/mm58274c.h" #include "bus/rs232/rs232.h" diff --git a/src/mame/drivers/facit4440.cpp b/src/mame/drivers/facit4440.cpp index 8ed509db549..2c066aa243c 100644 --- a/src/mame/drivers/facit4440.cpp +++ b/src/mame/drivers/facit4440.cpp @@ -32,7 +32,7 @@ #include "machine/clock.h" #include "machine/er1400.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "video/mc6845.h" #include "screen.h" diff --git a/src/mame/drivers/falcots.cpp b/src/mame/drivers/falcots.cpp index 69c00712909..78aa7b3811a 100644 --- a/src/mame/drivers/falcots.cpp +++ b/src/mame/drivers/falcots.cpp @@ -13,7 +13,7 @@ #include "machine/nvram.h" #include "machine/rstbuf.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "video/mc6845.h" #include "screen.h" diff --git a/src/mame/drivers/fs3216.cpp b/src/mame/drivers/fs3216.cpp index 7ecd6312289..5491a7a518b 100644 --- a/src/mame/drivers/fs3216.cpp +++ b/src/mame/drivers/fs3216.cpp @@ -18,7 +18,7 @@ #include "machine/upd765.h" #include "machine/x2212.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "video/mc6845.h" #include "screen.h" diff --git a/src/mame/drivers/isbc.cpp b/src/mame/drivers/isbc.cpp index a43104167ca..a0f92cfdfec 100644 --- a/src/mame/drivers/isbc.cpp +++ b/src/mame/drivers/isbc.cpp @@ -25,7 +25,6 @@ able to deal with 256byte sectors so fails to load the irmx 512byte sector image #include "machine/pit8253.h" #include "machine/i8255.h" #include "machine/i8251.h" -//#include "machine/z80dart.h" #include "machine/z80sio.h" #include "bus/centronics/ctronics.h" #include "bus/isbx/isbx.h" @@ -449,7 +448,6 @@ void isbc_state::isbc286(machine_config &config) pit.set_clk<0>(XTAL(22'118'400)/18); pit.out_handler<0>().set(m_pic_0, FUNC(pic8259_device::ir0_w)); pit.set_clk<1>(XTAL(22'118'400)/18); -// pit.out_handler<1>().set(m_uart8274, FUNC(z80dart_device::rxtxcb_w)); pit.out_handler<1>().set(m_uart8274, FUNC(i8274_device::rxtxcb_w)); pit.set_clk<2>(XTAL(22'118'400)/18); pit.out_handler<2>().set(FUNC(isbc_state::isbc286_tmr2_w)); @@ -491,26 +489,14 @@ void isbc_state::isbc286(machine_config &config) #endif rs232_port_device &rs232a(RS232_PORT(config, "rs232a", default_rs232_devices, nullptr)); -#if 0 - rs232a.rxd_handler().set(m_uart8274, FUNC(z80dart_device::rxa_w)); - rs232a.dcd_handler().set(m_uart8274, FUNC(z80dart_device::dcda_w)); - rs232a.cts_handler().set(m_uart8274, FUNC(z80dart_device::ctsa_w)); -#else rs232a.rxd_handler().set(m_uart8274, FUNC(i8274_device::rxa_w)); rs232a.dcd_handler().set(m_uart8274, FUNC(i8274_device::dcda_w)); rs232a.cts_handler().set(m_uart8274, FUNC(i8274_device::ctsa_w)); -#endif rs232_port_device &rs232b(RS232_PORT(config, "rs232b", default_rs232_devices, "terminal")); -#if 0 - rs232b.rxd_handler().set(m_uart8274, FUNC(z80dart_device::rxb_w)); - rs232b.dcd_handler().set(m_uart8274, FUNC(z80dart_device::dcdb_w)); - rs232b.cts_handler().set(m_uart8274, FUNC(z80dart_device::ctsb_w)); -#else rs232b.rxd_handler().set(m_uart8274, FUNC(i8274_device::rxb_w)); rs232b.dcd_handler().set(m_uart8274, FUNC(i8274_device::dcdb_w)); rs232b.cts_handler().set(m_uart8274, FUNC(i8274_device::ctsb_w)); -#endif rs232b.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(isbc286_terminal)); ISBX_SLOT(config, m_sbx[0], 0, isbx_cards, nullptr); diff --git a/src/mame/drivers/pulsar.cpp b/src/mame/drivers/pulsar.cpp index 9663dfaab63..7e4ff6b7cea 100644 --- a/src/mame/drivers/pulsar.cpp +++ b/src/mame/drivers/pulsar.cpp @@ -43,7 +43,7 @@ X - Test off-board memory banks #include "cpu/z80/z80.h" #include "imagedev/floppy.h" #include "machine/z80daisy.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/msm5832.h" #include "machine/i8255.h" #include "machine/com8116.h" diff --git a/src/mame/drivers/qvt103.cpp b/src/mame/drivers/qvt103.cpp index 82d6ba1399b..553d6f2d8c8 100644 --- a/src/mame/drivers/qvt103.cpp +++ b/src/mame/drivers/qvt103.cpp @@ -11,7 +11,7 @@ Skeleton driver for Qume QVT-103 video display terminal. #include "cpu/mcs48/mcs48.h" #include "machine/nvram.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "video/crt9007.h" #include "emupal.h" #include "screen.h" diff --git a/src/mame/drivers/qvt70.cpp b/src/mame/drivers/qvt70.cpp index 778768bad64..7b18d774e6a 100644 --- a/src/mame/drivers/qvt70.cpp +++ b/src/mame/drivers/qvt70.cpp @@ -26,7 +26,7 @@ #include "emu.h" #include "cpu/z80/z80.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "bus/centronics/ctronics.h" #include "bus/rs232/rs232.h" #include "emupal.h" diff --git a/src/mame/drivers/rc702.cpp b/src/mame/drivers/rc702.cpp index 26a62d7bf71..7c901446529 100644 --- a/src/mame/drivers/rc702.cpp +++ b/src/mame/drivers/rc702.cpp @@ -32,8 +32,8 @@ Issues: #include "machine/keyboard.h" #include "machine/upd765.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" #include "machine/z80pio.h" +#include "machine/z80sio.h" #include "sound/beep.h" #include "video/i8275.h" diff --git a/src/mame/drivers/superslave.cpp b/src/mame/drivers/superslave.cpp index fb714ae8785..fe9ff579d21 100644 --- a/src/mame/drivers/superslave.cpp +++ b/src/mame/drivers/superslave.cpp @@ -28,8 +28,8 @@ Oxx,yy = Out port #include "machine/am9519.h" #include "machine/com8116.h" #include "machine/ram.h" -#include "machine/z80dart.h" #include "machine/z80pio.h" +#include "machine/z80sio.h" #define Z80_TAG "u45" #define Z80DART_0_TAG "u14" diff --git a/src/mame/drivers/ti931.cpp b/src/mame/drivers/ti931.cpp index 9cec2549a9b..3531bf7ea13 100644 --- a/src/mame/drivers/ti931.cpp +++ b/src/mame/drivers/ti931.cpp @@ -11,7 +11,7 @@ //#include "bus/rs232/rs232.h" #include "machine/nvram.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "video/scn2674.h" #include "screen.h" diff --git a/src/mame/drivers/ts802.cpp b/src/mame/drivers/ts802.cpp index 70f79ba3383..c1d5a5462fb 100644 --- a/src/mame/drivers/ts802.cpp +++ b/src/mame/drivers/ts802.cpp @@ -28,7 +28,7 @@ #include "machine/terminal.h" #include "machine/z80dma.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/wd_fdc.h" class ts802_state : public driver_device diff --git a/src/mame/drivers/ts803.cpp b/src/mame/drivers/ts803.cpp index 54ac69a2c66..40689e4d067 100644 --- a/src/mame/drivers/ts803.cpp +++ b/src/mame/drivers/ts803.cpp @@ -52,7 +52,7 @@ PAGE SEL bit in PORT0 set to 1: #include "machine/z80daisy.h" #include "machine/keyboard.h" #include "machine/timer.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/wd_fdc.h" #include "machine/z80sti.h" #include "video/mc6845.h" diff --git a/src/mame/includes/abc1600.h b/src/mame/includes/abc1600.h index 72a62c0db50..2122c4ddf77 100644 --- a/src/mame/includes/abc1600.h +++ b/src/mame/includes/abc1600.h @@ -15,8 +15,8 @@ #include "machine/nmc9306.h" #include "machine/ram.h" #include "machine/wd_fdc.h" -#include "machine/z80dart.h" #include "machine/z80dma.h" +#include "machine/z80sio.h" #include "machine/z8536.h" #include "imagedev/floppy.h" #include "video/abc1600.h" diff --git a/src/mame/includes/abc80x.h b/src/mame/includes/abc80x.h index 1d1509817df..a22025a9563 100644 --- a/src/mame/includes/abc80x.h +++ b/src/mame/includes/abc80x.h @@ -16,7 +16,6 @@ #include "bus/abckb/abc800kb.h" #include "machine/e0516.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" #include "machine/z80sio.h" #include "machine/ram.h" #include "machine/timer.h" diff --git a/src/mame/includes/bullet.h b/src/mame/includes/bullet.h index 558fc877a80..c5b6d70d9ea 100644 --- a/src/mame/includes/bullet.h +++ b/src/mame/includes/bullet.h @@ -13,9 +13,9 @@ #include "machine/timer.h" #include "machine/wd_fdc.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" #include "machine/z80dma.h" #include "machine/z80pio.h" +#include "machine/z80sio.h" #define Z80_TAG "u20" #define Z80CTC_TAG "u1" diff --git a/src/mame/includes/mtx.h b/src/mame/includes/mtx.h index 361cd3932d4..463174ee3fd 100644 --- a/src/mame/includes/mtx.h +++ b/src/mame/includes/mtx.h @@ -17,7 +17,7 @@ #include "bus/mtx/exp.h" #include "cpu/z80/z80.h" #include "machine/z80daisy.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/z80ctc.h" #include "sound/sn76496.h" #include "machine/ram.h" diff --git a/src/mame/includes/super6.h b/src/mame/includes/super6.h index c51a7f9e59a..2aa8bd2621f 100644 --- a/src/mame/includes/super6.h +++ b/src/mame/includes/super6.h @@ -12,9 +12,9 @@ #include "machine/ram.h" #include "machine/wd_fdc.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" #include "machine/z80dma.h" #include "machine/z80pio.h" +#include "machine/z80sio.h" #define Z80_TAG "u30" #define Z80CTC_TAG "u20" diff --git a/src/mame/includes/tiki100.h b/src/mame/includes/tiki100.h index 802f8a3bbd4..fb04bdaf812 100644 --- a/src/mame/includes/tiki100.h +++ b/src/mame/includes/tiki100.h @@ -16,8 +16,8 @@ #include "machine/ram.h" #include "machine/timer.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" #include "machine/z80pio.h" +#include "machine/z80sio.h" #include "machine/wd_fdc.h" #include "sound/ay8910.h" #include "emupal.h" diff --git a/src/mame/includes/tranz330.h b/src/mame/includes/tranz330.h index ce0aa239ba5..71bcac68165 100644 --- a/src/mame/includes/tranz330.h +++ b/src/mame/includes/tranz330.h @@ -9,8 +9,8 @@ #include "cpu/z80/z80.h" #include "machine/z80daisy.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" #include "machine/z80pio.h" +#include "machine/z80sio.h" #include "machine/msm6242.h" #include "machine/roc10937.h" #include "bus/rs232/rs232.h" diff --git a/src/mame/machine/mtx.cpp b/src/mame/machine/mtx.cpp index 93457dc85f2..20134257f89 100644 --- a/src/mame/machine/mtx.cpp +++ b/src/mame/machine/mtx.cpp @@ -7,17 +7,9 @@ **************************************************************************/ #include "emu.h" -#include "formats/imageutl.h" #include "includes/mtx.h" -#include "cpu/z80/z80.h" -#include "imagedev/cassette.h" -#include "machine/ram.h" -#include "imagedev/snapquik.h" -#include "bus/centronics/ctronics.h" -#include "machine/z80ctc.h" -#include "machine/z80dart.h" -#include "video/tms9928a.h" -#include "sound/sn76496.h" + +#include "formats/imageutl.h" /*************************************************************************** READ/WRITE HANDLERS