Although Retrochallenge 04/2017 finished a few weeks ago, I have carried on with my project, making some improvements to my PS/2 keyboard interface for the 68HC11 microcontroller.
In particular, I now have the hardware interface working using only PORTA (pins 3 and 7, using the pulse-accumulator for the input-clock and the bidirectional-capable pin PA3 for the serial-data-line). This frees up PORTC so that the interface can be used both in single-chip mode and now also in expanded mode (eg: when PORTB/PORTC are needed for the external address-/data-bus). The actual circuit is identical, apart from which 68hc11 pins are used, but the program required changes.
However, this took rather longer than expected: the PORTA pins have so many “alternate option” functions that figuring out the necessary control-register settings, and debugging them, is rather more complex than the for PORTC (where there was only one control-register setting needed). The Motorola 68HC11 E-series reference manuals are a bit tricksy when describing all the alternative PORTA pin-modes and how they interact, esp things like what happens if you configure PA3 direction to be output, but configure the PA3 function to be input-capture, and then perform programmed writes to the PORTA data register… the darned PA3 pin can be used for multiple different purposes at the very same time, but figuring out how the different purposes interact can be a bit challenging unless you are used to it.
An Old IBM Firmware Bodge
As previously noted, this interface and program work fine with one of my Cherry PS/2 keyboards, but not with the other: with the large kiddy-coloured keyboard attached, the program just sees a continuous sequence of 0xAA byte values, at half-second intervals, even when keys are pressed/released: no actual scancodes are being received.
After spending much wasted time messing about with different-strength pull-up resistors (just a desperate hunch) and a separate higher-current voltage-regulator for the keyboard, I stumbled across https://www.cs.cmu.edu/~jmcm/info/key2.txt, which describes a not-uncommon but also not-universal “alternative” behaviour of some AT and PS/2 keyboards:
When the AT keyboard is first reset it’s supposed to send an AA if its
self-test passed or FD or FC if it failed. But before it does this, it
sends a continual stream of AAs with the parity incorrect. Once the
computer sends an FE to indicate that there is a parity error, the keyboard
stops sending bad AAs and sends a correct AA or an FD or FC. This sounds
like someone made a quick fix in the keyboard firmware for mis-matched reset
timing (the keyboard always finishes resetting before the computer so the
computer could miss the AA/FD/FC).
Aha! So the kiddy Cherry keyboard is reproducing an old IBM “bodge” behaviour (that predates the original 1987 PS/2 keyboard). Sheesh.
To get this particular keyboard working (and several others too, I suspect), I am going to have to implement full bidirectional communications and flow-control, parity-checking and response parsing, which will require a rather larger program. Fortunately, I am confident enough with the initialisation code, interrupt-handler and bi-partisan circular-buffer code that those can now be moved into on-chip EEPROM, thus freeing up some of the 280 bytes of usable on-chip RAM for more program code…
It often turns out this way, as other Retrochallengers have noticed: there is always room for improvement!