Converted Z80 SIO to device. Updated drivers accordingly.

This commit is contained in:
Aaron Giles 2008-09-30 05:29:59 +00:00
parent b91c8e11e2
commit e3dd5224c0
8 changed files with 243 additions and 206 deletions

View File

@ -566,7 +566,7 @@ static DEVICE_START( z80pio )
} }
void z80pio_reset( const device_config *device ) static DEVICE_RESET( z80pio )
{ {
z80pio_t *z80pio = get_safe_token( device ); z80pio_t *z80pio = get_safe_token( device );
int i; int i;
@ -586,12 +586,6 @@ void z80pio_reset( const device_config *device )
} }
static DEVICE_RESET( z80pio )
{
z80pio_reset( device );
}
static DEVICE_SET_INFO( z80pio ) static DEVICE_SET_INFO( z80pio )
{ {
switch (state) switch (state)

View File

@ -42,13 +42,6 @@ struct _z80pio_interface
/***************************************************************************
INITIALIZATION
***************************************************************************/
void z80pio_reset( const device_config *device );
/*************************************************************************** /***************************************************************************
CONTROL REGISTER READ/WRITE CONTROL REGISTER READ/WRITE
***************************************************************************/ ***************************************************************************/

View File

@ -167,7 +167,7 @@ struct _sio_channel
int inbuf; /* input buffer */ int inbuf; /* input buffer */
int outbuf; /* output buffer */ int outbuf; /* output buffer */
UINT8 int_on_next_rx; /* interrupt on next rx? */ UINT8 int_on_next_rx; /* interrupt on next rx? */
emu_timer *receive_timer; /* timer to clock data in */ emu_timer * receive_timer; /* timer to clock data in */
UINT8 receive_buffer[16]; /* buffer for incoming data */ UINT8 receive_buffer[16]; /* buffer for incoming data */
UINT8 receive_inptr; /* index of data coming in */ UINT8 receive_inptr; /* index of data coming in */
UINT8 receive_outptr; /* index of data going out */ UINT8 receive_outptr; /* index of data going out */
@ -179,13 +179,14 @@ struct _z80sio
{ {
sio_channel chan[2]; /* 2 channels */ sio_channel chan[2]; /* 2 channels */
UINT8 int_state[8]; /* interrupt states */ UINT8 int_state[8]; /* interrupt states */
UINT32 clock; /* clock value */
void (*irq_cb)(running_machine *machine, int state); void (*irq_cb)(const device_config *device, int state);
write8_machine_func dtr_changed_cb; write8_device_func dtr_changed_cb;
write8_machine_func rts_changed_cb; write8_device_func rts_changed_cb;
write8_machine_func break_changed_cb; write8_device_func break_changed_cb;
write8_machine_func transmit_cb; write8_device_func transmit_cb;
int (*receive_poll_cb)(int which); int (*receive_poll_cb)(const device_config *device, int channel);
}; };
@ -198,13 +199,6 @@ static TIMER_CALLBACK( serial_callback );
/***************************************************************************
GLOBAL VARIABLES
***************************************************************************/
static z80sio sios[MAX_SIO];
/* /*
Interrupt priorities: Interrupt priorities:
@ -257,15 +251,35 @@ static z80sio sios[MAX_SIO];
*/ */
/***************************************************************************
FUNCTION PROTOTYPES
***************************************************************************/
static int z80sio_irq_state(const device_config *device);
static int z80sio_irq_ack(const device_config *device);
static void z80sio_irq_reti(const device_config *device);
/*************************************************************************** /***************************************************************************
INLINE FUNCTIONS INLINE FUNCTIONS
***************************************************************************/ ***************************************************************************/
INLINE void interrupt_check(running_machine *machine, z80sio *sio) INLINE z80sio *get_safe_token(const device_config *device)
{
assert(device != NULL);
assert(device->token != NULL);
assert(device->type == Z80SIO);
return (z80sio *)device->token;
}
INLINE void interrupt_check(const device_config *device)
{ {
/* if we have a callback, update it with the current state */ /* if we have a callback, update it with the current state */
z80sio *sio = get_safe_token(device);
if (sio->irq_cb != NULL) if (sio->irq_cb != NULL)
(*sio->irq_cb)(machine, (z80sio_irq_state(sio - sios) & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE); (*sio->irq_cb)(device, (z80sio_irq_state(device) & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE);
} }
@ -281,38 +295,13 @@ INLINE attotime compute_time_per_character(z80sio *sio, int which)
INITIALIZATION/CONFIGURATION INITIALIZATION/CONFIGURATION
***************************************************************************/ ***************************************************************************/
/*-------------------------------------------------
z80sio_init - initialize a single SIO chip
-------------------------------------------------*/
void z80sio_init(int which, z80sio_interface *intf)
{
z80sio *sio = sios + which;
assert(which < MAX_SIO);
memset(sio, 0, sizeof(*sio));
sio->chan[0].receive_timer = timer_alloc(serial_callback, NULL);
sio->chan[1].receive_timer = timer_alloc(serial_callback, NULL);
sio->irq_cb = intf->irq_cb;
sio->dtr_changed_cb = intf->dtr_changed_cb;
sio->rts_changed_cb = intf->rts_changed_cb;
sio->break_changed_cb = intf->break_changed_cb;
sio->transmit_cb = intf->transmit_cb;
sio->receive_poll_cb = intf->receive_poll_cb;
z80sio_reset(which);
}
/*------------------------------------------------- /*-------------------------------------------------
reset_channel - reset a single SIO channel reset_channel - reset a single SIO channel
-------------------------------------------------*/ -------------------------------------------------*/
static void reset_channel(running_machine *machine, z80sio *sio, int ch) static void reset_channel(const device_config *device, int ch)
{ {
z80sio *sio = get_safe_token(device);
attotime tpc = compute_time_per_character(sio, ch); attotime tpc = compute_time_per_character(sio, ch);
sio_channel *chan = &sio->chan[ch]; sio_channel *chan = &sio->chan[ch];
@ -327,27 +316,10 @@ static void reset_channel(running_machine *machine, z80sio *sio, int ch)
sio->int_state[2 + 4*ch] = 0; sio->int_state[2 + 4*ch] = 0;
sio->int_state[3 + 4*ch] = 0; sio->int_state[3 + 4*ch] = 0;
interrupt_check(machine, sio); interrupt_check(device);
/* start the receive timer running */ /* start the receive timer running */
timer_adjust_periodic(chan->receive_timer, tpc, ((sio - sios) << 1) | ch, tpc); timer_adjust_periodic(chan->receive_timer, tpc, ch, tpc);
}
/*-------------------------------------------------
z80sio_reset - reset a single SIO chip
-------------------------------------------------*/
void z80sio_reset(int which)
{
z80sio *sio = sios + which;
int ch;
assert(which < MAX_SIO);
/* loop over channels */
for (ch = 0; ch < 2; ch++)
reset_channel(Machine, sio, ch);
} }
@ -360,9 +332,10 @@ void z80sio_reset(int which)
z80sio_c_w - write to a control register z80sio_c_w - write to a control register
-------------------------------------------------*/ -------------------------------------------------*/
void z80sio_c_w(running_machine *machine, int which, int ch, UINT8 data) WRITE8_DEVICE_HANDLER( z80sio_c_w )
{ {
z80sio *sio = sios + which; z80sio *sio = get_safe_token(device);
int ch = offset & 1;
sio_channel *chan = &sio->chan[ch]; sio_channel *chan = &sio->chan[ch];
int reg = chan->regs[0] & 7; int reg = chan->regs[0] & 7;
UINT8 old = chan->regs[reg]; UINT8 old = chan->regs[reg];
@ -386,44 +359,44 @@ void z80sio_c_w(running_machine *machine, int which, int ch, UINT8 data)
{ {
case SIO_WR0_COMMAND_CH_RESET: case SIO_WR0_COMMAND_CH_RESET:
VPRINTF(("%04X:SIO reset channel %c\n", activecpu_get_pc(), 'A' + ch)); VPRINTF(("%04X:SIO reset channel %c\n", activecpu_get_pc(), 'A' + ch));
reset_channel(machine, sio, ch); reset_channel(device, ch);
break; break;
case SIO_WR0_COMMAND_RES_STATUS_INT: case SIO_WR0_COMMAND_RES_STATUS_INT:
sio->int_state[INT_CHA_STATUS - 4*ch] &= ~Z80_DAISY_INT; sio->int_state[INT_CHA_STATUS - 4*ch] &= ~Z80_DAISY_INT;
interrupt_check(machine, sio); interrupt_check(device);
break; break;
case SIO_WR0_COMMAND_ENA_RX_INT: case SIO_WR0_COMMAND_ENA_RX_INT:
chan->int_on_next_rx = TRUE; chan->int_on_next_rx = TRUE;
interrupt_check(machine, sio); interrupt_check(device);
break; break;
case SIO_WR0_COMMAND_RES_TX_INT: case SIO_WR0_COMMAND_RES_TX_INT:
sio->int_state[INT_CHA_TRANSMIT - 4*ch] &= ~Z80_DAISY_INT; sio->int_state[INT_CHA_TRANSMIT - 4*ch] &= ~Z80_DAISY_INT;
interrupt_check(machine, sio); interrupt_check(device);
break; break;
case SIO_WR0_COMMAND_RES_ERROR: case SIO_WR0_COMMAND_RES_ERROR:
sio->int_state[INT_CHA_ERROR - 4*ch] &= ~Z80_DAISY_INT; sio->int_state[INT_CHA_ERROR - 4*ch] &= ~Z80_DAISY_INT;
interrupt_check(machine, sio); interrupt_check(device);
break; break;
} }
break; break;
/* SIO write register 1 */ /* SIO write register 1 */
case 1: case 1:
interrupt_check(machine, sio); interrupt_check(device);
break; break;
/* SIO write register 5 */ /* SIO write register 5 */
case 5: case 5:
if (((old ^ data) & SIO_WR5_DTR) && sio->dtr_changed_cb) if (((old ^ data) & SIO_WR5_DTR) && sio->dtr_changed_cb)
(*sio->dtr_changed_cb)(machine, ch, (data & SIO_WR5_DTR) != 0); (*sio->dtr_changed_cb)(device, ch, (data & SIO_WR5_DTR) != 0);
if (((old ^ data) & SIO_WR5_SEND_BREAK) && sio->break_changed_cb) if (((old ^ data) & SIO_WR5_SEND_BREAK) && sio->break_changed_cb)
(*sio->break_changed_cb)(machine, ch, (data & SIO_WR5_SEND_BREAK) != 0); (*sio->break_changed_cb)(device, ch, (data & SIO_WR5_SEND_BREAK) != 0);
if (((old ^ data) & SIO_WR5_RTS) && sio->rts_changed_cb) if (((old ^ data) & SIO_WR5_RTS) && sio->rts_changed_cb)
(*sio->rts_changed_cb)(machine, ch, (data & SIO_WR5_RTS) != 0); (*sio->rts_changed_cb)(device, ch, (data & SIO_WR5_RTS) != 0);
break; break;
} }
} }
@ -433,9 +406,10 @@ void z80sio_c_w(running_machine *machine, int which, int ch, UINT8 data)
z80sio_c_r - read from a control register z80sio_c_r - read from a control register
-------------------------------------------------*/ -------------------------------------------------*/
UINT8 z80sio_c_r(int which, int ch) READ8_DEVICE_HANDLER( z80sio_c_r )
{ {
z80sio *sio = sios + which; z80sio *sio = get_safe_token(device);
int ch = offset & 1;
sio_channel *chan = &sio->chan[ch]; sio_channel *chan = &sio->chan[ch];
int reg = chan->regs[0] & 7; int reg = chan->regs[0] & 7;
UINT8 result = chan->status[reg]; UINT8 result = chan->status[reg];
@ -446,7 +420,7 @@ UINT8 z80sio_c_r(int which, int ch)
/* SIO read register 0 */ /* SIO read register 0 */
case 0: case 0:
result &= ~SIO_RR0_INT_PENDING; result &= ~SIO_RR0_INT_PENDING;
if (z80sio_irq_state(which) & Z80_DAISY_INT) if (z80sio_irq_state(device) & Z80_DAISY_INT)
result |= SIO_RR0_INT_PENDING; result |= SIO_RR0_INT_PENDING;
break; break;
} }
@ -467,9 +441,10 @@ UINT8 z80sio_c_r(int which, int ch)
z80sio_d_w - write to a data register z80sio_d_w - write to a data register
-------------------------------------------------*/ -------------------------------------------------*/
void z80sio_d_w(running_machine *machine, int which, int ch, UINT8 data) WRITE8_DEVICE_HANDLER( z80sio_d_w )
{ {
z80sio *sio = sios + which; z80sio *sio = get_safe_token(device);
int ch = offset & 1;
sio_channel *chan = &sio->chan[ch]; sio_channel *chan = &sio->chan[ch];
VPRINTF(("%04X:sio_data_w(%c) = %02X\n", activecpu_get_pc(), 'A' + ch, data)); VPRINTF(("%04X:sio_data_w(%c) = %02X\n", activecpu_get_pc(), 'A' + ch, data));
@ -483,7 +458,7 @@ void z80sio_d_w(running_machine *machine, int which, int ch, UINT8 data)
/* reset the transmit interrupt */ /* reset the transmit interrupt */
sio->int_state[INT_CHA_TRANSMIT - 4*ch] &= ~Z80_DAISY_INT; sio->int_state[INT_CHA_TRANSMIT - 4*ch] &= ~Z80_DAISY_INT;
interrupt_check(machine, sio); interrupt_check(device);
/* stash the character */ /* stash the character */
chan->outbuf = data; chan->outbuf = data;
@ -494,9 +469,10 @@ void z80sio_d_w(running_machine *machine, int which, int ch, UINT8 data)
z80sio_d_r - read from a data register z80sio_d_r - read from a data register
-------------------------------------------------*/ -------------------------------------------------*/
UINT8 z80sio_d_r(running_machine *machine, int which, int ch) READ8_DEVICE_HANDLER( z80sio_d_r )
{ {
z80sio *sio = sios + which; z80sio *sio = get_safe_token(device);
int ch = offset & 1;
sio_channel *chan = &sio->chan[ch]; sio_channel *chan = &sio->chan[ch];
/* update the status register */ /* update the status register */
@ -504,7 +480,7 @@ UINT8 z80sio_d_r(running_machine *machine, int which, int ch)
/* reset the receive interrupt */ /* reset the receive interrupt */
sio->int_state[INT_CHA_RECEIVE - 4*ch] &= ~Z80_DAISY_INT; sio->int_state[INT_CHA_RECEIVE - 4*ch] &= ~Z80_DAISY_INT;
interrupt_check(machine, sio); interrupt_check(device);
VPRINTF(("%04X:sio_data_r(%c) = %02X\n", activecpu_get_pc(), 'A' + ch, chan->inbuf)); VPRINTF(("%04X:sio_data_r(%c) = %02X\n", activecpu_get_pc(), 'A' + ch, chan->inbuf));
@ -522,10 +498,10 @@ UINT8 z80sio_d_r(running_machine *machine, int which, int ch)
line line
-------------------------------------------------*/ -------------------------------------------------*/
int z80sio_get_dtr(int which, int ch) READ8_DEVICE_HANDLER( z80sio_get_dtr )
{ {
z80sio *sio = sios + which; z80sio *sio = get_safe_token(device);
sio_channel *chan = &sio->chan[ch]; sio_channel *chan = &sio->chan[offset & 1];
return ((chan->regs[5] & SIO_WR5_DTR) != 0); return ((chan->regs[5] & SIO_WR5_DTR) != 0);
} }
@ -535,10 +511,10 @@ int z80sio_get_dtr(int which, int ch)
line line
-------------------------------------------------*/ -------------------------------------------------*/
int z80sio_get_rts(int which, int ch) READ8_DEVICE_HANDLER( z80sio_get_rts )
{ {
z80sio *sio = sios + which; z80sio *sio = get_safe_token(device);
sio_channel *chan = &sio->chan[ch]; sio_channel *chan = &sio->chan[offset & 1];
return ((chan->regs[5] & SIO_WR5_RTS) != 0); return ((chan->regs[5] & SIO_WR5_RTS) != 0);
} }
@ -550,7 +526,8 @@ int z80sio_get_rts(int which, int ch)
static TIMER_CALLBACK( change_input_line ) static TIMER_CALLBACK( change_input_line )
{ {
z80sio *sio = sios + ((param >> 1) & 0x3f); const device_config *device = ptr;
z80sio *sio = get_safe_token(device);
sio_channel *chan = &sio->chan[param & 1]; sio_channel *chan = &sio->chan[param & 1];
UINT8 line = (param >> 8) & 0xff; UINT8 line = (param >> 8) & 0xff;
int state = (param >> 7) & 1; int state = (param >> 7) & 1;
@ -571,7 +548,7 @@ static TIMER_CALLBACK( change_input_line )
if (((old ^ chan->status[0]) & line) && (chan->regs[1] & SIO_WR1_STATUSINT_ENABLE)) if (((old ^ chan->status[0]) & line) && (chan->regs[1] & SIO_WR1_STATUSINT_ENABLE))
{ {
sio->int_state[INT_CHA_STATUS - 4*ch] |= Z80_DAISY_INT; sio->int_state[INT_CHA_STATUS - 4*ch] |= Z80_DAISY_INT;
interrupt_check(machine, sio); interrupt_check(device);
} }
} }
@ -581,10 +558,11 @@ static TIMER_CALLBACK( change_input_line )
line line
-------------------------------------------------*/ -------------------------------------------------*/
void z80sio_set_cts(int which, int ch, int state) WRITE8_DEVICE_HANDLER( z80sio_set_cts )
{ {
/* operate deferred */ /* operate deferred */
timer_call_after_resynch(NULL, (SIO_RR0_CTS << 8) + (state != 0) * 0x80 + which * 2 + ch, change_input_line); void *ptr = (void *)device;
timer_call_after_resynch(ptr, (SIO_RR0_CTS << 8) + (data != 0) * 0x80 + (offset & 1), change_input_line);
} }
@ -593,10 +571,11 @@ void z80sio_set_cts(int which, int ch, int state)
line line
-------------------------------------------------*/ -------------------------------------------------*/
void z80sio_set_dcd(int which, int ch, int state) WRITE8_DEVICE_HANDLER( z80sio_set_dcd )
{ {
/* operate deferred */ /* operate deferred */
timer_call_after_resynch(NULL, (SIO_RR0_DCD << 8) + (state != 0) * 0x80 + which * 2 + ch, change_input_line); void *ptr = (void *)device;
timer_call_after_resynch(ptr, (SIO_RR0_DCD << 8) + (data != 0) * 0x80 + (offset & 1), change_input_line);
} }
@ -605,10 +584,10 @@ void z80sio_set_dcd(int which, int ch, int state)
input lines input lines
-------------------------------------------------*/ -------------------------------------------------*/
void z80sio_receive_data(int which, int ch, UINT8 data) WRITE8_DEVICE_HANDLER( z80sio_receive_data )
{ {
z80sio *sio = sios + which; z80sio *sio = get_safe_token(device);
sio_channel *chan = &sio->chan[ch]; sio_channel *chan = &sio->chan[offset & 1];
int newinptr; int newinptr;
/* put it on the queue */ /* put it on the queue */
@ -630,9 +609,10 @@ void z80sio_receive_data(int which, int ch, UINT8 data)
static TIMER_CALLBACK( serial_callback ) static TIMER_CALLBACK( serial_callback )
{ {
z80sio *sio = sios + (param >> 1); const device_config *device = ptr;
sio_channel *chan = &sio->chan[param & 1]; z80sio *sio = get_safe_token(device);
int ch = param & 1; sio_channel *chan = &sio->chan[param];
int ch = param;
int data = -1; int data = -1;
/* first perform any outstanding transmits */ /* first perform any outstanding transmits */
@ -642,7 +622,7 @@ static TIMER_CALLBACK( serial_callback )
/* actually transmit the character */ /* actually transmit the character */
if (sio->transmit_cb != NULL) if (sio->transmit_cb != NULL)
(*sio->transmit_cb)(machine, ch, chan->outbuf); (*sio->transmit_cb)(device, ch, chan->outbuf);
/* update the status register */ /* update the status register */
chan->status[0] |= SIO_RR0_TX_BUFFER_EMPTY; chan->status[0] |= SIO_RR0_TX_BUFFER_EMPTY;
@ -651,7 +631,7 @@ static TIMER_CALLBACK( serial_callback )
if (chan->regs[1] & SIO_WR1_TXINT_ENABLE) if (chan->regs[1] & SIO_WR1_TXINT_ENABLE)
{ {
sio->int_state[INT_CHA_TRANSMIT - 4*ch] |= Z80_DAISY_INT; sio->int_state[INT_CHA_TRANSMIT - 4*ch] |= Z80_DAISY_INT;
interrupt_check(machine, sio); interrupt_check(device);
} }
/* reset the output buffer */ /* reset the output buffer */
@ -660,7 +640,7 @@ static TIMER_CALLBACK( serial_callback )
/* ask the polling callback if there is data to receive */ /* ask the polling callback if there is data to receive */
if (sio->receive_poll_cb != NULL) if (sio->receive_poll_cb != NULL)
data = (*sio->receive_poll_cb)(ch); data = (*sio->receive_poll_cb)(device, ch);
/* if we have buffered data, pull it */ /* if we have buffered data, pull it */
if (chan->receive_inptr != chan->receive_outptr) if (chan->receive_inptr != chan->receive_outptr)
@ -695,7 +675,7 @@ static TIMER_CALLBACK( serial_callback )
case SIO_WR1_RXINT_ALL_NOPARITY: case SIO_WR1_RXINT_ALL_NOPARITY:
case SIO_WR1_RXINT_ALL_PARITY: case SIO_WR1_RXINT_ALL_PARITY:
sio->int_state[INT_CHA_RECEIVE - 4*ch] |= Z80_DAISY_INT; sio->int_state[INT_CHA_RECEIVE - 4*ch] |= Z80_DAISY_INT;
interrupt_check(machine, sio); interrupt_check(device);
break; break;
} }
chan->int_on_next_rx = FALSE; chan->int_on_next_rx = FALSE;
@ -721,9 +701,9 @@ static const UINT8 int_priority[] =
}; };
int z80sio_irq_state(int which) static int z80sio_irq_state(const device_config *device)
{ {
z80sio *sio = sios + which; z80sio *sio = get_safe_token(device);
int state = 0; int state = 0;
int i; int i;
@ -749,9 +729,9 @@ int z80sio_irq_state(int which)
} }
int z80sio_irq_ack(int which) static int z80sio_irq_ack(const device_config *device)
{ {
z80sio *sio = sios + which; z80sio *sio = get_safe_token(device);
int i; int i;
/* loop over all interrupt sources */ /* loop over all interrupt sources */
@ -766,7 +746,7 @@ int z80sio_irq_ack(int which)
/* clear interrupt, switch to the IEO state, and update the IRQs */ /* clear interrupt, switch to the IEO state, and update the IRQs */
sio->int_state[inum] = Z80_DAISY_IEO; sio->int_state[inum] = Z80_DAISY_IEO;
interrupt_check(Machine, sio); interrupt_check(device);
return sio->chan[1].regs[2] + inum * 2; return sio->chan[1].regs[2] + inum * 2;
} }
} }
@ -776,9 +756,9 @@ int z80sio_irq_ack(int which)
} }
void z80sio_irq_reti(int which) static void z80sio_irq_reti(const device_config *device)
{ {
z80sio *sio = sios + which; z80sio *sio = get_safe_token(device);
int i; int i;
/* loop over all interrupt sources */ /* loop over all interrupt sources */
@ -793,10 +773,86 @@ void z80sio_irq_reti(int which)
/* clear the IEO state and update the IRQs */ /* clear the IEO state and update the IRQs */
sio->int_state[inum] &= ~Z80_DAISY_IEO; sio->int_state[inum] &= ~Z80_DAISY_IEO;
interrupt_check(Machine, sio); interrupt_check(device);
return; return;
} }
} }
logerror("z80sio_irq_reti: failed to find an interrupt to clear IEO on!\n"); logerror("z80sio_irq_reti: failed to find an interrupt to clear IEO on!\n");
} }
static DEVICE_START( z80sio )
{
const z80sio_interface *intf = device->static_config;
z80sio *sio = get_safe_token(device);
void *ptr = (void *)device;
int cpunum = -1;
if (intf->cpu != NULL)
cpunum = mame_find_cpu_index(device->machine, intf->cpu);
if (cpunum != -1)
sio->clock = device->machine->config->cpu[cpunum].clock;
else
sio->clock = intf->baseclock;
sio->chan[0].receive_timer = timer_alloc(serial_callback, ptr);
sio->chan[1].receive_timer = timer_alloc(serial_callback, ptr);
sio->irq_cb = intf->irq_cb;
sio->dtr_changed_cb = intf->dtr_changed_cb;
sio->rts_changed_cb = intf->rts_changed_cb;
sio->break_changed_cb = intf->break_changed_cb;
sio->transmit_cb = intf->transmit_cb;
sio->receive_poll_cb = intf->receive_poll_cb;
return DEVICE_START_OK;
}
static DEVICE_RESET( z80sio )
{
int ch;
/* loop over channels */
for (ch = 0; ch < 2; ch++)
reset_channel(device, ch);
}
static DEVICE_SET_INFO( z80sio )
{
switch (state)
{
/* no parameters to set */
}
}
DEVICE_GET_INFO( z80sio )
{
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(z80sio); 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_SET_INFO: info->set_info = DEVICE_SET_INFO_NAME(z80sio); break;
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(z80sio);break;
case DEVINFO_FCT_STOP: /* Nothing */ break;
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(z80sio);break;
case DEVINFO_FCT_IRQ_STATE: info->f = (genf *)z80sio_irq_state; break;
case DEVINFO_FCT_IRQ_ACK: info->f = (genf *)z80sio_irq_ack; break;
case DEVINFO_FCT_IRQ_RETI: info->f = (genf *)z80sio_irq_reti; break;
/* --- the following bits of info are returned as NULL-terminated strings --- */
case DEVINFO_STR_NAME: info->s = "Zilog Z80 SIO"; break;
case DEVINFO_STR_FAMILY: info->s = "Z80"; break;
case DEVINFO_STR_VERSION: info->s = "1.0"; break;
case DEVINFO_STR_SOURCE_FILE: info->s = __FILE__; break;
case DEVINFO_STR_CREDITS: info->s = "Copyright Nicola Salmoria and the MAME Team"; break;
}
}

