Mike's PCjr Page Logo

PCjr Keyboard Handling


One of the unique features of the PCjr is the keyboard. The original keyboard was famous for three big reasons:
  • The original version had oddly shaped keys that resembled pieces of "Chiclets" chewing gum. (Hence the nickname, "The Chiclet Keyboard".) This keyboard was replaced by a similar keyboard with more conventionally shaped keys later on.
  • The keyboard (both versions) could connect to the system unit by wire or wirelessly using an infra-red transmitter/receiver pair
  • The keyboard was small, and only had 62 keys.

These are obvious observations. The bigger story about the keyboard is buried in the wiring and BIOS programming of the machine, which are quite different than the keyboard on the IBM PC.

Keyboard Description

The standard keyboard is small, measuring in at 13.25 inches wide, 6.5 inches deep, and 1 inch tall. It is made of plastic, making it very light compared to the keyboard on the IBM PC. Unlike the keys of the IBM PC keyboard which used a "buckling spring", the keys on the PCjr keyboard are made of rubber domes and are activated by a change in capacitance. (This is similar to how modern television remote controls are made.) That makes the PCjr keyboard virtually silent compared to the IBM PC keyboard - so silent that IBM put a simulated key click routine in the BIOS of the machine that can be turned on and off by the user.

(Click on one of the keyboard icons for a larger picture.)

The keyboard connects to the system unit using an infra-red link. The keyboard transmits to a receiver mounted on the front of the machine. The choice of infra-red cuts down on radio signal inteference but it requires a direct line of site - you can not have the front of the keyboard pointed too far away from the receiver. The keyboard uses four AA batteries which would last a few months during normal use. (The electronics were very low power.) An optional keyboard cord that tethered the keyboard to the machine was available. With the keyboard cord batteries were not required, but mobility was reduced.

The keyboard has 62 keys compared to the IBM PC keyboard that has 83 keys. The "Fn" key is unique to the PCjr, and in combination with other keys allows the machine to emulate all of the keys of the IBM PC keyboard.

Communication to the system unit is a serial data stream. The same data stream is used over the keyboard cable and the infra-red link. An onboard 80C48 microprocessor does the encoding. Each bit takes 440 microseconds and 11 bits are sent, so it takes 4.8 milliseconds to transmit a scancode to the system unit. (It works out to around 2272 bits per second.) After each scan code the keyboard sends 11 stop bits which serve to give the system unit time to process other interrupts. These extra stop bits effectively limit the keyboard to transmiting a scancode every 10 milliseconds, which is still far faster than humans can type.


Hardware Interrupt Handling

Data received on the keyboard causes a hardware interrupt to be signaled. On the PCjr the Non-Maskable Interrupt (NMI) of the 8088 is used instead of IRQ 1 as on the IBM PC. This is done because the system unit does not have dedicated hardware to decode the incoming data stream, and so the main 8088 CPU is used to do it.

The implications of this design decision are far reaching and far more significant than the physical characteristics of the keyboard. The NMI interrupt has the highest priority as it is directly connected to the 8088 CPU. This interrupt can not be deferred or ignored, so keyboard processing will preempt all other activity on the system including other interrupts. Even when interrupts are disabled using the CLI command an NMI interrupt can still occur. (There is a way to disable the keyboard entirely so that it does not generate any interrupts.)

The leading edge of the start bit from the keyboard signals the NMI on the 8088. When the NMI occurs the PCjr jumps to a routine to start reading the incoming data stream from the keyboard. Interrupts are disabled during this time so any hardware event that requires service in 4.8 milliseconds to avoid an overrun condition might experience an overrun.

This explains why the PCjr can not reliably transfer data using the serial port at high speed:
  • The keyboard routine monopolizes the machine for 4.8ms to decode each key.
  • A 2400 bps data connection requires a byte to be read from the 8250 UART 240 times per second, or every 4.16 milliseconds. Therefore, it is possible for the 8250 UART to experience a buffer overrun when a single key is pressed.
  • After the data stream is deserialized the scan code has to be processed by the BIOS. So the delay is actually longer than 4.8ms.
  • Other interrupts, such as time of day need to be serviced as well. (Time of day happens 18.52 times per second.)
The machine is capable of driving the serial port much faster. The BIOS supports up to 4800bps, and I have used 9600bps connections. But if you press a key while data is coming in, you will lose data - there is no way around it.


Second Level Keyboard Handling

The first level interrupt handler is responsible for getting the raw scan code from the keyboard. After this happens, the scan code must be processed.

(Background: A scan code represents a key on the keyboard. The IBM PC series of keyboards sends scan codes instead of ASCII characters, which gives the programmer more control over how keys are processed. Arbitrary combinations of keys can be used in this scheme, but it requires an extra level of decoding to get from a scan code to an ASCII value or an extended keyboard code.)

One of the key differences between the PCjr keyboard and the IBM PC keyboard is the number of keys. The PCjr only has 62 keys and the scan codes for each key are completely different than those of the IBM PC. Yet the PCjr has to be compatible with existing PC software that uses scan codes and the PCjr has to be able to generate any scan code that the PC keyboard can generate. How is this done?

The IBM developers solved this problem by introducing a translation step during keyboard scan code processing. Each PCjr specific scancode received from the NMI routine is passed to INT 48, which converts the PCjr scan code to the equivalent PC scan code. It is here that the special 'Fn' key combinations are processed. When this routine is ready it invokes INT 9, which is the same interrupt handler that the IBM PC uses to service its keyboard directly. So at the INT 9 level the two machines are entirely compatible - any code that hooks INT 9 to intercept scan codes or to wake up periodically will work unmodified on the PCjr.

One small drawback to this scheme is that if you want to hook the keyboard interrupt to do your own key processing you have two places that you can do it. If you are going to be compatible with PC software you must hook INT 9 and use the PC scan codes. If you wanted to detect the "Fn" key you can't do that using INT 9 - you must hook INT 48 to do that.

The infra-red interface on the PCjr was designed to handle more than just the keyboard. It is possible that another device could send a scan code that the keyboard handling routine does not handle. This provision in the BIOS allows for things like wireless joysticks, wireless mice, etc.

Want to see evidence of this dual layer keyboard processing in action? Take a look at the built-in diagnostics for the keyboard sometime. There are two options for testing the keyboard, one that tests the standard 62 key keyboard and one that tests a keyboard that resembles the full 83 key keyboard on the IBM PC. If you select the first test the diagnostics show you each key on the 62 key keyboard being pressed, including the "Fn" key. For that to work it must be getting scan codes directly from the NMI handler. If you select the second test you can press the "Fn" key and nothing will happen, but if you do a valid combination of the "Fn" key with another key the corresponding IBM PC keyboard key will be selected. You can even test NumLock on a keyboard that doesn't have it!  This version of the test just be getting the keyboard data after the Int 48 mapping routine has run.


Interfacing third party keyboards

Besides the two revisions of the PCjr keyboard from IBM there were other keyboards available. As long as the other keyboards generated the same scan codes as the PCjr keyboard, they would work just fine. Most other keyboards looked like the conventional IBM PC keyboard, and thus had 83 or more keys and no "Fn" key. The irony of this is that these keyboards would have to emulate the PCjr scan codes faithfully to work. A user pressing the "F2" key would cause the keyboard to send a scan code for "Fn" followed by the scan code for "2" because the PCjr is going to run the scan codes through the INT 48 translation routine to get to the standard IBM PC keyboard scan codes.
Created February 15th, 2010
(C)opyright Michael B. Brutman, mbbrutman at gmail.com

Return to Mike's IBM PCjr Page main page