Excerpt from Understanding Personal Computer Hardware by Steven Roman, published by Springer-Verlag. ISBN: 0-387-98531-X.

Copyright © 1999 by The Roman Press, Inc. All Rights Reserved. You may view and print this document for your own personal use only. No portion of this document may be sold or incorporated into any other document for any reason.


On the surface, a keyboard looks like a fairly simple device, and its function is quite simple. However, as we will see, underneath the surface, quite a lot happens when a key is struck.

Figure 9.1 shows a close-up of a typical modern PC keyboard. Actually, keyboard configurations have varied over the years, starting with a PC keyboard that had only 83 keys. These days, most modern keyboards have a little over 100 keys. While there is still some variation in keyboard design, it does not affect the overall functioning of the keyboard, so we will not dwell on these minor differences.

Figure 9.1 - A typical PC keyboard

The keys on a keyboard are divided into four main groups. With a few exceptions, all keys have what is referred to as a typematic action, which means that if you hold down a key, it will repeat until you release it. The original PC keyboard had a fixed typematic repeat rate of 10 characters per second and a fixed typematic delay rate of 0.5 seconds, before the typematic action would begin. Newer keyboards have adjustable repeat and delay rates.

The main portion of the keyboard consists of the usual typewriter keys, along with a few special keys. The special keys in the lower row marked Ctrl are called the control keys. When one of these keys is held down, it changes the meaning of each of the ordinary character keys. This can be an extremely useful feature in many contexts. The keys marked Alt, and referred to as the alternate keys, have a similar purpose.

The keys on the top row of the keyboard, marked F1 through F12, are called function keys. These keys are used for different purposes by different programs. For instance, it is more-or-less common practice for the F1 function key to invoke the help system for an application.

The keys on the far right of the keyboard comprise the numeric keypad and are used to enter numbers. These keys are arranged in the form of a calculator keypad, thus allowing for the rapid entering of large quantities of numerical data into programs for which this is appropriate (such as spreadsheet programs and accounting programs). The cursor control keys are used as positioning keys, which is why they are marked with arrows, and words such as Home, End, PgUp (for Page Up), and PgDn (for Page down).

Physical Operation

Keyboards contain dedicated microprocessors designed to send information about which keys are pressed to the keyboard controller on the motherboard of the PC.

Inside the keyboard, there is a matrix of criss-crossed wires, referred to as x-lines and y-lines, as shown in Figure 9.2. At the intersection of the x and y lines is a switch that is closed when the corresponding key is pressed. When the switch closes, it connects the underlying x and y lines. Circuitry in the keyboard constantly sends a current through the x-lines. If a switch is closed (key pressed), the current will flow onto the corresponding y-line. In this way, the keyboard processor can detect when a given key is pressed and also when it is released.

In order to do this, the keyboard circuitry must constantly poll every y-line in the keyboard, to check for a current. This may seem inefficient. However, the circuitry is fast enough to not cause any serious delays.

Figure 9.2 - Inside a keyboard

Each key on the keyboard has associated with it a special number, called a scan code (also called a make scan code). Once the keyboard processor has determined which key was pressed, it sends the make scan code for that key to the keyboard controller. Similarly, if a key is released, the keyboard processor adds 128 (= 80h) to the key's make scan code to produce the key's break scan code, which it then sends to the keyboard controller. Most scan codes are one byte long, but some are more than one byte.

Note that each key has a unique scan code different from all other keys, even if the keys have the same labels. For instance, there are two shift keys on a keyboard, but they each have a different scan code. Knowing the values of the scan codes is not particularly important because even very few programmers work with these codes directly.

Each byte of keyboard data is sent through the keyboard cable along a single wire. Thus, keyboards communicate serially, that is, one bit at a time, paced by a clock signal that reaches the keyboard through another wire in the keyboard cable. In fact, each keyboard byte is preceded by a start bit, which is always a 0, followed in succession by each bit of the byte, followed in turn by a parity check bit, and then finally a stop bit, which is always equal to 1.

Logical Operation

Keyboards designed for the original PC supported only unidirectional communication; that is, all communication was directed from the keyboard to the PC. Subsequent keyboards are more intelligent and partake in bidirectional communication. Thus, a keyboard can accept commands from the keyboard controller. This allows the user to adjust certain features of the keyboard, such as its repeat rate and delay rates, usually through the operating system (such as Microsoft Windows).

