2 // Virtual 6522 Versatile Interface Adapter
5 // (C) 2018 Underground Software
10 #include <string.h> // for memset()
16 -------- -------------------------
19 2 Data Direction Register B
20 3 Data Direction Register A
21 4 Timer 1 Low byte counter (& latch)
22 5 Timer 1 Hgh byte counter (& latch)
23 6 Timer 1 Low byte latch
24 7 Timer 1 Hgh byte latch (& reset IRQ flag)
25 B Aux Control Register
26 D Interrupt Flag Register
27 E Interrupt Enable Register
30 0: Timed interrupt each time Timer 1 is loaded
31 1: Continuous interrupts
33 bit 7 enables PB7 (bit 6 controls output type):
39 V6522VIA::V6522VIA(): orb(0), ora(0), ddrb(0), ddra(0),
40 timer1counter(0), timer1latch(0), timer2counter(0),
41 acr(0), ifr(0), ier(0)
46 void V6522VIA::Reset(void)
48 memset(this, 0, sizeof(V6522VIA));
52 uint8_t V6522VIA::Read(uint8_t regNum)
57 //For some reason, this prevents Ankh from loading. Need to figure out what the MB *really* returns in its uninitialized state...
71 return timer1counter & 0xFF;
74 return (timer1counter & 0xFF00) >> 8;
77 return timer1latch & 0xFF;
80 return (timer1latch & 0xFF00) >> 8;
83 return timer2counter & 0xFF;
86 return (timer2counter & 0xFF00) >> 8;
92 return (ifr & 0x7F) | (ifr & 0x7F ? 0x80 : 0);
98 WriteLog("Unhandled 6522 register %X read (chip %d)\n", regNum, id);
105 void V6522VIA::Write(uint8_t regNum, uint8_t byte)
126 timer1latch = (timer1latch & 0xFF00) | byte;
130 timer1latch = (timer1latch & 0x00FF) | (((uint16_t)byte) << 8);
131 timer1counter = timer1latch;
132 ifr &= 0x3F; // Clear T1 interrupt flag
136 timer1latch = (timer1latch & 0xFF00)
141 timer1latch = (timer1latch & 0x00FF) | (((uint16_t)byte) << 8);
142 ifr &= 0x3F; // Clear T1 interrupt flag
155 // Setting bits in the IER
158 // Clearing bits in the IER
163 WriteLog("Unhandled 6522 register $%X write $%02X (chip %d)\n", regNum, byte, id);
168 bool V6522VIA::Run(uint16_t cycles)
170 // This is to signal to the caller that we hit an IRQ condition
171 bool response = false;
172 bool viaT1HitZero = (timer1counter <= cycles ? true : false);
174 timer1counter -= cycles;
175 timer2counter -= cycles;
181 timer1counter += timer1latch;
185 ifr |= (0x80 | 0x40);
191 // Disable T1 interrupt