Converted the z80pio implementation into a device.

This commit is contained in:
Wilbert Pol 2008-09-28 15:32:18 +00:00
parent e8896b0416
commit 08e57e7e28
8 changed files with 436 additions and 356 deletions

View File

@ -58,8 +58,8 @@ struct _z80pio
UINT8 vector[2]; /* interrupt vector */ UINT8 vector[2]; /* interrupt vector */
void (*intr)(running_machine *, int which); /* interrupt callbacks */ void (*intr)(running_machine *, int which); /* interrupt callbacks */
void (*rdyr[2])(int data); /* RDY active callback */ void (*rdyr[2])(int data); /* RDY active callback */
read8_machine_func port_read[2]; /* port read callbacks */ read8_device_func port_read[2]; /* port read callbacks */
write8_machine_func port_write[2]; /* port write callbacks */ write8_device_func port_write[2]; /* port write callbacks */
UINT8 mode[2]; /* mode 00=in,01=out,02=i/o,03=bit*/ UINT8 mode[2]; /* mode 00=in,01=out,02=i/o,03=bit*/
UINT8 enable[2]; /* interrupt enable */ UINT8 enable[2]; /* interrupt enable */
UINT8 mask[2]; /* mask folowers */ UINT8 mask[2]; /* mask folowers */
@ -70,149 +70,100 @@ struct _z80pio
UINT8 strobe[2]; /* strobe inputs */ UINT8 strobe[2]; /* strobe inputs */
UINT8 int_state[2]; /* interrupt status (daisy chain) */ UINT8 int_state[2]; /* interrupt status (daisy chain) */
}; };
typedef struct _z80pio z80pio; typedef struct _z80pio z80pio_t;
/*************************************************************************** /***************************************************************************
GLOBAL VARIABLES INLINE FUNCTIONS
***************************************************************************/ ***************************************************************************/
static z80pio pios[MAX_PIO]; INLINE z80pio_t *get_safe_token(const device_config *device)
{
assert(device != NULL);
assert(device->token != NULL);
assert(device->type == Z80PIO);
return (z80pio_t *)device->token;
}
/*************************************************************************** /***************************************************************************
INTERNAL STATE MANAGEMENT INTERNAL STATE MANAGEMENT
***************************************************************************/ ***************************************************************************/
static void set_rdy(z80pio *pio, int ch, int state) INLINE void set_rdy(const device_config *device, int ch, int state)
{ {
z80pio_t *z80pio = get_safe_token( device );
/* set state */ /* set state */
pio->rdy[ch] = state; z80pio->rdy[ch] = state;
/* call callback with state */ /* call callback with state */
if (pio->rdyr[ch]) if (z80pio->rdyr[ch])
(*pio->rdyr[ch])(pio->rdy[ch]); z80pio->rdyr[ch](z80pio->rdy[ch]);
} }
static void interrupt_check(running_machine *machine, int which) INLINE void interrupt_check(const device_config *device)
{ {
z80pio *pio = pios + which; z80pio_t *z80pio = get_safe_token( device );
/* if we have a callback, update it with the current state */ /* if we have a callback, update it with the current state */
if (pio->intr) if (z80pio->intr)
(*pio->intr)(machine, (z80pio_irq_state(which) & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE); z80pio->intr(device->machine, (z80pio_irq_state(device) & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE);
} }
static void update_irq_state(running_machine *machine, z80pio *pio, int ch) static void update_irq_state(const device_config *device, int ch)
{ {
int old_state = pio->int_state[ch]; z80pio_t *z80pio = get_safe_token( device );
int old_state = z80pio->int_state[ch];
int irq = 0; int irq = 0;
int data; int data;
if (pio->mode[ch] == 0x13 || (pio->enable[ch] & PIO_INT_MASK)) return; if (z80pio->mode[ch] == 0x13 || (z80pio->enable[ch] & PIO_INT_MASK)) return;
/* only check if interrupts are enabled */ /* only check if interrupts are enabled */
if (pio->enable[ch] & PIO_INT_ENABLE) if (z80pio->enable[ch] & PIO_INT_ENABLE)
{ {
/* in mode 3, interrupts are tricky */ /* in mode 3, interrupts are tricky */
if (pio->mode[ch] == PIO_MODE3) if (z80pio->mode[ch] == PIO_MODE3)
{ {
/* fetch input data (ignore output lines) */ /* fetch input data (ignore output lines) */
data = pio->in[ch] & pio->dir[ch]; data = z80pio->in[ch] & z80pio->dir[ch];
/* keep only relevant bits */ /* keep only relevant bits */
data &= ~pio->mask[ch]; data &= ~z80pio->mask[ch];
/* if active low, invert the bits */ /* if active low, invert the bits */
if (!(pio->enable[ch] & PIO_INT_HIGH)) if (!(z80pio->enable[ch] & PIO_INT_HIGH))
data ^= pio->mask[ch]; data ^= z80pio->mask[ch];
/* if AND logic, interrupt if all bits are set */ /* if AND logic, interrupt if all bits are set */
if (pio->enable[ch] & PIO_INT_AND) if (z80pio->enable[ch] & PIO_INT_AND)
irq = (data == pio->mask[ch]); irq = (data == z80pio->mask[ch]);
/* otherwise, interrupt if at least one bit is set */ /* otherwise, interrupt if at least one bit is set */
else else
irq = (data != 0); irq = (data != 0);
/* if portB, portA mode 2 check */ /* if portB, portA mode 2 check */
if (ch && (pio->mode[0] == PIO_MODE2)) if (ch && (z80pio->mode[0] == PIO_MODE2))
{ {
if (pio->rdy[ch] == 0) if (z80pio->rdy[ch] == 0)
irq = 1; irq = 1;
} }
} }
/* otherwise, just interrupt when ready is cleared */ /* otherwise, just interrupt when ready is cleared */
else else
irq = (pio->rdy[ch] == 0); irq = (z80pio->rdy[ch] == 0);
} }
if (irq) if (irq)
pio->int_state[ch] |= Z80_DAISY_INT; z80pio->int_state[ch] |= Z80_DAISY_INT;
else else
pio->int_state[ch] &= ~Z80_DAISY_INT; z80pio->int_state[ch] &= ~Z80_DAISY_INT;
if (old_state != pio->int_state[ch]) if (old_state != z80pio->int_state[ch])
interrupt_check(machine, pio - pios); interrupt_check(device);
}
/***************************************************************************
INITIALIZATION/CONFIGURATION
***************************************************************************/
void z80pio_init(int which, const z80pio_interface *intf)
{
z80pio *pio = pios + which;
assert(which < MAX_PIO);
memset(pio, 0, sizeof(*pio));
pio->intr = intf->intr;
pio->port_read[0] = intf->portAread;
pio->port_read[1] = intf->portBread;
pio->port_write[0] = intf->portAwrite;
pio->port_write[1] = intf->portBwrite;
pio->rdyr[0] = intf->rdyA;
pio->rdyr[1] = intf->rdyB;
z80pio_reset(which);
state_save_register_item_array("z80pio", which, pio->vector);
state_save_register_item_array("z80pio", which, pio->mode);
state_save_register_item_array("z80pio", which, pio->enable);
state_save_register_item_array("z80pio", which, pio->mask);
state_save_register_item_array("z80pio", which, pio->dir);
state_save_register_item_array("z80pio", which, pio->rdy);
state_save_register_item_array("z80pio", which, pio->in);
state_save_register_item_array("z80pio", which, pio->out);
state_save_register_item_array("z80pio", which, pio->strobe);
state_save_register_item_array("z80pio", which, pio->int_state);
}
void z80pio_reset(int which)
{
z80pio *pio = pios + which;
int i;
for (i = 0; i < 2; i++)
{
pio->mask[i] = 0xff; /* mask all on */
pio->enable[i] = 0x00; /* disable */
pio->mode[i] = 0x01; /* mode input */
pio->dir[i] = 0x01; /* dir input */
set_rdy(pio, i, 0); /* RDY = low */
pio->out[i] = 0x00; /* outdata = 0 */
pio->int_state[i] = 0;
pio->strobe[i] = 0;
}
interrupt_check(Machine, which);
} }
@ -221,70 +172,76 @@ void z80pio_reset(int which)
CONTROL REGISTER READ/WRITE CONTROL REGISTER READ/WRITE
***************************************************************************/ ***************************************************************************/
void z80pio_c_w(running_machine *machine, int which, int ch, UINT8 data) WRITE8_DEVICE_HANDLER( z80pio_c_w )
{ {
z80pio *pio = pios + which; z80pio_t *z80pio = get_safe_token( device );
/* There are only 2 channels */
offset &= 0x01;
/* load direction phase ? */ /* load direction phase ? */
if (pio->mode[ch] == 0x13) if (z80pio->mode[offset] == 0x13)
{ {
VPRINTF(("PIO-%c Bits %02x\n", 'A' + ch, data)); VPRINTF(("PIO-%c Bits %02x\n", 'A' + offset, data));
pio->dir[ch] = data; z80pio->dir[offset] = data;
pio->mode[ch] = 0x03; z80pio->mode[offset] = 0x03;
return; return;
} }
/* load mask folows phase ? */ /* load mask folows phase ? */
if (pio->enable[ch] & PIO_INT_MASK) if (z80pio->enable[offset] & PIO_INT_MASK)
{ {
/* load mask folows */ /* load mask folows */
pio->mask[ch] = data; z80pio->mask[offset] = data;
pio->enable[ch] &= ~PIO_INT_MASK; z80pio->enable[offset] &= ~PIO_INT_MASK;
VPRINTF(("PIO-%c interrupt mask %02x\n",'A'+ch,data )); VPRINTF(("PIO-%c interrupt mask %02x\n",'A'+offset,data ));
return; return;
} }
switch (data & 0x0f) switch (data & 0x0f)
{ {
case PIO_OP_MODE: /* mode select 0=out,1=in,2=i/o,3=bit */ case PIO_OP_MODE: /* mode select 0=out,1=in,2=i/o,3=bit */
pio->mode[ch] = (data >> 6); z80pio->mode[offset] = (data >> 6);
VPRINTF(("PIO-%c Mode %x\n", 'A' + ch, pio->mode[ch])); VPRINTF(("PIO-%c Mode %x\n", 'A' + offset, z80pio->mode[offset]));
if (pio->mode[ch] == 0x03) if (z80pio->mode[offset] == 0x03)
pio->mode[ch] = 0x13; z80pio->mode[offset] = 0x13;
return; return;
case PIO_OP_INTC: /* interrupt control */ case PIO_OP_INTC: /* interrupt control */
pio->enable[ch] = data & 0xf0; z80pio->enable[offset] = data & 0xf0;
pio->mask[ch] = 0x00; z80pio->mask[offset] = 0x00;
/* when interrupt enable , set vector request flag */ /* when interrupt enable , set vector request flag */
VPRINTF(("PIO-%c Controll %02x\n", 'A' + ch, data)); VPRINTF(("PIO-%c Controll %02x\n", 'A' + offset, data));
break; break;
case PIO_OP_INTE: /* interrupt enable controll */ case PIO_OP_INTE: /* interrupt enable controll */
pio->enable[ch] &= ~PIO_INT_ENABLE; z80pio->enable[offset] &= ~PIO_INT_ENABLE;
pio->enable[ch] |= (data & PIO_INT_ENABLE); z80pio->enable[offset] |= (data & PIO_INT_ENABLE);
VPRINTF(("PIO-%c enable %02x\n", 'A' + ch, data & 0x80)); VPRINTF(("PIO-%c enable %02x\n", 'A' + offset, data & 0x80));
break; break;
default: default:
if (!(data & 1)) if (!(data & 1))
{ {
pio->vector[ch] = data; z80pio->vector[offset] = data;
VPRINTF(("PIO-%c vector %02x\n", 'A' + ch, data)); VPRINTF(("PIO-%c vector %02x\n", 'A' + offset, data));
} }
else else
VPRINTF(("PIO-%c illegal command %02x\n", 'A' + ch, data)); VPRINTF(("PIO-%c illegal command %02x\n", 'A' + offset, data));
break; break;
} }
/* interrupt check */ /* interrupt check */
update_irq_state(machine, pio, ch); update_irq_state(device, offset);
} }
UINT8 z80pio_c_r(int which, int ch) READ8_DEVICE_HANDLER( z80pio_c_r )
{ {
VPRINTF(("PIO-%c controll read\n", 'A' + ch )); /* There are only 2 channels */
offset &= 0x01;
VPRINTF(("PIO-%c controll read\n", 'A' + offset ));
return 0; return 0;
} }
@ -294,20 +251,23 @@ UINT8 z80pio_c_r(int which, int ch)
DATA REGISTER READ/WRITE DATA REGISTER READ/WRITE
***************************************************************************/ ***************************************************************************/
void z80pio_d_w(running_machine *machine, int which, int ch, UINT8 data) WRITE8_DEVICE_HANDLER( z80pio_d_w )
{ {
z80pio *pio = pios + which; z80pio_t *z80pio = get_safe_token( device );
pio->out[ch] = data; /* latch out data */ /* There are only 2 channels */
if(pio->port_write[ch]) offset &= 0x01;
pio->port_write[ch](machine, 0, data);
switch (pio->mode[ch]) z80pio->out[offset] = data; /* latch out data */
if(z80pio->port_write[offset])
z80pio->port_write[offset](device, 0, data);
switch (z80pio->mode[offset])
{ {
case PIO_MODE0: /* mode 0 output */ case PIO_MODE0: /* mode 0 output */
case PIO_MODE2: /* mode 2 i/o */ case PIO_MODE2: /* mode 2 i/o */
set_rdy(pio, ch, 1); /* ready = H */ set_rdy(device, offset, 1); /* ready = H */
update_irq_state(machine, pio, ch); update_irq_state(device, offset);
return; return;
case PIO_MODE1: /* mode 1 input */ case PIO_MODE1: /* mode 1 input */
@ -315,41 +275,44 @@ void z80pio_d_w(running_machine *machine, int which, int ch, UINT8 data)
return; return;
default: default:
VPRINTF(("PIO-%c data write,bad mode\n",'A'+ch )); VPRINTF(("PIO-%c data write,bad mode\n",'A'+offset ));
} }
} }
UINT8 z80pio_d_r(running_machine *machine, int which, int ch) READ8_DEVICE_HANDLER( z80pio_d_r )
{ {
z80pio *pio = pios + which; z80pio_t *z80pio = get_safe_token( device );
switch (pio->mode[ch]) /* There are only 2 channels */
offset &= 0x01;
switch (z80pio->mode[offset])
{ {
case PIO_MODE0: /* mode 0 output */ case PIO_MODE0: /* mode 0 output */
return pio->out[ch]; return z80pio->out[offset];
case PIO_MODE1: /* mode 1 input */ case PIO_MODE1: /* mode 1 input */
set_rdy(pio, ch, 1); /* ready = H */ set_rdy(device, offset, 1); /* ready = H */
if(pio->port_read[ch]) if(z80pio->port_read[offset])
pio->in[ch] = pio->port_read[ch](machine, 0); z80pio->in[offset] = z80pio->port_read[offset](device, 0);
update_irq_state(machine, pio, ch); update_irq_state(device, offset);
return pio->in[ch]; return z80pio->in[offset];
case PIO_MODE2: /* mode 2 i/o */ case PIO_MODE2: /* mode 2 i/o */
if (ch) VPRINTF(("PIO-B mode 2 \n")); if (offset) VPRINTF(("PIO-B mode 2 \n"));
set_rdy(pio, 1, 1); /* brdy = H */ set_rdy(device, 1, 1); /* brdy = H */
if(pio->port_read[ch]) if(z80pio->port_read[offset])
pio->in[ch] = pio->port_read[ch](machine, 0); z80pio->in[offset] = z80pio->port_read[offset](device, 0);
update_irq_state(machine, pio, ch); update_irq_state(device, offset);
return pio->in[ch]; return z80pio->in[offset];
case PIO_MODE3: /* mode 3 bit */ case PIO_MODE3: /* mode 3 bit */
if(pio->port_read[ch]) if(z80pio->port_read[offset])
pio->in[ch] = pio->port_read[ch](machine, 0); z80pio->in[offset] = z80pio->port_read[offset](device, 0);
return (pio->in[ch] & pio->dir[ch]) | (pio->out[ch] & ~pio->dir[ch]); return (z80pio->in[offset] & z80pio->dir[offset]) | (z80pio->out[offset] & ~z80pio->dir[offset]);
} }
VPRINTF(("PIO-%c data read,bad mode\n",'A'+ch )); VPRINTF(("PIO-%c data read,bad mode\n",'A'+offset ));
return 0; return 0;
} }
@ -359,77 +322,71 @@ UINT8 z80pio_d_r(running_machine *machine, int which, int ch)
PORT I/O PORT I/O
***************************************************************************/ ***************************************************************************/
void z80pio_p_w(running_machine *machine, int which, UINT8 ch, UINT8 data) WRITE8_DEVICE_HANDLER( z80pio_p_w )
{ {
z80pio *pio = pios + which; z80pio_t *z80pio = get_safe_token( device );
pio->in[ch] = data; /* There are only 2 channels */
switch (pio->mode[ch]) offset &= 0x01;
z80pio->in[offset] = data;
switch (z80pio->mode[offset])
{ {
case PIO_MODE0: case PIO_MODE0:
VPRINTF(("PIO-%c OUTPUT mode and data write\n",'A'+ch )); VPRINTF(("PIO-%c OUTPUT mode and data write\n",'A'+offset ));
break; break;
case PIO_MODE2: /* only port A */ case PIO_MODE2: /* only port A */
ch = 1; /* handshake and IRQ is use portB */ offset = 1; /* handshake and IRQ is use portB */
case PIO_MODE1: case PIO_MODE1:
set_rdy(pio, ch, 0); set_rdy(device, offset, 0);
update_irq_state(machine, pio, ch); update_irq_state(device, offset);
break; break;
case PIO_MODE3: case PIO_MODE3:
/* irq check */ /* irq check */
update_irq_state(machine, pio, ch); update_irq_state(device, offset);
break; break;
} }
} }
int z80pio_p_r(running_machine *machine, int which, UINT8 ch) READ8_DEVICE_HANDLER( z80pio_p_r )
{ {
z80pio *pio = pios + which; z80pio_t *z80pio = get_safe_token( device );
switch (pio->mode[ch]) /* There are only 2 channels */
offset &= 0x01;
switch (z80pio->mode[offset])
{ {
case PIO_MODE2: /* port A only */ case PIO_MODE2: /* port A only */
case PIO_MODE0: case PIO_MODE0:
set_rdy(pio, ch, 0); set_rdy(device, offset, 0);
update_irq_state(machine, pio, ch); update_irq_state(device, offset);
break; break;
case PIO_MODE1: case PIO_MODE1:
VPRINTF(("PIO-%c INPUT mode and data read\n",'A'+ch )); VPRINTF(("PIO-%c INPUT mode and data read\n",'A'+offset ));
break; break;
case PIO_MODE3: case PIO_MODE3:
return (pio->in[ch] & pio->dir[ch]) | (pio->out[ch] & ~pio->dir[ch]); return (z80pio->in[offset] & z80pio->dir[offset]) | (z80pio->out[offset] & ~z80pio->dir[offset]);
} }
return pio->out[ch]; return z80pio->out[offset];
} }
WRITE8_HANDLER( z80pioA_0_p_w ) { z80pio_p_w(machine, 0, 0, data); }
WRITE8_HANDLER( z80pioB_0_p_w ) { z80pio_p_w(machine, 0, 1, data); }
READ8_HANDLER( z80pioA_0_p_r ) { return z80pio_p_r(machine, 0, 0); }
READ8_HANDLER( z80pioB_0_p_r ) { return z80pio_p_r(machine, 0, 1); }
WRITE8_HANDLER( z80pioA_1_p_w ) { z80pio_p_w(machine, 1, 0, data); }
WRITE8_HANDLER( z80pioB_1_p_w ) { z80pio_p_w(machine, 1, 1, data); }
READ8_HANDLER( z80pioA_1_p_r ) { return z80pio_p_r(machine, 1, 0); }
READ8_HANDLER( z80pioB_1_p_r ) { return z80pio_p_r(machine, 1, 1); }
/*************************************************************************** /***************************************************************************
STROBE STATE MANAGEMENT STROBE STATE MANAGEMENT
***************************************************************************/ ***************************************************************************/
static void z80pio_update_strobe(running_machine *machine, int which, int ch, int state) static void z80pio_update_strobe(const device_config *device, int ch, int state)
{ {
z80pio *pio = pios + which; z80pio_t *z80pio = get_safe_token( device );
switch (pio->mode[ch]) switch (z80pio->mode[ch])
{ {
/* output mode: a positive edge is used by peripheral to acknowledge /* output mode: a positive edge is used by peripheral to acknowledge
the receipt of data */ the receipt of data */
@ -439,7 +396,7 @@ static void z80pio_update_strobe(running_machine *machine, int which, int ch, in
state = state & 0x01; state = state & 0x01;
/* strobe changed state? */ /* strobe changed state? */
if ((pio->strobe[ch] ^ state) != 0) if ((z80pio->strobe[ch] ^ state) != 0)
{ {
/* yes */ /* yes */
if (state != 0) if (state != 0)
@ -448,22 +405,22 @@ static void z80pio_update_strobe(running_machine *machine, int which, int ch, in
VPRINTF(("PIO-%c positive strobe\n",'A' + ch)); VPRINTF(("PIO-%c positive strobe\n",'A' + ch));
/* ready is now inactive */ /* ready is now inactive */
set_rdy(pio, ch, 0); set_rdy(device, ch, 0);
/* int enabled? */ /* int enabled? */
if (pio->enable[ch] & PIO_INT_ENABLE) if (z80pio->enable[ch] & PIO_INT_ENABLE)
{ {
/* trigger an int request */ /* trigger an int request */
pio->int_state[ch] |= Z80_DAISY_INT; z80pio->int_state[ch] |= Z80_DAISY_INT;
} }
} }
} }
/* store strobe state */ /* store strobe state */
pio->strobe[ch] = state; z80pio->strobe[ch] = state;
/* check interrupt */ /* check interrupt */
interrupt_check(machine, which); interrupt_check(device);
} }
break; break;
@ -476,8 +433,8 @@ static void z80pio_update_strobe(running_machine *machine, int which, int ch, in
} }
void z80pio_astb_w(running_machine *machine, int which, int state) { z80pio_update_strobe(machine, which, 0, state); } void z80pio_astb_w(const device_config *device, int state) { z80pio_update_strobe(device, 0, state); }
void z80pio_bstb_w(running_machine *machine, int which, int state) { z80pio_update_strobe(machine, which, 1, state); } void z80pio_bstb_w(const device_config *device, int state) { z80pio_update_strobe(device, 1, state); }
@ -485,9 +442,9 @@ void z80pio_bstb_w(running_machine *machine, int which, int state) { z80pio_upda
DAISY CHAIN INTERFACE DAISY CHAIN INTERFACE
***************************************************************************/ ***************************************************************************/
int z80pio_irq_state(int which) int z80pio_irq_state(const device_config *device)
{ {
z80pio *pio = pios + which; z80pio_t *z80pio = get_safe_token( device );
int state = 0; int state = 0;
int ch; int ch;
@ -495,84 +452,165 @@ int z80pio_irq_state(int which)
for (ch = 0; ch < 2; ch++) for (ch = 0; ch < 2; ch++)
{ {
/* if we're servicing a request, don't indicate more interrupts */ /* if we're servicing a request, don't indicate more interrupts */
if (pio->int_state[ch] & Z80_DAISY_IEO) if (z80pio->int_state[ch] & Z80_DAISY_IEO)
{ {
state |= Z80_DAISY_IEO; state |= Z80_DAISY_IEO;
break; break;
} }
state |= pio->int_state[ch]; state |= z80pio->int_state[ch];
} }
return state; return state;
} }
int z80pio_irq_ack(int which) int z80pio_irq_ack(const device_config *device)
{ {
z80pio *pio = pios + which; z80pio_t *z80pio = get_safe_token( device );
int ch; int ch;
/* loop over all channels */ /* loop over all channels */
for (ch = 0; ch < 2; ch++) for (ch = 0; ch < 2; ch++)
/* find the first channel with an interrupt requested */ /* find the first channel with an interrupt requested */
if (pio->int_state[ch] & Z80_DAISY_INT) if (z80pio->int_state[ch] & Z80_DAISY_INT)
{ {
/* clear interrupt, switch to the IEO state, and update the IRQs */ /* clear interrupt, switch to the IEO state, and update the IRQs */
pio->int_state[ch] = Z80_DAISY_IEO; z80pio->int_state[ch] = Z80_DAISY_IEO;
interrupt_check(Machine, which); interrupt_check(device);
return pio->vector[ch]; return z80pio->vector[ch];
} }
VPRINTF(("z80pio_irq_ack: failed to find an interrupt to ack!")); VPRINTF(("z80pio_irq_ack: failed to find an interrupt to ack!"));
return pio->vector[0]; return z80pio->vector[0];
} }
void z80pio_irq_reti(int which) void z80pio_irq_reti(const device_config *device)
{ {
z80pio *pio = pios + which; z80pio_t *z80pio = get_safe_token( device );
int ch; int ch;
/* loop over all channels */ /* loop over all channels */
for (ch = 0; ch < 2; ch++) for (ch = 0; ch < 2; ch++)
/* find the first channel with an IEO pending */ /* find the first channel with an IEO pending */
if (pio->int_state[ch] & Z80_DAISY_IEO) if (z80pio->int_state[ch] & Z80_DAISY_IEO)
{ {
/* clear the IEO state and update the IRQs */ /* clear the IEO state and update the IRQs */
pio->int_state[ch] &= ~Z80_DAISY_IEO; z80pio->int_state[ch] &= ~Z80_DAISY_IEO;
interrupt_check(Machine, which); interrupt_check(device);
return; return;
} }
VPRINTF(("z80pio_irq_reti: failed to find an interrupt to clear IEO on!")); VPRINTF(("z80pio_irq_reti: failed to find an interrupt to clear IEO on!"));
} }
/*************************************************************************** /***************************************************************************
READ/WRITE HANDLERS READ/WRITE HANDLERS
***************************************************************************/ ***************************************************************************/
READ8_HANDLER(z80pio_0_r) READ8_DEVICE_HANDLER(z80pio_r)
{ {
return (offset & 2) ? z80pio_c_r(0, offset & 1) : z80pio_d_r(machine, 0, offset & 1); return (offset & 2) ? z80pio_c_r(device, offset & 1) : z80pio_d_r(device, offset & 1);
} }
WRITE8_HANDLER(z80pio_0_w) WRITE8_DEVICE_HANDLER(z80pio_w)
{ {
if (offset & 2) if (offset & 2)
z80pio_c_w(machine, 0, offset & 1, data); z80pio_c_w(device, offset & 1, data);
else else
z80pio_d_w(machine, 0, offset & 1, data); z80pio_d_w(device, offset & 1, data);
} }
READ8_HANDLER(z80pio_1_r)
static DEVICE_START( z80pio )
{ {
return (offset & 2) ? z80pio_c_r(1, offset & 1) : z80pio_d_r(machine, 1, offset & 1); const z80pio_interface *intf = device->static_config;
z80pio_t *z80pio = get_safe_token( device );
char unique_tag[30];
z80pio->intr = intf->intr;
z80pio->port_read[0] = intf->portAread;
z80pio->port_read[1] = intf->portBread;
z80pio->port_write[0] = intf->portAwrite;
z80pio->port_write[1] = intf->portBwrite;
z80pio->rdyr[0] = intf->rdyA;
z80pio->rdyr[1] = intf->rdyB;
/* register for save states */
state_save_combine_module_and_tag(unique_tag, "z80pio", device->tag);
state_save_register_item_array(unique_tag, 0, z80pio->vector);
state_save_register_item_array(unique_tag, 0, z80pio->mode);
state_save_register_item_array(unique_tag, 0, z80pio->enable);
state_save_register_item_array(unique_tag, 0, z80pio->mask);
state_save_register_item_array(unique_tag, 0, z80pio->dir);
state_save_register_item_array(unique_tag, 0, z80pio->rdy);
state_save_register_item_array(unique_tag, 0, z80pio->in);
state_save_register_item_array(unique_tag, 0, z80pio->out);
state_save_register_item_array(unique_tag, 0, z80pio->strobe);
state_save_register_item_array(unique_tag, 0, z80pio->int_state);
return DEVICE_START_OK;
} }
WRITE8_HANDLER(z80pio_1_w)
void z80pio_reset( const device_config *device )
{ {
if (offset & 2) z80pio_t *z80pio = get_safe_token( device );
z80pio_c_w(machine, 1, offset & 1, data); int i;
else
z80pio_d_w(machine, 1, offset & 1, data); for (i = 0; i < 2; i++)
{
z80pio->mask[i] = 0xff; /* mask all on */
z80pio->enable[i] = 0x00; /* disable */
z80pio->mode[i] = 0x01; /* mode input */
z80pio->dir[i] = 0x01; /* dir input */
set_rdy(device, i, 0); /* RDY = low */
z80pio->out[i] = 0x00; /* outdata = 0 */
z80pio->int_state[i] = 0;
z80pio->strobe[i] = 0;
}
interrupt_check(device);
} }
static DEVICE_RESET( z80pio )
{
z80pio_reset( device );
}
static DEVICE_SET_INFO( z80pio )
{
switch (state)
{
/* no parameters to set */
}
}
DEVICE_GET_INFO( z80pio )
{
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(z80pio_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_SET_INFO: info->set_info = DEVICE_SET_INFO_NAME(z80pio); break;
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(z80pio);break;
case DEVINFO_FCT_STOP: /* Nothing */ break;
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(z80pio);break;
/* --- the following bits of info are returned as NULL-terminated strings --- */
case DEVINFO_STR_NAME: info->s = "Zilog Z80PIO"; break;
case DEVINFO_STR_FAMILY: info->s = "Z80PIO"; 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 __Z80PIO_H_
CONSTANTS #define __Z80PIO_H_
***************************************************************************/
#define MAX_PIO 2
/*************************************************************************** /***************************************************************************
@ -22,83 +18,87 @@
struct _z80pio_interface struct _z80pio_interface
{ {
void (*intr)(running_machine *machine, int which); /* callback when change interrupt status */ void (*intr)(running_machine *machine, int which); /* callback when change interrupt status */
read8_machine_func portAread; /* port A read callback */ read8_device_func portAread; /* port A read callback */
read8_machine_func portBread; /* port B read callback */ read8_device_func portBread; /* port B read callback */
write8_machine_func portAwrite; /* port A write callback */ write8_device_func portAwrite; /* port A write callback */
write8_machine_func portBwrite; /* port B write callback */ write8_device_func portBwrite; /* port B write callback */
void (*rdyA)(int data); /* portA ready active callback (do not support yet)*/ void (*rdyA)(int data); /* portA ready active callback (do not support yet)*/
void (*rdyB)(int data); /* portB ready active callback (do not support yet)*/ void (*rdyB)(int data); /* portB ready active callback (do not support yet)*/
}; };
typedef struct _z80pio_interface z80pio_interface; typedef struct _z80pio_interface z80pio_interface;
/*************************************************************************** /***************************************************************************
INITIALIZATION/CONFIGURATION DEVICE CONFIGURATION MACROS
***************************************************************************/ ***************************************************************************/
void z80pio_init(int which, const z80pio_interface *intf); #define MDRV_Z80PIO_ADD(_tag, _intrf) \
void z80pio_reset(int which); MDRV_DEVICE_ADD(_tag, Z80PIO) \
MDRV_DEVICE_CONFIG(_intrf)
#define MDRV_Z80PIO_REMOVE(_tag) \
MDRV_DEVICE_REMOVE(_tag, Z80PIO)
/***************************************************************************
INITIALIZATION
***************************************************************************/
void z80pio_reset( const device_config *device );
/*************************************************************************** /***************************************************************************
CONTROL REGISTER READ/WRITE CONTROL REGISTER READ/WRITE
***************************************************************************/ ***************************************************************************/
void z80pio_c_w(running_machine *machine, int which, int ch, UINT8 data); WRITE8_DEVICE_HANDLER( z80pio_c_w );
UINT8 z80pio_c_r(int which, int ch); READ8_DEVICE_HANDLER( z80pio_c_r );
/*************************************************************************** /***************************************************************************
DATA REGISTER READ/WRITE DATA REGISTER READ/WRITE
***************************************************************************/ ***************************************************************************/
void z80pio_d_w(running_machine *machine, int which, int ch, UINT8 data); WRITE8_DEVICE_HANDLER( z80pio_d_w );
UINT8 z80pio_d_r(running_machine *machine, int which, int ch); READ8_DEVICE_HANDLER( z80pio_d_r );
/*************************************************************************** /***************************************************************************
PORT I/O PORT I/O
***************************************************************************/ ***************************************************************************/
void z80pio_p_w(running_machine *machine, int which, UINT8 ch, UINT8 data); WRITE8_DEVICE_HANDLER( z80pio_p_w );
int z80pio_p_r(running_machine *machine, int which, UINT8 ch); READ8_DEVICE_HANDLER( z80pio_p_r );
WRITE8_HANDLER( z80pioA_0_p_w );
WRITE8_HANDLER( z80pioB_0_p_w );
READ8_HANDLER( z80pioA_0_p_r );
READ8_HANDLER( z80pioB_0_p_r );
WRITE8_HANDLER( z80pioA_1_p_w );
WRITE8_HANDLER( z80pioB_1_p_w );
READ8_HANDLER( z80pioA_1_p_r );
READ8_HANDLER( z80pioB_1_p_r );
/*************************************************************************** /***************************************************************************
STROBE STATE MANAGEMENT STROBE STATE MANAGEMENT
***************************************************************************/ ***************************************************************************/
void z80pio_astb_w(running_machine *machine, int which, int state); void z80pio_astb_w(const device_config *device, int state);
void z80pio_bstb_w(running_machine *machine, int which, int state); void z80pio_bstb_w(const device_config *device, int state);
/*************************************************************************** /***************************************************************************
DAISY CHAIN INTERFACE DAISY CHAIN INTERFACE
***************************************************************************/ ***************************************************************************/
int z80pio_irq_state(int which); int z80pio_irq_state(const device_config *device);
int z80pio_irq_ack(int which); int z80pio_irq_ack(const device_config *device);
void z80pio_irq_reti(int which); void z80pio_irq_reti(const device_config *device);
/*************************************************************************** /***************************************************************************
READ/WRITE HANDLERS READ/WRITE HANDLERS
***************************************************************************/ ***************************************************************************/
READ8_HANDLER(z80pio_0_r); READ8_DEVICE_HANDLER(z80pio_r);
WRITE8_HANDLER(z80pio_0_w); WRITE8_DEVICE_HANDLER(z80pio_w);
READ8_HANDLER(z80pio_1_r);
WRITE8_HANDLER(z80pio_1_w);
/* ----- device interface ----- */
#define Z80PIO DEVICE_GET_INFO_NAME(z80pio)
DEVICE_GET_INFO( z80pio );
#endif

View File

@ -1,21 +1,64 @@
#include "driver.h" #include "driver.h"
#include "deprecat.h" #include "deprecat.h"
#include "cpu/z80/z80daisy.h"
#include "machine/z80pio.h" #include "machine/z80pio.h"
#include "machine/z80ctc.h" #include "machine/z80ctc.h"
#include "sound/samples.h" #include "sound/samples.h"
/* single tone generator */
#define SINGLE_LENGTH 10000
#define SINGLE_DIVIDER 8
static INT16 *_single;
static int single_rate = 1000;
static int single_volume = 0;
static const device_config *z80pio;
static void senjyo_z80pio_reset(int which)
{
z80pio_reset( z80pio );
}
static int senjyo_z80pio_irq_state(int which)
{
return z80pio_irq_state( z80pio );
}
static int senjyo_z80pio_irq_ack(int which)
{
return z80pio_irq_ack( z80pio );
}
static void senjyo_z80pio_irq_reti(int which)
{
z80pio_irq_reti( z80pio );
}
const struct z80_irq_daisy_chain senjyo_daisy_chain[] =
{
{ z80ctc_reset, z80ctc_irq_state, z80ctc_irq_ack, z80ctc_irq_reti , 0 }, /* device 0 = CTC_0 , high priority */
{ senjyo_z80pio_reset, senjyo_z80pio_irq_state, senjyo_z80pio_irq_ack, senjyo_z80pio_irq_reti , 0 }, /* device 1 = PIO_0 , low priority */
{ 0,0,0,0,-1} /* end mark */
};
/* z80 pio */ /* z80 pio */
static void pio_interrupt(running_machine *machine, int state) static void pio_interrupt(running_machine *machine, int state)
{ {
cpunum_set_input_line(machine, 1, 0, state); cpunum_set_input_line(machine, 1, 0, state);
} }
static const z80pio_interface pio_intf = const z80pio_interface senjyo_pio_intf =
{ {
pio_interrupt, pio_interrupt,
0, NULL,
0 NULL,
NULL,
NULL,
NULL,
NULL
}; };
/* z80 ctc */ /* z80 ctc */
@ -35,15 +78,6 @@ static z80ctc_interface ctc_intf =
}; };
/* single tone generator */
#define SINGLE_LENGTH 10000
#define SINGLE_DIVIDER 8
static INT16 *_single;
static int single_rate = 1000;
static int single_volume = 0;
WRITE8_HANDLER( senjyo_volume_w ) WRITE8_HANDLER( senjyo_volume_w )
{ {
single_volume = data & 0x0f; single_volume = data & 0x0f;
@ -72,8 +106,7 @@ void senjyo_sh_start(void)
ctc_intf.baseclock = cpunum_get_clock(1); ctc_intf.baseclock = cpunum_get_clock(1);
z80ctc_init (0, &ctc_intf); z80ctc_init (0, &ctc_intf);
/* z80 pio init */ z80pio = device_list_find_by_tag( Machine->config->devicelist, Z80PIO, "z80pio" );
z80pio_init (0, &pio_intf);
_single = (INT16 *)auto_malloc(SINGLE_LENGTH*2); _single = (INT16 *)auto_malloc(SINGLE_LENGTH*2);

View File

@ -701,10 +701,10 @@ 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_READWRITE(mcr_ipu_pio_0_r, mcr_ipu_pio_0_w) AM_RANGE(0x00, 0x03) AM_MIRROR(0xe0) AM_DEVREADWRITE(Z80PIO, "z80pio_0", 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_READWRITE(mcr_ipu_sio_r, mcr_ipu_sio_w)
AM_RANGE(0x08, 0x0b) AM_MIRROR(0xe0) AM_READWRITE(z80ctc_1_r, z80ctc_1_w) AM_RANGE(0x08, 0x0b) AM_MIRROR(0xe0) AM_READWRITE(z80ctc_1_r, z80ctc_1_w)
AM_RANGE(0x0c, 0x0f) AM_MIRROR(0xe0) AM_READWRITE(mcr_ipu_pio_1_r, mcr_ipu_pio_1_w) AM_RANGE(0x0c, 0x0f) AM_MIRROR(0xe0) AM_DEVREADWRITE(Z80PIO, "z80pio_1", 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)
AM_RANGE(0x1c, 0x1f) AM_MIRROR(0xe0) AM_READWRITE(mcr_ipu_watchdog_r, mcr_ipu_watchdog_w) AM_RANGE(0x1c, 0x1f) AM_MIRROR(0xe0) AM_READWRITE(mcr_ipu_watchdog_r, mcr_ipu_watchdog_w)
ADDRESS_MAP_END ADDRESS_MAP_END
@ -1601,6 +1601,9 @@ static MACHINE_DRIVER_START( mcr_91490_ipu )
MDRV_CPU_PROGRAM_MAP(ipu_91695_map,0) MDRV_CPU_PROGRAM_MAP(ipu_91695_map,0)
MDRV_CPU_IO_MAP(ipu_91695_portmap,0) MDRV_CPU_IO_MAP(ipu_91695_portmap,0)
MDRV_CPU_VBLANK_INT_HACK(mcr_ipu_interrupt,2) MDRV_CPU_VBLANK_INT_HACK(mcr_ipu_interrupt,2)
MDRV_Z80PIO_ADD( "z80pio_0", nflfoot_pio_intf )
MDRV_Z80PIO_ADD( "z80pio_1", nflfoot_pio_intf )
MACHINE_DRIVER_END MACHINE_DRIVER_END

View File

@ -93,6 +93,8 @@ PROGRAM# Program Version Program Differences
#define UART_CLK XTAL_18_432MHz #define UART_CLK XTAL_18_432MHz
static UINT8* meritm_ram; static UINT8* meritm_ram;
static const device_config *meritm_z80pio[2];
/************************************* /*************************************
* *
@ -297,7 +299,7 @@ static void meritm_vdp0_interrupt(running_machine *machine, int i)
meritm_vint |= 0x08; meritm_vint |= 0x08;
if(i) if(i)
z80pio_p_w(machine, 0, 0, meritm_vint); z80pio_p_w(meritm_z80pio[0], 0, meritm_vint);
} }
} }
@ -312,7 +314,7 @@ static void meritm_vdp1_interrupt(running_machine *machine, int i)
meritm_vint |= 0x10; meritm_vint |= 0x10;
if(i) if(i)
z80pio_p_w(machine, 0, 0, meritm_vint); z80pio_p_w(meritm_z80pio[0], 0, meritm_vint);
} }
} }
@ -556,8 +558,8 @@ static ADDRESS_MAP_START( meritm_crt250_io_map, ADDRESS_SPACE_IO, 8 )
AM_RANGE(0x22, 0x22) AM_WRITE(v9938_1_palette_w) AM_RANGE(0x22, 0x22) AM_WRITE(v9938_1_palette_w)
AM_RANGE(0x23, 0x23) AM_WRITE(v9938_1_register_w) AM_RANGE(0x23, 0x23) AM_WRITE(v9938_1_register_w)
AM_RANGE(0x30, 0x33) AM_DEVREADWRITE(PPI8255, "ppi8255", ppi8255_r, ppi8255_w) AM_RANGE(0x30, 0x33) AM_DEVREADWRITE(PPI8255, "ppi8255", ppi8255_r, ppi8255_w)
AM_RANGE(0x40, 0x43) AM_READWRITE(z80pio_0_r, z80pio_0_w) AM_RANGE(0x40, 0x43) AM_DEVREADWRITE(Z80PIO, "z80pio_0", z80pio_r, z80pio_w)
AM_RANGE(0x50, 0x53) AM_READWRITE(z80pio_1_r, z80pio_1_w) AM_RANGE(0x50, 0x53) AM_DEVREADWRITE(Z80PIO, "z80pio_1", z80pio_r, z80pio_w)
AM_RANGE(0x80, 0x80) AM_READWRITE(ay8910_read_port_0_r, ay8910_control_port_0_w) AM_RANGE(0x80, 0x80) AM_READWRITE(ay8910_read_port_0_r, ay8910_control_port_0_w)
AM_RANGE(0x81, 0x81) AM_WRITE(ay8910_write_port_0_w) AM_RANGE(0x81, 0x81) AM_WRITE(ay8910_write_port_0_w)
AM_RANGE(0xff, 0xff) AM_WRITE(meritm_crt250_bank_w) AM_RANGE(0xff, 0xff) AM_WRITE(meritm_crt250_bank_w)
@ -582,8 +584,8 @@ static ADDRESS_MAP_START( meritm_io_map, ADDRESS_SPACE_IO, 8 )
AM_RANGE(0x22, 0x22) AM_WRITE(v9938_1_palette_w) AM_RANGE(0x22, 0x22) AM_WRITE(v9938_1_palette_w)
AM_RANGE(0x23, 0x23) AM_WRITE(v9938_1_register_w) AM_RANGE(0x23, 0x23) AM_WRITE(v9938_1_register_w)
AM_RANGE(0x30, 0x33) AM_DEVREADWRITE(PPI8255, "ppi8255", ppi8255_r, ppi8255_w) AM_RANGE(0x30, 0x33) AM_DEVREADWRITE(PPI8255, "ppi8255", ppi8255_r, ppi8255_w)
AM_RANGE(0x40, 0x43) AM_READWRITE(z80pio_0_r, z80pio_0_w) AM_RANGE(0x40, 0x43) AM_DEVREADWRITE(Z80PIO, "z80pio_0", z80pio_r, z80pio_w)
AM_RANGE(0x50, 0x53) AM_READWRITE(z80pio_1_r, z80pio_1_w) AM_RANGE(0x50, 0x53) AM_DEVREADWRITE(Z80PIO, "z80pio_1", z80pio_r, z80pio_w)
AM_RANGE(0x60, 0x67) AM_READWRITE(pc16552d_0_r,pc16552d_0_w) AM_RANGE(0x60, 0x67) AM_READWRITE(pc16552d_0_r,pc16552d_0_w)
AM_RANGE(0x80, 0x80) AM_READWRITE(ay8910_read_port_0_r, ay8910_control_port_0_w) AM_RANGE(0x80, 0x80) AM_READWRITE(ay8910_read_port_0_r, ay8910_control_port_0_w)
AM_RANGE(0x81, 0x81) AM_WRITE(ay8910_write_port_0_w) AM_RANGE(0x81, 0x81) AM_WRITE(ay8910_write_port_0_w)
@ -758,42 +760,42 @@ static void meritm_io_pio_interrupt(running_machine *machine, int state)
} }
static READ8_HANDLER(meritm_audio_pio_port_a_r) static READ8_DEVICE_HANDLER(meritm_audio_pio_port_a_r)
{ {
return meritm_vint; return meritm_vint;
}; };
static READ8_HANDLER(meritm_audio_pio_port_b_r) static READ8_DEVICE_HANDLER(meritm_audio_pio_port_b_r)
{ {
return ds1204_r(); return ds1204_r();
}; };
static WRITE8_HANDLER(meritm_audio_pio_port_a_w) static WRITE8_DEVICE_HANDLER(meritm_audio_pio_port_a_w)
{ {
meritm_bank = (data & 7) | ((data >> 2) & 0x18); meritm_bank = (data & 7) | ((data >> 2) & 0x18);
//logerror("Writing BANK with %x (raw = %x)\n", meritm_bank, data); //logerror("Writing BANK with %x (raw = %x)\n", meritm_bank, data);
}; };
static WRITE8_HANDLER(meritm_audio_pio_port_b_w) static WRITE8_DEVICE_HANDLER(meritm_audio_pio_port_b_w)
{ {
ds1204_w((data & 0x4) >> 2, (data & 0x2) >> 1, data & 0x01); ds1204_w((data & 0x4) >> 2, (data & 0x2) >> 1, data & 0x01);
}; };
static READ8_HANDLER(meritm_io_pio_port_a_r) static READ8_DEVICE_HANDLER(meritm_io_pio_port_a_r)
{ {
return input_port_read(machine, "PIO1_PORTA"); return input_port_read(device->machine, "PIO1_PORTA");
}; };
static READ8_HANDLER(meritm_io_pio_port_b_r) static READ8_DEVICE_HANDLER(meritm_io_pio_port_b_r)
{ {
return input_port_read(machine, "PIO1_PORTB"); return input_port_read(device->machine, "PIO1_PORTB");
}; };
static WRITE8_HANDLER(meritm_io_pio_port_a_w) static WRITE8_DEVICE_HANDLER(meritm_io_pio_port_a_w)
{ {
}; };
static WRITE8_HANDLER(meritm_io_pio_port_b_w) static WRITE8_DEVICE_HANDLER(meritm_io_pio_port_b_w)
{ {
}; };
@ -826,17 +828,37 @@ static void meritm_pio1_portb_input_changed_callback(void *param, UINT32 oldval,
} }
#endif #endif
static void meritm_z80pio_reset(int which)
{
z80pio_reset( meritm_z80pio[which] );
}
static int meritm_z80pio_irq_state(int which)
{
return z80pio_irq_state( meritm_z80pio[which] );
}
static int meritm_z80pio_irq_ack(int which)
{
return z80pio_irq_ack( meritm_z80pio[which] );
}
static void meritm_z80pio_irq_reti(int which)
{
z80pio_irq_reti( meritm_z80pio[which] );
}
static const struct z80_irq_daisy_chain meritm_daisy_chain[] = static const struct z80_irq_daisy_chain meritm_daisy_chain[] =
{ {
{ z80pio_reset, z80pio_irq_state, z80pio_irq_ack, z80pio_irq_reti, 1 }, /* PIO number 1 */ { meritm_z80pio_reset, meritm_z80pio_irq_state, meritm_z80pio_irq_ack, meritm_z80pio_irq_reti, 1 }, /* PIO number 1 */
{ z80pio_reset, z80pio_irq_state, z80pio_irq_ack, z80pio_irq_reti, 0 }, /* PIO number 0 */ { meritm_z80pio_reset, meritm_z80pio_irq_state, meritm_z80pio_irq_ack, meritm_z80pio_irq_reti, 0 }, /* PIO number 0 */
{ 0, 0, 0, 0, -1 } /* end mark */ { 0, 0, 0, 0, -1 } /* end mark */
}; };
static MACHINE_START(merit_common) static MACHINE_START(merit_common)
{ {
z80pio_init(0, &meritm_audio_pio_intf); meritm_z80pio[0] = device_list_find_by_tag( machine->config->devicelist, Z80PIO, "z80pio_0" );
z80pio_init(1, &meritm_io_pio_intf); meritm_z80pio[1] = device_list_find_by_tag( machine->config->devicelist, Z80PIO, "z80pio_1" );
//input_port_set_changed_callback(port_tag_to_index("PIO1_PORTB"), 0xff, meritm_pio1_portb_input_changed_callback, NULL); //input_port_set_changed_callback(port_tag_to_index("PIO1_PORTB"), 0xff, meritm_pio1_portb_input_changed_callback, NULL);
}; };
@ -907,6 +929,9 @@ static MACHINE_DRIVER_START(meritm_crt250)
MDRV_DEVICE_ADD( "ppi8255", PPI8255 ) MDRV_DEVICE_ADD( "ppi8255", PPI8255 )
MDRV_DEVICE_CONFIG( crt250_ppi8255_intf ) MDRV_DEVICE_CONFIG( crt250_ppi8255_intf )
MDRV_Z80PIO_ADD( "z80pio_0", meritm_audio_pio_intf )
MDRV_Z80PIO_ADD( "z80pio_1", meritm_io_pio_intf )
MDRV_NVRAM_HANDLER(generic_0fill) MDRV_NVRAM_HANDLER(generic_0fill)
MDRV_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK) MDRV_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK)

View File

@ -97,15 +97,11 @@ VIDEO_START( senjyo );
VIDEO_UPDATE( senjyo ); VIDEO_UPDATE( senjyo );
extern int is_senjyo, senjyo_scrollhack; extern int is_senjyo, senjyo_scrollhack;
/* in audio/senjyo.c */
extern const struct z80_irq_daisy_chain senjyo_daisy_chain[];
extern const z80pio_interface senjyo_pio_intf;
void senjyo_sh_start(void); void senjyo_sh_start(void);
WRITE8_HANDLER( senjyo_sh_0_w );
WRITE8_HANDLER( senjyo_sh_1_w );
WRITE8_HANDLER( senjyo_sh_2_w );
WRITE8_HANDLER( starforc_pio_w );
READ8_HANDLER( starforc_pio_r );
WRITE8_HANDLER( senjyo_volume_w ); WRITE8_HANDLER( senjyo_volume_w );
@ -199,7 +195,7 @@ AM_RANGE(0x9e00, 0x9e3f) AM_WRITE(SMH_RAM)
AM_RANGE(0xb000, 0xb7ff) AM_WRITE(senjyo_bg1videoram_w) AM_BASE(&senjyo_bg1videoram) AM_RANGE(0xb000, 0xb7ff) AM_WRITE(senjyo_bg1videoram_w) AM_BASE(&senjyo_bg1videoram)
AM_RANGE(0xb800, 0xbbff) AM_WRITE(SMH_RAM) AM_BASE(&senjyo_radarram) AM_RANGE(0xb800, 0xbbff) AM_WRITE(SMH_RAM) AM_BASE(&senjyo_radarram)
AM_RANGE(0xd000, 0xd000) AM_WRITE(flip_screen_w) AM_RANGE(0xd000, 0xd000) AM_WRITE(flip_screen_w)
AM_RANGE(0xd004, 0xd004) AM_WRITE(z80pioA_0_p_w) AM_RANGE(0xd004, 0xd004) AM_DEVWRITE(Z80PIO, "z80pio", z80pio_p_w)
ADDRESS_MAP_END ADDRESS_MAP_END
@ -257,7 +253,7 @@ static ADDRESS_MAP_START( starforb_writemem, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0xb000, 0xb7ff) AM_WRITE(senjyo_bg1videoram_w) AM_BASE(&senjyo_bg1videoram) AM_RANGE(0xb000, 0xb7ff) AM_WRITE(senjyo_bg1videoram_w) AM_BASE(&senjyo_bg1videoram)
AM_RANGE(0xb800, 0xbbff) AM_WRITE(SMH_RAM) AM_BASE(&senjyo_radarram) AM_RANGE(0xb800, 0xbbff) AM_WRITE(SMH_RAM) AM_BASE(&senjyo_radarram)
AM_RANGE(0xd000, 0xd000) AM_WRITE(flip_screen_w) AM_RANGE(0xd000, 0xd000) AM_WRITE(flip_screen_w)
AM_RANGE(0xd004, 0xd004) AM_WRITE(z80pioA_0_p_w) AM_RANGE(0xd004, 0xd004) AM_DEVWRITE(Z80PIO, "z80pio", z80pio_p_w)
/* these aren't used / written, left here to make sure memory is allocated */ /* these aren't used / written, left here to make sure memory is allocated */
AM_RANGE(0xfe00, 0xfe1f) AM_WRITE(SMH_RAM) AM_BASE(&senjyo_fgscroll) AM_RANGE(0xfe00, 0xfe1f) AM_WRITE(SMH_RAM) AM_BASE(&senjyo_fgscroll)
@ -288,22 +284,22 @@ static ADDRESS_MAP_START( starforb_sound_writemem, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0xf000, 0xffff) AM_WRITE(SMH_RAM) AM_RANGE(0xf000, 0xffff) AM_WRITE(SMH_RAM)
ADDRESS_MAP_END ADDRESS_MAP_END
static WRITE8_HANDLER( pio_w ) static WRITE8_DEVICE_HANDLER( pio_w )
{ {
if (offset & 1) if (offset & 1)
z80pio_c_w(machine, 0, (offset >> 1) & 1, data); z80pio_c_w(device, (offset >> 1) & 1, data);
else else
z80pio_d_w(machine, 0, (offset >> 1) & 1, data); z80pio_d_w(device, (offset >> 1) & 1, data);
} }
static READ8_HANDLER( pio_r ) static READ8_DEVICE_HANDLER( pio_r )
{ {
return (offset & 1) ? z80pio_c_r(0, (offset >> 1) & 1) : z80pio_d_r(machine, 0, (offset >> 1) & 1); return (offset & 1) ? z80pio_c_r(device, (offset >> 1) & 1) : z80pio_d_r(device, (offset >> 1) & 1);
} }
static ADDRESS_MAP_START( sound_io_map, ADDRESS_SPACE_IO, 8 ) static ADDRESS_MAP_START( sound_io_map, ADDRESS_SPACE_IO, 8 )
ADDRESS_MAP_GLOBAL_MASK(0xff) ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x00, 0x03) AM_READWRITE(pio_r, pio_w) AM_RANGE(0x00, 0x03) AM_DEVREADWRITE(Z80PIO, "z80pio", pio_r, pio_w)
AM_RANGE(0x08, 0x0b) AM_READWRITE(z80ctc_0_r, z80ctc_0_w) AM_RANGE(0x08, 0x0b) AM_READWRITE(z80ctc_0_r, z80ctc_0_w)
ADDRESS_MAP_END ADDRESS_MAP_END
@ -619,15 +615,6 @@ GFXDECODE_END
static const struct z80_irq_daisy_chain daisy_chain[] =
{
{ z80ctc_reset, z80ctc_irq_state, z80ctc_irq_ack, z80ctc_irq_reti , 0 }, /* device 0 = CTC_0 , high priority */
{ z80pio_reset, z80pio_irq_state, z80pio_irq_ack, z80pio_irq_reti , 0 }, /* device 1 = PIO_0 , low priority */
{ 0,0,0,0,-1} /* end mark */
};
static const samples_interface senjyo_samples_interface = static const samples_interface senjyo_samples_interface =
{ {
1, 1,
@ -645,12 +632,14 @@ static MACHINE_DRIVER_START( senjyo )
MDRV_CPU_VBLANK_INT("main", senjyo_interrupt) MDRV_CPU_VBLANK_INT("main", senjyo_interrupt)
MDRV_CPU_ADD("sub", Z80, 2000000) /* 2 MHz? */ MDRV_CPU_ADD("sub", Z80, 2000000) /* 2 MHz? */
MDRV_CPU_CONFIG(daisy_chain) MDRV_CPU_CONFIG(senjyo_daisy_chain)
MDRV_CPU_PROGRAM_MAP(sound_readmem,sound_writemem) MDRV_CPU_PROGRAM_MAP(sound_readmem,sound_writemem)
MDRV_CPU_IO_MAP(sound_io_map,0) MDRV_CPU_IO_MAP(sound_io_map,0)
MDRV_MACHINE_RESET(senjyo) MDRV_MACHINE_RESET(senjyo)
MDRV_Z80PIO_ADD( "z80pio", senjyo_pio_intf )
/* video hardware */ /* video hardware */
MDRV_SCREEN_ADD("main", RASTER) MDRV_SCREEN_ADD("main", RASTER)
MDRV_SCREEN_REFRESH_RATE(60) MDRV_SCREEN_REFRESH_RATE(60)

View File

@ -22,6 +22,7 @@ extern attotime mcr68_timing_factor;
extern const struct z80_irq_daisy_chain mcr_daisy_chain[]; extern const struct z80_irq_daisy_chain mcr_daisy_chain[];
extern const struct z80_irq_daisy_chain mcr_ipu_daisy_chain[]; extern const struct z80_irq_daisy_chain mcr_ipu_daisy_chain[];
extern const z80pio_interface nflfoot_pio_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;
@ -52,11 +53,7 @@ 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_pio_0_r );
READ8_HANDLER( mcr_ipu_pio_1_r );
READ8_HANDLER( mcr_ipu_sio_r ); READ8_HANDLER( mcr_ipu_sio_r );
WRITE8_HANDLER( mcr_ipu_pio_0_w );
WRITE8_HANDLER( mcr_ipu_pio_1_w );
WRITE8_HANDLER( mcr_ipu_sio_w ); WRITE8_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 );

