diff options
Diffstat (limited to 'src/emu/machine/z80dart.c')
-rw-r--r-- | src/emu/machine/z80dart.c | 1754 |
1 files changed, 828 insertions, 926 deletions
diff --git a/src/emu/machine/z80dart.c b/src/emu/machine/z80dart.c index 5a802cac502..c15193823fa 100644 --- a/src/emu/machine/z80dart.c +++ b/src/emu/machine/z80dart.c @@ -23,14 +23,22 @@ #include "cpu/z80/z80.h" #include "cpu/z80/z80daisy.h" -/*************************************************************************** - PARAMETERS -***************************************************************************/ + + +//************************************************************************** +// DEBUGGING +//************************************************************************** #define VERBOSE 0 #define LOG(x) do { if (VERBOSE) logerror x; } while (0) + + +//************************************************************************** +// CONSTANTS +//************************************************************************** + enum { STATE_START = 0, @@ -48,228 +56,476 @@ enum INT_SPECIAL }; -#define Z80DART_RR0_RX_CHAR_AVAILABLE 0x01 -#define Z80DART_RR0_INTERRUPT_PENDING 0x02 -#define Z80DART_RR0_TX_BUFFER_EMPTY 0x04 -#define Z80DART_RR0_DCD 0x08 -#define Z80DART_RR0_RI 0x10 -#define Z80DART_RR0_CTS 0x20 -#define Z80DART_RR0_BREAK 0x80 /* not supported */ - -#define Z80DART_RR1_ALL_SENT 0x01 -#define Z80DART_RR1_PARITY_ERROR 0x10 -#define Z80DART_RR1_RX_OVERRUN_ERROR 0x20 -#define Z80DART_RR1_FRAMING_ERROR 0x40 - -#define Z80DART_WR0_REGISTER_MASK 0x07 -#define Z80DART_WR0_COMMAND_MASK 0x38 -#define Z80DART_WR0_NULL_CODE 0x00 -#define Z80DART_WR0_RESET_EXT_STATUS 0x10 -#define Z80DART_WR0_CHANNEL_RESET 0x18 -#define Z80DART_WR0_ENABLE_INT_NEXT_RX 0x20 -#define Z80DART_WR0_RESET_TX_INT 0x28 /* not supported */ -#define Z80DART_WR0_ERROR_RESET 0x30 -#define Z80DART_WR0_RETURN_FROM_INT 0x38 /* not supported */ - -#define Z80DART_WR1_EXT_INT_ENABLE 0x01 -#define Z80DART_WR1_TX_INT_ENABLE 0x02 -#define Z80DART_WR1_STATUS_VECTOR 0x04 -#define Z80DART_WR1_RX_INT_ENABLE_MASK 0x18 -#define Z80DART_WR1_RX_INT_DISABLE 0x00 -#define Z80DART_WR1_RX_INT_FIRST 0x08 -#define Z80DART_WR1_RX_INT_ALL_PARITY 0x10 /* not supported */ -#define Z80DART_WR1_RX_INT_ALL 0x18 -#define Z80DART_WR1_WRDY_ON_RX_TX 0x20 /* not supported */ -#define Z80DART_WR1_WRDY_FUNCTION 0x40 /* not supported */ -#define Z80DART_WR1_WRDY_ENABLE 0x80 /* not supported */ - -#define Z80DART_WR3_RX_ENABLE 0x01 -#define Z80DART_WR3_AUTO_ENABLES 0x20 -#define Z80DART_WR3_RX_WORD_LENGTH_MASK 0xc0 -#define Z80DART_WR3_RX_WORD_LENGTH_5 0x00 -#define Z80DART_WR3_RX_WORD_LENGTH_7 0x40 -#define Z80DART_WR3_RX_WORD_LENGTH_6 0x80 -#define Z80DART_WR3_RX_WORD_LENGTH_8 0xc0 - -#define Z80DART_WR4_PARITY_ENABLE 0x01 /* not supported */ -#define Z80DART_WR4_PARITY_EVEN 0x02 /* not supported */ -#define Z80DART_WR4_STOP_BITS_MASK 0x0c -#define Z80DART_WR4_STOP_BITS_1 0x04 -#define Z80DART_WR4_STOP_BITS_1_5 0x08 /* not supported */ -#define Z80DART_WR4_STOP_BITS_2 0x0c -#define Z80DART_WR4_CLOCK_MODE_MASK 0xc0 -#define Z80DART_WR4_CLOCK_MODE_X1 0x00 -#define Z80DART_WR4_CLOCK_MODE_X16 0x40 -#define Z80DART_WR4_CLOCK_MODE_X32 0x80 -#define Z80DART_WR4_CLOCK_MODE_X64 0xc0 - -#define Z80DART_WR5_RTS 0x02 -#define Z80DART_WR5_TX_ENABLE 0x08 -#define Z80DART_WR5_SEND_BREAK 0x10 -#define Z80DART_WR5_TX_WORD_LENGTH_MASK 0xc0 -#define Z80DART_WR5_TX_WORD_LENGTH_5 0x00 -#define Z80DART_WR5_TX_WORD_LENGTH_7 0x40 -#define Z80DART_WR5_TX_WORD_LENGTH_6 0x80 -#define Z80DART_WR5_TX_WORD_LENGTH_8 0xc0 -#define Z80DART_WR5_DTR 0x80 +const int Z80DART_RR0_RX_CHAR_AVAILABLE = 0x01; +const int Z80DART_RR0_INTERRUPT_PENDING = 0x02; +const int Z80DART_RR0_TX_BUFFER_EMPTY = 0x04; +const int Z80DART_RR0_DCD = 0x08; +const int Z80DART_RR0_RI = 0x10; +const int Z80DART_RR0_CTS = 0x20; +const int Z80DART_RR0_BREAK = 0x80; // not supported + +const int Z80DART_RR1_ALL_SENT = 0x01; +const int Z80DART_RR1_PARITY_ERROR = 0x10; +const int Z80DART_RR1_RX_OVERRUN_ERROR = 0x20; +const int Z80DART_RR1_FRAMING_ERROR = 0x40; + +const int Z80DART_WR0_REGISTER_MASK = 0x07; +const int Z80DART_WR0_COMMAND_MASK = 0x38; +const int Z80DART_WR0_NULL_CODE = 0x00; +const int Z80DART_WR0_RESET_EXT_STATUS = 0x10; +const int Z80DART_WR0_CHANNEL_RESET = 0x18; +const int Z80DART_WR0_ENABLE_INT_NEXT_RX = 0x20; +const int Z80DART_WR0_RESET_TX_INT = 0x28; // not supported +const int Z80DART_WR0_ERROR_RESET = 0x30; +const int Z80DART_WR0_RETURN_FROM_INT = 0x38; // not supported + +const int Z80DART_WR1_EXT_INT_ENABLE = 0x01; +const int Z80DART_WR1_TX_INT_ENABLE = 0x02; +const int Z80DART_WR1_STATUS_VECTOR = 0x04; +const int Z80DART_WR1_RX_INT_ENABLE_MASK = 0x18; +const int Z80DART_WR1_RX_INT_DISABLE = 0x00; +const int Z80DART_WR1_RX_INT_FIRST = 0x08; +const int Z80DART_WR1_RX_INT_ALL_PARITY = 0x10; // not supported +const int Z80DART_WR1_RX_INT_ALL = 0x18; +const int Z80DART_WR1_WRDY_ON_RX_TX = 0x20; // not supported +const int Z80DART_WR1_WRDY_FUNCTION = 0x40; // not supported +const int Z80DART_WR1_WRDY_ENABLE = 0x80; // not supported + +const int Z80DART_WR3_RX_ENABLE = 0x01; +const int Z80DART_WR3_AUTO_ENABLES = 0x20; +const int Z80DART_WR3_RX_WORD_LENGTH_MASK = 0xc0; +const int Z80DART_WR3_RX_WORD_LENGTH_5 = 0x00; +const int Z80DART_WR3_RX_WORD_LENGTH_7 = 0x40; +const int Z80DART_WR3_RX_WORD_LENGTH_6 = 0x80; +const int Z80DART_WR3_RX_WORD_LENGTH_8 = 0xc0; + +const int Z80DART_WR4_PARITY_ENABLE = 0x01; // not supported +const int Z80DART_WR4_PARITY_EVEN = 0x02; // not supported +const int Z80DART_WR4_STOP_BITS_MASK = 0x0c; +const int Z80DART_WR4_STOP_BITS_1 = 0x04; +const int Z80DART_WR4_STOP_BITS_1_5 = 0x08; // not supported +const int Z80DART_WR4_STOP_BITS_2 = 0x0c; +const int Z80DART_WR4_CLOCK_MODE_MASK = 0xc0; +const int Z80DART_WR4_CLOCK_MODE_X1 = 0x00; +const int Z80DART_WR4_CLOCK_MODE_X16 = 0x40; +const int Z80DART_WR4_CLOCK_MODE_X32 = 0x80; +const int Z80DART_WR4_CLOCK_MODE_X64 = 0xc0; + +const int Z80DART_WR5_RTS = 0x02; +const int Z80DART_WR5_TX_ENABLE = 0x08; +const int Z80DART_WR5_SEND_BREAK = 0x10; +const int Z80DART_WR5_TX_WORD_LENGTH_MASK = 0xc0; +const int Z80DART_WR5_TX_WORD_LENGTH_5 = 0x00; +const int Z80DART_WR5_TX_WORD_LENGTH_7 = 0x40; +const int Z80DART_WR5_TX_WORD_LENGTH_6 = 0x80; +const int Z80DART_WR5_TX_WORD_LENGTH_8 = 0xc0; +const int Z80DART_WR5_DTR = 0x80; + + + +//************************************************************************** +// MACROS +//************************************************************************** -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ +#define RXD \ + devcb_call_read_line(&m_in_rxd_func) + +#define TXD(_state) \ + devcb_call_write_line(&m_out_txd_func, _state) + +#define RTS(_state) \ + devcb_call_write_line(&m_out_rts_func, _state) + +#define DTR(_state) \ + devcb_call_write_line(&m_out_dtr_func, _state) + + + +//************************************************************************** +// DEVICE CONFIGURATION +//************************************************************************** -typedef struct _dart_channel dart_channel; -struct _dart_channel +//------------------------------------------------- +// z80dart_device_config - constructor +//------------------------------------------------- + +z80dart_device_config::z80dart_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) + : device_config(mconfig, static_alloc_device_config, tag, owner, clock), + device_config_z80daisy_interface(mconfig, *this) { - devcb_resolved_read_line in_rxd_func; - devcb_resolved_write_line out_txd_func; - devcb_resolved_write_line out_dtr_func; - devcb_resolved_write_line out_rts_func; - devcb_resolved_write_line out_wrdy_func; - - /* register state */ - UINT8 rr[3]; /* read register */ - UINT8 wr[6]; /* write register */ - - /* receiver state */ - UINT8 rx_data_fifo[3]; /* receive data FIFO */ - UINT8 rx_error_fifo[3]; /* receive error FIFO */ - UINT8 rx_shift; /* 8-bit receive shift register */ - UINT8 rx_error; /* current receive error */ - int rx_fifo; /* receive FIFO pointer */ - - int rx_clock; /* receive clock pulse count */ - int rx_state; /* receive state */ - int rx_bits; /* bits received */ - int rx_first; /* first character received */ - int rx_parity; /* received data parity */ - int rx_break; /* receive break condition */ - UINT8 rx_rr0_latch; /* read register 0 latched */ - - int ri; /* ring indicator latch */ - int cts; /* clear to send latch */ - int dcd; /* data carrier detect latch */ - - /* transmitter state */ - UINT8 tx_data; /* transmit data register */ - UINT8 tx_shift; /* transmit shift register */ - - int tx_clock; /* transmit clock pulse count */ - int tx_state; /* transmit state */ - int tx_bits; /* bits transmitted */ - int tx_parity; /* transmitted data parity */ - - int dtr; /* data terminal ready */ - int rts; /* request to send */ -}; +} + + +//------------------------------------------------- +// static_alloc_device_config - allocate a new +// configuration object +//------------------------------------------------- -typedef struct _z80dart_t z80dart_t; -struct _z80dart_t +device_config *z80dart_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) { - devcb_resolved_write_line out_int_func; + return global_alloc(z80dart_device_config(mconfig, tag, owner, clock)); +} - dart_channel channel[2]; /* channels */ - int int_state[8]; /* interrupt state */ +//------------------------------------------------- +// alloc_device - allocate a new device object +//------------------------------------------------- - /* timers */ - emu_timer *rxca_timer; - emu_timer *txca_timer; - emu_timer *rxtxcb_timer; -}; +device_t *z80dart_device_config::alloc_device(running_machine &machine) const +{ + return auto_alloc(&machine, z80dart_device(machine, *this)); +} -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ -static int z80dart_irq_state(running_device *device); -static void z80dart_irq_reti(running_device *device); +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- -/*************************************************************************** - INLINE FUNCTIONS -***************************************************************************/ +void z80dart_device_config::device_config_complete() +{ + // inherit a copy of the static data + const z80dart_interface *intf = reinterpret_cast<const z80dart_interface *>(static_config()); + if (intf != NULL) + *static_cast<z80dart_interface *>(this) = *intf; + + // or initialize to defaults if none provided + else + { + m_rx_clock_a = m_tx_clock_a = m_rx_tx_clock_b = 0; + memset(&m_in_rxda_func, 0, sizeof(m_in_rxda_func)); + memset(&m_out_txda_func, 0, sizeof(m_out_txda_func)); + memset(&m_out_dtra_func, 0, sizeof(m_out_dtra_func)); + memset(&m_out_rtsa_func, 0, sizeof(m_out_rtsa_func)); + memset(&m_out_wrdya_func, 0, sizeof(m_out_wrdya_func)); + memset(&m_in_rxdb_func, 0, sizeof(m_in_rxdb_func)); + memset(&m_out_txdb_func, 0, sizeof(m_out_txdb_func)); + memset(&m_out_dtrb_func, 0, sizeof(m_out_dtrb_func)); + memset(&m_out_rtsb_func, 0, sizeof(m_out_rtsb_func)); + memset(&m_out_wrdyb_func, 0, sizeof(m_out_wrdyb_func)); + memset(&m_out_int_func, 0, sizeof(m_out_int_func)); + } +} -INLINE z80dart_t *get_safe_token(running_device *device) + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// z80dart_device - constructor +//------------------------------------------------- + +z80dart_device::z80dart_device(running_machine &_machine, const z80dart_device_config &config) + : device_t(_machine, config), + device_z80daisy_interface(_machine, config, *this), + m_config(config) { - assert(device != NULL); - assert(device->token != NULL); - assert(device->type == Z80DART); - return (z80dart_t *)device->token; } -INLINE const z80dart_interface *get_interface(running_device *device) + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void z80dart_device::device_start() { - assert(device != NULL); - assert((device->type == Z80DART)); - return (const z80dart_interface *) device->baseconfig().static_config; + // resolve callbacks + devcb_resolve_write_line(&m_out_int_func, &m_config.m_out_int_func, this); + + m_channel[Z80DART_CH_A].start(this, Z80DART_CH_A, m_config.m_in_rxda_func, m_config.m_out_txda_func, m_config.m_out_dtra_func, m_config.m_out_rtsa_func, m_config.m_out_wrdya_func); + m_channel[Z80DART_CH_B].start(this, Z80DART_CH_B, m_config.m_in_rxdb_func, m_config.m_out_txdb_func, m_config.m_out_dtrb_func, m_config.m_out_rtsb_func, m_config.m_out_wrdyb_func); + + if (m_config.m_rx_clock_a != 0) + { + // allocate channel A receive timer + m_rxca_timer = timer_alloc(&m_machine, dart_channel::static_rxca_tick, (void *)&m_channel[Z80DART_CH_A]); + timer_adjust_periodic(m_rxca_timer, attotime_zero, 0, ATTOTIME_IN_HZ(m_config.m_rx_clock_a)); + } + + if (m_config.m_tx_clock_a != 0) + { + // allocate channel A transmit timer + m_txca_timer = timer_alloc(&m_machine, dart_channel::static_txca_tick, (void *)&m_channel[Z80DART_CH_A]); + timer_adjust_periodic(m_txca_timer, attotime_zero, 0, ATTOTIME_IN_HZ(m_config.m_tx_clock_a)); + } + + if (m_config.m_rx_tx_clock_b != 0) + { + // allocate channel B receive/transmit timer + m_rxtxcb_timer = timer_alloc(&m_machine, dart_channel::static_rxtxcb_tick, (void *)&m_channel[Z80DART_CH_B]); + timer_adjust_periodic(m_rxtxcb_timer, attotime_zero, 0, ATTOTIME_IN_HZ(m_config.m_rx_tx_clock_b)); + } + + state_save_register_device_item_array(this, 0, m_int_state); } -/*************************************************************************** - IMPLEMENTATION -***************************************************************************/ -#define RXD \ - devcb_call_read_line(&ch->in_rxd_func) +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- -#define TXD(_state) \ - devcb_call_write_line(&ch->out_txd_func, _state) +void z80dart_device::device_reset() +{ + LOG(("Z80DART \"%s\" Reset\n", tag())); + + for (int channel = Z80DART_CH_A; channel <= Z80DART_CH_B; channel++) + { + m_channel[channel].reset(); + } + + check_interrupts(); +} -#define RTS(_state) \ - devcb_call_write_line(&ch->out_rts_func, _state) -#define DTR(_state) \ - devcb_call_write_line(&ch->out_dtr_func, _state) -/*------------------------------------------------- - check_interrupts - control interrupt line --------------------------------------------------*/ +//************************************************************************** +// DAISY CHAIN INTERFACE +//************************************************************************** -static void check_interrupts(running_device *device) +//------------------------------------------------- +// z80daisy_irq_state - get interrupt status +//------------------------------------------------- + +int z80dart_device::z80daisy_irq_state() { - z80dart_t *z80dart = get_safe_token(device); - int state = (z80dart_irq_state(device) & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE; + int state = 0; + int i; - devcb_call_write_line(&z80dart->out_int_func, state); + LOG(("Z80DART \"%s\" : Interrupt State B:%d%d%d%d A:%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; } -/*------------------------------------------------- - take_interrupt - trigger interrupt --------------------------------------------------*/ -static void take_interrupt(running_device *device, int channel, int level) +//------------------------------------------------- +// z80daisy_irq_ack - interrupt acknowledge +//------------------------------------------------- + +int z80dart_device::z80daisy_irq_ack() { - z80dart_t *z80dart = get_safe_token(device); - dart_channel *ch = &z80dart->channel[channel]; - UINT8 vector = ch->wr[2]; - int priority = (channel << 2) | level; + int i; - LOG(("Z80DART \"%s\" Channel %c : Interrupt Request %u\n", device->tag(), 'A' + channel, level)); + LOG(("Z80DART \"%s\" Interrupt Acknowledge\n", tag())); - if ((channel == Z80DART_CH_B) && (ch->wr[1] & Z80DART_WR1_STATUS_VECTOR)) + // loop over all interrupt sources + for (i = 0; i < 8; i++) { - /* status affects vector */ - vector = (ch->wr[2] & 0xf1) | (!channel << 3) | (level << 1); + // 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_channel[Z80DART_CH_A].m_rr[0] &= ~Z80DART_RR0_INTERRUPT_PENDING; + check_interrupts(); + + LOG(("Z80DART \"%s\" : Interrupt Acknowledge Vector %02x\n", tag(), m_channel[Z80DART_CH_B].m_rr[2])); + + return m_channel[Z80DART_CH_B].m_rr[2]; + } } - /* update vector register */ - ch->rr[2] = vector; + logerror("z80dart_irq_ack: failed to find an interrupt to ack!\n"); + + return m_channel[Z80DART_CH_B].m_rr[2]; +} - /* trigger interrupt */ - z80dart->int_state[priority] |= Z80_DAISY_INT; - z80dart->channel[Z80DART_CH_A].rr[0] |= Z80DART_RR0_INTERRUPT_PENDING; - /* check for interrupt */ - check_interrupts(device); +//------------------------------------------------- +// 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"); } -/*------------------------------------------------- - get_clock_mode - get clock divisor --------------------------------------------------*/ -static int get_clock_mode(dart_channel *ch) + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +//------------------------------------------------- +// check_interrupts - control interrupt line +//------------------------------------------------- + +void z80dart_device::check_interrupts() +{ + int state = (z80daisy_irq_state() & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE; + devcb_call_write_line(&m_out_int_func, state); +} + + +//------------------------------------------------- +// take_interrupt - trigger interrupt +//------------------------------------------------- + +void z80dart_device::take_interrupt(int priority) +{ + m_int_state[priority] |= Z80_DAISY_INT; + m_channel[Z80DART_CH_A].m_rr[0] |= Z80DART_RR0_INTERRUPT_PENDING; + + // check for interrupt + check_interrupts(); +} + + + +//************************************************************************** +// DART CHANNEL +//************************************************************************** + +//------------------------------------------------- +// dart_channel - constructor +//------------------------------------------------- + +z80dart_device::dart_channel::dart_channel() + : m_rx_shift(0), + m_rx_error(0), + m_rx_fifo(0), + m_rx_clock(0), + m_rx_state(0), + m_rx_bits(0), + m_rx_first(0), + m_rx_parity(0), + m_rx_break(0), + m_rx_rr0_latch(0), + m_ri(0), + m_cts(0), + m_dcd(0), + m_tx_data(0), + m_tx_shift(0), + m_tx_clock(0), + m_tx_state(0), + m_tx_bits(0), + m_tx_parity(0), + m_dtr(0), + m_rts(0) +{ + memset(&m_in_rxd_func, 0, sizeof(m_in_rxd_func)); + memset(&m_out_txd_func, 0, sizeof(m_out_txd_func)); + memset(&m_out_dtr_func, 0, sizeof(m_out_dtr_func)); + memset(&m_out_rts_func, 0, sizeof(m_out_rts_func)); + memset(&m_out_wrdy_func, 0, sizeof(m_out_wrdy_func)); + memset(&m_rr, 0, sizeof(m_rr)); + memset(&m_wr, 0, sizeof(m_wr)); + memset(&m_rx_data_fifo, 0, sizeof(m_rx_data_fifo)); + memset(&m_rx_error_fifo, 0, sizeof(m_rx_error_fifo)); +} + + +//------------------------------------------------- +// start - channel startup +//------------------------------------------------- + +void z80dart_device::dart_channel::start(z80dart_device *device, int index, const devcb_read_line &in_rxd, const devcb_write_line &out_txd, const devcb_write_line &out_dtr, const devcb_write_line &out_rts, const devcb_write_line &out_wrdy) +{ + m_index = index; + + devcb_resolve_read_line(&m_in_rxd_func, &in_rxd, m_device); + devcb_resolve_write_line(&m_out_txd_func, &out_txd, m_device); + devcb_resolve_write_line(&m_out_dtr_func, &out_dtr, m_device); + devcb_resolve_write_line(&m_out_rts_func, &out_rts, m_device); + devcb_resolve_write_line(&m_out_wrdy_func, &out_wrdy, m_device); + + state_save_register_device_item_array(m_device, m_index, m_rr); + state_save_register_device_item_array(m_device, m_index, m_wr); + state_save_register_device_item_array(m_device, m_index, m_rx_data_fifo); + state_save_register_device_item_array(m_device, m_index, m_rx_error_fifo); + state_save_register_device_item(m_device, m_index, m_rx_shift); + state_save_register_device_item(m_device, m_index, m_rx_error); + state_save_register_device_item(m_device, m_index, m_rx_fifo); + state_save_register_device_item(m_device, m_index, m_rx_clock); + state_save_register_device_item(m_device, m_index, m_rx_state); + state_save_register_device_item(m_device, m_index, m_rx_bits); + state_save_register_device_item(m_device, m_index, m_rx_first); + state_save_register_device_item(m_device, m_index, m_rx_parity); + state_save_register_device_item(m_device, m_index, m_rx_break); + state_save_register_device_item(m_device, m_index, m_rx_rr0_latch); + state_save_register_device_item(m_device, m_index, m_ri); + state_save_register_device_item(m_device, m_index, m_cts); + state_save_register_device_item(m_device, m_index, m_dcd); + state_save_register_device_item(m_device, m_index, m_tx_data); + state_save_register_device_item(m_device, m_index, m_tx_shift); + state_save_register_device_item(m_device, m_index, m_tx_clock); + state_save_register_device_item(m_device, m_index, m_tx_state); + state_save_register_device_item(m_device, m_index, m_tx_bits); + state_save_register_device_item(m_device, m_index, m_tx_parity); + state_save_register_device_item(m_device, m_index, m_dtr); + state_save_register_device_item(m_device, m_index, m_rts); +} + + +//------------------------------------------------- +// take_interrupt - trigger interrupt +//------------------------------------------------- + +void z80dart_device::dart_channel::take_interrupt(int level) +{ + UINT8 vector = m_wr[2]; + int priority = (m_index << 2) | level; + + LOG(("Z80DART \"%s\" Channel %c : Interrupt Request %u\n", m_device->tag(), 'A' + m_index, level)); + + if ((m_index == Z80DART_CH_B) && (m_wr[1] & Z80DART_WR1_STATUS_VECTOR)) + { + // status affects vector + vector = (m_wr[2] & 0xf1) | (!m_index << 3) | (level << 1); + } + + // update vector register + m_rr[2] = vector; + + // trigger interrupt + m_device->take_interrupt(priority); +} + + +//------------------------------------------------- +// get_clock_mode - get clock divisor +//------------------------------------------------- + +int z80dart_device::dart_channel::get_clock_mode() { int clocks = 1; - switch (ch->wr[4] & Z80DART_WR4_CLOCK_MODE_MASK) + switch (m_wr[4] & Z80DART_WR4_CLOCK_MODE_MASK) { case Z80DART_WR4_CLOCK_MODE_X1: clocks = 1; break; case Z80DART_WR4_CLOCK_MODE_X16: clocks = 16; break; @@ -280,15 +536,16 @@ static int get_clock_mode(dart_channel *ch) return clocks; } -/*------------------------------------------------- - get_stop_bits - get number of stop bits --------------------------------------------------*/ -static float get_stop_bits(dart_channel *ch) +//------------------------------------------------- +// get_stop_bits - get number of stop bits +//------------------------------------------------- + +float z80dart_device::dart_channel::get_stop_bits() { float bits = 1; - switch (ch->wr[4] & Z80DART_WR4_STOP_BITS_MASK) + switch (m_wr[4] & Z80DART_WR4_STOP_BITS_MASK) { case Z80DART_WR4_STOP_BITS_1: bits = 1; break; case Z80DART_WR4_STOP_BITS_1_5: bits = 1.5; break; @@ -298,15 +555,16 @@ static float get_stop_bits(dart_channel *ch) return bits; } -/*------------------------------------------------- - get_rx_word_length - get receive word length --------------------------------------------------*/ -static int get_rx_word_length(dart_channel *ch) +//------------------------------------------------- +// get_rx_word_length - get receive word length +//------------------------------------------------- + +int z80dart_device::dart_channel::get_rx_word_length() { int bits = 5; - switch (ch->wr[3] & Z80DART_WR3_RX_WORD_LENGTH_MASK) + switch (m_wr[3] & Z80DART_WR3_RX_WORD_LENGTH_MASK) { case Z80DART_WR3_RX_WORD_LENGTH_5: bits = 5; break; case Z80DART_WR3_RX_WORD_LENGTH_6: bits = 6; break; @@ -317,15 +575,16 @@ static int get_rx_word_length(dart_channel *ch) return bits; } -/*------------------------------------------------- - get_rx_word_length - get transmit word length --------------------------------------------------*/ -static int get_tx_word_length(dart_channel *ch) +//------------------------------------------------- +// get_tx_word_length - get transmit word length +//------------------------------------------------- + +int z80dart_device::dart_channel::get_tx_word_length() { int bits = 5; - switch (ch->wr[5] & Z80DART_WR5_TX_WORD_LENGTH_MASK) + switch (m_wr[5] & Z80DART_WR5_TX_WORD_LENGTH_MASK) { case Z80DART_WR5_TX_WORD_LENGTH_5: bits = 5; break; case Z80DART_WR5_TX_WORD_LENGTH_6: bits = 6; break; @@ -336,300 +595,293 @@ static int get_tx_word_length(dart_channel *ch) return bits; } -/*------------------------------------------------- - reset_channel - reset channel status --------------------------------------------------*/ -static void reset_channel(running_device *device, int channel) -{ - z80dart_t *z80dart = get_safe_token(device); - dart_channel *ch = &z80dart->channel[channel]; +//------------------------------------------------- +// reset - reset channel status +//------------------------------------------------- - /* disable receiver */ - ch->wr[3] &= ~Z80DART_WR3_RX_ENABLE; - ch->rx_state = STATE_START; +void z80dart_device::dart_channel::reset() +{ + // disable receiver + m_wr[3] &= ~Z80DART_WR3_RX_ENABLE; + m_rx_state = STATE_START; - /* disable transmitter */ - ch->wr[5] &= ~Z80DART_WR5_TX_ENABLE; - ch->tx_state = STATE_START; + // disable transmitter + m_wr[5] &= ~Z80DART_WR5_TX_ENABLE; + m_tx_state = STATE_START; - /* reset external lines */ + // reset external lines RTS(1); DTR(1); - if (channel == Z80DART_CH_A) + if (m_index == Z80DART_CH_A) { - /* reset interrupt logic */ + // reset interrupt logic int i; for (i = 0; i < 8; i++) { - z80dart->int_state[i] = 0; + m_device->m_int_state[i] = 0; } - check_interrupts(device); + m_device->check_interrupts(); } } -/*------------------------------------------------- - detect_start_bit - detect start bit --------------------------------------------------*/ -static int detect_start_bit(dart_channel *ch) +//------------------------------------------------- +// detect_start_bit - detect start bit +//------------------------------------------------- + +int z80dart_device::dart_channel::detect_start_bit() { - if (!(ch->wr[3] & Z80DART_WR3_RX_ENABLE)) return 0; + if (!(m_wr[3] & Z80DART_WR3_RX_ENABLE)) return 0; return !RXD; } -/*------------------------------------------------- - shift_data_in - shift in serial data --------------------------------------------------*/ -static void shift_data_in(dart_channel *ch) +//------------------------------------------------- +// shift_data_in - shift in serial data +//------------------------------------------------- + +void z80dart_device::dart_channel::shift_data_in() { - if (ch->rx_bits < 8) + if (m_rx_bits < 8) { int rxd = RXD; - ch->rx_shift >>= 1; - ch->rx_shift = (rxd << 7) | (ch->rx_shift & 0x7f); - ch->rx_parity ^= rxd; - ch->rx_bits++; + m_rx_shift >>= 1; + m_rx_shift = (rxd << 7) | (m_rx_shift & 0x7f); + m_rx_parity ^= rxd; + m_rx_bits++; } } -/*------------------------------------------------- - character_completed - check if complete - data word has been transferred --------------------------------------------------*/ -static int character_completed(dart_channel *ch) +//------------------------------------------------- +// character_completed - check if complete +// data word has been transferred +//------------------------------------------------- + +bool z80dart_device::dart_channel::character_completed() { - return ch->rx_bits == get_rx_word_length(ch); + return m_rx_bits == get_rx_word_length(); } -/*------------------------------------------------- - detect_parity_error - detect parity error --------------------------------------------------*/ -static void detect_parity_error(running_device *device, int channel) -{ - z80dart_t *z80dart = get_safe_token(device); - dart_channel *ch = &z80dart->channel[channel]; +//------------------------------------------------- +// detect_parity_error - detect parity error +//------------------------------------------------- - int parity = (ch->wr[1] & Z80DART_WR4_PARITY_EVEN) ? 1 : 0; +void z80dart_device::dart_channel::detect_parity_error() +{ + int parity = (m_wr[1] & Z80DART_WR4_PARITY_EVEN) ? 1 : 0; - if (RXD != (ch->rx_parity ^ parity)) + if (RXD != (m_rx_parity ^ parity)) { - /* parity error detected */ - ch->rx_error |= Z80DART_RR1_PARITY_ERROR; + // parity error detected + m_rx_error |= Z80DART_RR1_PARITY_ERROR; - switch (ch->wr[1] & Z80DART_WR1_RX_INT_ENABLE_MASK) + switch (m_wr[1] & Z80DART_WR1_RX_INT_ENABLE_MASK) { case Z80DART_WR1_RX_INT_FIRST: - if (!ch->rx_first) + if (!m_rx_first) { - take_interrupt(device, channel, INT_SPECIAL); + take_interrupt(INT_SPECIAL); } break; case Z80DART_WR1_RX_INT_ALL_PARITY: - take_interrupt(device, channel, INT_SPECIAL); + take_interrupt(INT_SPECIAL); break; case Z80DART_WR1_RX_INT_ALL: - take_interrupt(device, channel, INT_RECEIVE); + take_interrupt(INT_RECEIVE); break; } } } -/*------------------------------------------------- - detect_framing_error - detect framing error --------------------------------------------------*/ -static void detect_framing_error(running_device *device, int channel) -{ - z80dart_t *z80dart = get_safe_token(device); - dart_channel *ch = &z80dart->channel[channel]; +//------------------------------------------------- +// detect_framing_error - detect framing error +//------------------------------------------------- +void z80dart_device::dart_channel::detect_framing_error() +{ if (!RXD) { - /* framing error detected */ - ch->rx_error |= Z80DART_RR1_FRAMING_ERROR; + // framing error detected + m_rx_error |= Z80DART_RR1_FRAMING_ERROR; - switch (ch->wr[1] & Z80DART_WR1_RX_INT_ENABLE_MASK) + switch (m_wr[1] & Z80DART_WR1_RX_INT_ENABLE_MASK) { case Z80DART_WR1_RX_INT_FIRST: - if (!ch->rx_first) + if (!m_rx_first) { - take_interrupt(device, channel, INT_SPECIAL); + take_interrupt(INT_SPECIAL); } break; case Z80DART_WR1_RX_INT_ALL_PARITY: case Z80DART_WR1_RX_INT_ALL: - take_interrupt(device, channel, INT_SPECIAL); + take_interrupt(INT_SPECIAL); break; } } } -/*------------------------------------------------- - receive - receive serial data --------------------------------------------------*/ -static void receive(running_device *device, int channel) -{ - z80dart_t *z80dart = get_safe_token(device); - dart_channel *ch = &z80dart->channel[channel]; +//------------------------------------------------- +// receive - receive serial data +//------------------------------------------------- - float stop_bits = get_stop_bits(ch); +void z80dart_device::dart_channel::receive() +{ + float stop_bits = get_stop_bits(); - switch (ch->rx_state) + switch (m_rx_state) { case STATE_START: - /* check for start bit */ - if (detect_start_bit(ch)) + // check for start bit + if (detect_start_bit()) { - /* start bit detected */ - ch->rx_shift = 0; - ch->rx_error = 0; - ch->rx_bits = 0; - ch->rx_parity = 0; - - /* next bit is a data bit */ - ch->rx_state = STATE_DATA; + // start bit detected + m_rx_shift = 0; + m_rx_error = 0; + m_rx_bits = 0; + m_rx_parity = 0; + + // next bit is a data bit + m_rx_state = STATE_DATA; } break; case STATE_DATA: - /* shift bit into shift register */ - shift_data_in(ch); + // shift bit into shift register + shift_data_in(); - if (character_completed(ch)) + if (character_completed()) { - /* all data bits received */ - if (ch->wr[4] & Z80DART_WR4_PARITY_ENABLE) + // all data bits received + if (m_wr[4] & Z80DART_WR4_PARITY_ENABLE) { - /* next bit is the parity bit */ - ch->rx_state = STATE_PARITY; + // next bit is the parity bit + m_rx_state = STATE_PARITY; } else { - /* next bit is a STOP bit */ + // next bit is a STOP bit if (stop_bits == 1) - ch->rx_state = STATE_STOP2; + m_rx_state = STATE_STOP2; else - ch->rx_state = STATE_STOP; + m_rx_state = STATE_STOP; } } break; case STATE_PARITY: - /* shift bit into shift register */ - shift_data_in(ch); + // shift bit into shift register + shift_data_in(); - /* check for parity error */ - detect_parity_error(device, channel); + // check for parity error + detect_parity_error(); - /* next bit is a STOP bit */ + // next bit is a STOP bit if (stop_bits == 1) - ch->rx_state = STATE_STOP2; + m_rx_state = STATE_STOP2; else - ch->rx_state = STATE_STOP; + m_rx_state = STATE_STOP; break; case STATE_STOP: - /* shift bit into shift register */ - shift_data_in(ch); + // shift bit into shift register + shift_data_in(); - /* check for framing error */ - detect_framing_error(device, channel); + // check for framing error + detect_framing_error(); - /* next bit is the second STOP bit */ - ch->rx_state = STATE_STOP2; + // next bit is the second STOP bit + m_rx_state = STATE_STOP2; break; case STATE_STOP2: - /* shift bit into shift register */ - shift_data_in(ch); + // shift bit into shift register + shift_data_in(); - /* check for framing error */ - detect_framing_error(device, channel); + // check for framing error + detect_framing_error(); - /* store data into FIFO */ - z80dart_receive_data(device, channel, ch->rx_shift); + // store data into FIFO + receive_data(m_rx_shift); - /* next bit is the START bit */ - ch->rx_state = STATE_START; + // next bit is the START bit + m_rx_state = STATE_START; break; } } -/*------------------------------------------------- - transmit - transmit serial data --------------------------------------------------*/ -static void transmit(running_device *device, int channel) -{ - z80dart_t *z80dart = get_safe_token(device); - dart_channel *ch = &z80dart->channel[channel]; +//------------------------------------------------- +// transmit - transmit serial data +//------------------------------------------------- - int word_length = get_tx_word_length(ch); - float stop_bits = get_stop_bits(ch); +void z80dart_device::dart_channel::transmit() +{ + int word_length = get_tx_word_length(); + float stop_bits = get_stop_bits(); - switch (ch->tx_state) + switch (m_tx_state) { case STATE_START: - if ((ch->wr[5] & Z80DART_WR5_TX_ENABLE) && !(ch->rr[0] & Z80DART_RR0_TX_BUFFER_EMPTY)) + if ((m_wr[5] & Z80DART_WR5_TX_ENABLE) && !(m_rr[0] & Z80DART_RR0_TX_BUFFER_EMPTY)) { - /* transmit start bit */ + // transmit start bit TXD(0); - ch->tx_bits = 0; - ch->tx_shift = ch->tx_data; + m_tx_bits = 0; + m_tx_shift = m_tx_data; - /* empty transmit buffer */ - ch->rr[0] |= Z80DART_RR0_TX_BUFFER_EMPTY; + // empty transmit buffer + m_rr[0] |= Z80DART_RR0_TX_BUFFER_EMPTY; - if (ch->wr[1] & Z80DART_WR1_TX_INT_ENABLE) - take_interrupt(device, channel, INT_TRANSMIT); + if (m_wr[1] & Z80DART_WR1_TX_INT_ENABLE) + take_interrupt(INT_TRANSMIT); - ch->tx_state = STATE_DATA; + m_tx_state = STATE_DATA; } - else if (ch->wr[5] & Z80DART_WR5_SEND_BREAK) + else if (m_wr[5] & Z80DART_WR5_SEND_BREAK) { - /* transmit break */ + // transmit break TXD(0); } else { - /* transmit marking line */ + // transmit marking line TXD(1); } break; case STATE_DATA: - /* transmit data bit */ - TXD(BIT(ch->tx_shift, 0)); + // transmit data bit + TXD(BIT(m_tx_shift, 0)); - /* shift data */ - ch->tx_shift >>= 1; - ch->tx_bits++; + // shift data + m_tx_shift >>= 1; + m_tx_bits++; - if (ch->rx_bits == word_length) + if (m_rx_bits == word_length) { - if (ch->wr[4] & Z80DART_WR4_PARITY_ENABLE) - ch->tx_state = STATE_PARITY; + if (m_wr[4] & Z80DART_WR4_PARITY_ENABLE) + m_tx_state = STATE_PARITY; else { if (stop_bits == 1) - ch->tx_state = STATE_STOP2; + m_tx_state = STATE_STOP2; else - ch->tx_state = STATE_STOP; + m_tx_state = STATE_STOP; } } break; @@ -637,91 +889,86 @@ static void transmit(running_device *device, int channel) case STATE_PARITY: // TODO: calculate parity if (stop_bits == 1) - ch->tx_state = STATE_STOP2; + m_tx_state = STATE_STOP2; else - ch->tx_state = STATE_STOP; + m_tx_state = STATE_STOP; break; case STATE_STOP: - /* transmit stop bit */ + // transmit stop bit TXD(1); - ch->tx_state = STATE_STOP2; + m_tx_state = STATE_STOP2; break; case STATE_STOP2: - /* transmit stop bit */ + // transmit stop bit TXD(1); - /* if transmit buffer is empty */ - if (ch->rr[0] & Z80DART_RR0_TX_BUFFER_EMPTY) + // if transmit buffer is empty + if (m_rr[0] & Z80DART_RR0_TX_BUFFER_EMPTY) { - /* then all characters have been sent */ - ch->rr[1] |= Z80DART_RR1_ALL_SENT; + // then all characters have been sent + m_rr[1] |= Z80DART_RR1_ALL_SENT; - /* when the RTS bit is reset, the _RTS output goes high after the transmitter empties */ - if (!ch->rts) + // when the RTS bit is reset, the _RTS output goes high after the transmitter empties + if (!m_rts) RTS(1); } - ch->tx_state = STATE_START; + m_tx_state = STATE_START; break; } } -/*------------------------------------------------- - z80dart_c_r - read control register --------------------------------------------------*/ -READ8_DEVICE_HANDLER( z80dart_c_r ) +//------------------------------------------------- +// control_read - read control register +//------------------------------------------------- + +UINT8 z80dart_device::dart_channel::control_read() { - z80dart_t *z80dart = get_safe_token(device); - int channel = offset & 0x01; - dart_channel *ch = &z80dart->channel[channel]; UINT8 data = 0; - int reg = ch->wr[0] & Z80DART_WR0_REGISTER_MASK; + int reg = m_wr[0] & Z80DART_WR0_REGISTER_MASK; switch (reg) { case 0: case 1: - data = ch->rr[reg]; + data = m_rr[reg]; break; case 2: - /* channel B only */ - if (channel == Z80DART_CH_B) - data = ch->rr[reg]; + // channel B only + if (m_index == Z80DART_CH_B) + data = m_rr[reg]; break; } - LOG(("Z80DART \"%s\" Channel %c : Control Register Read '%02x'\n", device->tag(), 'A' + channel, data)); + LOG(("Z80DART \"%s\" Channel %c : Control Register Read '%02x'\n", m_device->tag(), 'A' + m_index, data)); return data; } -/*------------------------------------------------- - z80dart_c_w - write control register --------------------------------------------------*/ -WRITE8_DEVICE_HANDLER( z80dart_c_w ) -{ - z80dart_t *z80dart = get_safe_token(device); - int channel = offset & 0x01; - dart_channel *ch = &z80dart->channel[channel]; +//------------------------------------------------- +// control_write - write control register +//------------------------------------------------- - int reg = ch->wr[0] & Z80DART_WR0_REGISTER_MASK; +void z80dart_device::dart_channel::control_write(UINT8 data) +{ + int reg = m_wr[0] & Z80DART_WR0_REGISTER_MASK; - LOG(("Z80DART \"%s\" Channel %c : Control Register Write '%02x'\n", device->tag(), 'A' + channel, data)); + LOG(("Z80DART \"%s\" Channel %c : Control Register Write '%02x'\n", m_device->tag(), 'A' + m_index, data)); - /* write data to selected register */ - ch->wr[reg] = data; + // write data to selected register + m_wr[reg] = data; if (reg != 0) { - /* mask out register index */ - ch->wr[0] &= ~Z80DART_WR0_REGISTER_MASK; + // mask out register index + m_wr[0] &= ~Z80DART_WR0_REGISTER_MASK; } switch (reg) @@ -730,621 +977,409 @@ WRITE8_DEVICE_HANDLER( z80dart_c_w ) switch (data & Z80DART_WR0_COMMAND_MASK) { case Z80DART_WR0_RESET_EXT_STATUS: - /* reset external/status interrupt */ - ch->rr[0] &= ~(Z80DART_RR0_DCD | Z80DART_RR0_RI | Z80DART_RR0_CTS | Z80DART_RR0_BREAK); + // reset external/status interrupt + m_rr[0] &= ~(Z80DART_RR0_DCD | Z80DART_RR0_RI | Z80DART_RR0_CTS | Z80DART_RR0_BREAK); - if (!ch->dcd) ch->rr[0] |= Z80DART_RR0_DCD; - if (ch->ri) ch->rr[0] |= Z80DART_RR0_RI; - if (ch->cts) ch->rr[0] |= Z80DART_RR0_CTS; + if (!m_dcd) m_rr[0] |= Z80DART_RR0_DCD; + if (m_ri) m_rr[0] |= Z80DART_RR0_RI; + if (m_cts) m_rr[0] |= Z80DART_RR0_CTS; - ch->rx_rr0_latch = 0; + m_rx_rr0_latch = 0; - LOG(("Z80DART \"%s\" Channel %c : Reset External/Status Interrupt\n", device->tag(), 'A' + channel)); + LOG(("Z80DART \"%s\" Channel %c : Reset External/Status Interrupt\n", m_device->tag(), 'A' + m_index)); break; case Z80DART_WR0_CHANNEL_RESET: - /* channel reset */ - LOG(("Z80DART \"%s\" Channel %c : Channel Reset\n", device->tag(), 'A' + channel)); - reset_channel(device, channel); + // channel reset + LOG(("Z80DART \"%s\" Channel %c : Channel Reset\n", m_device->tag(), 'A' + m_index)); + reset(); break; case Z80DART_WR0_ENABLE_INT_NEXT_RX: - /* enable interrupt on next receive character */ - LOG(("Z80DART \"%s\" Channel %c : Enable Interrupt on Next Received Character\n", device->tag(), 'A' + channel)); - ch->rx_first = 1; + // enable interrupt on next receive character + LOG(("Z80DART \"%s\" Channel %c : Enable Interrupt on Next Received Character\n", m_device->tag(), 'A' + m_index)); + m_rx_first = 1; break; case Z80DART_WR0_RESET_TX_INT: - /* reset transmitter interrupt pending */ - LOG(("Z80DART \"%s\" Channel %c : Reset Transmitter Interrupt Pending\n", device->tag(), 'A' + channel)); + // reset transmitter interrupt pending + LOG(("Z80DART \"%s\" Channel %c : Reset Transmitter Interrupt Pending\n", m_device->tag(), 'A' + m_index)); break; case Z80DART_WR0_ERROR_RESET: - /* error reset */ - LOG(("Z80DART \"%s\" Channel %c : Error Reset\n", device->tag(), 'A' + channel)); - ch->rr[1] &= ~(Z80DART_RR1_FRAMING_ERROR | Z80DART_RR1_RX_OVERRUN_ERROR | Z80DART_RR1_PARITY_ERROR); + // error reset + LOG(("Z80DART \"%s\" Channel %c : Error Reset\n", m_device->tag(), 'A' + m_index)); + m_rr[1] &= ~(Z80DART_RR1_FRAMING_ERROR | Z80DART_RR1_RX_OVERRUN_ERROR | Z80DART_RR1_PARITY_ERROR); break; case Z80DART_WR0_RETURN_FROM_INT: - /* return from interrupt */ - LOG(("Z80DART \"%s\" Channel %c : Return from Interrupt\n", device->tag(), 'A' + channel)); - z80dart_irq_reti(device); + // return from interrupt + LOG(("Z80DART \"%s\" Channel %c : Return from Interrupt\n", m_device->tag(), 'A' + m_index)); + m_device->z80daisy_irq_reti(); break; } break; case 1: - LOG(("Z80DART \"%s\" Channel %c : External Interrupt Enable %u\n", device->tag(), 'A' + channel, (data & Z80DART_WR1_EXT_INT_ENABLE) ? 1 : 0)); - LOG(("Z80DART \"%s\" Channel %c : Transmit Interrupt Enable %u\n", device->tag(), 'A' + channel, (data & Z80DART_WR1_TX_INT_ENABLE) ? 1 : 0)); - LOG(("Z80DART \"%s\" Channel %c : Status Affects Vector %u\n", device->tag(), 'A' + channel, (data & Z80DART_WR1_STATUS_VECTOR) ? 1 : 0)); - LOG(("Z80DART \"%s\" Channel %c : Wait/Ready Enable %u\n", device->tag(), 'A' + channel, (data & Z80DART_WR1_WRDY_ENABLE) ? 1 : 0)); + LOG(("Z80DART \"%s\" Channel %c : External Interrupt Enable %u\n", m_device->tag(), 'A' + m_index, (data & Z80DART_WR1_EXT_INT_ENABLE) ? 1 : 0)); + LOG(("Z80DART \"%s\" Channel %c : Transmit Interrupt Enable %u\n", m_device->tag(), 'A' + m_index, (data & Z80DART_WR1_TX_INT_ENABLE) ? 1 : 0)); + LOG(("Z80DART \"%s\" Channel %c : Status Affects Vector %u\n", m_device->tag(), 'A' + m_index, (data & Z80DART_WR1_STATUS_VECTOR) ? 1 : 0)); + LOG(("Z80DART \"%s\" Channel %c : Wait/Ready Enable %u\n", m_device->tag(), 'A' + m_index, (data & Z80DART_WR1_WRDY_ENABLE) ? 1 : 0)); switch (data & Z80DART_WR1_RX_INT_ENABLE_MASK) { case Z80DART_WR1_RX_INT_DISABLE: - LOG(("Z80DART \"%s\" Channel %c : Receiver Interrupt Disabled\n", device->tag(), 'A' + channel)); + LOG(("Z80DART \"%s\" Channel %c : Receiver Interrupt Disabled\n", m_device->tag(), 'A' + m_index)); break; case Z80DART_WR1_RX_INT_FIRST: - LOG(("Z80DART \"%s\" Channel %c : Receiver Interrupt on First Character\n", device->tag(), 'A' + channel)); + LOG(("Z80DART \"%s\" Channel %c : Receiver Interrupt on First Character\n", m_device->tag(), 'A' + m_index)); break; case Z80DART_WR1_RX_INT_ALL_PARITY: - LOG(("Z80DART \"%s\" Channel %c : Receiver Interrupt on All Characters, Parity Affects Vector\n", device->tag(), 'A' + channel)); + LOG(("Z80DART \"%s\" Channel %c : Receiver Interrupt on All Characters, Parity Affects Vector\n", m_device->tag(), 'A' + m_index)); break; case Z80DART_WR1_RX_INT_ALL: - LOG(("Z80DART \"%s\" Channel %c : Receiver Interrupt on All Characters\n", device->tag(), 'A' + channel)); + LOG(("Z80DART \"%s\" Channel %c : Receiver Interrupt on All Characters\n", m_device->tag(), 'A' + m_index)); break; } - check_interrupts(device); + m_device->check_interrupts(); break; case 2: - /* interrupt vector */ - check_interrupts(device); - LOG(("Z80DART \"%s\" Channel %c : Interrupt Vector %02x\n", device->tag(), 'A' + channel, data)); + // interrupt vector + m_device->check_interrupts(); + LOG(("Z80DART \"%s\" Channel %c : Interrupt Vector %02x\n", m_device->tag(), 'A' + m_index, data)); break; case 3: - LOG(("Z80DART \"%s\" Channel %c : Receiver Enable %u\n", device->tag(), 'A' + channel, (data & Z80DART_WR3_RX_ENABLE) ? 1 : 0)); - LOG(("Z80DART \"%s\" Channel %c : Auto Enables %u\n", device->tag(), 'A' + channel, (data & Z80DART_WR3_AUTO_ENABLES) ? 1 : 0)); - LOG(("Z80DART \"%s\" Channel %c : Receiver Bits/Character %u\n", device->tag(), 'A' + channel, get_rx_word_length(ch))); + LOG(("Z80DART \"%s\" Channel %c : Receiver Enable %u\n", m_device->tag(), 'A' + m_index, (data & Z80DART_WR3_RX_ENABLE) ? 1 : 0)); + LOG(("Z80DART \"%s\" Channel %c : Auto Enables %u\n", m_device->tag(), 'A' + m_index, (data & Z80DART_WR3_AUTO_ENABLES) ? 1 : 0)); + LOG(("Z80DART \"%s\" Channel %c : Receiver Bits/Character %u\n", m_device->tag(), 'A' + m_index, get_rx_word_length())); break; case 4: - LOG(("Z80DART \"%s\" Channel %c : Parity Enable %u\n", device->tag(), 'A' + channel, (data & Z80DART_WR4_PARITY_ENABLE) ? 1 : 0)); - LOG(("Z80DART \"%s\" Channel %c : Parity %s\n", device->tag(), 'A' + channel, (data & Z80DART_WR4_PARITY_EVEN) ? "Even" : "Odd")); - LOG(("Z80DART \"%s\" Channel %c : Stop Bits %f\n", device->tag(), 'A' + channel, get_stop_bits(ch))); - LOG(("Z80DART \"%s\" Channel %c : Clock Mode %uX\n", device->tag(), 'A' + channel, get_clock_mode(ch))); + LOG(("Z80DART \"%s\" Channel %c : Parity Enable %u\n", m_device->tag(), 'A' + m_index, (data & Z80DART_WR4_PARITY_ENABLE) ? 1 : 0)); + LOG(("Z80DART \"%s\" Channel %c : Parity %s\n", m_device->tag(), 'A' + m_index, (data & Z80DART_WR4_PARITY_EVEN) ? "Even" : "Odd")); + LOG(("Z80DART \"%s\" Channel %c : Stop Bits %f\n", m_device->tag(), 'A' + m_index, get_stop_bits())); + LOG(("Z80DART \"%s\" Channel %c : Clock Mode %uX\n", m_device->tag(), 'A' + m_index, get_clock_mode())); break; case 5: - LOG(("Z80DART \"%s\" Channel %c : Transmitter Enable %u\n", device->tag(), 'A' + channel, (data & Z80DART_WR5_TX_ENABLE) ? 1 : 0)); - LOG(("Z80DART \"%s\" Channel %c : Transmitter Bits/Character %u\n", device->tag(), 'A' + channel, get_tx_word_length(ch))); - LOG(("Z80DART \"%s\" Channel %c : Send Break %u\n", device->tag(), 'A' + channel, (data & Z80DART_WR5_SEND_BREAK) ? 1 : 0)); - LOG(("Z80DART \"%s\" Channel %c : Request to Send %u\n", device->tag(), 'A' + channel, (data & Z80DART_WR5_RTS) ? 1 : 0)); - LOG(("Z80DART \"%s\" Channel %c : Data Terminal Ready %u\n", device->tag(), 'A' + channel, (data & Z80DART_WR5_DTR) ? 1 : 0)); + LOG(("Z80DART \"%s\" Channel %c : Transmitter Enable %u\n", m_device->tag(), 'A' + m_index, (data & Z80DART_WR5_TX_ENABLE) ? 1 : 0)); + LOG(("Z80DART \"%s\" Channel %c : Transmitter Bits/Character %u\n", m_device->tag(), 'A' + m_index, get_tx_word_length())); + LOG(("Z80DART \"%s\" Channel %c : Send Break %u\n", m_device->tag(), 'A' + m_index, (data & Z80DART_WR5_SEND_BREAK) ? 1 : 0)); + LOG(("Z80DART \"%s\" Channel %c : Request to Send %u\n", m_device->tag(), 'A' + m_index, (data & Z80DART_WR5_RTS) ? 1 : 0)); + LOG(("Z80DART \"%s\" Channel %c : Data Terminal Ready %u\n", m_device->tag(), 'A' + m_index, (data & Z80DART_WR5_DTR) ? 1 : 0)); if (data & Z80DART_WR5_RTS) { - /* when the RTS bit is set, the _RTS output goes low */ + // when the RTS bit is set, the _RTS output goes low RTS(0); - ch->rts = 1; + m_rts = 1; } else { - /* when the RTS bit is reset, the _RTS output goes high after the transmitter empties */ - ch->rts = 0; + // when the RTS bit is reset, the _RTS output goes high after the transmitter empties + m_rts = 0; } - /* data terminal ready output follows the state programmed into the DTR bit*/ - ch->dtr = (data & Z80DART_WR5_DTR) ? 0 : 1; - DTR(ch->dtr); + // data terminal ready output follows the state programmed into the DTR bit*/ + m_dtr = (data & Z80DART_WR5_DTR) ? 0 : 1; + DTR(m_dtr); break; } } -/*------------------------------------------------- - z80dart_d_r - read data register --------------------------------------------------*/ -READ8_DEVICE_HANDLER( z80dart_d_r ) +//------------------------------------------------- +// data_read - read data register +//------------------------------------------------- + +UINT8 z80dart_device::dart_channel::data_read() { - z80dart_t *z80dart = get_safe_token(device); - int channel = offset & 0x01; - dart_channel *ch = &z80dart->channel[channel]; UINT8 data = 0; - if (ch->rx_fifo >= 0) + if (m_rx_fifo >= 0) { - /* load data from the FIFO */ - data = ch->rx_data_fifo[ch->rx_fifo]; + // load data from the FIFO + data = m_rx_data_fifo[m_rx_fifo]; - /* load error status from the FIFO, retain overrun and parity errors */ - ch->rr[1] = (ch->rr[1] & (Z80DART_RR1_RX_OVERRUN_ERROR | Z80DART_RR1_PARITY_ERROR)) | ch->rx_error_fifo[ch->rx_fifo]; + // load error status from the FIFO, retain overrun and parity errors + m_rr[1] = (m_rr[1] & (Z80DART_RR1_RX_OVERRUN_ERROR | Z80DART_RR1_PARITY_ERROR)) | m_rx_error_fifo[m_rx_fifo]; - /* decrease FIFO pointer */ - ch->rx_fifo--; + // decrease FIFO pointer + m_rx_fifo--; - if (ch->rx_fifo < 0) + if (m_rx_fifo < 0) { - /* no more characters available in the FIFO */ - ch->rr[0] &= ~ Z80DART_RR0_RX_CHAR_AVAILABLE; + // no more characters available in the FIFO + m_rr[0] &= ~ Z80DART_RR0_RX_CHAR_AVAILABLE; } } - LOG(("Z80DART \"%s\" Channel %c : Data Register Read '%02x'\n", device->tag(), 'A' + channel, data)); + LOG(("Z80DART \"%s\" Channel %c : Data Register Read '%02x'\n", m_device->tag(), 'A' + m_index, data)); return data; } -/*------------------------------------------------- - z80dart_d_w - write data register --------------------------------------------------*/ -WRITE8_DEVICE_HANDLER( z80dart_d_w ) -{ - z80dart_t *z80dart = get_safe_token(device); - int channel = offset & 0x01; - dart_channel *ch = &z80dart->channel[channel]; +//------------------------------------------------- +// data_write - write data register +//------------------------------------------------- - ch->tx_data = data; +void z80dart_device::dart_channel::data_write(UINT8 data) +{ + m_tx_data = data; - ch->rr[0] &= ~Z80DART_RR0_TX_BUFFER_EMPTY; - ch->rr[1] &= ~Z80DART_RR1_ALL_SENT; + m_rr[0] &= ~Z80DART_RR0_TX_BUFFER_EMPTY; + m_rr[1] &= ~Z80DART_RR1_ALL_SENT; - LOG(("Z80DART \"%s\" Channel %c : Data Register Write '%02x'\n", device->tag(), 'A' + channel, data)); + LOG(("Z80DART \"%s\" Channel %c : Data Register Write '%02x'\n", m_device->tag(), 'A' + m_index, data)); } -/*------------------------------------------------- - z80dart_receive_data - receive data word --------------------------------------------------*/ -void z80dart_receive_data(running_device *device, int channel, UINT8 data) -{ - z80dart_t *z80dart = get_safe_token(device); - dart_channel *ch = &z80dart->channel[channel]; +//------------------------------------------------- +// receive_data - receive data word +//------------------------------------------------- - LOG(("Z80DART \"%s\" Channel %c : Receive Data Byte '%02x'\n", device->tag(), 'A' + channel, data)); +void z80dart_device::dart_channel::receive_data(UINT8 data) +{ + LOG(("Z80DART \"%s\" Channel %c : Receive Data Byte '%02x'\n", m_device->tag(), 'A' + m_index, data)); - if (ch->rx_fifo == 2) + if (m_rx_fifo == 2) { - /* receive overrun error detected */ - ch->rx_error |= Z80DART_RR1_RX_OVERRUN_ERROR; + // receive overrun error detected + m_rx_error |= Z80DART_RR1_RX_OVERRUN_ERROR; - switch (ch->wr[1] & Z80DART_WR1_RX_INT_ENABLE_MASK) + switch (m_wr[1] & Z80DART_WR1_RX_INT_ENABLE_MASK) { case Z80DART_WR1_RX_INT_FIRST: - if (!ch->rx_first) + if (!m_rx_first) { - take_interrupt(device, channel, INT_SPECIAL); + take_interrupt(INT_SPECIAL); } break; case Z80DART_WR1_RX_INT_ALL_PARITY: case Z80DART_WR1_RX_INT_ALL: - take_interrupt(device, channel, INT_SPECIAL); + take_interrupt(INT_SPECIAL); break; } } else { - ch->rx_fifo++; + m_rx_fifo++; } - /* store received character and error status into FIFO */ - ch->rx_data_fifo[ch->rx_fifo] = data; - ch->rx_error_fifo[ch->rx_fifo] = ch->rx_error; + // store received character and error status into FIFO + m_rx_data_fifo[m_rx_fifo] = data; + m_rx_error_fifo[m_rx_fifo] = m_rx_error; - ch->rr[0] |= Z80DART_RR0_RX_CHAR_AVAILABLE; + m_rr[0] |= Z80DART_RR0_RX_CHAR_AVAILABLE; - /* receive interrupt */ - switch (ch->wr[1] & Z80DART_WR1_RX_INT_ENABLE_MASK) + // receive interrupt + switch (m_wr[1] & Z80DART_WR1_RX_INT_ENABLE_MASK) { case Z80DART_WR1_RX_INT_FIRST: - if (ch->rx_first) + if (m_rx_first) { - take_interrupt(device, channel, INT_RECEIVE); + take_interrupt(INT_RECEIVE); - ch->rx_first = 0; + m_rx_first = 0; } break; case Z80DART_WR1_RX_INT_ALL_PARITY: case Z80DART_WR1_RX_INT_ALL: - take_interrupt(device, channel, INT_RECEIVE); + take_interrupt(INT_RECEIVE); break; } } -/*------------------------------------------------- - cts_w - clear to send handler --------------------------------------------------*/ -static void cts_w(running_device *device, int channel, int state) -{ - z80dart_t *z80dart = get_safe_token(device); - dart_channel *ch = &z80dart->channel[channel]; +//------------------------------------------------- +// cts_w - clear to send handler +//------------------------------------------------- - LOG(("Z80DART \"%s\" Channel %c : CTS %u\n", device->tag(), 'A' + channel, state)); +void z80dart_device::dart_channel::cts_w(int state) +{ + LOG(("Z80DART \"%s\" Channel %c : CTS %u\n", m_device->tag(), 'A' + m_index, state)); - if (ch->cts != state) + if (m_cts != state) { - /* enable transmitter if in auto enables mode */ + // enable transmitter if in auto enables mode if (!state) - if (ch->wr[3] & Z80DART_WR3_AUTO_ENABLES) - ch->wr[5] |= Z80DART_WR5_TX_ENABLE; + if (m_wr[3] & Z80DART_WR3_AUTO_ENABLES) + m_wr[5] |= Z80DART_WR5_TX_ENABLE; - /* set clear to send */ - ch->cts = state; + // set clear to send + m_cts = state; - if (!ch->rx_rr0_latch) + if (!m_rx_rr0_latch) { - if (!ch->cts) - ch->rr[0] |= Z80DART_RR0_CTS; + if (!m_cts) + m_rr[0] |= Z80DART_RR0_CTS; else - ch->rr[0] &= ~Z80DART_RR0_CTS; + m_rr[0] &= ~Z80DART_RR0_CTS; - /* trigger interrupt */ - if (ch->wr[1] & Z80DART_WR1_EXT_INT_ENABLE) + // trigger interrupt + if (m_wr[1] & Z80DART_WR1_EXT_INT_ENABLE) { - /* trigger interrupt */ - take_interrupt(device, channel, INT_EXTERNAL); + // trigger interrupt + take_interrupt(INT_EXTERNAL); - /* latch read register 0 */ - ch->rx_rr0_latch = 1; + // latch read register 0 + m_rx_rr0_latch = 1; } } } } -/*------------------------------------------------- - z80dart_ctsa_w - clear to send (channel A) --------------------------------------------------*/ - -WRITE_LINE_DEVICE_HANDLER( z80dart_ctsa_w ) -{ - cts_w(device, Z80DART_CH_A, state); -} -/*------------------------------------------------- - z80dart_ctsb_w - clear to send (channel B) --------------------------------------------------*/ +//------------------------------------------------- +// dcd_w - data carrier detected handler +//------------------------------------------------- -WRITE_LINE_DEVICE_HANDLER( z80dart_ctsb_w ) +void z80dart_device::dart_channel::dcd_w(int state) { - cts_w(device, Z80DART_CH_B, state); -} - -/*------------------------------------------------- - dcd_w - data carrier detected handler --------------------------------------------------*/ - -static void dcd_w(running_device *device, int channel, int state) -{ - z80dart_t *z80dart = get_safe_token(device); - dart_channel *ch = &z80dart->channel[channel]; - - LOG(("Z80DART \"%s\" Channel %c : DCD %u\n", device->tag(), 'A' + channel, state)); + LOG(("Z80DART \"%s\" Channel %c : DCD %u\n", m_device->tag(), 'A' + m_index, state)); - if (ch->dcd != state) + if (m_dcd != state) { - /* enable receiver if in auto enables mode */ + // enable receiver if in auto enables mode if (!state) - if (ch->wr[3] & Z80DART_WR3_AUTO_ENABLES) - ch->wr[3] |= Z80DART_WR3_RX_ENABLE; + if (m_wr[3] & Z80DART_WR3_AUTO_ENABLES) + m_wr[3] |= Z80DART_WR3_RX_ENABLE; - /* set data carrier detect */ - ch->dcd = state; + // set data carrier detect + m_dcd = state; - if (!ch->rx_rr0_latch) + if (!m_rx_rr0_latch) { - if (ch->dcd) - ch->rr[0] |= Z80DART_RR0_DCD; + if (m_dcd) + m_rr[0] |= Z80DART_RR0_DCD; else - ch->rr[0] &= ~Z80DART_RR0_DCD; + m_rr[0] &= ~Z80DART_RR0_DCD; - if (ch->wr[1] & Z80DART_WR1_EXT_INT_ENABLE) + if (m_wr[1] & Z80DART_WR1_EXT_INT_ENABLE) { - /* trigger interrupt */ - take_interrupt(device, channel, INT_EXTERNAL); + // trigger interrupt + take_interrupt(INT_EXTERNAL); - /* latch read register 0 */ - ch->rx_rr0_latch = 1; + // latch read register 0 + m_rx_rr0_latch = 1; } } } } -/*------------------------------------------------- - z80dart_dcda_w - data carrier detected - (channel A) --------------------------------------------------*/ - -WRITE_LINE_DEVICE_HANDLER( z80dart_dcda_w ) -{ - dcd_w(device, Z80DART_CH_A, state); -} - -/*------------------------------------------------- - z80dart_dcdb_w - data carrier detected - (channel B) --------------------------------------------------*/ -WRITE_LINE_DEVICE_HANDLER( z80dart_dcdb_w ) -{ - dcd_w(device, Z80DART_CH_B, state); -} - -/*------------------------------------------------- - ri_w - ring indicator handler --------------------------------------------------*/ +//------------------------------------------------- +// ri_w - ring indicator handler +//------------------------------------------------- -static void ri_w(running_device *device, int channel, int state) +void z80dart_device::dart_channel::ri_w(int state) { - z80dart_t *z80dart = get_safe_token(device); - dart_channel *ch = &z80dart->channel[channel]; + LOG(("Z80DART \"%s\" Channel %c : RI %u\n", m_device->tag(), 'A' + m_index, state)); - LOG(("Z80DART \"%s\" Channel %c : RI %u\n", device->tag(), 'A' + channel, state)); - - if (ch->ri != state) + if (m_ri != state) { - /* set ring indicator state */ - ch->ri = state; + // set ring indicator state + m_ri = state; - if (!ch->rx_rr0_latch) + if (!m_rx_rr0_latch) { - if (ch->ri) - ch->rr[0] |= Z80DART_RR0_RI; + if (m_ri) + m_rr[0] |= Z80DART_RR0_RI; else - ch->rr[0] &= ~Z80DART_RR0_RI; + m_rr[0] &= ~Z80DART_RR0_RI; - if (ch->wr[1] & Z80DART_WR1_EXT_INT_ENABLE) + if (m_wr[1] & Z80DART_WR1_EXT_INT_ENABLE) { - /* trigger interrupt */ - take_interrupt(device, channel, INT_EXTERNAL); + // trigger interrupt + take_interrupt(INT_EXTERNAL); - /* latch read register 0 */ - ch->rx_rr0_latch = 1; + // latch read register 0 + m_rx_rr0_latch = 1; } } } } -/*------------------------------------------------- - z80dart_ria_w - ring indicator (channel A) --------------------------------------------------*/ - -WRITE_LINE_DEVICE_HANDLER( z80dart_ria_w ) -{ - ri_w(device, Z80DART_CH_A, state); -} - -/*------------------------------------------------- - z80dart_rib_w - ring indicator (channel B) --------------------------------------------------*/ - -WRITE_LINE_DEVICE_HANDLER( z80dart_rib_w ) -{ - ri_w(device, Z80DART_CH_B, state); -} -/*------------------------------------------------- - z80dart_rxca_w - receive clock (channel A) --------------------------------------------------*/ +//------------------------------------------------- +// rx_w - receive clock +//------------------------------------------------- -WRITE_LINE_DEVICE_HANDLER( z80dart_rxca_w ) +void z80dart_device::dart_channel::rx_w(int state) { - z80dart_t *z80dart = get_safe_token(device); - dart_channel *ch = &z80dart->channel[Z80DART_CH_A]; - - int clocks = get_clock_mode(ch); + int clocks = get_clock_mode(); if (!state) return; - LOG(("Z80DART \"%s\" Channel A : Receiver Clock Pulse\n", device->tag())); + LOG(("Z80DART \"%s\" Channel %c : Receiver Clock Pulse\n", m_device->tag(), m_index + 'A')); - ch->rx_clock++; - - if (ch->rx_clock == clocks) + m_rx_clock++; + if (m_rx_clock == clocks) { - ch->rx_clock = 0; - - /* receive data */ - receive(device, Z80DART_CH_A); + m_rx_clock = 0; + receive(); } } -/*------------------------------------------------- - z80dart_txca_w - transmit clock (channel A) --------------------------------------------------*/ - -WRITE_LINE_DEVICE_HANDLER( z80dart_txca_w ) -{ - z80dart_t *z80dart = get_safe_token(device); - dart_channel *ch = &z80dart->channel[Z80DART_CH_A]; - - int clocks = get_clock_mode(ch); - - if (!state) return; - LOG(("Z80DART \"%s\" Channel A : Transmitter Clock Pulse\n", device->tag())); +//------------------------------------------------- +// tx_w - transmit clock +//------------------------------------------------- - ch->tx_clock++; - - if (ch->tx_clock == clocks) - { - ch->tx_clock = 0; - - /* transmit data */ - transmit(device, Z80DART_CH_A); - } -} - -/*------------------------------------------------- - z80dart_rxtxcb_w - receive/transmit clock - (channel B) --------------------------------------------------*/ - -WRITE_LINE_DEVICE_HANDLER( z80dart_rxtxcb_w ) +void z80dart_device::dart_channel::tx_w(int state) { - z80dart_t *z80dart = get_safe_token(device); - dart_channel *ch = &z80dart->channel[Z80DART_CH_B]; - - int clocks = get_clock_mode(ch); + int clocks = get_clock_mode(); if (!state) return; - LOG(("Z80DART \"%s\" Channel A : Receiver/Transmitter Clock Pulse\n", device->tag())); - - ch->rx_clock++; - ch->tx_clock++; + LOG(("Z80DART \"%s\" Channel %c : Transmitter Clock Pulse\n", m_device->tag(), m_index + 'A')); - if (ch->rx_clock == clocks) + m_tx_clock++; + if (m_tx_clock == clocks) { - ch->rx_clock = 0; - ch->tx_clock = 0; - - /* receive and transmit data */ - receive(device, Z80DART_CH_B); - transmit(device, Z80DART_CH_B); + m_tx_clock = 0; + transmit(); } } -/*------------------------------------------------- - TIMER_CALLBACK( rxca_tick ) --------------------------------------------------*/ -static TIMER_CALLBACK( rxca_tick ) -{ - z80dart_rxca_w((running_device *)ptr, 1); -} -/*------------------------------------------------- - TIMER_CALLBACK( txca_tick ) --------------------------------------------------*/ +//************************************************************************** +// GLOBAL STUBS +//************************************************************************** -static TIMER_CALLBACK( txca_tick ) -{ - z80dart_txca_w((running_device *)ptr, 1); -} - -/*------------------------------------------------- - TIMER_CALLBACK( rxtxcb_tick ) --------------------------------------------------*/ - -static TIMER_CALLBACK( rxtxcb_tick ) -{ - z80dart_rxtxcb_w((running_device *)ptr, 1); -} +READ8_DEVICE_HANDLER( z80dart_c_r ) { return downcast<z80dart_device *>(device)->control_read(offset & 1); } +READ8_DEVICE_HANDLER( z80dart_d_r ) { return downcast<z80dart_device *>(device)->data_read(offset & 1); } -/*------------------------------------------------- - z80dart_irq_state - get interrupt status --------------------------------------------------*/ +WRITE8_DEVICE_HANDLER( z80dart_c_w ) { downcast<z80dart_device *>(device)->control_write(offset & 1, data); } +WRITE8_DEVICE_HANDLER( z80dart_d_w ) { downcast<z80dart_device *>(device)->data_write(offset & 1, data); } -static int z80dart_irq_state(running_device *device) -{ - z80dart_t *z80dart = get_safe_token( device ); - int state = 0; - int i; +WRITE_LINE_DEVICE_HANDLER( z80dart_ctsa_w ) { downcast<z80dart_device *>(device)->cts_w(Z80DART_CH_A, state); } +WRITE_LINE_DEVICE_HANDLER( z80dart_ctsb_w ) { downcast<z80dart_device *>(device)->cts_w(Z80DART_CH_B, state); } +WRITE_LINE_DEVICE_HANDLER( z80dart_dcda_w ) { downcast<z80dart_device *>(device)->dcd_w(Z80DART_CH_A, state); } +WRITE_LINE_DEVICE_HANDLER( z80dart_dcdb_w ) { downcast<z80dart_device *>(device)->dcd_w(Z80DART_CH_B, state); } +WRITE_LINE_DEVICE_HANDLER( z80dart_ria_w ) { downcast<z80dart_device *>(device)->ri_w(Z80DART_CH_A, state); } +WRITE_LINE_DEVICE_HANDLER( z80dart_rib_w ) { downcast<z80dart_device *>(device)->ri_w(Z80DART_CH_B, state); } - LOG(("Z80DART \"%s\" : Interrupt State B:%d%d%d%d A:%d%d%d%d\n", device->tag(), - z80dart->int_state[0], z80dart->int_state[1], z80dart->int_state[2], z80dart->int_state[3], - z80dart->int_state[4], z80dart->int_state[5], z80dart->int_state[6], z80dart->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 (z80dart->int_state[i] & Z80_DAISY_IEO) - { - state |= Z80_DAISY_IEO; - break; - } - state |= z80dart->int_state[i]; - } - - LOG(("Z80DART \"%s\" : Interrupt State %u\n", device->tag(), state)); - - return state; -} - -/*------------------------------------------------- - z80dart_irq_ack - interrupt acknowledge --------------------------------------------------*/ - -static int z80dart_irq_ack(running_device *device) -{ - z80dart_t *z80dart = get_safe_token( device ); - int i; - - LOG(("Z80DART \"%s\" Interrupt Acknowledge\n", device->tag())); - - /* loop over all interrupt sources */ - for (i = 0; i < 8; i++) - { - /* find the first channel with an interrupt requested */ - if (z80dart->int_state[i] & Z80_DAISY_INT) - { - /* clear interrupt, switch to the IEO state, and update the IRQs */ - z80dart->int_state[i] = Z80_DAISY_IEO; - z80dart->channel[Z80DART_CH_A].rr[0] &= ~Z80DART_RR0_INTERRUPT_PENDING; - check_interrupts(device); - - LOG(("Z80DART \"%s\" : Interrupt Acknowledge Vector %02x\n", device->tag(), z80dart->channel[Z80DART_CH_B].rr[2])); - - return z80dart->channel[Z80DART_CH_B].rr[2]; - } - } - - logerror("z80dart_irq_ack: failed to find an interrupt to ack!\n"); - - return z80dart->channel[Z80DART_CH_B].rr[2]; -} - -/*------------------------------------------------- - z80dart_irq_reti - return from interrupt --------------------------------------------------*/ - -static void z80dart_irq_reti(running_device *device) -{ - z80dart_t *z80dart = get_safe_token( device ); - int i; - - LOG(("Z80DART \"%s\" Return from Interrupt\n", device->tag())); - - /* loop over all interrupt sources */ - for (i = 0; i < 8; i++) - { - /* find the first channel with an IEO pending */ - if (z80dart->int_state[i] & Z80_DAISY_IEO) - { - /* clear the IEO state and update the IRQs */ - z80dart->int_state[i] &= ~Z80_DAISY_IEO; - check_interrupts(device); - return; - } - } - - logerror("z80dart_irq_reti: failed to find an interrupt to clear IEO on!\n"); -} - -/*------------------------------------------------- - z80dart_cd_ba_r - register read --------------------------------------------------*/ +WRITE_LINE_DEVICE_HANDLER( z80dart_rxca_w ) { downcast<z80dart_device *>(device)->rx_w(Z80DART_CH_A, state); } +WRITE_LINE_DEVICE_HANDLER( z80dart_txca_w ) { downcast<z80dart_device *>(device)->tx_w(Z80DART_CH_A, state); } +WRITE_LINE_DEVICE_HANDLER( z80dart_rxtxcb_w ) { downcast<z80dart_device *>(device)->rx_w(Z80DART_CH_B, state); downcast<z80dart_device *>(device)->tx_w(Z80DART_CH_B, state); } READ8_DEVICE_HANDLER( z80dart_cd_ba_r ) { return (offset & 2) ? z80dart_c_r(device, offset & 1) : z80dart_d_r(device, offset & 1); } -/*------------------------------------------------- - z80dart_cd_ba_w - register write --------------------------------------------------*/ - WRITE8_DEVICE_HANDLER( z80dart_cd_ba_w ) { if (offset & 2) @@ -1353,10 +1388,6 @@ WRITE8_DEVICE_HANDLER( z80dart_cd_ba_w ) z80dart_d_w(device, offset & 1, data); } -/*------------------------------------------------- - z80dart_ba_cd_r - register read --------------------------------------------------*/ - READ8_DEVICE_HANDLER( z80dart_ba_cd_r ) { int channel = BIT(offset, 1); @@ -1364,10 +1395,6 @@ READ8_DEVICE_HANDLER( z80dart_ba_cd_r ) return (offset & 1) ? z80dart_c_r(device, channel) : z80dart_d_r(device, channel); } -/*------------------------------------------------- - z80dart_ba_cd_w - register write --------------------------------------------------*/ - WRITE8_DEVICE_HANDLER( z80dart_ba_cd_w ) { int channel = BIT(offset, 1); @@ -1377,128 +1404,3 @@ WRITE8_DEVICE_HANDLER( z80dart_ba_cd_w ) else z80dart_d_w(device, channel, data); } - -/*------------------------------------------------- - DEVICE_START( z80dart ) --------------------------------------------------*/ - -static DEVICE_START( z80dart ) -{ - z80dart_t *z80dart = get_safe_token(device); - const z80dart_interface *intf = (const z80dart_interface *)device->baseconfig().static_config; - int channel; - - /* resolve callbacks */ - devcb_resolve_read_line(&z80dart->channel[Z80DART_CH_A].in_rxd_func, &intf->in_rxda_func, device); - devcb_resolve_write_line(&z80dart->channel[Z80DART_CH_A].out_txd_func, &intf->out_txda_func, device); - devcb_resolve_write_line(&z80dart->channel[Z80DART_CH_A].out_dtr_func, &intf->out_dtra_func, device); - devcb_resolve_write_line(&z80dart->channel[Z80DART_CH_A].out_rts_func, &intf->out_rtsa_func, device); - devcb_resolve_write_line(&z80dart->channel[Z80DART_CH_A].out_wrdy_func, &intf->out_wrdya_func, device); - devcb_resolve_read_line(&z80dart->channel[Z80DART_CH_B].in_rxd_func, &intf->in_rxdb_func, device); - devcb_resolve_write_line(&z80dart->channel[Z80DART_CH_B].out_txd_func, &intf->out_txdb_func, device); - devcb_resolve_write_line(&z80dart->channel[Z80DART_CH_B].out_dtr_func, &intf->out_dtrb_func, device); - devcb_resolve_write_line(&z80dart->channel[Z80DART_CH_B].out_rts_func, &intf->out_rtsb_func, device); - devcb_resolve_write_line(&z80dart->channel[Z80DART_CH_B].out_wrdy_func, &intf->out_wrdyb_func, device); - devcb_resolve_write_line(&z80dart->out_int_func, &intf->out_int_func, device); - - if (intf->rx_clock_a) - { - /* allocate channel A receive timer */ - z80dart->rxca_timer = timer_alloc(device->machine, rxca_tick, (void *)device); - timer_adjust_periodic(z80dart->rxca_timer, attotime_zero, 0, ATTOTIME_IN_HZ(intf->rx_clock_a)); - } - - if (intf->tx_clock_a) - { - /* allocate channel A transmit timer */ - z80dart->txca_timer = timer_alloc(device->machine, txca_tick, (void *)device); - timer_adjust_periodic(z80dart->txca_timer, attotime_zero, 0, ATTOTIME_IN_HZ(intf->tx_clock_a)); - } - - if (intf->rx_tx_clock_b) - { - /* allocate channel B receive/transmit timer */ - z80dart->rxtxcb_timer = timer_alloc(device->machine, rxtxcb_tick, (void *)device); - timer_adjust_periodic(z80dart->rxtxcb_timer, attotime_zero, 0, ATTOTIME_IN_HZ(intf->rx_tx_clock_b)); - } - - /* register for state saving */ - for (channel = Z80DART_CH_A; channel <= Z80DART_CH_B; channel++) - { - state_save_register_device_item_array(device, channel, z80dart->channel[channel].rr); - state_save_register_device_item_array(device, channel, z80dart->channel[channel].wr); - state_save_register_device_item_array(device, channel, z80dart->channel[channel].rx_data_fifo); - state_save_register_device_item_array(device, channel, z80dart->channel[channel].rx_error_fifo); - state_save_register_device_item(device, channel, z80dart->channel[channel].rx_shift); - state_save_register_device_item(device, channel, z80dart->channel[channel].rx_error); - state_save_register_device_item(device, channel, z80dart->channel[channel].rx_fifo); - state_save_register_device_item(device, channel, z80dart->channel[channel].rx_clock); - state_save_register_device_item(device, channel, z80dart->channel[channel].rx_state); - state_save_register_device_item(device, channel, z80dart->channel[channel].rx_bits); - state_save_register_device_item(device, channel, z80dart->channel[channel].rx_first); - state_save_register_device_item(device, channel, z80dart->channel[channel].rx_parity); - state_save_register_device_item(device, channel, z80dart->channel[channel].rx_break); - state_save_register_device_item(device, channel, z80dart->channel[channel].rx_rr0_latch); - state_save_register_device_item(device, channel, z80dart->channel[channel].ri); - state_save_register_device_item(device, channel, z80dart->channel[channel].cts); - state_save_register_device_item(device, channel, z80dart->channel[channel].dcd); - state_save_register_device_item(device, channel, z80dart->channel[channel].tx_data); - state_save_register_device_item(device, channel, z80dart->channel[channel].tx_shift); - state_save_register_device_item(device, channel, z80dart->channel[channel].tx_clock); - state_save_register_device_item(device, channel, z80dart->channel[channel].tx_state); - state_save_register_device_item(device, channel, z80dart->channel[channel].tx_bits); - state_save_register_device_item(device, channel, z80dart->channel[channel].tx_parity); - state_save_register_device_item(device, channel, z80dart->channel[channel].dtr); - state_save_register_device_item(device, channel, z80dart->channel[channel].rts); - } - - state_save_register_device_item_array(device, 0, z80dart->int_state); -} - -/*------------------------------------------------- - DEVICE_RESET( z80dart ) --------------------------------------------------*/ - -static DEVICE_RESET( z80dart ) -{ - int channel; - - LOG(("Z80DART \"%s\" Reset\n", device->tag())); - - for (channel = Z80DART_CH_A; channel <= Z80DART_CH_B; channel++) - { - reset_channel(device, channel); - } - - check_interrupts(device); -} - -/*------------------------------------------------- - DEVICE_GET_INFO( z80dart ) --------------------------------------------------*/ - -DEVICE_GET_INFO( z80dart ) -{ - switch (state) - { - /* --- the following bits of info are returned as 64-bit signed integers --- */ - case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(z80dart_t); break; - case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break; - case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(z80dart); break; - case DEVINFO_FCT_STOP: /* Nothing */ break; - case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(z80dart); break; - case DEVINFO_FCT_IRQ_STATE: info->f = (genf *)z80dart_irq_state; break; - case DEVINFO_FCT_IRQ_ACK: info->f = (genf *)z80dart_irq_ack; break; - case DEVINFO_FCT_IRQ_RETI: info->f = (genf *)z80dart_irq_reti; break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case DEVINFO_STR_NAME: strcpy(info->s, "Zilog Z80 DART"); break; - case DEVINFO_STR_FAMILY: strcpy(info->s, "Z80"); break; - case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break; - case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; - case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright the MESS Team"); break; - } -} |