TransKey-II Communication Protocol
TransKey-II acts like a very smart bridge between a PS/2 input device like a keyboard or numeric key pad -to- the Atari's keyboard controller chip (POKEY). What I mean by smart, is that it needs to do more than simply making the letter "A" on the PS/2 keyboard show up on the Atari screen when pressed. Although it does need to do that, and do it reliably.
So what I am actually saying when I say "smart"?
There are a lot more keys on the PS/2 keyboard, and some are meant to do some very special stuff that the Atari never implemented on the E: handler. Things like automatically making space for inserted characters, or if back spacing in the middle of a sentence or a line of code, to not only rub out the character under the cursor, but to also eliminate the space that character occupied. And then there is the navigation section, the numeric pad, and the 12 function keys, all of which require special attention and handling.
This has already been covered in great detail on a good number of websites, so I'll just gloss over the highlights and provide some links for those that want to go more in depth.
Basically the PS/2 Keyboard and mouse use an identical clocked serial communications protocol having one start bit, 8 data bits, a parity bit, and a stop bit (11 bits all together). It is a bidirectional system, with data corresponding to a key pressed, mouse movement, a scroll wheel turned, or a button pressed all being sent from the keyboard (or mouse) to the Host, which in our case is TK-II. And when certain things such as the status LEDs (Caps Lock, Num Lock, Scroll Lock) need to be turned on or off, then the communications direction changes, and goes from the Host to the PS/2 device.
In order for the Host to take charge, the Host must bring the Clock Line low, followed by the Data Line also going low, and then releasing the Clock Line. This lets the PS/2 device know to start clocking in data from the Host.
And although the serial protocol is the same, the actual data sent is very much different between the keyboard and the mouse.
Talking to POKEY
POKEY has a 6-Bit counter (K0-K5) that addresses an 8x8 key matrix via two CMOS 4051 Mux Chips (3-Bits to address each Mux). So basically the idea is that when any two converging points on the matrix are physically connected (shorted out), a low going signal is sent to either KR1 or KR2 letting POKEY know that a key at a specific intersection has been pressed. POKEY's count determines what key that is. The KR1 input is the Key Response line for all the normal keys, and KR2 is the response line for Control, Shift, or Break.
So if you want to simulate the keyboard matrix with a PIC chip as I've done with TK-II, you need to read POKEY's counter, and compare that to the key value you wish to send. When POKEY's count matches your key, pull the KR1 line low. And when the match goes away as POKEY's count progresses, then release KR1 (bring it high). But you will need to do this repeatably for a while, so that POKEY's debounce system sees it as a real key press. As it turns out, doing this over and over for about 0.025 seconds is about the minimal time duration for reliability (no dropped keys). The same thing is done in parallel for Control, Shift, and Break using KR2.
Reference: Pokey Keyboard Scan
Reference: Beyond Logic: Interfacing the AT Keyboard
Keyboard Scan Codes
The keyboard uses what are called Scan Codes, for each and every key, of which there are a hundred plus on most modern versions.
The scan codes unfortunately have a lot of holes and gaps in the numerical sequence, and due to legacy support deriving from the IBM XT, it also has an extra prefix added for the navigation keys (0xE0), but still shares the identical scan codes with the num pad. Also there is another prefix to designate when a key has been released (0xF0). And lastly, there are some very strange key sequences added when dealing with the num pad in either a shifted or non-shifted state. And all of this needs to be taken into account when attempting to interpret the data being received.
So the approach I took with TK-II was to first translate the scan codes into ASCII, and then translate that into POKEY key codes. Most of this was done with a couple of look up tables. I went to ASCII first, since it allowed me to better organize the scan code data into something a little more sensical that contained both a shifted and a non-shifted aspect built-in. This was then a little easier to put into a form that POKEY could use, by going through yet another look up table (although much smaller this time).