void ppi8255_device::ppi8255_input(int port, UINT8 data) { int changed = 0; m_read[port] = data; /* port C is special */ if (port == 2) { if (((m_group_a_mode == 1) && (m_port_a_dir == 0)) || (m_group_a_mode == 2)) { /* is !ACKA asserted? */ if (m_obf_a && !(data & 0x40)) { m_obf_a = 0; changed = 1; } } if (((m_group_a_mode == 1) && (m_port_a_dir == 1)) || (m_group_a_mode == 2)) { /* is !STBA asserted? */ if (!m_ibf_a && !(data & 0x10)) { m_ibf_a = 1; changed = 1; } } if ((m_group_b_mode == 1) && (m_port_b_dir == 0)) { /* is !ACKB asserted? */ if (m_obf_b && !(data & 0x04)) { m_obf_b = 0; changed = 1; } } if ((m_group_b_mode == 1) && (m_port_b_dir == 1)) { /* is !STBB asserted? */ if (!m_ibf_b && !(data & 0x04)) { m_ibf_b = 1; changed = 1; } } if (changed) { ppi8255_write_port(2); } } }
static void ppi8255_input(running_device *device, int port, UINT8 data) { ppi8255_t *ppi8255 = get_safe_token(device); int changed = 0; ppi8255->read[port] = data; /* port C is special */ if (port == 2) { if (((ppi8255->group_a_mode == 1) && (ppi8255->port_a_dir == 0)) || (ppi8255->group_a_mode == 2)) { /* is !ACKA asserted? */ if (ppi8255->obf_a && !(data & 0x40)) { ppi8255->obf_a = 0; changed = 1; } } if (((ppi8255->group_a_mode == 1) && (ppi8255->port_a_dir == 1)) || (ppi8255->group_a_mode == 2)) { /* is !STBA asserted? */ if (!ppi8255->ibf_a && !(data & 0x10)) { ppi8255->ibf_a = 1; changed = 1; } } if ((ppi8255->group_b_mode == 1) && (ppi8255->port_b_dir == 0)) { /* is !ACKB asserted? */ if (ppi8255->obf_b && !(data & 0x04)) { ppi8255->obf_b = 0; changed = 1; } } if ((ppi8255->group_b_mode == 1) && (ppi8255->port_b_dir == 1)) { /* is !STBB asserted? */ if (!ppi8255->ibf_b && !(data & 0x04)) { ppi8255->ibf_b = 1; changed = 1; } } if (changed) ppi8255_write_port(device, 2); } }
static void set_mode(running_device *device, int data, int call_handlers) { ppi8255_t *ppi8255 = get_safe_token(device); int i; /* parse out mode */ ppi8255->group_a_mode = (data >> 5) & 3; ppi8255->group_b_mode = (data >> 2) & 1; ppi8255->port_a_dir = (data >> 4) & 1; ppi8255->port_b_dir = (data >> 1) & 1; ppi8255->port_ch_dir = (data >> 3) & 1; ppi8255->port_cl_dir = (data >> 0) & 1; /* normalize group_a_mode */ if (ppi8255->group_a_mode == 3) ppi8255->group_a_mode = 2; /* Port A direction */ if (ppi8255->group_a_mode == 2) ppi8255->in_mask[0] = 0xFF, ppi8255->out_mask[0] = 0xFF; /* bidirectional */ else if (ppi8255->port_a_dir) ppi8255->in_mask[0] = 0xFF, ppi8255->out_mask[0] = 0x00; /* input */ else ppi8255->in_mask[0] = 0x00, ppi8255->out_mask[0] = 0xFF; /* output */ /* Port B direction */ if (ppi8255->port_b_dir) ppi8255->in_mask[1] = 0xFF, ppi8255->out_mask[1] = 0x00; /* input */ else ppi8255->in_mask[1] = 0x00, ppi8255->out_mask[1] = 0xFF; /* output */ /* Port C upper direction */ if (ppi8255->port_ch_dir) ppi8255->in_mask[2] = 0xF0, ppi8255->out_mask[2] = 0x00; /* input */ else ppi8255->in_mask[2] = 0x00, ppi8255->out_mask[2] = 0xF0; /* output */ /* Port C lower direction */ if (ppi8255->port_cl_dir) ppi8255->in_mask[2] |= 0x0F; /* input */ else ppi8255->out_mask[2] |= 0x0F; /* output */ /* now depending on the group modes, certain Port C lines may be replaced * with varying control signals */ switch(ppi8255->group_a_mode) { case 0: /* Group A mode 0 */ /* no changes */ break; case 1: /* Group A mode 1 */ /* bits 5-3 are reserved by Group A mode 1 */ ppi8255->in_mask[2] &= ~0x38; ppi8255->out_mask[2] &= ~0x38; break; case 2: /* Group A mode 2 */ /* bits 7-3 are reserved by Group A mode 2 */ ppi8255->in_mask[2] &= ~0xF8; ppi8255->out_mask[2] &= ~0xF8; break; } switch(ppi8255->group_b_mode) { case 0: /* Group B mode 0 */ /* no changes */ break; case 1: /* Group B mode 1 */ /* bits 2-0 are reserved by Group B mode 1 */ ppi8255->in_mask[2] &= ~0x07; ppi8255->out_mask[2] &= ~0x07; break; } /* KT: 25-Dec-99 - 8255 resets latches when mode set */ ppi8255->latch[0] = ppi8255->latch[1] = ppi8255->latch[2] = 0; if (call_handlers) { for (i = 0; i < 3; i++) ppi8255_write_port(device, i); } /* reset flip-flops */ ppi8255->obf_a = ppi8255->ibf_a = 0; ppi8255->obf_b = ppi8255->ibf_b = 0; ppi8255->inte_a = ppi8255->inte_b = ppi8255->inte_1 = ppi8255->inte_2 = 0; /* store control word */ ppi8255->control = data; }
WRITE8_DEVICE_HANDLER_TRAMPOLINE(ppi8255, ppi8255_w) { offset %= 4; switch( offset ) { case 0: /* Port A write */ case 1: /* Port B write */ case 2: /* Port C write */ m_latch[offset] = data; ppi8255_write_port(offset); switch(offset) { case 0: if (!m_port_a_dir && (m_group_a_mode != 0)) { m_obf_a = 1; ppi8255_write_port(2); } break; case 1: if (!m_port_b_dir && (m_group_b_mode != 0)) { m_obf_b = 1; ppi8255_write_port(2); } break; } break; case 3: /* Control word */ if (data & 0x80) { set_mode(data & 0x7f, 1); } else { /* bit set/reset */ int bit = (data >> 1) & 0x07; if (data & 1) { m_latch[2] |= (1 << bit); /* set bit */ } else { m_latch[2] &= ~(1 << bit); /* reset bit */ } if (m_group_b_mode == 1) { if (bit == 2) { m_inte_b = data & 1; } } if (m_group_a_mode == 1) { if (bit == 4 && m_port_a_dir) { m_inte_a = data & 1; } if (bit == 6 && !m_port_a_dir) { m_inte_a = data & 1; } } if (m_group_a_mode == 2) { if (bit == 4) { m_inte_2 = data & 1; } if (bit == 6) { m_inte_1 = data & 1; } } ppi8255_write_port(2); } break; } }