Vintage PC pages
Home -> Vintage PCs -> IBM AT keyboard controller trivia

IBM AT keyboard controller trivia

These more-or-less random facts relate to the 8042 keyboard controller in the IBM AT.

XT keyboard support

The AT keyboard controller supports the XT keyboard protocol as well as its native one. This has been documented in a number of places, but always in fairly obscure terms. The Interrupt List, for example, refers to the feature as "use 8086 codes" or "IBM PC mode"; so does the Keyboard Scancodes page. It is, however, clearly documented in 8042 INTERN.

XT keyboard support must be switched on manually, by setting bit 5 of the controller command byte. On PS/2 and later computers, this bit is used to disable the mouse, so this feature is pretty certain not to work on any system with a PS/2 mouse.

On a real IBM 5170 AT, on the other hand, it works fine. The BIOS did not detect the XT keyboard and (for unrelated reasons) will not boot without a keyboard present, so I had to boot with an AT keyboard connected, switch XT support on, and hotplug the XT keyboard. This is obviously not an ideal solution, since IBM keyboards are not supposed to be hotplugged.

If you want to try this, KBXT.EXE will set/clear the appropriate bit of the command byte:

KBXT    -- displays status.
KBXT XT -- switches the keyboard controller into XT mode. 
KBXT AT -- switches the keyboard controller into AT mode.

Keylock

The keylock only blocks scancodes that correspond to set 3 keys. That is, scancodes 00h-7Fh, plus 83h and 84h. Other scancodes, such as the 0E0h prefix from an enhanced keyboard, or the Windows keys on a keyboard using set 3, are still passed through to the BIOS.

Scancode translation table

At the time the AT keyboard controller was created, Scancode Set 2 did not exist — only Sets 1 and 3. The controller contains a 128-byte table, mapping from Set 3 scancodes to Set 1. This supports all 127 Set 3 keys, even though the AT keyboard can only return 89 of them.

Some notes on scancode sets:

The table below describes the position of each key using the 6110344 keyboard. To avoid ambiguity, the ten function keys on the left are referred to as L1-L10, and the 24 function keys at the top are referred to as PF1-PF24. For some keys, I have also said what key would be in that position on a standard 102-key keyboard.

Keys where the translated scancode is higher than 0x54 (SysRQ) are generally not present on the AT keyboard, though eight of them correspond to unused positions under double-size keys. The translated scancodes in this case are 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x7C and 0x57.

Except for two clear ranges (0x58-0x6E correspond to PF1-PF23, and 0x70-0x75 are unused positions in the main alphanumeric area) there seems to be no attempt to group related keys. I also can't explain why PF24 should be mapped to 0x76 rather than 0x6F, the next key in sequence after PF23.

Key Set 3 code Set 1 code Notes
Error code0x000xFFError code
L90x010x43
L70x020x41Never seen on the wire; the keyboard sends 0x83 instead. The controller internally changes 0x83 back to 0x02 before translating it.
L50x030x3f
L30x040x3d
L10x050x3b
L20x060x3c
PF10x070x58
PF130x080x64
L100x090x44
L80x0a0x42
L60x0b0x40
L40x0c0x3e
Tab0x0d0x0f
~ `0x0e0x29
PF20x0f0x59
PF140x100x65
Left Ctrl0x110x38
Left Shift0x120x2a
\ (between left shift and Z)0x130x70
Caps Lock0x140x1d
Q0x150x10
10x160x02
PF30x170x5a
PF150x180x66
Left Alt0x190x71
Z0x1a0x2c
S0x1b0x1f
A0x1c0x1e
W0x1d0x11
20x1e0x03
PF40x1f0x5b
PF160x200x67
C0x210x2e
X0x220x2d
D0x230x20
E0x240x12
40x250x05
30x260x04
PF50x270x5c
PF170x280x68
Space0x290x39
V0x2a0x2f
F0x2b0x21
T0x2c0x14
R0x2d0x13
50x2e0x06
PF60x2f0x5d
PF180x300x69
N0x310x31
B0x320x30
H0x330x23
G0x340x22
Y0x350x15
60x360x07
PF70x370x5e
PF190x380x6a
Right Alt0x390x72
M0x3a0x32
J0x3b0x24
U0x3c0x16
70x3d0x08
80x3e0x09
PF80x3f0x5f
PF200x400x6b
< ,0x410x33
K0x420x25
I0x430x17
O0x440x18
00x450x0b
90x460x0a
PF90x470x60
PF210x480x6c
> .0x490x34
? /0x4a0x35
L0x4b0x26
: ;0x4c0x27
P0x4d0x19
_0x4e0x0c
PF100x4f0x61
PF220x500x6d
Between / and Right Shift0x510x73
@ '0x520x28
Key left of Return (ISO)0x530x74
{ [0x540x1a
+ =0x550x0d
PF110x560x62
PF230x570x6e
Right Ctrl0x580x3a
Right Shift0x590x36
Return0x5a0x1c
} ]0x5b0x1b
Key above Return (ANSI)0x5c0x75
Between + and Backspace0x5d0x2b
PF120x5e0x63
PF240x5f0x76
Cursor down0x600x55
Cursor left0x610x56
Cursor home0x620x77
Cursor up0x630x78
Backtab [Del on 102-key]0x640x79
Insert [End on 102-key]0x650x7a
Backspace0x660x0e
PA1 [Ins on 102-key]0x670x7b
Under keypad 00x680x7c
Keypad 10x690x4f
Cursor right0x6a0x7d
Keypad 40x6b0x4b
Keypad 70x6c0x47
Del [PgDn on 102-key]0x6d0x7e
PA2 [Home on 102-key]0x6e0x7f
PA3 [PgUp on 102-key]0x6f0x6f
Keypad 00x700x52
Keypad .0x710x53
Keypad 20x720x50
Keypad 50x730x4c
Keypad 60x740x4d
Keypad 80x750x48
Keypad Esc [Numlock on 102-key]0x760x01
Keypad NumLk [Keypad / on 102-key]0x770x45
Under keypad Enter0x780x57
Keypad Enter0x790x4e
Keypad 30x7a0x51
Keypad - [under keypad + on 102-key]0x7b0x4a
Keypad +0x7c0x37
Keypad 90x7d0x49
Keypad ScrLk [Keypad * on 102-key]0x7e0x46
Keypad Space [Keypad - on 102-key]0x7f0x54 Never seen on the wire. The keyboard sends 0x84 instead. The controller internally changes 0x84 back to 0x7F before translating it.
L70x830x41
Keypad Space [Keypad - on 102-key]0x840x54

John Elliott 3 April 2011.