Page 3 of 3
Re: 6522 VIA partial shifts?
Posted: Mon Jun 27, 2022 9:21 pm
by AndersNielsen
Edit3: This actually seems to work. My debug pin tells me it's sampling SR right before the 10th rising edge. (Which is later than what I would expect with PB6 count being set to 9 and not 10)
It's typical to need to subtract 2 from timer durations with the 6522 because the interrupts and automatic timer reloads happen during the clock cycle after the "-1" count - I've been using this in a BBC Micro recently to keep video special effects in sync with the vertical refresh.
So for example in this 50Hz video system, using timer 1 in free running mode I need to set the latches to 19998 rather than 20000 to wait a whole frame.
But looking at the datasheet this isn't meant to be the case for pulse-counting mode - the diagram clearly shows IRQB falling when the count reaches zero.
I'd still expect it to be delayed based on the system clock, but presumably the keyboard clock rate is much slower, so the system clock delay (and IRQ processing time) shouldn't be significant.
Note that if your IRQ handler is busy when the next interrupt arrives then it will respond to it late.
The MOS datasheet is incorrect and you’re right, George - there’s a correction in the SY6522 sheet:
http://81.174.146.201/acorn/Semiconduct ... Y6522A.pdf (not my server)
I also have a feeling PB6 isn’t edge triggered when enabling it - it seems to count once if PB6 is low when pulse counting mode is enabled instead of waiting for an edge. So PB6 should be “normally high” or add a count when enabling.
Still have to confirm.
These two things help a bit with my sanity as it explains why I could only get the correct counts by fiddling with re-enabling PC-mode.
Currently trying to read all 11 bits in two IRQ’s as getting rid of the start/stop bits isn’t helpful.
Re: 6522 VIA partial shifts?
Posted: Tue Jun 28, 2022 9:03 pm
by AndersNielsen
Success! Much better now!
I was missing two important pieces of information:
1) T2 IRQ fires on FF, not on 0 as is written in the MCS datasheet. Counts loaded into T2LL must be 1 lower than expected - 0 means IRQ after 1 pulse. 2 means IRQ after 3 pulses.
2) The shift register IFR flag must be cleared immediately when it's set as it blocks further shifts - I read the datasheet like a read/write on bit 6 for instance would reset the counter.. Nope. It can ONLY be cleared after the IFR is set after exactly 8 shifts. Solved by setting up an ISR that resets and exits when it fires - that works.
I now have access to all 11 bits by doing 6+5 pulses. Nibbles just had to be juggled into correct places. (Along with the previously mentioned LSB MSB lookup table).
I should probably write the error handling now that I can... But.. It really works perfect without it

Re: 6522 VIA partial shifts?
Posted: Tue Sep 06, 2022 4:43 am
by epooch
Maybe I could suggest a solution that does not seem well documented anywhere... Just use an MC6850 ACIA connected to a 74LS05 (for open collector I/O). When set to 1x clock, 8 bits, odd parity, 1 stop bit, the ACIA will do everything for you, including parity checking.
The only issue I can see is that the ACIA does not seem to get enough clocks with the PS/2 protocol to set the read register full flag. So, you end up one byte behind the keyboard. That seems to work fine though because you will get the key code when it repeats or sends the break code (on key up) anyway. So a key down/up cycle gives you this:
[previous key code]...[key code][$F0]
instead of:
[key code]...[$F0][keycode]
It is nice because it is does not take a lot of processor cycles, has a smaller footprint than using a VIA, and only one support IC with some pull up resistors.
Edit: Sorry, I missed the last page of posts and just realized that you already resolved this!
Re: 6522 VIA partial shifts?
Posted: Tue Sep 06, 2022 5:58 am
by BigEd
(I see you've been here for a while epooch, but good to see your first post!)
Re: 6522 VIA partial shifts?
Posted: Wed Sep 07, 2022 6:27 am
by AndersNielsen
Maybe I could suggest a solution that does not seem well documented anywhere... Just use an MC6850 ACIA connected to a 74LS05 (for open collector I/O). When set to 1x clock, 8 bits, odd parity, 1 stop bit, the ACIA will do everything for you, including parity checking.
The only issue I can see is that the ACIA does not seem to get enough clocks with the PS/2 protocol to set the read register full flag. So, you end up one byte behind the keyboard. That seems to work fine though because you will get the key code when it repeats or sends the break code (on key up) anyway. So a key down/up cycle gives you this:
[previous key code]...[key code][$F0]
instead of:
[key code]...[$F0][keycode]
It is nice because it is does not take a lot of processor cycles, has a smaller footprint than using a VIA, and only one support IC with some pull up resistors.
Edit: Sorry, I missed the last page of posts and just realized that you already resolved this!
Always great to have alternatives! I'm happy I got it working with only an extra half '74 but it is a bit demanding on the software side - not too many cycles but it does require extra attention to IRQ handling.
Many 6502 builds will have an ACIA already and if it wasn't for the extra board space I would probably incorporate one - also because they too are relatively well available second hand.
I think I've see a minimal build or two with simply an ACIA, 6502, RAM, ROM and address decoding and I guess it wouldn't be that hard to use the ACIA for both keyboard input and serial output - but that would be missing the TX clock.. I guess the 6502 could run at a multiple of the common serial clocks.
Re: 6522 VIA partial shifts?
Posted: Sat Sep 10, 2022 2:23 pm
by fachat
Maybe now that it works would you mind writing a summary of how it works in a single post? I'm afraid I can't get it together with the whole thread. Thanks in advance!
Re: 6522 VIA partial shifts?
Posted: Tue Sep 13, 2022 6:27 am
by AndersNielsen
Maybe now that it works would you mind writing a summary of how it works in a single post? I'm afraid I can't get it together with the whole thread. Thanks in advance!
Well, the working source is already on Github.
https://github.com/AndersBNielsen/abn65 ... n6502rom.s
The code is a bit out of sync with my local copy that I cleaned up a lot but the essence is the same - it might be more readable after I push changes this week when I publish a new (unrelated) video.
Also I have one last bug to weed out - my resetkb subroutine doesn't actually seem to recover from errors even though it works fine to initialize the keyboard and also doesn't break the kb if I just call it. Maybe I should do yet another blog post about this three pin PS/2 interface when I get error checking 100% reliable.
TL;DR for how I did it:
1) Used the 6522 shift register with a 74'74 to kill the SR bug.
2) Used clocks on PB6 to alternately generate IRQ's after 6 and 5 PS/2 clocks
3) Join the two half packets, check error bits, reverse the bits in a lookup table, and save the scan code in a buffer (I shortened that to 8 bytes in my local copy) in the ISR
4) Scan code -> ASCII in the main loop