View File

@ -71,6 +71,7 @@ static attotime m6840_internal_counter_period; /* 68000 CLK / 10 */
static emu_timer *ipu_watchdog_timer; static emu_timer *ipu_watchdog_timer;
static const device_config *nflfoot_z80pio[2];
/************************************* /*************************************
@ -207,12 +208,32 @@ const struct z80_irq_daisy_chain mcr_daisy_chain[] =
}; };
static void nflfoot_z80pio_reset(int which)
{
z80pio_reset( nflfoot_z80pio[which] );
}
static int nflfoot_z80pio_irq_state(int which)
{
return z80pio_irq_state( nflfoot_z80pio[which] );
}
static int nflfoot_z80pio_irq_ack(int which)
{
return z80pio_irq_ack( nflfoot_z80pio[which] );
}
static void nflfoot_z80pio_irq_reti(int which)
{
z80pio_irq_reti( nflfoot_z80pio[which] );
}
const struct z80_irq_daisy_chain mcr_ipu_daisy_chain[] = const struct z80_irq_daisy_chain mcr_ipu_daisy_chain[] =
{ {
{ z80ctc_reset, z80ctc_irq_state, z80ctc_irq_ack, z80ctc_irq_reti, 1 }, /* CTC number 1 */ { z80ctc_reset, z80ctc_irq_state, z80ctc_irq_ack, z80ctc_irq_reti, 1 }, /* CTC number 1 */
{ z80pio_reset, z80pio_irq_state, z80pio_irq_ack, z80pio_irq_reti, 1 }, /* PIO number 1 */ { nflfoot_z80pio_reset, nflfoot_z80pio_irq_state, nflfoot_z80pio_irq_ack, nflfoot_z80pio_irq_reti, 1 }, /* PIO number 1 */
{ z80sio_reset, z80sio_irq_state, z80sio_irq_ack, z80sio_irq_reti, 0 }, /* SIO number 0 */ { z80sio_reset, z80sio_irq_state, z80sio_irq_ack, z80sio_irq_reti, 0 }, /* SIO number 0 */
{ z80pio_reset, z80pio_irq_state, z80pio_irq_ack, z80pio_irq_reti, 0 }, /* PIO number 0 */ { nflfoot_z80pio_reset, nflfoot_z80pio_irq_state, nflfoot_z80pio_irq_ack, nflfoot_z80pio_irq_reti, 0 }, /* PIO number 0 */
{ 0, 0, 0, 0, -1 } /* end mark */ { 0, 0, 0, 0, -1 } /* end mark */
}; };
@ -239,11 +260,15 @@ static z80ctc_interface nflfoot_ctc_intf =
}; };
static const z80pio_interface nflfoot_pio_intf = const z80pio_interface nflfoot_pio_intf =
{ {
ipu_ctc_interrupt, ipu_ctc_interrupt,
0, NULL,
0 NULL,
NULL,
NULL,
NULL,
NULL
}; };
@ -284,8 +309,8 @@ MACHINE_START( nflfoot )
nflfoot_ctc_intf.baseclock = cpunum_get_clock(3); nflfoot_ctc_intf.baseclock = cpunum_get_clock(3);
z80ctc_init(1, &nflfoot_ctc_intf); z80ctc_init(1, &nflfoot_ctc_intf);
z80pio_init(0, &nflfoot_pio_intf); nflfoot_z80pio[0] = device_list_find_by_tag( machine->config->devicelist, Z80PIO, "z80pio_0" );
z80pio_init(1, &nflfoot_pio_intf); nflfoot_z80pio[1] = device_list_find_by_tag( machine->config->devicelist, Z80PIO, "z80pio_1" );
nflfoot_sio_intf.baseclock = cpunum_get_clock(3); nflfoot_sio_intf.baseclock = cpunum_get_clock(3);
z80sio_init(0, &nflfoot_sio_intf); z80sio_init(0, &nflfoot_sio_intf);
@ -934,42 +959,12 @@ static WRITE8_HANDLER( ipu_break_changed )
} }
READ8_HANDLER( mcr_ipu_pio_0_r )
{
return (offset & 2) ? z80pio_c_r(0, offset & 1) : z80pio_d_r(machine, 0, offset & 1);
}
READ8_HANDLER( mcr_ipu_pio_1_r )
{
return (offset & 2) ? z80pio_c_r(1, offset & 1) : z80pio_d_r(machine, 1, offset & 1);
}
READ8_HANDLER( mcr_ipu_sio_r ) READ8_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(0, offset & 1) : z80sio_d_r(machine, 0, offset & 1);
} }
WRITE8_HANDLER( mcr_ipu_pio_0_w )
{
if (offset & 2)
z80pio_c_w(machine, 0, offset & 1, data);
else
z80pio_d_w(machine, 0, offset & 1, data);
}
WRITE8_HANDLER( mcr_ipu_pio_1_w )
{
if (offset & 2)
z80pio_c_w(machine, 1, offset & 1, data);
else
z80pio_d_w(machine, 1, offset & 1, data);
}
WRITE8_HANDLER( mcr_ipu_sio_w ) WRITE8_HANDLER( mcr_ipu_sio_w )
{ {
if (offset & 2) if (offset & 2)
@ -995,8 +990,8 @@ static TIMER_CALLBACK( ipu_watchdog_reset )
logerror("ipu_watchdog_reset\n"); logerror("ipu_watchdog_reset\n");
cpunum_set_input_line(machine, 3, INPUT_LINE_RESET, PULSE_LINE); cpunum_set_input_line(machine, 3, INPUT_LINE_RESET, PULSE_LINE);
z80ctc_reset(1); z80ctc_reset(1);
z80pio_reset(0); z80pio_reset( nflfoot_z80pio[0] );
z80pio_reset(1); z80pio_reset( nflfoot_z80pio[1] );
z80sio_reset(0); z80sio_reset(0);
} }