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)


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
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License