BYTE viacore_peek(via_context_t *via_context, WORD addr) { CLOCK rclk = *(via_context->clk_ptr); addr &= 0xf; if (via_context->tai && (via_context->tai <= *(via_context->clk_ptr))) viacore_intt1(*(via_context->clk_ptr) - via_context->tai, (void *)via_context); if (via_context->tbi && (via_context->tbi <= *(via_context->clk_ptr))) viacore_intt2(*(via_context->clk_ptr) - via_context->tbi, (void *)via_context); switch (addr) { case VIA_PRA: return viacore_read(via_context, VIA_PRA_NHS); case VIA_PRB: /* port B */ { BYTE byte; #ifdef MYVIA_NEED_LATCHING if (IS_PB_INPUT_LATCH()) { byte = via_context->ilb; } else { byte = (via_context->read_prb)(via_context); } #else byte = (via_context->read_prb)(via_context); #endif byte = (byte & ~(via_context->via[VIA_DDRB])) | (via_context->via[VIA_PRB] & via_context->via[VIA_DDRB]); if (via_context->via[VIA_ACR] & 0x80) { update_myviatal(via_context, rclk); byte = (byte & 0x7f) | (((via_context->pb7 ^ via_context->pb7x) | via_context->pb7o) ? 0x80 : 0); } return byte; } /* Timers */ case VIA_T1CL /*TIMER_AL */ : /* timer A low */ return (BYTE)(myviata(via_context) & 0xff); case VIA_T2CL /*TIMER_BL */ : /* timer B low */ return (BYTE)(myviatb(via_context) & 0xff); default: break; } /* switch */ return viacore_read(via_context, addr); }
void viacore_signal(via_context_t *via_context, int line, int edge) { switch (line) { case VIA_SIG_CA1: if ((edge ? 1 : 0) == (via_context->via[VIA_PCR] & 0x01)) { if (IS_CA2_TOGGLE_MODE() && !(via_context->ca2_state)) { via_context->ca2_state = 1; (via_context->set_ca2)(via_context, via_context->ca2_state); } via_context->ifr |= VIA_IM_CA1; update_myviairq(via_context); #ifdef MYVIA_NEED_LATCHING if (IS_PA_INPUT_LATCH()) { via_context->ila = (via_context->read_pra)(via_context, addr); } #endif } break; case VIA_SIG_CA2: if (!(via_context->via[VIA_PCR] & 0x08)) { via_context->ifr |= (((edge << 2) ^ via_context->via[VIA_PCR]) & 0x04) ? 0 : VIA_IM_CA2; update_myviairq(via_context); } break; case VIA_SIG_CB1: if ((edge ? 0x10 : 0) == (via_context->via[VIA_PCR] & 0x10)) { if (IS_CB2_TOGGLE_MODE() && !(via_context->cb2_state)) { via_context->cb2_state = 1; (via_context->set_cb2)(via_context, via_context->cb2_state); } via_context->ifr |= VIA_IM_CB1; update_myviairq(via_context); #ifdef MYVIA_NEED_LATCHING if (IS_PB_INPUT_LATCH()) { via_context->ilb = (via_context->read_prb)(via_context); } #endif } break; case VIA_SIG_CB2: if (!(via_context->via[VIA_PCR] & 0x80)) { via_context->ifr |= (((edge << 6) ^ via_context->via[VIA_PCR]) & 0x40) ? 0 : VIA_IM_CB2; update_myviairq(via_context); } break; } }
BYTE viacore_read_(via_context_t *via_context, WORD addr) { #endif BYTE byte = 0xff; CLOCK rclk; addr &= 0xf; via_context->read_clk = *(via_context->clk_ptr); via_context->read_offset = 0; rclk = *(via_context->clk_ptr); if (addr >= VIA_T1CL && addr <= VIA_IER) { if (via_context->tai && (via_context->tai < *(via_context->clk_ptr))) viacore_intt1(*(via_context->clk_ptr) - via_context->tai, (void *)via_context); if (via_context->tbi && (via_context->tbi < *(via_context->clk_ptr))) viacore_intt2(*(via_context->clk_ptr) - via_context->tbi, (void *)via_context); } switch (addr) { case VIA_PRA: /* port A */ via_context->ifr &= ~VIA_IM_CA1; if ((via_context->via[VIA_PCR] & 0x0a) != 0x02) { via_context->ifr &= ~VIA_IM_CA2; } if (IS_CA2_HANDSHAKE()) { via_context->ca2_state = 0; (via_context->set_ca2)(via_context, via_context->ca2_state); if (IS_CA2_PULSE_MODE()) { via_context->ca2_state = 1; (via_context->set_ca2)(via_context, via_context->ca2_state); } } if (via_context->ier & (VIA_IM_CA1 | VIA_IM_CA2)) update_myviairq(via_context); case VIA_PRA_NHS: /* port A, no handshake */ /* WARNING: this pin reads the voltage of the output pins, not the ORA value as the other port. Value read might be different from what is expected due to excessive load. */ #ifdef MYVIA_NEED_LATCHING if (IS_PA_INPUT_LATCH()) { byte = via_context->ila; } else { byte = (via_context->read_pra)(via_context, addr); } #else byte = (via_context->read_pra)(via_context, addr); #endif via_context->ila = byte; via_context->last_read = byte; return byte; case VIA_PRB: /* port B */ via_context->ifr &= ~VIA_IM_CB1; if ((via_context->via[VIA_PCR] & 0xa0) != 0x20) via_context->ifr &= ~VIA_IM_CB2; if (via_context->ier & (VIA_IM_CB1 | VIA_IM_CB2)) update_myviairq(via_context); /* WARNING: this pin reads the ORA for output pins, not the voltage on the pins as the other port. */ #ifdef MYVIA_NEED_LATCHING if (IS_PB_INPUT_LATCH()) { byte = via_context->ilb; } else { byte = (via_context->read_prb)(via_context); } #else byte = (via_context->read_prb)(via_context); #endif via_context->ilb = byte; byte = (byte & ~(via_context->via[VIA_DDRB])) | (via_context->via[VIA_PRB] & via_context->via[VIA_DDRB]); if (via_context->via[VIA_ACR] & 0x80) { update_myviatal(via_context, rclk); byte = (byte & 0x7f) | (((via_context->pb7 ^ via_context->pb7x) | via_context->pb7o) ? 0x80 : 0); } via_context->last_read = byte; return byte; /* Timers */ case VIA_T1CL /*TIMER_AL */ : /* timer A low */ via_context->ifr &= ~VIA_IM_T1; update_myviairq(via_context); via_context->last_read = (BYTE)(myviata(via_context) & 0xff); return via_context->last_read; case VIA_T1CH /*TIMER_AH */ : /* timer A high */ via_context->last_read = (BYTE)((myviata(via_context) >> 8) & 0xff); return via_context->last_read; case VIA_T2CL /*TIMER_BL */ : /* timer B low */ via_context->ifr &= ~VIA_IM_T2; update_myviairq(via_context); via_context->last_read = (BYTE)(myviatb(via_context) & 0xff); return via_context->last_read; case VIA_T2CH /*TIMER_BH */ : /* timer B high */ via_context->last_read = (BYTE)((myviatb(via_context) >> 8) & 0xff); return via_context->last_read; case VIA_SR: /* Serial Port Shift Register */ via_context->last_read = via_context->via[addr]; return via_context->last_read; /* Interrupts */ case VIA_IFR: /* Interrupt Flag Register */ { BYTE t = via_context->ifr; if (via_context->ifr & via_context->ier /*[VIA_IER] */ ) t |= 0x80; via_context->last_read = t; return (t); } case VIA_IER: /* 6522 Interrupt Control Register */ via_context->last_read = (via_context->ier /*[VIA_IER] */ | 0x80); return via_context->last_read; } /* switch */ via_context->last_read = via_context->via[addr]; return via_context->via[addr]; }