View File

@ -7,12 +7,8 @@
***************************************************************************/ ***************************************************************************/
/*************************************************************************** #ifndef __Z80SIO_H__
CONSTANTS #define __Z80SIO_H__
***************************************************************************/
#define MAX_SIO 2
/*************************************************************************** /***************************************************************************
@ -22,23 +18,28 @@
typedef struct _z80sio_interface z80sio_interface; typedef struct _z80sio_interface z80sio_interface;
struct _z80sio_interface struct _z80sio_interface
{ {
const char *cpu; /* CPU whose clock we use for our base */
int baseclock; int baseclock;
void (*irq_cb)(running_machine *machine, int state); void (*irq_cb)(const device_config *device, int state);
write8_machine_func dtr_changed_cb; write8_device_func dtr_changed_cb;
write8_machine_func rts_changed_cb; write8_device_func rts_changed_cb;
write8_machine_func break_changed_cb; write8_device_func break_changed_cb;
write8_machine_func transmit_cb; write8_device_func transmit_cb;
int (*receive_poll_cb)(int which); int (*receive_poll_cb)(const device_config *device, int channel);
}; };
/*************************************************************************** /***************************************************************************
INITIALIZATION/CONFIGURATION DEVICE CONFIGURATION MACROS
***************************************************************************/ ***************************************************************************/
void z80sio_init(int which, z80sio_interface *intf); #define MDRV_Z80SIO_ADD(_tag, _intrf) \
void z80sio_reset(int which); MDRV_DEVICE_ADD(_tag, Z80SIO) \
MDRV_DEVICE_CONFIG(_intrf)
#define MDRV_Z80SIO_REMOVE(_tag) \
MDRV_DEVICE_REMOVE(_tag, Z80SIO)
@ -46,8 +47,8 @@ void z80sio_reset(int which);
CONTROL REGISTER READ/WRITE CONTROL REGISTER READ/WRITE
***************************************************************************/ ***************************************************************************/
void z80sio_c_w(running_machine *machine, int which, int ch, UINT8 data); WRITE8_DEVICE_HANDLER( z80sio_c_w );
UINT8 z80sio_c_r(int which, int ch); READ8_DEVICE_HANDLER( z80sio_c_r );
@ -55,8 +56,8 @@ UINT8 z80sio_c_r(int which, int ch);
DATA REGISTER READ/WRITE DATA REGISTER READ/WRITE
***************************************************************************/ ***************************************************************************/
void z80sio_d_w(running_machine *machine, int which, int ch, UINT8 data); WRITE8_DEVICE_HANDLER( z80sio_d_w );
UINT8 z80sio_d_r(running_machine *machine, int which, int ch); READ8_DEVICE_HANDLER( z80sio_d_r );
@ -64,18 +65,16 @@ UINT8 z80sio_d_r(running_machine *machine, int which, int ch);
CONTROL LINE READ/WRITE CONTROL LINE READ/WRITE
***************************************************************************/ ***************************************************************************/
int z80sio_get_dtr(int which, int ch); READ8_DEVICE_HANDLER( z80sio_get_dtr );
int z80sio_get_rts(int which, int ch); READ8_DEVICE_HANDLER( z80sio_get_rts );
void z80sio_set_cts(int which, int ch, int state); WRITE8_DEVICE_HANDLER( z80sio_set_cts );
void z80sio_set_dcd(int which, int ch, int state); WRITE8_DEVICE_HANDLER( z80sio_set_dcd );
void z80sio_receive_data(int which, int ch, UINT8 data); WRITE8_DEVICE_HANDLER( z80sio_receive_data );
/* ----- device interface ----- */
/*************************************************************************** #define Z80SIO DEVICE_GET_INFO_NAME(z80sio)
DAISY CHAIN INTERFACE DEVICE_GET_INFO( z80sio );
***************************************************************************/
int z80sio_irq_state(int which); #endif
int z80sio_irq_ack(int which);
void z80sio_irq_reti(int which);

