int z80pio_interrupt( int which ) { z80pio *pio = pios + which; int ch = 0; /* port A */ if( pio->int_state[0] == Z80_INT_REQ ) { pio->int_state[0] |= Z80_INT_IEO; } if( pio->int_state[0] == 0 ) { /* port B */ ch = 1; if( pio->int_state[1] == Z80_INT_REQ ) { pio->int_state[1] |= Z80_INT_IEO; } else { if (errorlog) fprintf(errorlog,"PIO entry INT : non IRQ\n"); ch = 0; } } z80pio_interrupt_check( pio ); return pio->vector[ch]; }
static void z80pio_check_irq( z80pio *pio , int ch ) { int irq = 0; int data; int old_state; if( pio->enable[ch] & PIO_INT_ENABLE ) { if( pio->mode[ch] == PIO_MODE3 ) { data = pio->in[ch] & pio->dir[ch]; /* input data only */ data &= ~pio->mask[ch]; /* mask follow */ if( !(pio->enable[ch]&PIO_INT_HIGH) )/* active level */ data ^= pio->mask[ch]; /* active low */ if( pio->enable[ch]&PIO_INT_AND ) /* logic */ { if( data == pio->mask[ch] ) irq = 1; } else { if( data == 0 ) irq = 1; } /* if portB , portA mode 2 check */ if( ch && (pio->mode[0]==PIO_MODE2) ) { if( pio->rdy[ch] == 0 ) irq = 1; } } else if( pio->rdy[ch] == 0 ) irq = 1; } old_state = pio->int_state[ch]; if( irq ) pio->int_state[ch] |= Z80_INT_REQ; else pio->int_state[ch] &= ~Z80_INT_REQ; if( old_state != pio->int_state[ch] ) z80pio_interrupt_check( pio ); }
void z80pio_reti( int which ) { z80pio *pio = pios + which; if( pio->int_state[0] & Z80_INT_IEO ) { pio->int_state[0] &= ~Z80_INT_IEO; } else if( pio->int_state[1] & Z80_INT_IEO ) { pio->int_state[1] &= ~Z80_INT_IEO; } /* set next interrupt stattus */ z80pio_interrupt_check( pio ); }
void z80pio_reset (int which) { z80pio *pio = pios + which; int i; for( i = 0 ; i <= 1 ; 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 */ pio->rdy[i] = 0x00; /* RDY = low */ pio->out[i] = 0x00; /* outdata = 0 */ pio->int_state[i] = 0; } z80pio_interrupt_check( pio ); }
static void z80pio_update_strobe(int which, int ch, int state) { z80pio *pio = pios + which; if (ch) ch=1; switch (pio->mode[ch]) { /* output mode */ case PIO_MODE0: { /* ensure valid */ state = state & 0x01; /* strobe changed state? */ if ((pio->strobe[ch]^state)!=0) { /* yes */ if (state!=0) { /* positive edge */ logerror("PIO-%c positive strobe\n",'A'+ch ); /* ready is now inactive */ z80pio_set_rdy(pio, ch, 0); /* int enabled? */ if (pio->enable[ch] & PIO_INT_ENABLE) { /* trigger an int request */ pio->int_state[ch] |= Z80_INT_REQ; } } } /* store strobe state */ pio->strobe[ch] = state; /* check interrupt */ z80pio_interrupt_check( pio ); } break; default: break; } }