Version 0.9a IBM Keyboard/Scancode FAQ File Richard STEVEn Walz rel 10 June 1994 *please retain this banner* rstevew@armory.com The IBM keyboard was designed to be completely reconfigurable short of giving you keycaps with replacable transparencies under a clear top!!! Any key can be interpreted by a program as anything. They needed more than the ASCII codes for this (what's the ASCII code for 'left shift" and 'alt'?!), so they assigned scancodes whose values were arbitrary, except perhaps from a PC board layout and trace routing or keyboard controller firmware perspective. Thus these scancodes are sent by the keyboard, in time to its own clock, both of which go to the 8255 PIA port chip on the motherboard, after a bit of serial to parallel work by a couple other chips. The keyboard clock and data lines are open collector, meaning that they are pulled up with resistors and can be pulled down by either end of the line to for communication in either direction. Thus there is a protocol that each end observes about their logic states. The keyboard monitors the state of the data and clock lines prior to any send to the computer. If the clock line is LO, (TTL LO or near 0 Volts), then the keyboard is disabled and will not send. If the clock line is high, (TTL HI or getting close to but not greater than 5 Volts), and the data line is LO, then input TO the keyboard is accepted FROM the computer! Finally it should be mentioned that the keyboard only starts a send to the computer when the data line and the clock line are high. This means that the computer is not trying to talk to the keyboard or trying to make the keyboard wait to send. When the two lines are high, since the lines are open collector and pulled up passively, the keyboard can take them over and start the clock and pull the data line low. On the falling edge of the 10 kHz clock, the keyboard again raises the data line to form two start bits of .2 ms duration, signaling the start of the byte send. Then the bits are sent in LSB first (D0) and then on up through the eight bit byte to the MSB (D7), and then the line returns to the LO state! This is an unusual setup compared to most types of serial communications, as usually the line remains HI when not being pulled LO to make a start bit or bits, and THEN the data is sent using its correct logical value as a HI '1' or a LO '0'. Here the data is sent with its logical sense preserved, but the start bits are suddenly HI from a inactive but ready LO data line, and the bits are read by timing off the received clock on the clock line, which is also taken over by the keyboard and pulled LO to signify time to start a bit, a start bit OR a data bit. The diagram is thus: HI 10 kHz --------------| |-| |-| |-| |-| |-| |-| |-| |-| |-| |-| |------------------ clock line | | | | | | | | | | | | | | | | | | | | | | bits start on LO |-| |-| |-| |-| |-| |-| |-| |-| |-| |-| |-| falling edges HI -----| |-------| |-----------| |---| | data | start | 0 | 1 1 1 | 0 | 1 | 0 0 LO |--------| | |---| | | |---| |---|---|----------------- line s s D0 D1 D2 D3 D4 D5 D6 D7 stop/idle As was noted above, there is a state of the two lines where the computer can send data to the keyboard, and my documentation on this was more vague. If anyone can add to it, I would appreciate it. My BTC-5060 "el cheapo" terminal/AT-type keyboard manual shows a timing diagram which I believe to be fallacious, as they even have the bits in reverse order. I will want to test this keyboard with the scope to see the real story. The manual DOES, however, indicate that this keyboard will correctly operate either an XT or an AT computer and up, and it truly does! I would like to know how to make it shift to the other mode and how to control its LED states as well. This paragraph is a call for more info from out there, and more research on my part, as I see conflicting information. This should be considered a preliminary release. This keyboard sends data not just of occurence of a key press and release but it scans the keyboard keys thousands of times a second and sends data to the computer as to whether a key has been pressed and whether it has been released, and in the order these occurred, and it stores this change data in a buffer waiting to send it as soon as the computer will accept it. This makes this keyboard extremely configurable, as we always know then what has occurred and the key presses and releases can be noted with great complexity and interpreted to our heart's content. All keys are on an equal footing and are not simply super-shift keys in the case of control, alt, and shifts. These can be read as well and used in a program. In addition, this keyboard has the IBM "typematic" action, whereby if a key is held down for more than the assigned delay, the keyboard resends its 'make' code over and over till it is released or another key takes its place as the repeater. The scancodes for the XT are each different bytes with the 'make' byte given one hexadecimal number and the 'break' byte given the same number with its high bit (MSB) set to "1", thus the break codes are all derivable by adding 80 hexadecimal to the make code for each key. The codes have nothing to do with the ASCII value of a character seen on the keycap. They are simply codes. All values below are hexadecimal, which means to get the decimal, you can multiply the left number by 16, where the left number is a digit such that 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, and F really mean numbers 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, and 15 in decimal. Then you take the right digit and convert it straight away and add it to the multiplication of the left digits's value which was multiplied by 16. Thus the decimal equivalent for the hexadecimal for C9 is 'C' or 12 times 16, which is 192, plus '9', which is just 9, to make 201. Likewise 3F converts to '3' or 3 times 16, which is 48, plus 'F' which is 15, which add to 63. And once more for good measure, BD converts to decimal thus: 'B' is 11, and 11 times 16 is 176, and 'D' is 13, so added they make 189. The scancodes found at port 60H or 96 are the 'make' codes for those keys. In BASIC language, the first INKEY$ byte is the ASCII interpretation in decimal, unless there are two bytes for the interpretation of extended characters, then it is the second. These INKEY$ codes, while often called scancodes mistakenly, are merely extended keycodes particular to BASIC language. The XT Scancodes These are all hexadecimal: 'make' code top / 'break' below F1 F2 ` 1 2 3 4 5 6 7 8 9 0 - = \ BS ESC NUML SCRL SYSR ----- --------------------------------------------- ------------------ 3B 3C 29 02 03 04 05 06 07 08 09 0A 0B 0C 0D 2B 0E 01 45 46 ** BB BC A9 82 83 84 85 86 87 88 89 8A 8B 8C 8D AB 8E 81 C5 C6 F3 F4 TAB Q W E R T Y U I O P [ ] Home Up PgUp PrtSc ----- ----------------------------------------- ------------------- 3D 3E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 47 48 49 37 BD BE 8F 90 91 92 93 94 95 96 97 98 99 9A 9B C7 C8 C9 B7 F5 F6 CNTL A S D F G H J K L ; ' ENTER Left 5 Right - ----- -------------------------------------------- ------------------ 3F 40 1D 1E 1F 20 21 22 23 24 25 26 27 28 1C 4B 4C 4D 4A BF C0 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 9C CB CC CD CA F7 F8 LSHFT Z X C V B N M , . / RSHFT End Dn PgDn + ----- -------------------------------------------- ------------------ 41 42 2A 2C 2D 2E 2F 30 31 32 33 34 35 36 4F 50 51 4E C1 C2 AA AC AD AE AF B0 B1 B2 B3 B4 B5 B6 CF D0 D1 CE F9 F10 ALT SPC CAPLOCK Ins Del ------ -------------------------------------------- ------------- 43 44 38 39 3A 52 53 C3 C4 B8 B9 BA D2 D3 ------------------------------------------ Now I will explain the AT scan codes. They are done slightly differently. The AT keyboard response is a different set of events. When the key is pressed, the scan code is sent, and when the key is released, two bytes are sent, the keyboard sends F0 hex and then the scancode again, thus we will only need to list the scancodes below for the AT keyboard activity. Now they use a ROM-masked 8049 as the input processor from this AT keyboard hardware to convert the AT hardware codes coming from the keyboard hardware back into the old XT scancode set to the internal bus, for purposes of downward compatibility, surely the work of some fresh idiot graduate engineer who simply thought he HAD to change SOMETHING!!! This was generally considered a no-brainer in hardware design circles!!! The AT Scancodes Again, these are hexadecimal: F1 F2 ` 1 2 3 4 5 6 7 8 9 0 - = \ BS ESC NUML SCRL SYSR ----- --------------------------------------------- ------------------ 05 06 0E 16 1E 26 25 2E 36 3D 3E 46 45 4E 55 5D 66 76 77 7E 84 F3 F4 TAB Q W E R T Y U I O P [ ] Home Up PgUp PrtSc ----- ----------------------------------------- ------------------- 04 0C 0D 15 1D 24 2D 2C 35 3C 43 44 4D 54 5B 6C 75 7D 7C F5 F6 CNTL A S D F G H J K L ; ' ENTER Left 5 Right - ----- -------------------------------------------- ------------------ 03 0B 14 1C 1B 23 28 34 33 38 42 4B 4C 52 5A 6B 73 74 7B F7 F8 LSHFT Z X C V B N M , . / RSHFT End Dn PgDn + ----- -------------------------------------------- ------------------ 83 0A 12 1A 22 21 2A 32 31 3A 41 49 4A 59 69 72 7A 79 F9 F10 ALT SPC CAPLOCK Ins Del ------ -------------------------------------------- ------------- 01 09 11 29 58 70 71 ---------------------------------- And that's all I know about it. If you would like to add information to this small tutorial FAQ, please send it to rstevew@armory.com for review and please don't add to this FAQ and republish it without my consent. I will keep this up to date if you will be kind and handle it that way. Thanks. -Steve Walz rstevew@armory.com