void C6821::SetCA1(BYTE byData) { byData = byData ? 1 : 0; // the new state has caused a transition if ( m_byCA1 ^ byData ) { // handle the active transition if ( ( byData && C1_LOW_TO_HIGH( m_byCTLA ) ) || ( !byData && C1_HIGH_TO_LOW( m_byCTLA ) ) ) { // mark the IRQ SET_IRQ1(m_byCTLA); // update externals UpdateInterrupts(); // CA2 is configured as output and in read strobe mode and cleared by a CA1 transition if ( C2_OUTPUT( m_byCTLA ) && C2_STROBE_MODE( m_byCTLA ) && STROBE_C1_RESET( m_byCTLA ) ) { // call the CA2 output function if ( !m_byOCA2 ) PIA_W_CALLBACK( m_stOutCA2, 1 ); // clear CA2 m_byOCA2 = 1; } } } // set the new value for CA1 m_byCA1 = byData; }
void pia_set_input_cb1 (int which, int data) { struct pia6821 *p = pia + which; /* limit the data to 0 or 1 */ data = data ? 1 : 0; /* the new state has caused a transition */ if (p->in_cb1 ^ data) { /* handle the active transition */ if ((data && C1_LOW_TO_HIGH (p->ctl_b)) || (!data && C1_HIGH_TO_LOW (p->ctl_b))) { /* mark the IRQ */ p->irq_b1 = 1; /* call the IRQ function if enabled */ if (IRQ1_ENABLED (p->ctl_b)) if (p->irq_b_func) p->irq_b_func (); /* CB2 is configured as output and in write strobe mode and cleared by a CA1 transition */ if (C2_OUTPUT (p->ctl_b) && C2_STROBE_MODE (p->ctl_b) && STROBE_C1_RESET (p->ctl_b)) { /* the IRQ1 flag must have also been cleared */ if (!p->irq_b1) { /* call the CB2 output function */ if (!p->out_cb2) if (p->out_cb2_func) p->out_cb2_func (0, 1); /* clear CB2 */ p->out_cb2 = 1; } } } } /* set the new value for CB1 */ p->in_cb1 = data; }
UINT8 pia6821_device::port_b_r() { UINT8 ret = get_in_b_value(); // This read will implicitly clear the IRQ B1 flag. If CB2 is in write-strobe // mode with CB1 restore, and a CB1 active transition set the flag, // clearing it will cause CB2 to go high again. Note that this is different // from what happens with port A. if(m_irq_b1 && C2_STROBE_MODE(m_ctl_b) && STROBE_C1_RESET(m_ctl_b)) { set_out_cb2(TRUE); } // IRQ flags implicitly cleared by a read m_irq_b1 = FALSE; m_irq_b2 = FALSE; update_interrupts(); LOG(("PIA #%s: port B read = %02X\n", tag(), ret)); return ret; }
static UINT8 port_b_r(const device_config *device) { pia6821_state *p = get_token(device); UINT8 ret = get_in_b_value(device); /* This read will implicitly clear the IRQ B1 flag. If CB2 is in write-strobe mode with CB1 restore, and a CB1 active transition set the flag, clearing it will cause CB2 to go high again. Note that this is different from what happens with port A. */ if (p->irq_b1 && C2_STROBE_MODE(p->ctl_b) && STROBE_C1_RESET(p->ctl_b)) set_out_cb2(device, TRUE); /* IRQ flags implicitly cleared by a read */ p->irq_b1 = FALSE; p->irq_b2 = FALSE; update_interrupts(device); LOG(("PIA #%s: port B read = %02X\n", device->tag, ret)); return ret; }
void pia_set_input_ca1(int which, int data) { struct pia6821 *p = pia + which; /* limit the data to 0 or 1 */ data = data ? 1 : 0; /* the new state has caused a transition */ if (p->in_ca1 ^ data) { /* handle the active transition */ if ((data && C1_LOW_TO_HIGH(p->ctl_a)) || (!data && C1_HIGH_TO_LOW(p->ctl_a))) { /* mark the IRQ */ p->irq_a1 = 1; /* update externals */ update_6821_interrupts(p); /* CA2 is configured as output and in read strobe mode and cleared by a CA1 transition */ if (C2_OUTPUT(p->ctl_a) && C2_STROBE_MODE(p->ctl_a) && STROBE_C1_RESET(p->ctl_a)) { /* call the CA2 output function */ if (!p->out_ca2) if (p->intf->out_ca2_func) p->intf->out_ca2_func(0, 1); /* clear CA2 */ p->out_ca2 = 1; } } } /* set the new value for CA1 */ p->in_ca1 = data; p->in_set |= PIA_IN_SET_CA1; }
int pia_read(int which, int offset) { pia6821 *p = pia + which; int val = 0; /* adjust offset for 16-bit and ordering */ offset &= 3; if (p->addr & PIA_ALTERNATE_ORDERING) offset = swizzle_address[offset]; switch (offset) { /******************* port A output/DDR read *******************/ case PIA_DDRA: /* read output register */ if (OUTPUT_SELECTED(p->ctl_a)) { /* update the input */ if ((FPTR)(p->intf->in_a_func) > 0x100) p->in_a = p->intf->in_a_func(0); #ifdef MAME_DEBUG else if ((p->ddr_a ^ 0xff) && !(p->in_set & PIA_IN_SET_A)) { logerror("PIA%d: Warning! no port A read handler. Assuming pins %02x not connected\n", which, p->ddr_a ^ 0xff); p->in_set |= PIA_IN_SET_A; // disable logging } #endif // MAME_DEBUG /* combine input and output values */ val = (p->out_a & p->ddr_a) + (p->in_a & ~p->ddr_a); /* IRQ flags implicitly cleared by a read */ p->irq_a1 = p->irq_a2 = 0; update_6821_interrupts(p); /* CA2 is configured as output and in read strobe mode */ if (C2_OUTPUT(p->ctl_a) && C2_STROBE_MODE(p->ctl_a)) { /* this will cause a transition low; call the output function if we're currently high */ if (p->out_ca2) if (p->intf->out_ca2_func) p->intf->out_ca2_func(0, 0); p->out_ca2 = 0; /* if the CA2 strobe is cleared by the E, reset it right away */ if (STROBE_E_RESET(p->ctl_a)) { if (p->intf->out_ca2_func) p->intf->out_ca2_func(0, 1); p->out_ca2 = 1; } } LOG(("%04x: PIA%d read port A = %02X\n", activecpu_get_previouspc(), which, val)); } /* read DDR register */ else { val = p->ddr_a; LOG(("%04x: PIA%d read DDR A = %02X\n", activecpu_get_previouspc(), which, val)); } break; /******************* port B output/DDR read *******************/ case PIA_DDRB: /* read output register */ if (OUTPUT_SELECTED(p->ctl_b)) { /* update the input */ if ((FPTR)(p->intf->in_b_func) > 0x100) p->in_b = p->intf->in_b_func(0); #ifdef MAME_DEBUG else if ((p->ddr_b ^ 0xff) && !(p->in_set & PIA_IN_SET_B)) { logerror("PIA%d: Error! no port B read handler. Three-state pins %02x are undefined\n", which, p->ddr_b ^ 0xff); p->in_set |= PIA_IN_SET_B; // disable logging } #endif // MAME_DEBUG /* combine input and output values */ val = (p->out_b & p->ddr_b) + (p->in_b & ~p->ddr_b); /* This read will implicitly clear the IRQ B1 flag. If CB2 is in write-strobe output mode with CB1 restore, and a CB1 active transition set the flag, clearing it will cause CB2 to go high again. Note that this is different from what happens with port A. */ if (p->irq_b1 && C2_OUTPUT(p->ctl_b) && C2_STROBE_MODE(p->ctl_b) && STROBE_C1_RESET(p->ctl_b)) { /* call the CB2 output function */ if (!p->out_cb2) if (p->intf->out_cb2_func) p->intf->out_cb2_func(0, 1); /* clear CB2 */ p->out_cb2 = 1; } /* IRQ flags implicitly cleared by a read */ p->irq_b1 = p->irq_b2 = 0; update_6821_interrupts(p); LOG(("%04x: PIA%d read port B = %02X\n", activecpu_get_previouspc(), which, val)); } /* read DDR register */ else { val = p->ddr_b; LOG(("%04x: PIA%d read DDR B = %02X\n", activecpu_get_previouspc(), which, val)); } break; /******************* port A control read *******************/ case PIA_CTLA: /* Update CA1 & CA2 if callback exists, these in turn may update IRQ's */ if ((FPTR)(p->intf->in_ca1_func) > 0x100) pia_set_input_ca1(which, p->intf->in_ca1_func(0)); #ifdef MAME_DEBUG else if (!(p->in_set & PIA_IN_SET_CA1)) { logerror("PIA%d: Warning! no CA1 read handler. Assuming pin not connected\n",which); p->in_set |= PIA_IN_SET_CA1; // disable logging } #endif // MAME_DEBUG if ((FPTR)(p->intf->in_ca2_func) > 0x100) pia_set_input_ca2(which, p->intf->in_ca2_func(0)); #ifdef MAME_DEBUG else if (C2_INPUT(p->ctl_a) && !(p->in_set & PIA_IN_SET_CA2)) { logerror("PIA%d: Warning! no CA2 read handler. Assuming pin not connected\n",which); p->in_set |= PIA_IN_SET_CA2; // disable logging } #endif // MAME_DEBUG /* read control register */ val = p->ctl_a; /* set the IRQ flags if we have pending IRQs */ if (p->irq_a1) val |= PIA_IRQ1; if (p->irq_a2 && C2_INPUT(p->ctl_a)) val |= PIA_IRQ2; LOG(("%04x: PIA%d read control A = %02X\n", activecpu_get_previouspc(), which, val)); break; /******************* port B control read *******************/ case PIA_CTLB: /* Update CB1 & CB2 if callback exists, these in turn may update IRQ's */ if ((FPTR)(p->intf->in_cb1_func) > 0x100) pia_set_input_cb1(which, p->intf->in_cb1_func(0)); #ifdef MAME_DEBUG else if (!(p->in_set & PIA_IN_SET_CB1)) { logerror("PIA%d: Error! no CB1 read handler. Three-state pin is undefined\n",which); p->in_set |= PIA_IN_SET_CB1; // disable logging } #endif // MAME_DEBUG if ((FPTR)(p->intf->in_cb2_func) > 0x100) pia_set_input_cb2(which, p->intf->in_cb2_func(0)); #ifdef MAME_DEBUG else if (C2_INPUT(p->ctl_b) && !(p->in_set & PIA_IN_SET_CB2)) { logerror("PIA%d: Error! no CB2 read handler. Three-state pin is undefined\n",which); p->in_set |= PIA_IN_SET_CB2; // disable logging } #endif // MAME_DEBUG /* read control register */ val = p->ctl_b; /* set the IRQ flags if we have pending IRQs */ if (p->irq_b1) val |= PIA_IRQ1; if (p->irq_b2 && C2_INPUT(p->ctl_b)) val |= PIA_IRQ2; LOG(("%04x: PIA%d read control B = %02X\n", activecpu_get_previouspc(), which, val)); break; } return val; }