mirror of
https://github.com/holub/mame
synced 2025-05-17 19:24:59 +03:00
Converted the z80pio implementation into a device.
This commit is contained in:
parent
e8896b0416
commit
08e57e7e28
@ -58,8 +58,8 @@ struct _z80pio
|
||||
UINT8 vector[2]; /* interrupt vector */
|
||||
void (*intr)(running_machine *, int which); /* interrupt callbacks */
|
||||
void (*rdyr[2])(int data); /* RDY active callback */
|
||||
read8_machine_func port_read[2]; /* port read callbacks */
|
||||
write8_machine_func port_write[2]; /* port write callbacks */
|
||||
read8_device_func port_read[2]; /* port read callbacks */
|
||||
write8_device_func port_write[2]; /* port write callbacks */
|
||||
UINT8 mode[2]; /* mode 00=in,01=out,02=i/o,03=bit*/
|
||||
UINT8 enable[2]; /* interrupt enable */
|
||||
UINT8 mask[2]; /* mask folowers */
|
||||
@ -70,149 +70,100 @@ struct _z80pio
|
||||
UINT8 strobe[2]; /* strobe inputs */
|
||||
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
|
||||
***************************************************************************/
|
||||
|
||||
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 */
|
||||
pio->rdy[ch] = state;
|
||||
z80pio->rdy[ch] = state;
|
||||
|
||||
/* call callback with state */
|
||||
if (pio->rdyr[ch])
|
||||
(*pio->rdyr[ch])(pio->rdy[ch]);
|
||||
if (z80pio->rdyr[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 (pio->intr)
|
||||
(*pio->intr)(machine, (z80pio_irq_state(which) & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE);
|
||||
if (z80pio->intr)
|
||||
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 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 */
|
||||
if (pio->enable[ch] & PIO_INT_ENABLE)
|
||||
if (z80pio->enable[ch] & PIO_INT_ENABLE)
|
||||
{
|
||||
/* in mode 3, interrupts are tricky */
|
||||
if (pio->mode[ch] == PIO_MODE3)
|
||||
if (z80pio->mode[ch] == PIO_MODE3)
|
||||
{
|
||||
/* fetch input data (ignore output lines) */
|
||||
data = pio->in[ch] & pio->dir[ch];
|
||||
data = z80pio->in[ch] & z80pio->dir[ch];
|
||||
|
||||
/* keep only relevant bits */
|
||||
data &= ~pio->mask[ch];
|
||||
data &= ~z80pio->mask[ch];
|
||||
|
||||
/* if active low, invert the bits */
|
||||
if (!(pio->enable[ch] & PIO_INT_HIGH))
|
||||
data ^= pio->mask[ch];
|
||||
if (!(z80pio->enable[ch] & PIO_INT_HIGH))
|
||||
data ^= z80pio->mask[ch];
|
||||
|
||||
/* if AND logic, interrupt if all bits are set */
|
||||
if (pio->enable[ch] & PIO_INT_AND)
|
||||
irq = (data == pio->mask[ch]);
|
||||
if (z80pio->enable[ch] & PIO_INT_AND)
|
||||
irq = (data == z80pio->mask[ch]);
|
||||
|
||||
/* otherwise, interrupt if at least one bit is set */
|
||||
else
|
||||
irq = (data != 0);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* otherwise, just interrupt when ready is cleared */
|
||||
else
|
||||
irq = (pio->rdy[ch] == 0);
|
||||
irq = (z80pio->rdy[ch] == 0);
|
||||
}
|
||||
|
||||
if (irq)
|
||||
pio->int_state[ch] |= Z80_DAISY_INT;
|
||||
z80pio->int_state[ch] |= Z80_DAISY_INT;
|
||||
else
|
||||
pio->int_state[ch] &= ~Z80_DAISY_INT;
|
||||
z80pio->int_state[ch] &= ~Z80_DAISY_INT;
|
||||
|
||||
if (old_state != pio->int_state[ch])
|
||||
interrupt_check(machine, pio - pios);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
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);
|
||||
if (old_state != z80pio->int_state[ch])
|
||||
interrupt_check(device);
|
||||
}
|
||||
|
||||
|
||||
@ -221,70 +172,76 @@ void z80pio_reset(int which)
|
||||
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 ? */
|
||||
if (pio->mode[ch] == 0x13)
|
||||
if (z80pio->mode[offset] == 0x13)
|
||||
{
|
||||
VPRINTF(("PIO-%c Bits %02x\n", 'A' + ch, data));
|
||||
pio->dir[ch] = data;
|
||||
pio->mode[ch] = 0x03;
|
||||
VPRINTF(("PIO-%c Bits %02x\n", 'A' + offset, data));
|
||||
z80pio->dir[offset] = data;
|
||||
z80pio->mode[offset] = 0x03;
|
||||
return;
|
||||
}
|
||||
|
||||
/* load mask folows phase ? */
|
||||
if (pio->enable[ch] & PIO_INT_MASK)
|
||||
if (z80pio->enable[offset] & PIO_INT_MASK)
|
||||
{
|
||||
/* load mask folows */
|
||||
pio->mask[ch] = data;
|
||||
pio->enable[ch] &= ~PIO_INT_MASK;
|
||||
VPRINTF(("PIO-%c interrupt mask %02x\n",'A'+ch,data ));
|
||||
z80pio->mask[offset] = data;
|
||||
z80pio->enable[offset] &= ~PIO_INT_MASK;
|
||||
VPRINTF(("PIO-%c interrupt mask %02x\n",'A'+offset,data ));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (data & 0x0f)
|
||||
{
|
||||
case PIO_OP_MODE: /* mode select 0=out,1=in,2=i/o,3=bit */
|
||||
pio->mode[ch] = (data >> 6);
|
||||
VPRINTF(("PIO-%c Mode %x\n", 'A' + ch, pio->mode[ch]));
|
||||
if (pio->mode[ch] == 0x03)
|
||||
pio->mode[ch] = 0x13;
|
||||
z80pio->mode[offset] = (data >> 6);
|
||||
VPRINTF(("PIO-%c Mode %x\n", 'A' + offset, z80pio->mode[offset]));
|
||||
if (z80pio->mode[offset] == 0x03)
|
||||
z80pio->mode[offset] = 0x13;
|
||||
return;
|
||||
|
||||
case PIO_OP_INTC: /* interrupt control */
|
||||
pio->enable[ch] = data & 0xf0;
|
||||
pio->mask[ch] = 0x00;
|
||||
z80pio->enable[offset] = data & 0xf0;
|
||||
z80pio->mask[offset] = 0x00;
|
||||
/* 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;
|
||||
|
||||
case PIO_OP_INTE: /* interrupt enable controll */
|
||||
pio->enable[ch] &= ~PIO_INT_ENABLE;
|
||||
pio->enable[ch] |= (data & PIO_INT_ENABLE);
|
||||
VPRINTF(("PIO-%c enable %02x\n", 'A' + ch, data & 0x80));
|
||||
z80pio->enable[offset] &= ~PIO_INT_ENABLE;
|
||||
z80pio->enable[offset] |= (data & PIO_INT_ENABLE);
|
||||
VPRINTF(("PIO-%c enable %02x\n", 'A' + offset, data & 0x80));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!(data & 1))
|
||||
{
|
||||
pio->vector[ch] = data;
|
||||
VPRINTF(("PIO-%c vector %02x\n", 'A' + ch, data));
|
||||
z80pio->vector[offset] = data;
|
||||
VPRINTF(("PIO-%c vector %02x\n", 'A' + offset, data));
|
||||
}
|
||||
else
|
||||
VPRINTF(("PIO-%c illegal command %02x\n", 'A' + ch, data));
|
||||
VPRINTF(("PIO-%c illegal command %02x\n", 'A' + offset, data));
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@ -294,20 +251,23 @@ UINT8 z80pio_c_r(int which, int ch)
|
||||
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 */
|
||||
if(pio->port_write[ch])
|
||||
pio->port_write[ch](machine, 0, data);
|
||||
/* There are only 2 channels */
|
||||
offset &= 0x01;
|
||||
|
||||
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_MODE2: /* mode 2 i/o */
|
||||
set_rdy(pio, ch, 1); /* ready = H */
|
||||
update_irq_state(machine, pio, ch);
|
||||
set_rdy(device, offset, 1); /* ready = H */
|
||||
update_irq_state(device, offset);
|
||||
return;
|
||||
|
||||
case PIO_MODE1: /* mode 1 input */
|
||||
@ -315,41 +275,44 @@ void z80pio_d_w(running_machine *machine, int which, int ch, UINT8 data)
|
||||
return;
|
||||
|
||||
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 */
|
||||
return pio->out[ch];
|
||||
return z80pio->out[offset];
|
||||
|
||||
case PIO_MODE1: /* mode 1 input */
|
||||
set_rdy(pio, ch, 1); /* ready = H */
|
||||
if(pio->port_read[ch])
|
||||
pio->in[ch] = pio->port_read[ch](machine, 0);
|
||||
update_irq_state(machine, pio, ch);
|
||||
return pio->in[ch];
|
||||
set_rdy(device, offset, 1); /* ready = H */
|
||||
if(z80pio->port_read[offset])
|
||||
z80pio->in[offset] = z80pio->port_read[offset](device, 0);
|
||||
update_irq_state(device, offset);
|
||||
return z80pio->in[offset];
|
||||
|
||||
case PIO_MODE2: /* mode 2 i/o */
|
||||
if (ch) VPRINTF(("PIO-B mode 2 \n"));
|
||||
set_rdy(pio, 1, 1); /* brdy = H */
|
||||
if(pio->port_read[ch])
|
||||
pio->in[ch] = pio->port_read[ch](machine, 0);
|
||||
update_irq_state(machine, pio, ch);
|
||||
return pio->in[ch];
|
||||
if (offset) VPRINTF(("PIO-B mode 2 \n"));
|
||||
set_rdy(device, 1, 1); /* brdy = H */
|
||||
if(z80pio->port_read[offset])
|
||||
z80pio->in[offset] = z80pio->port_read[offset](device, 0);
|
||||
update_irq_state(device, offset);
|
||||
return z80pio->in[offset];
|
||||
|
||||
case PIO_MODE3: /* mode 3 bit */
|
||||
if(pio->port_read[ch])
|
||||
pio->in[ch] = pio->port_read[ch](machine, 0);
|
||||
return (pio->in[ch] & pio->dir[ch]) | (pio->out[ch] & ~pio->dir[ch]);
|
||||
if(z80pio->port_read[offset])
|
||||
z80pio->in[offset] = z80pio->port_read[offset](device, 0);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -359,77 +322,71 @@ UINT8 z80pio_d_r(running_machine *machine, int which, int ch)
|
||||
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;
|
||||
switch (pio->mode[ch])
|
||||
/* There are only 2 channels */
|
||||
offset &= 0x01;
|
||||
|
||||
z80pio->in[offset] = data;
|
||||
switch (z80pio->mode[offset])
|
||||
{
|
||||
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;
|
||||
|
||||
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:
|
||||
set_rdy(pio, ch, 0);
|
||||
update_irq_state(machine, pio, ch);
|
||||
set_rdy(device, offset, 0);
|
||||
update_irq_state(device, offset);
|
||||
break;
|
||||
|
||||
case PIO_MODE3:
|
||||
/* irq check */
|
||||
update_irq_state(machine, pio, ch);
|
||||
update_irq_state(device, offset);
|
||||
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_MODE0:
|
||||
set_rdy(pio, ch, 0);
|
||||
update_irq_state(machine, pio, ch);
|
||||
set_rdy(device, offset, 0);
|
||||
update_irq_state(device, offset);
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
***************************************************************************/
|
||||
|
||||
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
|
||||
the receipt of data */
|
||||
@ -439,7 +396,7 @@ static void z80pio_update_strobe(running_machine *machine, int which, int ch, in
|
||||
state = state & 0x01;
|
||||
|
||||
/* strobe changed state? */
|
||||
if ((pio->strobe[ch] ^ state) != 0)
|
||||
if ((z80pio->strobe[ch] ^ state) != 0)
|
||||
{
|
||||
/* yes */
|
||||
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));
|
||||
|
||||
/* ready is now inactive */
|
||||
set_rdy(pio, ch, 0);
|
||||
set_rdy(device, ch, 0);
|
||||
|
||||
/* int enabled? */
|
||||
if (pio->enable[ch] & PIO_INT_ENABLE)
|
||||
if (z80pio->enable[ch] & PIO_INT_ENABLE)
|
||||
{
|
||||
/* trigger an int request */
|
||||
pio->int_state[ch] |= Z80_DAISY_INT;
|
||||
z80pio->int_state[ch] |= Z80_DAISY_INT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* store strobe state */
|
||||
pio->strobe[ch] = state;
|
||||
z80pio->strobe[ch] = state;
|
||||
|
||||
/* check interrupt */
|
||||
interrupt_check(machine, which);
|
||||
interrupt_check(device);
|
||||
}
|
||||
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_bstb_w(running_machine *machine, int which, int state) { z80pio_update_strobe(machine, which, 1, state); }
|
||||
void z80pio_astb_w(const device_config *device, int state) { z80pio_update_strobe(device, 0, 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
|
||||
***************************************************************************/
|
||||
|
||||
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 ch;
|
||||
|
||||
@ -495,84 +452,165 @@ int z80pio_irq_state(int which)
|
||||
for (ch = 0; ch < 2; ch++)
|
||||
{
|
||||
/* 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;
|
||||
break;
|
||||
}
|
||||
state |= pio->int_state[ch];
|
||||
state |= z80pio->int_state[ch];
|
||||
}
|
||||
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;
|
||||
|
||||
/* loop over all channels */
|
||||
for (ch = 0; ch < 2; ch++)
|
||||
|
||||
/* 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 */
|
||||
pio->int_state[ch] = Z80_DAISY_IEO;
|
||||
interrupt_check(Machine, which);
|
||||
return pio->vector[ch];
|
||||
z80pio->int_state[ch] = Z80_DAISY_IEO;
|
||||
interrupt_check(device);
|
||||
return z80pio->vector[ch];
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* loop over all channels */
|
||||
for (ch = 0; ch < 2; ch++)
|
||||
|
||||
/* 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 */
|
||||
pio->int_state[ch] &= ~Z80_DAISY_IEO;
|
||||
interrupt_check(Machine, which);
|
||||
z80pio->int_state[ch] &= ~Z80_DAISY_IEO;
|
||||
interrupt_check(device);
|
||||
return;
|
||||
}
|
||||
|
||||
VPRINTF(("z80pio_irq_reti: failed to find an interrupt to clear IEO on!"));
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
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)
|
||||
z80pio_c_w(machine, 0, offset & 1, data);
|
||||
z80pio_c_w(device, offset & 1, data);
|
||||
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_c_w(machine, 1, offset & 1, data);
|
||||
else
|
||||
z80pio_d_w(machine, 1, offset & 1, data);
|
||||
z80pio_t *z80pio = get_safe_token( device );
|
||||
int i;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,12 +7,8 @@
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
#define MAX_PIO 2
|
||||
|
||||
#ifndef __Z80PIO_H_
|
||||
#define __Z80PIO_H_
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
@ -22,83 +18,87 @@
|
||||
struct _z80pio_interface
|
||||
{
|
||||
void (*intr)(running_machine *machine, int which); /* callback when change interrupt status */
|
||||
read8_machine_func portAread; /* port A read callback */
|
||||
read8_machine_func portBread; /* port B read callback */
|
||||
write8_machine_func portAwrite; /* port A write callback */
|
||||
write8_machine_func portBwrite; /* port B write callback */
|
||||
read8_device_func portAread; /* port A read callback */
|
||||
read8_device_func portBread; /* port B read callback */
|
||||
write8_device_func portAwrite; /* port A write callback */
|
||||
write8_device_func portBwrite; /* port B write callback */
|
||||
void (*rdyA)(int data); /* portA 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;
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
INITIALIZATION/CONFIGURATION
|
||||
DEVICE CONFIGURATION MACROS
|
||||
***************************************************************************/
|
||||
|
||||
void z80pio_init(int which, const z80pio_interface *intf);
|
||||
void z80pio_reset(int which);
|
||||
#define MDRV_Z80PIO_ADD(_tag, _intrf) \
|
||||
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
|
||||
***************************************************************************/
|
||||
|
||||
void z80pio_c_w(running_machine *machine, int which, int ch, UINT8 data);
|
||||
UINT8 z80pio_c_r(int which, int ch);
|
||||
|
||||
WRITE8_DEVICE_HANDLER( z80pio_c_w );
|
||||
READ8_DEVICE_HANDLER( z80pio_c_r );
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
DATA REGISTER READ/WRITE
|
||||
***************************************************************************/
|
||||
|
||||
void z80pio_d_w(running_machine *machine, int which, int ch, UINT8 data);
|
||||
UINT8 z80pio_d_r(running_machine *machine, int which, int ch);
|
||||
|
||||
WRITE8_DEVICE_HANDLER( z80pio_d_w );
|
||||
READ8_DEVICE_HANDLER( z80pio_d_r );
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
PORT I/O
|
||||
***************************************************************************/
|
||||
|
||||
void z80pio_p_w(running_machine *machine, int which, UINT8 ch, UINT8 data);
|
||||
int z80pio_p_r(running_machine *machine, int which, UINT8 ch);
|
||||
|
||||
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 );
|
||||
|
||||
WRITE8_DEVICE_HANDLER( z80pio_p_w );
|
||||
READ8_DEVICE_HANDLER( z80pio_p_r );
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
STROBE STATE MANAGEMENT
|
||||
***************************************************************************/
|
||||
|
||||
void z80pio_astb_w(running_machine *machine, int which, int state);
|
||||
void z80pio_bstb_w(running_machine *machine, int which, int state);
|
||||
|
||||
void z80pio_astb_w(const device_config *device, int state);
|
||||
void z80pio_bstb_w(const device_config *device, int state);
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
DAISY CHAIN INTERFACE
|
||||
***************************************************************************/
|
||||
|
||||
int z80pio_irq_state(int which);
|
||||
int z80pio_irq_ack(int which);
|
||||
void z80pio_irq_reti(int which);
|
||||
int z80pio_irq_state(const device_config *device);
|
||||
int z80pio_irq_ack(const device_config *device);
|
||||
void z80pio_irq_reti(const device_config *device);
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
READ/WRITE HANDLERS
|
||||
***************************************************************************/
|
||||
READ8_HANDLER(z80pio_0_r);
|
||||
WRITE8_HANDLER(z80pio_0_w);
|
||||
READ8_HANDLER(z80pio_1_r);
|
||||
WRITE8_HANDLER(z80pio_1_w);
|
||||
READ8_DEVICE_HANDLER(z80pio_r);
|
||||
WRITE8_DEVICE_HANDLER(z80pio_w);
|
||||
|
||||
|
||||
/* ----- device interface ----- */
|
||||
|
||||
#define Z80PIO DEVICE_GET_INFO_NAME(z80pio)
|
||||
DEVICE_GET_INFO( z80pio );
|
||||
|
||||
#endif
|
||||
|
@ -1,21 +1,64 @@
|
||||
#include "driver.h"
|
||||
#include "deprecat.h"
|
||||
#include "cpu/z80/z80daisy.h"
|
||||
#include "machine/z80pio.h"
|
||||
#include "machine/z80ctc.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 */
|
||||
static void pio_interrupt(running_machine *machine, int state)
|
||||
{
|
||||
cpunum_set_input_line(machine, 1, 0, state);
|
||||
}
|
||||
|
||||
static const z80pio_interface pio_intf =
|
||||
const z80pio_interface senjyo_pio_intf =
|
||||
{
|
||||
pio_interrupt,
|
||||
0,
|
||||
0
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* 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 )
|
||||
{
|
||||
single_volume = data & 0x0f;
|
||||
@ -72,8 +106,7 @@ void senjyo_sh_start(void)
|
||||
ctc_intf.baseclock = cpunum_get_clock(1);
|
||||
z80ctc_init (0, &ctc_intf);
|
||||
|
||||
/* z80 pio init */
|
||||
z80pio_init (0, &pio_intf);
|
||||
z80pio = device_list_find_by_tag( Machine->config->devicelist, Z80PIO, "z80pio" );
|
||||
|
||||
_single = (INT16 *)auto_malloc(SINGLE_LENGTH*2);
|
||||
|
||||
|
@ -701,10 +701,10 @@ ADDRESS_MAP_END
|
||||
static ADDRESS_MAP_START( ipu_91695_portmap, ADDRESS_SPACE_IO, 8 )
|
||||
ADDRESS_MAP_UNMAP_HIGH
|
||||
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(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(0x1c, 0x1f) AM_MIRROR(0xe0) AM_READWRITE(mcr_ipu_watchdog_r, mcr_ipu_watchdog_w)
|
||||
ADDRESS_MAP_END
|
||||
@ -1601,6 +1601,9 @@ static MACHINE_DRIVER_START( mcr_91490_ipu )
|
||||
MDRV_CPU_PROGRAM_MAP(ipu_91695_map,0)
|
||||
MDRV_CPU_IO_MAP(ipu_91695_portmap,0)
|
||||
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
|
||||
|
||||
|
||||
|
@ -93,6 +93,8 @@ PROGRAM# Program Version Program Differences
|
||||
#define UART_CLK XTAL_18_432MHz
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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(0x23, 0x23) AM_WRITE(v9938_1_register_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(0x50, 0x53) AM_READWRITE(z80pio_1_r, z80pio_1_w)
|
||||
AM_RANGE(0x40, 0x43) AM_DEVREADWRITE(Z80PIO, "z80pio_0", z80pio_r, z80pio_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(0x81, 0x81) AM_WRITE(ay8910_write_port_0_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(0x23, 0x23) AM_WRITE(v9938_1_register_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(0x50, 0x53) AM_READWRITE(z80pio_1_r, z80pio_1_w)
|
||||
AM_RANGE(0x40, 0x43) AM_DEVREADWRITE(Z80PIO, "z80pio_0", z80pio_r, z80pio_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(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)
|
||||
@ -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;
|
||||
};
|
||||
|
||||
static READ8_HANDLER(meritm_audio_pio_port_b_r)
|
||||
static READ8_DEVICE_HANDLER(meritm_audio_pio_port_b_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);
|
||||
//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);
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
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[] =
|
||||
{
|
||||
{ z80pio_reset, z80pio_irq_state, z80pio_irq_ack, 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, 1 }, /* PIO number 1 */
|
||||
{ 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 */
|
||||
};
|
||||
|
||||
static MACHINE_START(merit_common)
|
||||
{
|
||||
z80pio_init(0, &meritm_audio_pio_intf);
|
||||
z80pio_init(1, &meritm_io_pio_intf);
|
||||
meritm_z80pio[0] = device_list_find_by_tag( machine->config->devicelist, Z80PIO, "z80pio_0" );
|
||||
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);
|
||||
|
||||
};
|
||||
@ -907,6 +929,9 @@ static MACHINE_DRIVER_START(meritm_crt250)
|
||||
MDRV_DEVICE_ADD( "ppi8255", PPI8255 )
|
||||
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_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK)
|
||||
|
@ -97,15 +97,11 @@ VIDEO_START( senjyo );
|
||||
VIDEO_UPDATE( senjyo );
|
||||
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);
|
||||
|
||||
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 );
|
||||
|
||||
|
||||
@ -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(0xb800, 0xbbff) AM_WRITE(SMH_RAM) AM_BASE(&senjyo_radarram)
|
||||
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
|
||||
|
||||
|
||||
@ -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(0xb800, 0xbbff) AM_WRITE(SMH_RAM) AM_BASE(&senjyo_radarram)
|
||||
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 */
|
||||
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)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static WRITE8_HANDLER( pio_w )
|
||||
static WRITE8_DEVICE_HANDLER( pio_w )
|
||||
{
|
||||
if (offset & 1)
|
||||
z80pio_c_w(machine, 0, (offset >> 1) & 1, data);
|
||||
z80pio_c_w(device, (offset >> 1) & 1, data);
|
||||
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 )
|
||||
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)
|
||||
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 =
|
||||
{
|
||||
1,
|
||||
@ -645,12 +632,14 @@ static MACHINE_DRIVER_START( senjyo )
|
||||
MDRV_CPU_VBLANK_INT("main", senjyo_interrupt)
|
||||
|
||||
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_IO_MAP(sound_io_map,0)
|
||||
|
||||
MDRV_MACHINE_RESET(senjyo)
|
||||
|
||||
MDRV_Z80PIO_ADD( "z80pio", senjyo_pio_intf )
|
||||
|
||||
/* video hardware */
|
||||
MDRV_SCREEN_ADD("main", RASTER)
|
||||
MDRV_SCREEN_REFRESH_RATE(60)
|
||||
|
@ -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_ipu_daisy_chain[];
|
||||
extern const z80pio_interface nflfoot_pio_intf;
|
||||
extern UINT8 mcr_cocktail_flip;
|
||||
|
||||
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_lower_r );
|
||||
|
||||
READ8_HANDLER( mcr_ipu_pio_0_r );
|
||||
READ8_HANDLER( mcr_ipu_pio_1_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_laserdisk_w );
|
||||
READ8_HANDLER( mcr_ipu_watchdog_r );
|
||||
|
@ -71,6 +71,7 @@ static attotime m6840_internal_counter_period; /* 68000 CLK / 10 */
|
||||
|
||||
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[] =
|
||||
{
|
||||
{ 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 */
|
||||
{ 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 */
|
||||
};
|
||||
|
||||
@ -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,
|
||||
0,
|
||||
0
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
@ -284,8 +309,8 @@ MACHINE_START( nflfoot )
|
||||
nflfoot_ctc_intf.baseclock = cpunum_get_clock(3);
|
||||
z80ctc_init(1, &nflfoot_ctc_intf);
|
||||
|
||||
z80pio_init(0, &nflfoot_pio_intf);
|
||||
z80pio_init(1, &nflfoot_pio_intf);
|
||||
nflfoot_z80pio[0] = device_list_find_by_tag( machine->config->devicelist, Z80PIO, "z80pio_0" );
|
||||
nflfoot_z80pio[1] = device_list_find_by_tag( machine->config->devicelist, Z80PIO, "z80pio_1" );
|
||||
|
||||
nflfoot_sio_intf.baseclock = cpunum_get_clock(3);
|
||||
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 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
if (offset & 2)
|
||||
@ -995,8 +990,8 @@ static TIMER_CALLBACK( ipu_watchdog_reset )
|
||||
logerror("ipu_watchdog_reset\n");
|
||||
cpunum_set_input_line(machine, 3, INPUT_LINE_RESET, PULSE_LINE);
|
||||
z80ctc_reset(1);
|
||||
z80pio_reset(0);
|
||||
z80pio_reset(1);
|
||||
z80pio_reset( nflfoot_z80pio[0] );
|
||||
z80pio_reset( nflfoot_z80pio[1] );
|
||||
z80sio_reset(0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user