Programming the PC Keyboard
The keyboard on a standard AT or PS/2 will accept the commands and return the codes shown below. The CPU has no direct access to the keyboard. The commands are sent and the codes received through the keyboard controller.
Key Codes
Keystrokes are indicated by the keyboard by default as "make" codes when the key is depressed and "break" codes when it is released. Prior to the AT - i.e. on the PC and XT - key break codes were the make codes with bit 7 set. The AT changed to use 0xf0 as a prefix to the make code to indicate a break.
For example, the key with make code 0x01 would have a break code of 0x81 on the XT and the two-byte sequence 0xF0, 0x01 on the AT. For compatibility the AT keyboard controller usually translates these break codes to those used earlier. So, in the example, the keyboard would send 0xf0, 0x01 and the controller would translate this pair of bytes into the single byte 0x81 before passing it to the CPU.
The keyboard controller can be told not to translate key codes. In which case it passes on each byte unchanged. And a PS/2 keyboard can be instructed to use different scan codes. See below for command 0xf0 (not to be confused with the response 0xf0 which is sent in the other direction).
The keyboard controller passes commands through to the keyboard unaltered.
Commands to the Keyboard
Command | AT Keyboard | PS/2 Keyboard | Description of the command |
---|---|---|---|
0xED X | Yes (ph) | Yes (ph) | Set LEDs according to X. Bits 7 :- 3 are reserved. Bit 2 -> Caps Lock. Bit 1 -> Num Lock. Bit 0 -> Scroll Lock (ph) |
0xEE | Yes (ph) | Yes (ph) | Echo. Returns 0xEE (ph) |
0xF0 X | No (ph) | Yes (ph) | Control scan code set X = 0 means report current scan code set X = 1 means activate set 1 X = 2 means activate set 2 X = 3 means activate set 3 (ph) If your keyboard controller translates scan codes be sure to turn its translation off while reading the scan code set to prevent it translating the number of the scan code set. This will change the state of the command byte bit 6. (upc) |
0xF2 | No (ph) | Yes (ph) | Send 2-byte keyboard identification code. (ph) Be sure to wait at least 10 ms for the keyboard to respond. (upc) Not supported on all keyboards. (upc) |
0xF3 X | Yes (ph) | Yes (ph) | Set typematic rates to X. X = 0ddrrrr0. dd sets delay, rrrr sets rate. (ph) For X = 0ddRRrrr the delay is (dd + 1) * 250 ms +/- 20% and the repeat rate is (2 ** RR) * (rrr + 8) +/- 20% in units of 1/240 second (atrm) |
0xF4 | Yes (ph) | Yes (ph) | Enable keyboard. Keyboard acknowledges, clears buffer and starts scanning (ph) If a transmit error occurs the keyboard is automatically disabled. This command reenables the keyboard and clears the keyboard's internal 16-character buffer (upc) |
0xF5 | Yes (ph) | Yes (ph) | Reset keyboard power on conditions, stop scanning and await instructions (ph) |
0xF6 | Yes (ph) | Yes (ph) | Default the keyboard. Reset power on state and continue scanning (ph) If the keyboard was enabled it continues to scan for key state changes (upc) |
0xF7 (see note) | No (ph) | Yes (ph) | Set all keys as typematic (ph) |
0xF8 (see note) | No (ph) | Yes (ph) | Set all keys as make/break (ph) |
0xF9 (see note) | No (ph) | Yes (ph) | Set all keys as make (ph) |
0xFA (see note) | No (ph) | Yes (ph) | Set all keys as typematic/make/break (ph) |
0xFB X | No (ph) | Yes (ph) | Set key with scan code X as typematic (ph) |
0xFC X | No (ph) | Yes (ph) | Set key with scan code X as make/break (ph) |
0xFD X | No (ph) | Yes (ph) | Set key with scan code X as make (ph) |
0xFE | Yes (ph) | Yes (ph) | Resend the previous output (ph) After a failed receipt this command instructs the keyboard to resend its last byte. This is normally used by the controller and is not sent by the BIOS software (upc) |
0xFF | Yes (ph) | Yes (ph) | Reset to power on state, perform self-test, clear buffer, set default parameters (ph) |
Note: Commands 0xf7 .. 0xfa only affect the keyboard when scan code set 3 is in use. See command 0xf0. (upc)
Responses from the Keyboard
The keyboard will send keystrokes and values in response to commands as follows. Note that keys can be distinguished from command responses by value.
Code | AT Keyboard | PS/2 Keyboard | Meaning of the Code |
---|---|---|---|
0x00 | Yes (ph) | Yes (ph) | Overrun. 0 is placed in the last position in the keyboard buffer (ph) |
0x00 | No (ph) | Yes (ph) | Overrun character for scan sets 2 and 3, also used for key error (ph) |
0x01+ | Yes (ph) | Yes (ph) | Scan code of a key |
0xAA | Yes (ph) | Yes (ph) | Basic assurance test response if successful. Any other code indicates a fault (ph) |
0xAB, 0x83 | No (ph) | Yes (ph) | Keyboard response to command 0xF2. 0xAB, 0x83 is the Multifunction II keyboard ID code (ph) |
0xEE | Yes (ph) | Yes (ph) | Response to echo command 0xEE (ph) |
0xF0 | Yes (ph) | No (ph) | Prefix to scan code on break of key contact (ph) |
0xFA | Yes (ph) | Yes (ph) | Acknowledge. Response to any valid input except echo (0xEE) or resend (0xFE) commands (ph) |
0xFC | No (ph) | Yes (ph) | Basic assurance test found a fault (ph) |
0xFD | Yes (ph) | No (ph) | Diagnostic. Problem detected in the sense amplifier (ph) |
0xFE | Yes (ph) | Yes (ph) | Resend. Issued by keyboard after receiving an invalid input (ph) |
0xFF | No (ph) | Yes (ph) | Overrun character for scan set 1. Also used for key error (ph) |
Sources
The sources of the above information are
- (atrm) - IBM Technical Reference - Personal Computer/AT
- (ph) - PC Programmer's Handbook – Second edition
- (upc) - The Undocumented PC, Frank van Gilluwe