View File

@ -88,23 +88,23 @@ static void dleuro_interrupt(const device_config *device, int state)
} }
static WRITE8_HANDLER( serial_transmit ) static WRITE8_DEVICE_HANDLER( serial_transmit )
{ {
laserdisc_data_w(laserdisc, data); laserdisc_data_w(laserdisc, data);
} }
static int serial_receive(int ch) static int serial_receive(const device_config *device, int channel)
{ {
/* if we still have data to send, do it now */ /* if we still have data to send, do it now */
if (ch == 0 && laserdisc_line_r(laserdisc, LASERDISC_LINE_DATA_AVAIL) == ASSERT_LINE) if (channel == 0 && laserdisc_line_r(laserdisc, LASERDISC_LINE_DATA_AVAIL) == ASSERT_LINE)
return laserdisc_data_r(laserdisc); return laserdisc_data_r(laserdisc);
return -1; return -1;
} }
static z80ctc_interface ctc_intf = static const z80ctc_interface ctc_intf =
{ {
"main", /* clock comes from main CPU's clock */ "main", /* clock comes from main CPU's clock */
0, /* clock (filled in from the CPU clock) */ 0, /* clock (filled in from the CPU clock) */
@ -116,10 +116,11 @@ static z80ctc_interface ctc_intf =
}; };
static z80sio_interface sio_intf = static const z80sio_interface sio_intf =
{ {
0, /* clock (filled in from the CPU 3 clock) */ "main", /* clock comes from main CPU's clock */
0,// dleuro_interrupt, /* interrupt handler */ 0, /* clock (filled in from the CPU clock) */
dleuro_interrupt, /* interrupt handler */
0, /* DTR changed handler */ 0, /* DTR changed handler */
0, /* RTS changed handler */ 0, /* RTS changed handler */
0, /* BREAK changed handler */ 0, /* BREAK changed handler */
@ -130,7 +131,7 @@ static z80sio_interface sio_intf =
static const z80_daisy_chain dleuro_daisy_chain[] = static const z80_daisy_chain dleuro_daisy_chain[] =
{ {
// { Z80SIO, "sio" }, { Z80SIO, "sio" },
{ Z80CTC, "ctc" }, { Z80CTC, "ctc" },
{ NULL } { NULL }
}; };
@ -191,16 +192,6 @@ static MACHINE_START( dlair )
} }
static MACHINE_START( dleuro )
{
laserdisc = device_list_find_by_tag(machine->config->devicelist, LASERDISC, "laserdisc");
/* initialize the CTC and SIO peripherals */
sio_intf.baseclock = cpunum_get_clock(0);
z80sio_init(0, &sio_intf);
}
static MACHINE_RESET( dlair ) static MACHINE_RESET( dlair )
{ {
/* determine the laserdisc player from the DIP switches */ /* determine the laserdisc player from the DIP switches */
@ -362,18 +353,18 @@ static WRITE8_HANDLER( laserdisc_w )
* *
*************************************/ *************************************/
static READ8_HANDLER( sio_r ) static READ8_DEVICE_HANDLER( sio_r )
{ {
return (offset & 1) ? z80sio_c_r(0, (offset >> 1) & 1) : z80sio_d_r(machine, 0, (offset >> 1) & 1); return (offset & 1) ? z80sio_c_r(device, (offset >> 1) & 1) : z80sio_d_r(device, (offset >> 1) & 1);
} }
static WRITE8_HANDLER( sio_w ) static WRITE8_DEVICE_HANDLER( sio_w )
{ {
if (offset & 1) if (offset & 1)
z80sio_c_w(machine, 0, (offset >> 1) & 1, data); z80sio_c_w(device, (offset >> 1) & 1, data);
else else
z80sio_d_w(machine, 0, (offset >> 1) & 1, data); z80sio_d_w(device, (offset >> 1) & 1, data);
} }
@ -432,7 +423,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( dleuro_io_map, ADDRESS_SPACE_IO, 8 ) static ADDRESS_MAP_START( dleuro_io_map, ADDRESS_SPACE_IO, 8 )
ADDRESS_MAP_GLOBAL_MASK(0xff) ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x00, 0x03) AM_MIRROR(0x7c) AM_DEVREADWRITE(Z80CTC, "ctc", z80ctc_r, z80ctc_w) AM_RANGE(0x00, 0x03) AM_MIRROR(0x7c) AM_DEVREADWRITE(Z80CTC, "ctc", z80ctc_r, z80ctc_w)
AM_RANGE(0x80, 0x83) AM_MIRROR(0x7c) AM_READWRITE(sio_r, sio_w) AM_RANGE(0x80, 0x83) AM_MIRROR(0x7c) AM_DEVREADWRITE(Z80SIO, "sio", sio_r, sio_w)
ADDRESS_MAP_END ADDRESS_MAP_END
@ -753,10 +744,11 @@ static MACHINE_DRIVER_START( dleuro )
MDRV_CPU_VBLANK_INT("main", vblank_callback) MDRV_CPU_VBLANK_INT("main", vblank_callback)
MDRV_Z80CTC_ADD("ctc", ctc_intf) MDRV_Z80CTC_ADD("ctc", ctc_intf)
MDRV_Z80SIO_ADD("sio", sio_intf)
MDRV_WATCHDOG_TIME_INIT(UINT64_ATTOTIME_IN_HZ(MASTER_CLOCK_EURO/(16*16*16*16*16*8))) MDRV_WATCHDOG_TIME_INIT(UINT64_ATTOTIME_IN_HZ(MASTER_CLOCK_EURO/(16*16*16*16*16*8)))
MDRV_MACHINE_START(dleuro) MDRV_MACHINE_START(dlair)
MDRV_MACHINE_RESET(dlair) MDRV_MACHINE_RESET(dlair)
MDRV_LASERDISC_ADD("laserdisc", PHILLIPS_22VP932, "main", "ldsound") MDRV_LASERDISC_ADD("laserdisc", PHILLIPS_22VP932, "main", "ldsound")

View File

@ -498,7 +498,7 @@ static WRITE8_HANDLER( dotron_op4_w )
* *
*************************************/ *************************************/
WRITE8_HANDLER( mcr_ipu_sio_transmit ) WRITE8_DEVICE_HANDLER( mcr_ipu_sio_transmit )
{ {
logerror("ipu_sio_transmit: %02X\n", data); logerror("ipu_sio_transmit: %02X\n", data);
@ -531,6 +531,8 @@ static READ8_HANDLER( nflfoot_ip2_r )
static WRITE8_HANDLER( nflfoot_op4_w ) static WRITE8_HANDLER( nflfoot_op4_w )
{ {
const device_config *sio = devtag_get_device(machine, Z80SIO, "ipu_sio");
/* bit 7 = J3-7 on IPU board = /RXDA on SIO */ /* bit 7 = J3-7 on IPU board = /RXDA on SIO */
logerror("%04X:op4_w(%d%d%d)\n", activecpu_get_pc(), (data >> 7) & 1, (data >> 6) & 1, (data >> 5) & 1); logerror("%04X:op4_w(%d%d%d)\n", activecpu_get_pc(), (data >> 7) & 1, (data >> 6) & 1, (data >> 5) & 1);
@ -559,12 +561,12 @@ static WRITE8_HANDLER( nflfoot_op4_w )
{ {
logerror(" -- stop bit = %d; final value = %02X\n", (data >> 7) & 1, nflfoot_serial_out_bits); logerror(" -- stop bit = %d; final value = %02X\n", (data >> 7) & 1, nflfoot_serial_out_bits);
nflfoot_serial_out_active = FALSE; nflfoot_serial_out_active = FALSE;
z80sio_receive_data(0, 0, nflfoot_serial_out_bits); z80sio_receive_data(sio, 0, nflfoot_serial_out_bits);
} }
} }
/* bit 6 = J3-3 on IPU board = CTSA on SIO */ /* bit 6 = J3-3 on IPU board = CTSA on SIO */
z80sio_set_cts(0, 0, (data >> 6) & 1); z80sio_set_cts(sio, 0, (data >> 6) & 1);
/* bit 4 = SEL0 (J1-8) on squawk n talk board */ /* bit 4 = SEL0 (J1-8) on squawk n talk board */
/* bits 3-0 = MD3-0 connected to squawk n talk (J1-4,3,2,1) */ /* bits 3-0 = MD3-0 connected to squawk n talk (J1-4,3,2,1) */
@ -701,8 +703,8 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( ipu_91695_portmap, ADDRESS_SPACE_IO, 8 ) static ADDRESS_MAP_START( ipu_91695_portmap, ADDRESS_SPACE_IO, 8 )
ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_UNMAP_HIGH
ADDRESS_MAP_GLOBAL_MASK(0xff) ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x00, 0x03) AM_MIRROR(0xe0) AM_DEVREADWRITE(Z80PIO, "ipu_pio0", z80pio_r,z80pio_w) AM_RANGE(0x00, 0x03) AM_MIRROR(0xe0) AM_DEVREADWRITE(Z80PIO, "ipu_pio0", z80pio_r, z80pio_w)
AM_RANGE(0x04, 0x07) AM_MIRROR(0xe0) AM_READWRITE(mcr_ipu_sio_r, mcr_ipu_sio_w) AM_RANGE(0x04, 0x07) AM_MIRROR(0xe0) AM_DEVREADWRITE(Z80SIO, "ipu_sio", mcr_ipu_sio_r, mcr_ipu_sio_w)
AM_RANGE(0x08, 0x0b) AM_MIRROR(0xe0) AM_DEVREADWRITE(Z80CTC, "ipu_ctc", z80ctc_r, z80ctc_w) AM_RANGE(0x08, 0x0b) AM_MIRROR(0xe0) AM_DEVREADWRITE(Z80CTC, "ipu_ctc", z80ctc_r, z80ctc_w)
AM_RANGE(0x0c, 0x0f) AM_MIRROR(0xe0) AM_DEVREADWRITE(Z80PIO, "ipu_pio1", z80pio_r, z80pio_w) AM_RANGE(0x0c, 0x0f) AM_MIRROR(0xe0) AM_DEVREADWRITE(Z80PIO, "ipu_pio1", z80pio_r, z80pio_w)
AM_RANGE(0x10, 0x13) AM_MIRROR(0xe0) AM_WRITE(mcr_ipu_laserdisk_w) AM_RANGE(0x10, 0x13) AM_MIRROR(0xe0) AM_WRITE(mcr_ipu_laserdisk_w)
@ -1607,6 +1609,7 @@ static MACHINE_DRIVER_START( mcr_91490_ipu )
MDRV_Z80CTC_ADD("ipu_ctc", nflfoot_ctc_intf) MDRV_Z80CTC_ADD("ipu_ctc", nflfoot_ctc_intf)
MDRV_Z80PIO_ADD("ipu_pio0", nflfoot_pio_intf) MDRV_Z80PIO_ADD("ipu_pio0", nflfoot_pio_intf)
MDRV_Z80PIO_ADD("ipu_pio1", nflfoot_pio_intf) MDRV_Z80PIO_ADD("ipu_pio1", nflfoot_pio_intf)
MDRV_Z80SIO_ADD("ipu_sio", nflfoot_sio_intf)
MACHINE_DRIVER_END MACHINE_DRIVER_END

View File

@ -7,6 +7,7 @@
#include "cpu/z80/z80daisy.h" #include "cpu/z80/z80daisy.h"
#include "machine/z80ctc.h" #include "machine/z80ctc.h"
#include "machine/z80pio.h" #include "machine/z80pio.h"
#include "machine/z80sio.h"
/* constants */ /* constants */
#define MAIN_OSC_MCR_I XTAL_19_968MHz #define MAIN_OSC_MCR_I XTAL_19_968MHz
@ -14,7 +15,7 @@
/*----------- defined in drivers/mcr.c -----------*/ /*----------- defined in drivers/mcr.c -----------*/
WRITE8_HANDLER( mcr_ipu_sio_transmit ); WRITE8_DEVICE_HANDLER( mcr_ipu_sio_transmit );
@ -27,6 +28,7 @@ extern const z80_daisy_chain mcr_ipu_daisy_chain[];
extern const z80ctc_interface mcr_ctc_intf; extern const z80ctc_interface mcr_ctc_intf;
extern const z80ctc_interface nflfoot_ctc_intf; extern const z80ctc_interface nflfoot_ctc_intf;
extern const z80pio_interface nflfoot_pio_intf; extern const z80pio_interface nflfoot_pio_intf;
extern const z80sio_interface nflfoot_sio_intf;
extern UINT8 mcr_cocktail_flip; extern UINT8 mcr_cocktail_flip;
extern const gfx_layout mcr_bg_layout; extern const gfx_layout mcr_bg_layout;
@ -57,8 +59,8 @@ WRITE16_HANDLER( mcr68_6840_lower_w );
READ16_HANDLER( mcr68_6840_upper_r ); READ16_HANDLER( mcr68_6840_upper_r );
READ16_HANDLER( mcr68_6840_lower_r ); READ16_HANDLER( mcr68_6840_lower_r );
READ8_HANDLER( mcr_ipu_sio_r ); READ8_DEVICE_HANDLER( mcr_ipu_sio_r );
WRITE8_HANDLER( mcr_ipu_sio_w ); WRITE8_DEVICE_HANDLER( mcr_ipu_sio_w );
WRITE8_HANDLER( mcr_ipu_laserdisk_w ); WRITE8_HANDLER( mcr_ipu_laserdisk_w );
READ8_HANDLER( mcr_ipu_watchdog_r ); READ8_HANDLER( mcr_ipu_watchdog_r );
WRITE8_HANDLER( mcr_ipu_watchdog_w ); WRITE8_HANDLER( mcr_ipu_watchdog_w );

View File

@ -91,7 +91,7 @@ static void zwackery_pia_irq(running_machine *machine, int state);
static void reload_count(int counter); static void reload_count(int counter);
static TIMER_CALLBACK( counter_fired_callback ); static TIMER_CALLBACK( counter_fired_callback );
static TIMER_CALLBACK( ipu_watchdog_reset ); static TIMER_CALLBACK( ipu_watchdog_reset );
static WRITE8_HANDLER( ipu_break_changed ); static WRITE8_DEVICE_HANDLER( ipu_break_changed );
@ -209,9 +209,9 @@ const z80_daisy_chain mcr_daisy_chain[] =
const z80_daisy_chain mcr_ipu_daisy_chain[] = const z80_daisy_chain mcr_ipu_daisy_chain[] =
{ {
{ Z80CTC, "ipu_ctc" }, { Z80CTC, "ipu_ctc" },
{ Z80PIO, "ipt_pio1" }, { Z80PIO, "ipu_pio1" },
// { Z80SIO, "ipt_sio" }, { Z80SIO, "ipu_sio" },
{ Z80PIO, "ipt_pio0" }, { Z80PIO, "ipu_pio0" },
{ NULL } { NULL }
}; };
@ -252,10 +252,11 @@ const z80pio_interface nflfoot_pio_intf =
}; };
static z80sio_interface nflfoot_sio_intf = const z80sio_interface nflfoot_sio_intf =
{ {
"ipu", /* clock from the IPU cpu */
0, /* clock (filled in from the CPU 3 clock) */ 0, /* clock (filled in from the CPU 3 clock) */
0,// ipu_ctc_interrupt, /* interrupt handler */ ipu_ctc_interrupt, /* interrupt handler */
0, /* DTR changed handler */ 0, /* DTR changed handler */
0, /* RTS changed handler */ 0, /* RTS changed handler */
ipu_break_changed, /* BREAK changed handler */ ipu_break_changed, /* BREAK changed handler */
@ -278,9 +279,6 @@ MACHINE_START( mcr )
MACHINE_START( nflfoot ) MACHINE_START( nflfoot )
{ {
nflfoot_sio_intf.baseclock = cpunum_get_clock(3);
z80sio_init(0, &nflfoot_sio_intf);
/* allocate a timer for the IPU watchdog */ /* allocate a timer for the IPU watchdog */
ipu_watchdog_timer = timer_alloc(ipu_watchdog_reset, NULL); ipu_watchdog_timer = timer_alloc(ipu_watchdog_reset, NULL);
} }
@ -917,30 +915,30 @@ READ16_HANDLER( mcr68_6840_lower_r )
* *
*************************************/ *************************************/
static WRITE8_HANDLER( ipu_break_changed ) static WRITE8_DEVICE_HANDLER( ipu_break_changed )
{ {
/* channel B is connected to the CED player */ /* channel B is connected to the CED player */
if (offset == 1) if (offset == 1)
{ {
logerror("DTR changed -> %d\n", data); logerror("DTR changed -> %d\n", data);
if (data == 1) if (data == 1)
z80sio_receive_data(0, 1, 0); z80sio_receive_data(device, 1, 0);
} }
} }
READ8_HANDLER( mcr_ipu_sio_r ) READ8_DEVICE_HANDLER( mcr_ipu_sio_r )
{ {
return (offset & 2) ? z80sio_c_r(0, offset & 1) : z80sio_d_r(machine, 0, offset & 1); return (offset & 2) ? z80sio_c_r(device, offset & 1) : z80sio_d_r(device, offset & 1);
} }
WRITE8_HANDLER( mcr_ipu_sio_w ) WRITE8_DEVICE_HANDLER( mcr_ipu_sio_w )
{ {
if (offset & 2) if (offset & 2)
z80sio_c_w(machine, 0, offset & 1, data); z80sio_c_w(device, offset & 1, data);
else else
z80sio_d_w(machine, 0, offset & 1, data); z80sio_d_w(device, offset & 1, data);
} }
@ -962,7 +960,7 @@ static TIMER_CALLBACK( ipu_watchdog_reset )
devtag_reset(machine, Z80CTC, "ipu_ctc"); devtag_reset(machine, Z80CTC, "ipu_ctc");
devtag_reset(machine, Z80PIO, "ipu_pio0"); devtag_reset(machine, Z80PIO, "ipu_pio0");
devtag_reset(machine, Z80PIO, "ipu_pio1"); devtag_reset(machine, Z80PIO, "ipu_pio1");
z80sio_reset(0); devtag_reset(machine, Z80SIO, "ipu_sio");
} }