The Keyboard Buffer
When a key is pressed, the keyboard processor sends the appropriate scan code to the keyboard controller, through I/O port number 96 (= 60h). The keyboard controller issues a hardware interrupt on IRQ1. The microprocessor then executes the BIOS interrupt 9 service routine. This routine figures out the corresponding ASCII code for the key, if the key is an ordinary character key (letter, digit, punctuation mark, etc.). It then places the scan code and the ASCII code in a special location in the BIOS data area (in low memory) called the keyboard buffer. The rules for what gets placed in the keyboard buffer when a non-ASCII key is pressed are a bit involved, and are not important for our discussion.

The keyboard buffer has room for 16 keystrokes. If you overrun the buffer by typing too fast for the application that is using the keystrokes, you will hear a warning beep and some keystrokes will be lost, since they never make it into the buffer. (There are methods for enlarging the keyboard buffer to hold more keystrokes, chiefly by relocating it in a different section of memory.)

An application can retrieve keystrokes from the keyboard buffer by using a different BIOS service routine, namely, interrupt 16h. In short, interrupt 9 is used to fill the keyboard buffer and interrupt 16h is used to read the buffer.

When the key is released, a similar procedure takes place, resulting in an interrupt 9. However, the interrupt 9 service routine ignores the event, which is why nothing special happens (usually) when a key is released.

_ Experiment-Looking at the Keyboard Buffer
In case you missed it in Chapter 3, let's take a look at the keyboard buffer.

1. Save all current work and start debug, as described in the appendix (Trying the Experiments).


2. Next, let us fill the keyboard buffer with junk. Press and hold down the x key for a second, to generate several x's. Then hit the Enter key. You should get the following:


^ Error

3. Now do a dump of memory at the address of the keyboard buffer.

-d 0:41e _

You should see the following:

If you look closely at every other symbol in the keyboard buffer on the far right, you can see the x's. You can also make out the very last keystrokes we entered in order to perform the memory dump, which also ended up in the keyboard buffer. (The reason that the keystrokes occupy every other character in the keyboard buffer will be explained in the chapter on keyboards.)

4. Now enter a different string of letters, say by holding down the z key.


^ Error

and do another dump of memory.

-d 0:41e_

The results are similar, but with z's instead of x's.

We have also pointed out a few other data values in the BIOS data area.

5. Quit debug using the q command.

-q _

_ End of Experiment
_ Experiment-Trying the Interrupt 16 Keyboard Service Routine
Service number 10h of interrupt 16h is used to read a character from the keyboard buffer. According to the documentation, this service routine will wait for a keystroke to appear in the keyboard buffer, and then place the scan code of the key in the AH register and the ASCII code (if there is one) in the AL register. Let's give it a try.

1. Save all current work and start debug, as described in the appendix (Trying the Experiments).


2. Assemble the two-line program shown below.

-a 100_

116B:0100 mov ah,10_

116B:0102 int 16_


3. Run the program.

-g=100 104_

The program is now waiting for a keystroke. Strike the A key. You should see something like the following:

AX=1E61 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000

DS=116B ES=116B SS=116B CS=116B IP=0104 NV UP EI PL NZ NA PO NC

116B:0104 10CD ADC CH,CL

Observe that the AH register contains 1Eh, which is the scan code for the A key, and the AL register contains 61 (= 97 decimal), which is the ASCII code for the "a" key (lower case).

4. Run the program again.

-g=100 104_

Hold down the Shift key and strike the A key. You should see something like the following:

AX=1E41 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000

DS=116B ES=116B SS=116B CS=116B IP=0104 NV UP EI PL NZ NA PO NC

116B:0104 10CD ADC CH,CL

Now the AH register still contains 1Eh, which is the scan code for the A key, but the AL register contains 41 (= 65 decimal), which is the ASCII code for the upper case "A" key.

5. Run the program once more

-g=100 104_

Strike the ESC key. You should see something similar to the following:

AX=011B BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000

DS=116B ES=116B SS=116B CS=116B IP=0104 NV UP EI PL NZ NA PO NC

116B:0104 10CD ADC CH,CL

The AH register contains 01, which is the scan code for the Escape key, and the AL register contains 1B (= 27 decimal), which is the ASCII code for ESC.

6. Quit debug.

_ End of Experiment

