summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine/z80dart.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/machine/z80dart.c')
-rw-r--r--src/emu/machine/z80dart.c1754
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;
- }
-}