Sample Page

Broadly speaking, a scancode (or scan code) is either a number[a] or bit array[b] that is used by a keyboard protocol to uniquely identify[c] a keyboard key. Keyboards normally[d] send scancodes to the computer to update the computer’s internal keyboard state (which tracks what keys are being held down). The exact mechanism how, when and what scancodes are sent depends on the protocol.

A keyboard protocol may use other means to update the computer’s internal keyboard state, such as sending a bitmap that encodes the state of keys (pressed/released). This is partially the case for a keyboard using the HID protocol when the Boot Protocol is selected. It will send the states of modifier keys encoded in a bitmap (where each bit represents a key state) alongside a scancode array of pressed keys (excluding modifier keys).[1]

History

Mapping key positions by row and column requires less complex computer hardware; therefore, in the past, using software or firmware to translate the scancodes to text characters was less expensive than wiring the keyboard by text character.[2] This cost difference is not as profound as it used to be. However, many types of computers still use their traditional scancodes to maintain backward compatibility.

PC compatibles

IBM PC compatible computer keyboards send a scancode when a key is pressed and released. When a key is pressed its so called “make” scancode is send which differs from its so called “break” scancode that is send when the key is released. The IBM PC compatible standard also allows keyboards to generate “typematic” repeating keys by having the keyboard itself generate the make scancode repeatedly while a key is held down.[3] Most character keys have a single byte make scancode; keys that perform special functions have 2-byte or 3-byte scancodes, usually beginning with the byte (in hexadecimal) E0, E1, or E2. In addition, a few keys send longer scancodes which emulate a series of keys to make it easier for different types of software to process.

PC keyboards since the PS/2 keyboard support up to three scancode sets. A PS/2 compatible keyboard can be told to send scancodes in set 1, 2 or 3, although it is keyboard-dependent which scancode sets are supported by the keyboard.[4] The most commonly encountered are the “XT” (“set 1”) scancodes, based on the 83-key keyboard used by the IBM PC XT and earlier. These mostly consist of a single byte; the low 7 bits identify the key, and the most significant bit is clear for a key press (make scancode) or set for a key release (break scancode). Some additional keys have an E0 (or rarely, E1 or E2) prefix. These were initially assigned so that ignoring the E0 prefix (which is in the key-up range and thus would have no effect on an operating system that did not understand them) would produce reasonable results. For example the numeric keypad’s Enter key produces a scancode of E0 1C, which corresponds to the Return key’s scancode of 1C.

The IBM 3270 PC introduced its own set of scancodes (“set 3”), with a different key numbering and where a key release is indicated by an F0 prefix. For backward compatibility, the 3270 PC translated these to XT (set 1) scancodes using an add-on card and a BIOS extension.

The IBM PC AT introduced the “AT” (“set 2”) scancodes. On the 84-key AT keyboard these were largely a subset of set 3, with some differences caused by the revised layout (for example, the position and scancodes of the function keys changed). Keys added since the PC AT often have different scancodes in set 2 and set 3, and in set 2 frequently have an E0 or E1 prefix. Again, key release is indicated by an F0 prefix.

For computers since the IBM PC AT, the keyboard controller on the motherboard translates AT (set 2) scancodes into XT (set 1) scancodes in so called translation mode.[5] This translation can be disabled in pass-through-mode, allowing the raw scancodes to be seen.[6] Therefore, whether a software developer will encounter set 2 scancodes or set 1 scancodes on a modern PC-compatible depends on how the keyboard is being accessed. If linux detects a translation from set 2 to set 1 by the keyboard controller it will use set 1, otherwise it will almost certainly use set 2.[7]


Example PC compatible (IBM PS/2) scancodes
key set 1 (IBM PC XT)[8] set 2 (IBM PC AT)[9] set 3 (IBM 3270 PC)[10]
press release press release press release
A (simple letter) 1E 9E 1C F0 1C 1C F0 1C
↵ Enter (main keyboard) 1C 9C 5A F0 5A 5A F0 5A
↵ Enter (numeric keypad) E0 1C E0 9C E0 5A E0 F0 5A 79 F0 79
Left ⊞ Win (Windows key) E0 5B E0 DB E0 1F E0 F0 1F 8B F0 8B
Right ⊞ Win E0 5C E0 DC E0 27 E0 F0 27 8C F0 8C

USB

USB keyboards use a new set of scancodes, mostly specified in the USB standard. All computers that recognize USB keyboards recognize these new scancodes.[11]

Further information

On some operating systems one may discover a key’s downpress scancode by holding the key down while the computer is booting. With luck, the scancode (or some part of it) will be specified in the resulting “stuck key” error message. [Note: On Windows 7 only one byte of the scancode appears.]

A virtual keyboard does not input scancodes but Unicode characters.

See also

Notes

  1. ^ For example, Usage IDs in the HID Keyboard/Keypad Usage Page that are defined in the USB specification: https://www.usb.org/sites/default/files/hut1_7.pdf
  2. ^ For example, PS/2 scancodes: https://oe7twj.at/images/6/6a/PS2_Keyboard.pdf
  3. ^ “uniquely identify” refers to a N:1 mapping according to wikipedia. So this sentence implies that multiple scancodes can be associated with a key. For example, PS/2 associates two scancodes with every key (except the Pause key).
  4. ^ Some keyboard protocols do not define scancodes. For example, PCW keyboards use a bitmap which encodes the keyboard state. See https://www.seasip.info/Unix/Joyce/pcwkbd.html

References

  1. ^ Device Class Definition for Human Interface Devices (HID) (PDF) (Report). USB-IF. 2026. pp. 56, 59–60.
  2. ^ For example, the traditional 12-key numeric keypad is scanned as 3 columns by 4 rows, requiring a total of 7 connections. Scanning each key separately would require 12 connections.
  3. ^ https://www-ug.eecg.toronto.edu/msl/nios_devices/datasheets/PS2%20Keyboard%20Protocol.htm#:~:text=Make%20Codes%2C%20Break%20Codes%2C%20and%20Typematic%20Repeat
  4. ^ https://aeb.win.tue.nl/linux/kbd/scancodes-12.html#:~:text=Command%20f0
  5. ^ Brouwer, Andries (2004-05-20), “Section 10, “Keyboard internal scancodes”, Keyboard scancodes (Version 1.2e ed.), retrieved 2006-11-15
  6. ^ Brouwer, Andries (2009-07-07), “Section 11, “The AT keyboard controller”, Keyboard scancodes (Version 1.2g ed.), retrieved 2010-07-18
  7. ^ https://elixir.bootlin.com/linux/v6.19/source/drivers/input/keyboard/atkbd.c#L881 (Notice: Ignore the outdated comment in the source code)
  8. ^ https://www.marjorie.de/ps2/scancode-set1.htm
  9. ^ https://www.marjorie.de/ps2/scancode-set2.htm
  10. ^ https://www.marjorie.de/ps2/scancode-set3.htm
  11. ^ Microsoft Corporation (2000-03-16), “Appendix C, “USB Keyboard/Keypad Page (0x07)”“, Microsoft Keyboard Scan Code Specification (Revision 1.3a ed.), retrieved 2018-10-13