The IBM 1397000 Keyboard
Note: You need a browser capable of displaying SVG images to see the keyboard layouts.
The IBM 1397000 keyboard (described on the box as the "IBM Personal System/2 Host Connected Keyboard") is a 122-key Model M terminal emulator keyboard.
This particular model uses the US layout and has a detachable SDL cable.
Some serial numbers associated with this keyboard are:
- 1397000
- The keyboard part number
- 1397050
- The keyboard FRU number
- 1396400
- The part number for the complete package (keyboard plus driver floppy)
- 1396063
- Controller PCB
- 1396064
- 6805 Microcontroller
Identity
When sent an identify command (0xF2), the keyboard returns the byte sequence 0xAB 0x86.
Scancodes
The keys on the 1397000 are laid out like this:
The keyboard supports all three IBM scancode sets. The scancodes it returns are:
Set 1
Notes:
- Smaller numbers shown in circles are holes in the keyboard with no springs, corresponding to unused positions covered by double-sized keys.
- As on other Model M keyboards I've seen, there's a second hole under the spacebar, which doesn't respond when poked with a screwdriver and is therefore probably just for a stabiliser.
- Attn / SysRQ (shaded magenta) generates 71 if Alt is not held down, 54 if it is.
- Pause / ErInp (shaded yellow) generates the sequence E11D,45,E19D,C5 when pressed (ie, Press fake Ctrl, press NumLock, release fake Ctrl, release NumLock) and nothing on release. If real Ctrl is held, it sends scancodes E145, E1C5 on press and nothing on release.
- Print / PrtSc (shaded green) generates scancodes E02A, E037 (ie: Press fake Shift, press PrintScreen) on press, and E0B7, E0AA on release. If any of Shift, Ctrl or Alt are pressed, it generates only E037 on press and E0B7 on release.
- NumLk / ScrLk (shaded cyan) generates scancode 46 [Scroll Lock] if Shift is not pressed, 45 [Num lock] if Shift is pressed.
- Space / Slash / Break (shaded violet) generates E035 (Keypad /) if no Ctrl key is down. If one is it sends E046 E0C6 (Ctrl-Break down, Ctrl-Break up) on press, and nothing on release.
- A number of keys send fake shift press and release codes under various circumstances. I am assuming these to be the same as for the 101-key PS/2 keyboard, listed here.
Set 1 is not intended to be translated by the keyboard controller. If you do turn translation on, you get these codes:
Notes:
- These are 'make' codes. The 'break' codes, being in the 80-FF range, mostly avoid being translated; so (for example) A has the make code 03 but the break code 9E.
Set 2
Notes:
- The five highlighted keys, as in Set 1, send different key sequences depending on what shifts are pressed:
- Attn / SysRQ sends 19 if Alt is not pressed, 84 if it is.
- Pause / ErInp sends E114 77 E1F014 F077 if Ctrl is not pressed, E177 E1F077 if it is.
- Print / Prtsc sends E012 E07C if none of Shift / Ctrl / Alt is pressed, E07C if one is.
- NumLk / ScrLk sends 7E if Shift is not pressed, 77 if it is.
- Space / Slash / Break sends E04A if Ctrl is not pressed. If Ctrl is pressed it sends E07E E0F07E on press and nothing on release.
These scancodes are expected to be translated by the keyboard controller, producing the same output that you'd get from (untranslated) Set 1:
Set 3
Set 3 uses the same position-based coding as the 122-key terminal keyboards and the 84-key AT keyboard. It is the only set to distinguish between the key position above Return (where Backslash is on a 101-key keyboard) and the one to the left of Return (where Hash is on a 102-key keyboard).
Notes:
- Only the keys highlighted in grey return break codes (F0 xx).
- Compared to a 102-key keyboard, some keys have different Set 3 scancodes. For example, on a 102-key keyboard PgUp and PgDn have the set 3 scancodes 6F and 6D, respectively. On a 122-key keyboard they have set 3 scancodes 6E and 6F, because they're in different places.
After translation by the keyboard controller, these codes become:
So, here's my grand unified list of Set 3 scancodes, sorted by number.
- The "Key position" columns are an indication of position rather than keycap.
- Keys where the set 1 / 2 scancode differs between the 122-key keyboard and a normal 101 / 102-key keyboard are highlighted.
Set 3 code | Translated Set 3 code | 122-key | 101 / 102-key | Key position | Set 2 code | Set 1 code | Key position | Set 2 code | Set 1 code |
---|---|---|---|---|---|---|---|
01 | 43 | F9 (left function key block) | 5C | 75 | |||
02 | -- | Not assigned (why?) | -- | -- | |||
03 | 3F | F5 (left function key block) | 53 | 74 | |||
04 | 3D | F3 (left function key block) | 39 | 72 | |||
05 | 3B | F1 (left function key block) | 19 / 84 | 71 / 54 | |||
06 | 3C | F2 (left function key block) | 5F | 76 | |||
07 | 58 | F1 (top function key block) | 05 | 3B | same | 05 | 3B |
08 | 64 | F13 (top function key block) | 1F | 5B | Esc | 76 | 01 |
09 | 44 | F10 (left function key block) | 48 | 6C | |||
0A | 42 | F8 (left function key block) | 6F | 6F | |||
0B | 40 | F6 (left function key block) | 50 | 6D | |||
0C | 3E | F4 (left function key block) | 77 / E177 | 45 / E145 | |||
0D | 0F | Tab | 0D | 0F | same | 0D | 0F |
0E | 29 | Key to the left of 1 | 0E | 29 | same | 0E | 29 |
0F | 59 | F2 (top function key block) | 06 | 3C | same | 06 | 3C |
10 | 65 | F14 (top function key block) | 27 | 5C | |||
11 | 38 | Left Ctrl | 14 | 1D | same | 14 | 1D |
12 | 2A | Left Shift | 12 | 2A | same | 12 | 2A |
13 | 70 | \ (if adjacent to left Shift) | 61 | 56 | same | 61 | 56 |
14 | 1D | Caps Lock | 58 | 3A | same | 58 | 3A |
15 | 10 | Q | 15 | 10 | same | 15 | 10 |
16 | 02 | 1 | 16 | 02 | same | 16 | 02 |
17 | 5A | F3 (top function key block) | 04 | 3D | same | 04 | 3D |
18 | 66 | F15 (top function key block) | 5E | 5D | |||
19 | 71 | Left Alt | 11 | 38 | same | 11 | 38 |
1A | 2C | Z | 1A | 2C | same | 1A | 2C |
1B | 1F | S | 1B | 1F | same | 1B | 1F |
1C | 1E | A | 1C | 1E | same | 1C | 1E |
1D | 11 | W | 1D | 11 | same | 1D | 11 |
1E | 03 | 2 | 1E | 03 | same | 1E | 03 |
1F | 5B | F4 (top function key block) | 0C | 3E | same | 0C | 3E |
20 | 67 | F16 (top function key block) | 5E | 63 | |||
21 | 2E | C | 21 | 2E | same | 21 | 2E |
22 | 2D | X | 22 | 2D | same | 22 | 2D |
23 | 20 | D | 23 | 20 | same | 23 | 20 |
24 | 12 | E | 24 | 12 | same | 24 | 12 |
25 | 05 | 4 | 25 | 05 | same | 25 | 05 |
26 | 04 | 3 | 26 | 04 | same | 26 | 04 |
27 | 5C | F5 (top function key block) | 03 | 3F | same | 03 | 3F |
28 | 68 | F17 (top function key block) | 08 | 64 | |||
29 | 39 | Spacebar | 29 | 39 | same | 29 | 39 |
2A | 2F | V | 2A | 2F | same | 2A | 2F |
2B | 21 | F | 2B | 21 | same | 2B | 21 |
2C | 14 | T | 2C | 14 | same | 2C | 14 |
2D | 13 | R | 2D | 13 | same | 2D | 13 |
2E | 06 | 5 | 2E | 06 | same | 2E | 06 |
2F | 5D | F6 (top function key block) | 0B | 40 | same | 0B | 40 |
30 | 69 | F18 (top function key block) | 10 | 65 | |||
31 | 31 | N | 31 | 31 | same | 31 | 31 |
32 | 30 | B | 32 | 30 | same | 32 | 30 |
33 | 23 | H | 33 | 23 | same | 33 | 23 |
34 | 22 | G | 34 | 22 | same | 34 | 22 |
35 | 15 | Y | 35 | 15 | same | 35 | 15 |
36 | 07 | 6 | 36 | 07 | same | 36 | 07 |
37 | 5E | F7 (top function key block) | 83 | 41 | same | 83 | 41 |
38 | 6A | F19 (top function key block) | 18 | 66 | |||
39 | 72 | Right Alt | E011 | E038 | same | E011 | E038 |
3A | 32 | M | 3A | 32 | same | 3A | 32 |
3B | 24 | J | 3B | 24 | same | 3B | 24 |
3C | 16 | U | 3C | 16 | same | 3C | |
3D | 08 | 7 | 3D | 08 | same | 3D | 08 |
3E | 09 | 8 | 3E | 09 | same | 3E | 09 |
3F | 5F | F8 (top function key block) | 0A | 42 | same | 0A | 42 |
40 | 6B | F20 (top function key block) | 20 | 67 | |||
41 | 33 | < | 41 | 33 | same | 41 | 33 |
42 | 25 | K | 42 | 25 | same | 42 | 25 |
43 | 17 | I | 43 | 17 | same | 43 | 17 |
44 | 18 | O | 44 | 18 | same | 44 | 18 |
45 | 0B | 0 | 45 | 0B | same | 45 | 0B |
46 | 0A | 9 | 46 | 0A | same | 46 | 0A |
47 | 60 | F9 (top function key block) | 01 | 43 | same | 01 | 43 |
48 | 6C | F21 (top function key block) | 28 | 68 | |||
49 | 34 | > | 49 | 34 | same | 49 | 34 |
4A | 35 | ? | 4A | 35 | same | 4A | 35 |
4B | 26 | L | 4B | 26 | same | 4B | 26 |
4C | 27 | : | 4C | 27 | same | 4C | 27 |
4D | 19 | P | 4D | 19 | same | 4D | 19 |
4E | 0C | - | 4E | 0C | same | 4E | 0C |
4F | 61 | F10 (top function key block) | 09 | 44 | same | 09 | 44 |
50 | 6D | F22 (top function key block) | 30 | 69 | |||
51 | 73 | Unused position under right Shift | 51 | 73 | same | 51 | 73 |
52 | 28 | @ | 52 | 28 | same | 52 | 28 |
53 | 74 | \ (if adjacent to Enter) | 5D | 2B | same | 5D | 2B |
54 | 1A | [ | 54 | 1A | same | 54 | 1A |
55 | 0D | + | 55 | 0D | same | 55 | 0D |
56 | 62 | F11 (top function key block) | 78 | 57 | same | 78 | 57 |
57 | 6E | F23 (top function key block) | 40 | 6A | Print Screen / SysRQ | E07C / 84 | E037 / 54 |
58 | 3A | Right Ctrl | E014 | E01D | same | E014 | E01D |
59 | 36 | Right Shift | 59 | 36 | same | 59 | 36 |
5A | 1C | Enter | 5A | 1C | same | 5A | 1C |
5B | 1B | ] | 5B | 1B | same | 5B | 1B |
5C | 75 | \ (if above Enter) | 5D | 2B | same | 5D | 2B |
5D | 2B | \ (if adjacent to Backspace) | 6A | 7D | same | 6A | 7D |
5E | 63 | F12 (top function key block) | 07 | 58 | same | 07 | 58 |
5F | 76 | F24 (top function key block) | 40 | 6B | Scroll Lock | 7E | 46 |
60 | 55 | Cursor down | E072 | E050 | same | E072 | E050 |
61 | 56 | Cursor left | E06B | E04B | same | E06B | E04B |
62 | 77 | Key between cursor keys | E06C | E047 | Pause / Break | 77 / E07E | 45 / E046 |
63 | 78 | Cursor up | E075 | E048 | same | E075 | E048 |
64 | 79 | 3x2 block, lower row, left column (End) | E069 | E04F | (Delete) | E071 | E053 |
65 | 7A | 3x2 block, lower row, middle column (Insert) | E070 | E052 | (End) | E069 | E04F |
66 | 0E | Backspace | 66 | 0E | same | 66 | 0E |
67 | 7B | 3x2 block, upper row, left column (PA1) | 17 | 5A | (Insert) | E070 | E052 |
68 | 7C | Unused position under keypad 0 | 68 | 7C | same | 68 | 7C |
69 | 4F | Keypad 1 | 69 | 4F | same | 69 | 4F |
6A | 7D | Cursor right | E074 | E04D | same | E074 | E04D |
6B | 4B | Keypad 4 | 6B | 4B | same | 6B | 4B |
6C | 47 | Keypad 7 | 6C | 47 | same | 6C | 47 |
6D | 7E | 3x2 block, lower row, right column (Delete) | E071 | E053 | (PgDn) | E07A | E051 |
6E | 7F | 3x2 block, upper row, middle column (PgUp) | E07D | E049 | (Home) | E06C | E047 |
6F | 6F | 3x2 block, upper row, right column (PgDn) | E07A | E051 | (PgUp) | E07D | E049 |
70 | 52 | Keypad 0 | 70 | 52 | same | 70 | 52 |
71 | 53 | Keypad . | 71 | 53 | same | 71 | 53 |
72 | 50 | Keypad 2 | 72 | 50 | same | 72 | 50 |
73 | 4C | Keypad 5 | 73 | 4C | same | 73 | 4C |
74 | 4D | Keypad 6 | 74 | 4D | same | 74 | 4D |
75 | 48 | Keypad 8 | 75 | 48 | same | 75 | 48 |
76 | 01 | Keypad top left corner (Esc) | 76 | 01 | (Num Lock) | 77 | 46 |
77 | 45 | Keypad top row, second column (NumLk / ScrLk) | 7E / 77 | 46 / 45 | (Keypad /) | E04A | E035 |
78 | 57 | Unused position under keypad Enter | 63 | 78 | same | 63 | 78 |
79 | 4E | Keypad Enter | E05A | E01C | same | E05A | E01C |
7A | 51 | Keypad 3 | 7A | 51 | same | 7A | 51 |
7B | 4A | Keypad - | 7B | 4A | Unused position under Keypad + | 6D | 7E |
7C | 37 | Keypad + | 79 | 4E | same | 79 | 4E |
7D | 49 | Keypad 9 | 7D | 49 | same | 7D | 49 |
7E | 46 | Keypad top row, third column (*) | 7C | 37 | same | 7C | 37 |
83 | 41 | F7 (left function key block) | E07C | E037 | |||
84 | 54 | Keypad top right hand corner (/) | E04A / E07E | E035 / E046 | (keypad -) | 7B | 4A |
And the following three aren't present on the 122-key board, but are included for completeness: | |||||||
8B | 8B | Left Windows | E01F | E05B | |||
8C | 8C | Right Windows | E027 | E05C | |||
8D | 8D | Menu | E02F | E05D |
A minor oddity: A 122-key IBM board in set 3 can return 127 scancodes. These are all in a nice consecutive 7-bit range, except for two. The key that (from diagrams) you'd expect to send 02h, sends 83h. And the 7Fh key sends 84h. If the microcontroller on the motherboard is translating scancodes, it treats these pairs as identical: both 02h and 83h get mapped to 41h, and both 7Fh and 84h get mapped to 54h.
Possibly these two keys had some special meaning on the 3270-series terminals where set 3 scancodes seem to have originated.
Under Windows 3.0
The keyboard is supplied with a driver for Windows 3.0, which must be installed by editing SYSTEM.INI. The driver makes scancodes from the extra keys on the keyboard register as Windows virtual keys.
Oddly, the VK codes returned by function keys F17-F24 do not match the ones defined in <windows.h>. This appears to be because VK_F17 and VK_F18 have different definitions in the Windows SDK and DDK, and VK_F19 and up just aren't there. The same mismatch on VK_F17 and VK_F18 is still present in the Windows 98 DDK. There is a brief mention in the DDK documentation that the 'wrong' F17 and F18 are specific to the Olivetti M24 102-key keyboard, but that still doesn't explain why the same symbols were used for different keycodes, or why the DDK is missing VK_F19 to VK_F24.
Key | VK_ code in Windows 3.1 SDK | Driver returns |
---|---|---|
F17 | 0x80 | 0xE0 (Olivetti F17) |
F18 | 0x81 | 0xE1 (Olivetti F18) |
F19 | 0x82 | 0x8A |
F20 | 0x83 | 0x8B |
F21 | 0x84 | 0x8C |
F22 | 0x85 | 0x8D |
F23 | 0x86 | 0x8E |
F24 | 0x87 | 0x8F |
Driver Internals
Internally, the driver is very similar to the one that comes with Windows 3.0. The points of difference are:
- The keyboard subtype (obtained by
GetKeyboardType(1)
) is set to 1. The normal driver returns subtype 0. - Scancode tables are longer to support the extra scan codes.
- The
GetKeyNameText()
function supports the extra scan codes. - If interrogated by
GetKeyboardType(2)
, the driver reports 24 function keys rather than 12. - Keys with scancodes between 0x70 and 0x76 (ie: Attn, Clear, CrSel, ExSel and Zoom) generate key-down and key-up events when pressed, and nothing when released.
- Since SysRq is not on the same key as PrintScreen, the code that distinguishes between SysRq and PrintScreen is slightly different.
- On keyboards with a Shift Lock (rather than Caps Lock) key, there is extra code in ToASCII() to distinguish real shifts from shifts generated by Shift Lock being on.
Under Windows NT / 2000 / XP
The extra keys (F13-F24 and so on) return scancodes under Windows NT 3.5 and later. However, the VK_ codes they use do not match the keycaps. This can be corrected with replacement layout DLLs. Suitable US/UK files are available here, with instructions how to generate your own in other languages.
Under Linux
The following scripts allow the extra keys to be used under Linux (tested on Ubuntu 9.10, in X11):
- keycodes_1227t: Assigns Linux keycodes to the
extra keys. Put this in (say) /usr/local/sbin:
sudo install -m 755 keycodes_1227t /usr/local/sbin
and then add a line to /etc/rc.local to call it, just before the "exit 0":# By default this script does nothing.
/usr/local/sbin/keycodes_1227t
exit 0 - xmodmap should be saved in your home directory and
renamed to
.Xmodmap
, with a leading dot and a capital X. The next time you log in, you should be asked whether to load the file. Highlight the ".Xmodmap" file and click "Load". - You will probably also need to add the option atkbd.softraw=0 to
the kernel command line. Edit
/boot/grub/menu.lst
and add it to the end of the line that startskernel
.
If this worked, you should be able to run xev and see keypresses on the extra keys being detected.
John Elliott 21 July 2011.