The Keyboard Status Bytes
The interrupt 9 keyboard service routine is fairly complicated, since it needs to keep track of a number of different cases. For instance, the BIOS checks to see if the key pressed is a shift key (Ctrl, Shift, or Alt keys) or a toggle key (such as Num Lock or Shift Lock). This information is recorded in a two-byte section of the BIOS data area at addresses 417h and 418h, as shown in Figure 9.3. These are referred to as the keyboard status bytes. This information, being in RAM, is easily accessible by all applications, and also easily changed by the programmer, as the next experiment shows.

Figure 9.3 - Keyboard status bytes

_ Experiment-Playing with the Keyboard Status Bytes
In this experiment, we examine the keyboard status bytes.

Debug Version
1. Save all current work and start debug, as described in the appendix (Trying the Experiments).


2. The e command is used to enter a value into memory. We will enter values at the location of the first keyboard status byte (at 417h).

First enter 0 at address 417h as follows:

Debug will respond by displaying the address (in segmented form) along with the current value. You enter the new value, which in this case is 0.

Note that the status lights on your keyboard should all be off. Now repeat the process, entering values as shown below and observing the change in the keyboard status lights.

Referring to Figure 9.3, to turn on only the CAPS LOCK key, we want the first keyboard status byte to contain the binary number 0100 0000, which is 40h. Thus, we place 40h into the first keyboard status byte. We then place 20h into the byte to turn on only the NUM LOCK key, and finally 10h to turn on only the SCROLL LOCK key.

3. Quit debug.


QuickBasic Version
1. Save any current work and start QBASIC. Enter the following program and save it.

The POKE command puts a byte into memory at the specified location, and is the equivalent of debug's e command. First, we put 0 in the keyboard status byte, which should turn off all toggle and shift keys. Referring to Figure 9.3, to turn on only the CAPS LOCK key, we want the first keyboard status byte to contain the binary number 0100 0000, which is 40h. Thus, we next poke 40h into the first keyboard status byte. We then poke 20h into the byte to turn on only the NUM LOCK key, and finally 10h to turn on only the SCROLL LOCK key.

2. Run the program by hitting the F5 function key. The program will stop several times. Each time it stops, check the keyboard status lights on your keyboard. You should see them change as the value in the keyboard status byte is changed. You can continue the program by hitting the F5 function key.

3. If you want to turn on more than one key at a time, just add the corresponding values. Thus, a value of 40h + 20h = 60h will turn on both CAPS LOCK and NUM LOCK.
_ End of Experiment

Special Keystroke Combinations

It is worth mentioning that the keyboard service routine for interrupt 9 ignores certain keystroke combinations (for some reason) so if a programmer wants to be able to use those combinations, he or she may need to replace the original BIOS routine with another routine (that is, trap interrupt 9).

The BIOS keyboard routine recognizes certain special keystroke combinations. Note, however, that Microsoft Windows often uses these keystroke combinations for its own purposes, or ignores them altogether. Here are some examples.

Under DOS, this key combination causes what is referred to as a warm reboot. This will perform a "minor" reboot of the computer, but, as discussed earlier in the book, will not run the POST. This feature is quite useful when a program locks up the computer, but will only work if the BIOS keyboard routines are still working. If not, a cold reboot, initiated by the reset button on the PC, may be necessary. This resets all values in memory. Windows 95 uses this key combination in a similar manner but is thoughtful enough to provide a warning message before rebooting the system.

This key combination clears the keyboard buffer and issues an interrupt 27. This is often used to stop the execution of a program. (It also works in some Windows applications.)

PrintScreen and Alt+PrintScreen
The BIOS issues an interrupt 5 when the PrintScreen key is struck. An application can trap this interrupt to perform whatever operation is desired. Under Windows, for instance, a PrintScreen copies the screen to the Clipboard. When Alt+PrintScreen is struck, the active window is copied to the Clipboard.

Pause or Ctrl+Num Lock
Under DOS, this will pause operation until another key is pressed. Windows applications seem, in general, to ignore this keystroke.

Alt+Number from Keypad
When you hold down the Alt key and type an ASCII value from the numeric keypad, the BIOS inserts the number into the keyboard buffer as if a key with that ASCII value were pressed (whether or not there actually is such a key). The same feature works under Windows, with a difference. Under Windows, you can hold down the Alt key, then type 0 followed by a three-digit number, to get high-order ANSI characters.