#include "6522.h" void via_init(via_t *via) { via->ira = 0; via->irb = 0; via->ora = 0; via->orb = 0; via->ddra = 0; via->ddrb = 0; via->tca = 0; via->tcb = 0; via->tla = 0; via->tlb = 0; via->acr = 0; via->pcr = 0; via->ifr = 0; via->ier = 0; via->tav = true; via->tbv = true; } void via_read(via_t *via, uint8_t addr, uint8_t *v, uint8_t cycle) { uint16_t tca = via->tca - cycle; uint16_t tcb = via->tcb - cycle; switch (addr) { case 0: via_pb_read(via, cycle); *v = (via->irb & ~via->ddrb) | (via->orb & via->ddrb); via->ifr &= 0b11100111; if (via->ifr == 0x80) via->ifr = 0; break; case 1: via_pa_read(via, cycle); *v = via->ira; via->ifr &= 0b11111100; if (via->ifr == 0x80) via->ifr = 0; break; case 2: *v = via->ddrb; break; case 3: *v = via->ddra; break; case 4: *v = tca & 0xff; via->ifr &= 0b10111111; if (via->ifr == 0x80) via->ifr = 0; break; case 5: *v = (tca & 0xff00) >> 8; break; case 6: *v = via->tla & 0xff; break; case 7: *v = (via->tla & 0xff00) >> 8; break; case 8: *v = tcb & 0xff; via->ifr &= 0b11011111; if (via->ifr == 0x80) via->ifr = 0; break; case 9: *v = (tcb & 0xff00) >> 8; case 11: *v = via->acr; break; case 12: *v = via->pcr; break; case 13: *v = via->ifr; break; case 14: *v = via->ier | 0x80; break; default: break; } } void via_write(via_t *via, uint8_t addr, uint8_t v, uint8_t cycle) { switch (addr) { case 0: via->orb = v; via_pb_write(via, cycle); via->ifr &= 0b11100111; if (via->ifr == 0x80) via->ifr = 0; break; case 1: via->ora = v; via_pa_write(via, cycle); via->ifr &= 0b11111100; if (via->ifr == 0x80) via->ifr = 0; break; case 2: via->ddrb = v; via_pb_write(via, cycle); break; case 3: via->ddra = v; via_pa_write(via, cycle); break; case 4: via->tla = (via->tla & 0xff00) | v; break; case 5: via->tla = (via->tla & 0xff) | (v << 8); via->tca = via->tla + cycle + 1; via->ifr &= 0b10111111; if (via->ifr == 0x80) via->ifr = 0; via->tav = false; break; case 6: via->tla = (via->tla & 0xff00) | v; break; case 7: via->tla = (via->tla & 0xff) | (v << 8); via->ifr &= 0b10111111; if (via->ifr == 0x80) via->ifr = 0; break; case 8: via->tlb = (via->tlb & 0xff00) | v; break; case 9: via->tlb = (via->tlb & 0xff) | (v << 8); via->tcb = via->tlb + cycle + 1; via->tbv = false; via->ifr &= 0b11011111; if (via->ifr == 0x80) via->ifr = 0; break; case 11: via->acr = v; break; case 12: via->pcr = v; break; case 13: via->ifr &= ~(v & 0x7f); if (via->ifr == 0x80) via->ifr = 0; break; case 14: if (v & 0x80) { via->ier |= v & 0x7f; } else { via->ier &= ~v; } break; default: break; } } void via_cycle(via_t *via, uint8_t cycles) { if (!via->tav) { uint16_t tca = via->tca - cycles; if (tca > via->tca) { via->ifr |= 0b11000000; if ((via->acr & 0b01000000) == 0) { tca = via->tla; via->tav = true; } else { tca = via->tla + tca + 1; } } via->tca = tca; } uint16_t tcb = via->tcb - cycles; if (tcb > via->tcb) { if (!via->tbv) { via->ifr |= 0b10100000; } via->tbv = true; } via->tcb = tcb; } bool via_irq(via_t *via) { return (via->ifr & via->ier) > 0; }