================================================================ IBM PC KEYBOARD INFORMATION FOR SOFTWARE DEVELOPERS ================================================================ Your host: Chris Giese http://www.execpc.com/~geezer/os Distribute freely. Last revised on Jan 3, 2002 Sources: PORTS.A of Ralf Brown's interrupt list collection repairfaq.org keyboard FAQ(doesn't appear to exsist) Linux source code Test hardware: New Samsung KB3T001SAXAA 104-key keyboard Old Maxi 2186035-00-21 101-key keyboard NO WARRANTY. NO GUARANTEE. I have tried to make this information accurate. I don't know if I succeeded. Corrections or additional information would be welcome. This is a plain-text document. If you use a word-processor to view it, use a fixed-pitch font (like Courier) so columnar data and ASCII art lines up properly. Lessons learned: - Both the 8048 MCU in the keyboard and the 8042 controller on the motherboard accept command bytes. - There is a bit (KCC) in the poorly-named "Command Byte" which seems to enable AT-to-XT scancode conversion (scancode set 2 to scancode set 1). After booting DOS, my keyboard uses scancode set 2 with this conversion bit turned on. If I turn the bit off and switch to scancode set 1, operation remains the same. - Scancode set 3 is probably the most elegant, in that it returns a one-byte make code for _every_ key. Unfortunately, not all keyboards support it. - The scancodes of some keys depend on the internal num lock state of the keyboard. ================================================================ KEYBOARD I/O REGISTERS ON THE PC ================================================================ 60h data 64h command (write) 64h Status (read) Bits in Status register (names from Linux source) b7 PERR parity error in data received from keyboard b6 GTO receive timeout b5 transmit timeout (or PS/2 mouse?) b4 keyboard is locked b3 0=60h was the port last accessed, 1=61h was last (?) b2 System Flag status: 0=power-up/reset, 1=selftest OK (?) b1 IBF input buffer full (data from host to keyboard) b0 OBF output buffer full (data from keyboard to host) Bits in Output Port of 8042 chip (Table P0383 in PORTS.A) The Output Port is written by controller command D1h, and read by controller command D0h b7 keyboard data output b6 keyboard clock output b5 input buffer NOT full b4 output buffer NOT empty b3 (varies) b2 (varies) b1 A20 gate b0 system reset (THIS BIT SHOULD ALWAYS BE SET TO 1) Bits in Input Port of 8042 chip The Input Port is read by controller command C0h b7 keyboard NOT locked b6-b0 (varies) Bits in "Command Byte" (confusing name; from Table P0404 in PORTS.A) The "Command Byte" is written by controller command 60h and read by controller command 20h (names from Linux source) b7 (reserved) b6 KCC convert set 2 scancodes to set 1 ("IBM PC compatibility mode") b5 DMS disables PS/2 mouse when set b4 disables keyboard when set b3 ignore keyboard lock switch when set b2 SYS System Flag (same as b2 in Status register, it seems) b1 enables IRQ12 from PS/2 mouse when set b0 EKI enables IRQ1 on keyboard output buffer full Result Byte for interface self-tests (Table P0406 in PORTS.A) Returned by controller commands A9h or ABh 0 no error 1 clock line stuck low 2 clock line stuck high 3 data line stuck low 4 data line stuck high ================================================================ CONTROLLER COMMANDS (from Table P0401 of PORTS.A) ================================================================ Before writing each byte of these commands to port 64h, poll the status register (port 60h) until bit b1=0. 20h-2Fh reads byte with address=lower 5 bits of command The byte at address 0 is the "Command Byte". 60h-7Fh nn writes byte nn to address=lower 5 bits of command The byte at address 0 is the "Command Byte". A7h disables PS/2 mouse port (MCA only?) A8h enables PS/2 mouse port (MCA only?) A9h self-test mouse interface, returns Result Byte (see above) AAh self-test controller; returns 55h if success, FCh if failure ABh self-test keyboard interface, returns Result Byte (see above) ADh disables keyboard (sets b4 of "Command Byte") AEh enables keyboard (clears b4 of "Command Byte") C0h reads Input Port D0h reads Output Port D1h nn writes Output Port Important: bit 0 (system reset) should always be set here, as the system may hang constantly. To reset the PC, pulse b0 of the Output Port with command FEh instead. DDh disable A20 (Not all systems support this byte) DFh enable A20 (Not all systems support this byte) E0h read test inputs. return value= b1 kbd data b0 kbd clock EDh nn write LEDs. nn= b2 Caps Lock b1 Num Lock b0 Scroll Lock F0h-FFh pulse bit(s) of Output Port low for 6 microseconds. If b0-b3 of the command is low, the corresponding bit in the Output Port will be pulsed low. b0=system reset, and should ALWAYS be PULSED low, never set low constantly. ================================================================ KEYBOARD COMMANDS (from Table P0386 of PORTS.A) ================================================================ Before writing each byte of these commands to port 60h, poll the status register (port 60h) until bit b1=0. Unless otherwise noted: each command responds with FAh (ACKnowledge) or FEh (Resend) after receiving each byte of the command. EDh nn write LEDs, as above EEh echo, keyboard responds with EEh EFh no-operation (reserved) F0h nn selects scancode set nn=1-3 or 0 to return current set F2h read ID. Keyboard responds with ACK (FAh) and two optional ID bytes: (none) AT keyboard 83h ABh (?) ABh 41h MF2, translation mode ABh 83h MF2, pass-through mode F3h nn set typematic (auto-repeat) rate/delay. nn= b7 unused b6..5 Repeat delay (00=250 msec ... 11=1000msec) b4..0 Repeat rate (00000=30 Hz ... 11111=2 Hz). F4h clears output buffer, enables keyboard F5h disables keyboard, resets to defaults F6h sets keyboard defaults F7h make all keys typematic (auto-repeat) [*] F8h make all keys make-break [*] F9h make all keys make-only [*] FAh make all keys typematic and make-break [*] FBh nn make one key typematic [*] FCh nn make one key make-break [*] FDh nn make one key make-only [*] [*] these commands may work only for scancode set 3; I'm not sure. FEh resend previous scan code FFh reset keyboard CPU, do power-on self-test, return self-test result byte non-key status bytes -------------------- 00h Key detection error or buffer full. AAh Power-on/reset diagnostics successful. E0h (scancode sets 1 and 2) Prefix byte for "gray" keys (keys not on original 83-/84-key keyboard) EEh Sent in response to ECHO command. F0h (scancode sets 2 and 3) Prefix byte for break codes. FAh ACKknowledge; response to most commands. FCh Diagnostics failed (MF keyboard). FDh Diagnostics failed (AT keyboard). The keyboard stops scanning and waits for next command after returning code FCh or FDh FEh Last command was invalid or had parity error; resend it. FFh Key detection error or buffer full. ==================================================================== SCANCODES FOR SCANCODE SET 1 (XT) ==================================================================== US 104-key keyboard, set 1 scancodes "Make" code is generated when key is pressed. "Break" code is generated when key is released. Hex value of make code for each key is shown. Most keys: one-byte make code = nn one-byte repeat code = nn one-byte break code = 80h + nn "Gray" keys (not on original 84-key keyboard): two-byte make code = E0nn two-byte repeat code = E0nn two-byte break code = E0 followed by 80h + nn "Gray" keys noted by [1] are NumLock-sensitive. When the keyboard's internal NumLock is active: four-byte make code = E02AE0nn two-byte repeat code = E0nn four-byte break code = E0 followed by 80h + nn followed by E0AA ____ ___________________ ___________________ ___________________ | | | | | | | | | | | | | | | | | |Esc | |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10 |F11 |F12 | | | | | | | | | | | | | | | | | | | 01| | 3B| 3C| 3D| 3E| | 3F| 40| 41| 42| | 43| 44| 57| 58| |____| |____|____|____|____| |____|____|____|____| |____|____|____|____| __________________________________________________________________________ | | | | | | | | | | | | | | | | |~ |! |@ |# |$ |% |^ |& |* |( |) |_ |+ || |bksp| |` |1 |2 |3 |4 |5 |6 |7 |8 |9 |0 |- |= |\ | | | 29| 02| 03| 04| 05| 06| 07| 08| 09| 0A| 0B| 0C| 0D| 2B| 0E| |____|____|____|____|____|____|____|____|____|____|____|____|____|____|____| | | | | | | | | | | | | | | | |Tab |Q |W |E |R |T |Y |U |I |O |P |{ |} | | | | | | | | | | | | | |[ |] | | | 0F| 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 1A| 1B| | |____|____|____|____|____|____|____|____|____|____|____|____|____| | | | | | | | | | | | | | | | |Caps|A |S |D |F |G |H |J |K |L |: |" | Enter | | | | | | | | | | | |; |' | | | 3A| 1E| 1F| 20| 21| 22| 23| 24| 25| 26| 27| 28| 1C| |____|____|____|____|____|____|____|____|____|____|____|____|______________| | | | | | | | | | | | | | | L Shift |Z |X |C |V |B |N |M |< |> |? | R Shift | | | | | | | | | |, |. |/ | | | 2A| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 34| 35| 36| |_________|____|____|____|____|____|____|____|____|____|____|______________| | | | | | | | | | |L Ctrl | L win | L Alt | space | R Alt | R win | menu |R Ctrl | | |[1] | | | |[1] |[1] | | | 1D| E05B| 38| 39| E038| E05C| E05D| E01D| |_______|_______|_______|__________________|_______|_______|_______|_______| [2] For PrintScreen/SysRq key: make code = E02AE037, repeat code = E037, break code = E0B7E0AA [3] The Pause/Break key does not repeat, and it does not generate a break code. Its make code is E11D45E19DC5 ____ ____ ____ | | | | |Prt |Scrl|Paus| |Scrn|Lock|Brk | | [2]| 46| [3]| |____|____|____| ____ ____ ____ ____ ____ ____ ____ | | | | | | | | | |Ins |Home|PgUp| |Num |/ |* |- | |[1] |[1] |[1] | |Lock| | | | |E052|E047|E049| | 45|E035| 37| 4A| |____|____|____| |____|____|____|____| | | | | | | | | | |Del |End |PgDn| |7 |8 |9 | | |[1] |[1] |[1] | |Home|(U) |PgUp| | |E053|E04F|E051| | 47| 48| 49| | |____|____|____| |____|____|____| | | | | |+ | |4 |5 |6 | | |(L) | |(R) | | | 4B| 4C| 4D| 4E| ____ |____|____|____|____| | | | | | | | |(U) | |1 |2 |3 | | |[1] | |End |(D) |PgDn| | |E048| | 4F| 50| 51|Ent | ____|____|____ |____|____|____| | | | | | | | | | |(L) |(D) |(R) | |0 |. | | |[1] |[1] |[1] | |Ins |Del | | |E04B|E050|E04D| | 52| 53|E01C| |____|____|____| |_________|____|____| code key code key code key code key ---- --- ---- --- ---- --- ---- --- 01 Esc 0F Tab 1D L Ctrl 2B \| 02 1! 10 Q 1E A 2C Z 03 2" 11 W 1F S 2D X 04 3# 12 E 20 D 2E C 05 4$ 13 R 21 F 2F V 06 5% 14 T 22 G 30 B 07 6^ 15 Y 23 H 31 N 08 7& 16 U 24 J 32 M 09 8* 17 I 25 K 33 ,< 0A 9( 18 O 26 L 34 .> 0B 0) 19 P 27 ;: 35 /? 0C -_ 1A [{ 28 '" 36 R Shift 0D =+ 1B ]} 29 `~ 37 * 0E BackSpace 1C Enter 2A L Shift 38 L Alt code key code key code key code key ---- --- ---- --- ---- --- ---- --- 39 Space 41 F7 49 PageUp 9 51 PageDown 3 3A CapsLock 42 F8 4A - 52 Insert 0 3B F1 43 F9 4B (left) 4 53 Del . 3C F2 44 F10 4C 5 3D F3 45 NumLock 4D (right) 6 57 F11 3E F4 46 ScrollLock 4E + 58 F12 3F F5 47 Home 7 4F End 1 40 F6 48 (up) 8 50 (down) 2 code key ---- --- E01C Enter (on numeric keypad) E01D R Ctrl E02A make code prefix for keyboard internal numlock E02AE037 PrintScreen make code E035 / E037 PrintScreen repeat code E038 R Alt E047 Home E048 (up) E049 PageUp E04B (left) E04D (right) E04F End E050 (down) E051 PageDown E052 Insert E053 Del E05B L Win E05C R Win E05D Menu E0AA break code suffix for keyboard internal numlock E0B7E0AA PrintScreen break code E11D45E19DC5 Pause ==================================================================== SCANCODES FOR SCANCODE SET 2 (AT) ==================================================================== US 104-key keyboard, set 2 scancodes, 8042 AT-to-XT scancode translation OFF "Make" code is generated when key is pressed. "Break" code is generated when key is released. Hex value of make code for each key is shown. Most keys: one-byte make code = nn one-byte repeat code = nn two-byte break code = F0nn "Gray" keys (not on original 84-key keyboard): two-byte make code = E0nn two-byte repeat code = E0nn three-byte break code = E0F0nn "Gray" keys noted by [1] are NumLock-sensitive. When the keyboard's internal NumLock is active: four-byte make code = E012E0nn two-byte repeat code = E0nn six-byte break code = E0F0nnE0F012 ____ ___________________ ___________________ ___________________ | | | | | | | | | | | | | | | | | |Esc | |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10 |F11 |F12 | | | | | | | | | | | | | | | | | | | 76| | 05| 06| 04| 0C| | 03| 0B| 83| 0A| | 01| 09| 78| 07| |____| |____|____|____|____| |____|____|____|____| |____|____|____|____| __________________________________________________________________________ | | | | | | | | | | | | | | | | |~ |! |@ |# |$ |% |^ |& |* |( |) |_ |+ || |bksp| |` |1 |2 |3 |4 |5 |6 |7 |8 |9 |0 |- |= |\ | | | 0E| 16| 1E| 26| 25| 2E| 36| 3D| 3E| 46| 45| 4E| 55| 5D| 66| |____|____|____|____|____|____|____|____|____|____|____|____|____|____|____| | | | | | | | | | | | | | | | |Tab |Q |W |E |R |T |Y |U |I |O |P |{ |} | | | | | | | | | | | | | |[ |] | | | 0D| 15| 1D| 24| 2D| 2C| 35| 3C| 43| 44| 4D| 54| 5B| | |____|____|____|____|____|____|____|____|____|____|____|____|____| | | | | | | | | | | | | | | | |Caps|A |S |D |F |G |H |J |K |L |: |" | Enter | | | | | | | | | | | |; |' | | | 58| 1C| 1B| 23| 2B| 34| 33| 3B| 42| 4B| 4C| 52| 5A| |____|____|____|____|____|____|____|____|____|____|____|____|______________| | | | | | | | | | | | | | | L Shift |Z |X |C |V |B |N |M |< |> |? | R Shift | | | | | | | | | |, |. |/ | | | 12| 1A| 22| 21| 2A| 32| 31| 3A| 41| 49| 4A| 59| |_________|____|____|____|____|____|____|____|____|____|____|______________| | | | | | | | | | |L Ctrl | L win | L Alt | space | R Alt | R win | menu |R Ctrl | | |[1] | | | |[1] |[1] | | | 14| E01F| 11| 29| E011| E027| E02F| E014| |_______|_______|_______|__________________|_______|_______|_______|_______| [2] For PrintScreen/SysRq key: make code = E012E07C, repeat code = E07C, break code = E0F07CE0F012 [3] The Pause/Break key does not repeat, and it does not generate a break code. Its make code is E11477E1F014F077 ____ ____ ____ | | | | |Prt |Scrl|Paus| |Scrn|Lock|Brk | | [2]| 7E| [3]| |____|____|____| ____ ____ ____ ____ ____ ____ ____ | | | | | | | | | |Ins |Home|PgUp| |Num |/ |* |- | |[1] |[1] |[1] | |Lock| | | | |E070|E06C|E07D| | 77|E04A| 7C| 7B| |____|____|____| |____|____|____|____| | | | | | | | | | |Del |End |PgDn| |7 |8 |9 | | |[1] |[1] |[1] | |Home|(U) |PgUp| | |E071|E069|E07A| | 6C| 75| 7D| | |____|____|____| |____|____|____| | | | | |+ | |4 |5 |6 | | |(L) | |(R) | | | 6B| 73| 74| 79| ____ |____|____|____|____| | | | | | | | |(U) | |1 |2 |3 | | |[1] | |End |(D) |PgDn| | |E075| | 69| 72| 7A|Ent | ____|____|____ |____|____|____| | | | | | | | | | |(L) |(D) |(R) | |0 |. | | |[1] |[1] |[1] | |Ins |Del | | |E06B|E072|E074| | 70| 71|E05A| |____|____|____| |_________|____|____| code key code key code key code key ---- --- ---- --- ---- --- ---- --- 01 F9 66 BackSpace 21 C 41 ,< 03 F5 22 X 42 K 69 End 1 04 F3 23 D 43 I 05 F1 24 E 44 O 6B (left) 4 06 F2 25 4$ 45 0) 6C Home 7 07 F12 26 3# 46 9( 70 Ins 0 09 F10 29 Space 49 .> 71 Del . 0A F8 2A V 4A /? 72 (down) 2 0B F6 2B F 4B L 73 5 0C F4 2C T 4C ;: 74 (right) 6 0D Tab 2D R 4D P 75 (up) 8 0E `~ 2E 5% 4E -_ 76 Esc 77 NumLock 11 L Alt 31 N 52 '" 78 F11 12 L Shift 32 B 79 + 33 H 54 [{ 7A PageDown 3 14 L Ctrl 34 G 55 =+ 7B - 15 Q 35 Y 7C * 16 1! 36 6^ 58 CapsLock 7D PageUp 9 59 R Shift 7E ScrollLock 1A Z 3A M 5A Enter 1B S 3B J 5B ]} 83 F7 1C A 3C U 1D W 3D 7& 5D \| 1E 2@ 3E 8* code key ---- --- E011 R Alt E012E07C PrintScreen make code E014 R Ctrl E01F L Win E027 R Win E02F Menu E04A / E05A Enter (on numeric keypad) E069 End E06B Left E06C Home E070 Ins E071 Del E072 (down) E074 (right) E075 (up) E07A PageDown E07C PrintScreen repeat code E07D PageUp E0F07CE0F012 PrintScreen break code E11477E1F014F077 Pause ==================================================================== SCANCODES FOR SCANCODE SET 3 ==================================================================== US 104-key keyboard, set 3 scancodes "Make" code is generated when key is pressed. "Break" code is generated when key is released. Hex value of make code for each key is shown. All keys: one-byte make code = nn one-byte repeat code = nn two-byte break code = F0nn When operating in scancode set 3, the keyboard does not maintain an internal NumLock state. ____ ___________________ ___________________ ___________________ | | | | | | | | | | | | | | | | | |Esc | |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10 |F11 |F12 | | | | | | | | | | | | | | | | | | | 08| | 07| 0F| 17| 1F| | 27| 2F| 37| 3F| | 47| 4F| 56| 5E| |____| |____|____|____|____| |____|____|____|____| |____|____|____|____| __________________________________________________________________________ | | | | | | | | | | | | | | | | |~ |! |@ |# |$ |% |^ |& |* |( |) |_ |+ || |bksp| |` |1 |2 |3 |4 |5 |6 |7 |8 |9 |0 |- |= |\ | | | 0E| 16| 1E| 26| 25| 2E| 36| 3D| 3E| 46| 45| 4E| 55| 5C| 66| |____|____|____|____|____|____|____|____|____|____|____|____|____|____|____| | | | | | | | | | | | | | | | |Tab |Q |W |E |R |T |Y |U |I |O |P |{ |} | | | | | | | | | | | | | |[ |] | | | 0D| 15| 1D| 24| 2D| 2C| 35| 3C| 43| 44| 4D| 54| 5B| | |____|____|____|____|____|____|____|____|____|____|____|____|____| | | | | | | | | | | | | | | | |Caps|A |S |D |F |G |H |J |K |L |: |" | Enter | | | | | | | | | | | |; |' | | | 14| 1C| 1B| 23| 2B| 34| 33| 3B| 42| 4B| 4C| 52| 5A| |____|____|____|____|____|____|____|____|____|____|____|____|______________| | | | | | | | | | | | | | | L Shift |Z |X |C |V |B |N |M |< |> |? | R Shift | | | | | | | | | |, |. |/ | | | 12| 1A| 22| 21| 2A| 32| 31| 3A| 41| 49| 4A| 59| |_________|____|____|____|____|____|____|____|____|____|____|______________| | | | | | | | | | |L Ctrl | L win | L Alt | space | R Alt | R win | menu |R Ctrl | | | | | | | | | | | 11| 8B| 19| 29| 39| 8C| 8D| 58| |_______|_______|_______|__________________|_______|_______|_______|_______| ____ ____ ____ | | | | |Prt |Scrl|Paus| |Scrn|Lock|Brk | | 57| 5F| 62| |____|____|____| ____ ____ ____ ____ ____ ____ ____ | | | | | | | | | |Ins |Home|PgUp| |Num |/ |* |- | | | | | |Lock| | | | | 67| 6E| 6F| | 76| 77| 7E| 84| |____|____|____| |____|____|____|____| | | | | | | | | | |Del |End |PgDn| |7 |8 |9 | | | | | | |Home|(U) |PgUp| | | 64| 65| 6D| | 6C| 75| 7D| | |____|____|____| |____|____|____| | | | | |+ | |4 |5 |6 | | |(L) | |(R) | | | 6B| 73| 74| 7C| ____ |____|____|____|____| | | | | | | | |(U) | |1 |2 |3 | | | | |End |(D) |PgDn| | | 63| | 69| 72| 7A|Ent | ____|____|____ |____|____|____| | | | | | | | | | |(L) |(D) |(R) | |0 |. | | | | | | |Ins |Del | | | 61| 60| 6A| | 70| 71| 79| |____|____|____| |_________|____|____| code key code key code key code key ---- --- ---- --- ---- --- ---- --- 07 F1 2A V 4A /? 6B (left) 4 08 Esc 2B F 4B L 6C Home 7 2C T 4C ;: 6D PageDown 0D Tab 2D R 4D P 6E Home 0E `~ 2E 5% 4E -_ 6F PageUp 0F F2 2F F6 4F F10 70 Ins 0 71 Del . 11 L Ctrl 31 N 52 '" 72 (down) 2 12 L Shift 32 B 73 5 33 H 54 [{ 74 (right) 6 14 CapsLock 34 G 55 =+ 75 (up) 8 15 Q 35 Y 56 F11 76 NumLock 16 1! 36 6^ 57 PrintScr 77 / 17 F3 37 F7 58 R Ctrl 59 R Shift 79 Enter (on numeric keypad) 19 L Alt 39 R Alt 5A Enter 7A PageDown 3 1A Z 3A M 5B ]} 1B S 3B J 5C \| 7C + 1C A 3C U 7D PageUp 9 1D W 3D 7& 5E F12 7E * 1E 2@ 3E 8* 5F ScrollLock 1F F4 3F F8 60 (down) 84 - 61 (left) 21 C 41 ,< 62 Pause 8B L Win 22 X 42 K 63 (up) 8C R Win 23 D 43 I 64 Del 8D Menu 24 E 44 O 65 End 25 4$ 45 0) 66 BackSpace 26 3# 46 9( 67 Ins 27 F5 47 F9 69 End 1 29 Space 49 .> 6A (right)