_______________________________________________________________
How does the keyboard interface work?
The IBM keyboard is connected to the computer through a serial interface
similar to a COM port. When you press a key, the keyboard sends a
"scan-code" for that key to the computer. When you release the key, the
keyboard sends a release code to the computer. If you hold down one key and press and release another key, the computer will receive the scan-code for the held key and a scan and release code for the other key. Since the
release code for the held key was not received, the computer knows that the held key was down while the other key was pressed. In this way, the
computer can handle the Shift, Alt and Ctrl keys (and any key could work
like a shift key, since all keys work alike). The ROM BIOS in the computer buffers the data from the keyboard, translates the scan-codes to ASCII and handles the operation of the shift and lock keys. The keyboard itself also has a small buffer and there is hardware flow-control for preventing overruns. All of this seems simple and quite elegant, but by the time we get to the AT keyboard the details of the implementation are so complicated as to ruin an otherwise ideal keyboard.
The XT keyboard's interface almost captures the above elegance (indeed it is the only elegant thing about the XT, IMHO). The interface uses a 5-pin DIN connector with these signal assignments:
1 CLK/CTS (open-collector)
2 RxD
3 RESET
4 GND
5 +5V
When the keyboard has a byte to send to the computer, it shifts 9 bits out
to the data line (RxD) with nine clock pulses on the CLK line. The data
format is 1 start bit, followed by 8 data bits. The baud rate is roughly
2000 bits per second and is not precisely defined. Once a byte is
completely transmitted, the computer holds the Clear-To-Send (CTS) line low
to prevent the keyboard from sending any more bytes until the keyboard
interrupt handler reads the current one. Usually a simple 9-bit clearable
TTL shift register is used to receive keyboard data. The 9th bit of the
shift register is used to drive an open-collector buffer connected to the
CTS line. When the start-bit gets all of the way through the shift
register, it holds the CTS line low itself. Once the CPU reads the
assembled byte, it has only to clear the shift register to release the CTS
line and allow another byte to be received. Three TTL chips or a single PAL can implement an entire XT keyboard interface.
The data bytes which the XT sends are also simple. Codes 0-127 are the
scan-codes. Codes 128-255 are the release codes- they're the same as the
scan codes, but with the high bit set. The XT keyboard has only 84 keys, so not all of the scan-codes are used.
The only problems with the XT keyboard are the lock-status lights
(Caps-lock, Scroll-lock and Num-lock) and the key repeat mechanism. The
lock-status lights can get out of sync with the computer's idea of which
lock keys are activated, but this only happens if someone resets the
keyboard by unplugging it temporarily. When you hold a key down long
enough, the keyboard starts repeating the scan-code for that key. The
release code is still only transmitted once, when the key is released. The problem here is that the delay to the start of the repeats and the repeat rate were made too slow. Of course, the keyboard really doesn't have to handle repeat at all, since the computer knows when keys are pressed and released and has a timer itself. Old XT keyboard TSRs allowed you to adjust the repeat delay and rate by duplicating the key repeat mechanism in the computer.
Once IBM found that it had a nearly perfect keyboard it, of course, decided that it had to be almost completely redesigned for the AT. The keyboard didn't have to be redesigned- there were enough extra scan-codes for the AT's 101 key keyboard and the repeat mechanism could simply have been moved to the BIOS. But no, they had to redesign everything.
The AT uses a 5-pin DIN and the PS/2 uses a smaller connector with the same signals:
1 CLK/CTS (open-collector)
2 RxD/TxD/RTS (open-collector)
3 Not connected or Reset
4 GND
5 +5V
Now the interface is bi-directional. When the computer wants to send a byte to the keyboard, it asserts RTS and releases CTS. If you're lucky, the keyboard isn't deciding to transmit at the same time and it responds by giving 10 clock pulses (at about 10000 baud) on the CLK line. The computer shifts a frame out on TxD on rising clock edges. The frame format is now 1 start bit, 8 data bits and 1 odd parity bit. The keyboard takes RTS being held low as the first start bit, and the first data bit should be sent on TxD after the first clock edge is received. Yes, now you need a full UART for the keyboard interface since you have to both transmit and receive and
generate and check parity (but it's still not RS-232- that would have been
too logical). Why do you need parity checking on a three foot long keyboard cable? Because collisions can occur since the lines are so overloaded with signals with different meanings and parity provides the means for detecting these collisions.
The AT documentation says that pin 3 is "reserved", so the keyboard has to
provide its own reset. But on the original AT, pin 3 was still Reset and
IBM's own keyboards at that time needed Reset (original AT keyboards won't
work on some old clones because of this). Don't ask me... I don't
understand why they did this.
The protocol on the keyboard interface is now much more complicated. These bytes are defined:
Commands
ED <byte> Set leds depending on byte
bit 0 is Scroll lock
bit 1 is Num lock
bit 2 is Caps lock
EE Echo EE (for testing?)
F0 <mode> Select mode 1, 2 or 3
F2 Send keyboard I.D.
F3 <byte> Set repeat delay and rate
byte is: 0ddbbaaa
delay is (dd+1)*250 msec
rate is (8+aaa)*2^bb*4 msec
F4 Clear buffer
F5 Restore default settings and wait for enable
F6 Restore default settings
FA Acknowledge
FE Error- please retransmit
FF Reset keyboard
Status returns
00 Buffer overflow
AA Self-test passed
F0 <scan-code> Release code
FA Acknowledge last command
FD Self-test failed
FC Self-test failed
FE Last command in error; re-send
E0 scan/release code Extended keys in Mode 2
The computer and keyboard must acknowledge each command and key code with
either FA if there was no error, or FE if the last command/key-code should
be re-sent. There are three modes of operation for the keyboard, depending on which scan code assignments you want (these can often be set by a switch on the back of keyboard, except that if mode 1 is selected from the switch, the protocol is eliminated an the keyboard works exactly like an original XT keyboard- newer keyboards only support modes 1 and 3). In mode 1, the keyboard gives XT scan-codes. The keyboard handles the cursor keypad (which didn't exist on the XT) by simulating pressing or releasing a shift key (depending on whether shift or num-lock are pressed) and sending codes from the numeric keypad. Mode 2 works like mode 1, except that when the keyboard does the weird stuff with the numeric keypad it prefixes everything with E0 and the release codes are the scan-codes prefixed with F0. In mode 3, each key gets a unique code and the release codes work as in mode 2: the release are the scan-codes prefixed by F0.
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).