diff options
Diffstat (limited to 'docs/www.computer-engineering.org/ps2keyboard/index.html')
-rw-r--r-- | docs/www.computer-engineering.org/ps2keyboard/index.html | 2393 |
1 files changed, 2393 insertions, 0 deletions
diff --git a/docs/www.computer-engineering.org/ps2keyboard/index.html b/docs/www.computer-engineering.org/ps2keyboard/index.html new file mode 100644 index 0000000..72d0b4e --- /dev/null +++ b/docs/www.computer-engineering.org/ps2keyboard/index.html @@ -0,0 +1,2393 @@ +<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + + + <meta http-equiv="Content-Type" + content="text/html; charset=iso-8859-1"> + + <meta name="GENERATOR" + content="Mozilla/4.76 [en] (Win98; U) [Netscape]"> + + <meta name="Author" content="Adam Chapweske"> + <title>The PS/2 Keyboard Interface</title> + <!--This file created 10:20 PM 3/29/01 by Claris Home Page version 3.0--> + + <meta name="author" content="Adam Chapweske"> +</head> + <body bgcolor="#ffffff" link="#3333ff" vlink="#3333ff" alink="#3333ff"> + <small><b><font face="Arial,Helvetica"><font size="+3"><small>The PS/2 +Keyboard Interface</small></font></font></b></small><br> + + +<center></center> + +<center> +<hr width="400" size="1" align="left" noshade="noshade"></center> + <br> + <font face="Arial,Helvetica">Source: <a + href="http://www.Computer-Engineering.org">http://www.Computer-Engineering.org</a></font><br> + <font face="Arial,Helvetica">Author: Adam Chapweske<br> + Last Updated: 04/01/03<br> + + <br> + </font><b>Legal Information:</b><br> + <br> + All information within this article is provided "as is" and without +any express or implied warranties, including, without limitation, the implied + warranties of merchantibility and fitness for a particular purpose. <br> + <br> + This article is protected under copyright law. This document may + be copied only if the source, author, date, and legal information is included.<br> + <br> + + <b>Abstract:</b><br> + <br> + This article tries to cover every aspect of AT and PS/2 keyboards. + It includes information on the low-level signals and protocol, scan codes, + the command set, initialization, compatibility issues, and other miscellaneous + information. Since it's closely related, I've also included information + on the PC keyboard controller. All code samples involving the keyboard + encoder are written in assembly for <a href="http://www.microchip.com">Microchip's</a> + PIC microcontrollers. All code samples related to the keyboard +controller are written in x86 assembly<br> + + +<p><b>A History Lesson:</b> </p> + +<p>The most popular keyboards in use today include: </p> + +<ul> + <li> USB keyboard - Latest keyboard supported by all new computers (Macintosh + and IBM/compatible). These are relatively complicated to interface + and are not covered in this article.</li> + <li> IBM/Compatible keyboards - Also known as "AT keyboards" or "PS/2 + keyboards", all modern PCs support this device. They're the easiest + to interface, and are the subject of this article.</li> + + <li> ADB keyboards - Connect to the Apple Desktop Bus of older Macintosh + systems. These are not covered in this article </li> + +</ul> + IBM introduced a new keyboard with each of its major desktop computer + models. The original IBM PC, and later the IBM XT, used what we +call the "XT keyboard." These are obsolete and differ significantly +from modern keyboards; the XT keyboard is not covered in this article. + Next came the IBM AT system and later the IBM PS/2. They introduced + the keyboards we use today, and are the topic of this article. AT + keyboards and PS/2 keyboards were very similar devices, but the PS/2 device + used a smaller connector and supported a few additional features. + +Nonetheless, it remained backward compatible with AT systems and few of +the additional features ever caught on (since software also wanted to +remain backward compatible.) Below is a summary of IBM's three major +keyboards. +<p>IBM PC/XT Keyboard (1981): </p> + +<ul> + <li> 83 keys</li> + <li> 5-pin DIN connector</li> + <li> Simple uni-directional serial protocol</li> + + <li> Uses what we now refer to as scan code set 1</li> + <li> No host-to-keyboard commands</li> + +</ul> + IBM AT Keyboard (1984) - Not backward compatible with XT systems<tt><a + href="#A%20History%20Lesson%20FN">(1)</a></tt>. + +<ul> + <li> 84 -101 keys</li> + + <li> 5-pin DIN connector</li> + <li> Bi-directional serial protocol</li> + <li> Uses what we now refer to as scan code set 2</li> + <li> Eight host-to-keyboard commands</li> + + +</ul> + IBM PS/2 Keyboard (1987) - Compatible with AT systems, not compatible + with XT systems<tt><a href="#A%20History%20Lesson%20FN">(1)</a></tt>. + +<ul> + <li> 84 - 101 keys</li> + <li> 6-pin mini-DIN connector</li> + <li> Bi-direction serial protocol</li> + + <li> Offers optional scan code set 3</li> + <li> 17 host-to-keyboard commands </li> + +</ul> + The PS/2 keyboard was originally an extension of the AT device. + It supported a few additional host-to-keyboard commands and featured +a smaller connector. These were the only differences between the +two devices. However, computer hardware has never been about standards + as much as compatibility. For this reason, any keyboard you buy +today will be <i>compatible</i> with PS/2 and AT systems, but it may not +fully support all the features of the original devices. + + +<p>Today, "AT keyboard" and "PS/2 keyboard" refers only to their connector + size. Which settings/commands any given keyboard does or does not + support is anyone's guess. For example, the keyboard I'm using right + now has a PS/2-style connector but only fully supports seven commands, partially + supports two, and merely "acknowledges" the rest. In contrast, my + "Test" keyboard has an AT-style connector but supports every feature/command + of the original PS/2 device (plus a few extra.) It's important you + treat modern keyboards as compatible, not standard. If your design +a keyboard-related device that relies on non-general features, it may work +on some systems, but not on others... </p> + +<p>Modern PS/2 (AT) compatible keyboards </p> + +<ul> + + <li> Any number of keys (usually 101 or 104)</li> + <li> 5-pin or 6-pin connector; adaptor usually included</li> + <li> Bi-directional serial protocol</li> + <li> Only scan code set 2 guaranteed.</li> + <li> Acknowledges all commands; may not act on all of them.</li> + + +</ul> + <a name="A History Lesson FN"></a> <br> + <i>Footnote 1) XT keyboards use a completely different protocol + than that used by AT and PS/2 systems, making it incompatible with the + newer PCs. However, there was a transition period where some keyboard + controllers supported both XT and AT (PS/2) keyboards (through a switch, +jumper, or auto-sense.) Also, some keyboards were made to work on +both types of systems (again, through the use of a switch or auto-sensing.) +If you've owned such a PC or keyboard, don't let it fool you--XT keyboards +are NOT compatible with modern computers.</i> + +<p><b>General Description:</b> </p> + + +<p>Keyboards consist of a large matrix of keys, all of which are monitored + by an on-board processor (called the "keyboard encoder".) The specific + processor<tt><a href="#General%20Description%20FN">(1)</a></tt> varies + from keyboard-to-keyboard but they all basically do the same thing: + Monitor which key(s) are being pressed/released and send the appropriate + data to the host. This processor takes care of all the debouncing +and buffers any data in its 16-byte buffer, if needed. Your motherboard + contains a "keyboard controller"<tt><a + href="#General%20Description%20FN">(2)</a></tt> that is in charge of decoding + all of the data received from the keyboard and informing your software of + what's going on. All communication between the host and the keyboard + uses an IBM protocol. <br> + + <a name="General Description FN"></a> <br> + <i>Footnote 1) Originally, IBM used the Intel 8048 microcontroller + as its keyboard encoder. There are now a wide variety of keyboard + encoder chips available from many different manufacturers.</i> </p> + <i>Footnote 2) Originally, + IBM used the Intel 8042 microcontroller as its keyboard controller. + This has since been replaces with compatible devices integrated in motherboards' + chipsets. The keyboard controller is covered later in this article.</i> + +<p><b>Electrical Interface / Protocol:</b> </p> + + +<p>The AT and PS/2 keyboards use the same protocol as the PS/2 mouse. + Click <a href="../ps2protocol">here</a> for detailed information on + this protocol. </p> + +<p><b>Scan Codes:</b> </p> + +<p>Your keyboard's processor spends most of its time "scanning", or monitoring, + the matrix of keys. If it finds that any key is being pressed, released, + or held down, the keyboard will send a packet of information known as a +"scan code" to your computer. There are two different types of scan +codes: "make codes"<i> </i>and "break codes". A make code is sent when +a key is pressed or held down. A break code is sent when a key is +released. Every key is assigned its own unique make code and break +code so the host can determine exactly what happened to which key by looking + at a single scan code. The set of make and break codes for every key + comprises a "scan code set". There are three standard scan code sets, + named one, two, and three. All modern keyboards default to set two.<tt><a + href="#Scancodes%20FN">(1)</a></tt> </p> + + +<p>So how do you figure out what the scan codes are for each key? + Unfortunately, there's no simple formula for calculating this. If + you want to know what the make code or break code is for a specific key, + you'll have to look it up in a table. I've composed tables for all +make codes and break codes in all three scan code sets: </p> + +<ul> + <li> <a href="scancodes1.html">Scan Code Set 1</a> - Original XT scan + code set; supported by some modern keyboards</li> + + <li> <a href="scancodes2.html">Scan Code Set 2</a> - Default scan +code set for all modern keyboards</li> + <li> <a href="scancodes3.html">Scan Code Set 3</a> - Optional PS/2 +scan code set--rarely used</li> + +</ul> + <a name="Scancodes FN"></a> <br> + + <i>Footnote 1) Originally, the AT keyboard only supported set + two, and the PS/2 keyboard would default to set two but supported all three. + Most modern keyboards behave like the PS/2 device, but I have come across + a few that didn't support set one, set three, or both. Also, if +you've ever done any low-level PC programming, you've probably notice +the keyboard controller supplies set ONE scan codes by default. This +is because the keyboard controller converts all incomming scan codes to +set one (this stems from retaining compatibility with software written for +XT systems.) However, it's still set two scan codes being sent down +the keyboard's serial line. </i> + +<p><b>Make Codes, Break Codes, and Typematic Repeat:</b> </p> + +<p>Whenever a key is pressed, that key's make code is sent to the computer. + Keep in mind that a make code only represents a <u>key</u> on a keyboard--it + does not represent the character printed on that key. This means + that there is no defined relationship between a make code and an ASCII code. + + It's up to the host to translate scan codes to characters or commands. + </p> + +<p>Although most set two make codes are only one-byte wide, there are a + handfull of "extended keys" whose make codes are two or four bytes wide. + These make codes can be identified by the fact that their first byte is + E0h. </p> + +<p>Just as a make code is sent to the computer whenever a key is pressed, + a break code is sent whenever a key is released. In addition to +every key having its own unique make code, they all have their own unique +break code<tt><a href="#MakeBreakTypematic%20FN">(1)</a></tt>. Fortunately, + however, you won't always have to use lookup tables to figure out a key's + break code--certain relationships do exist between make codes and break + codes. Most set two break codes are two bytes long where the first + byte is F0h and the second byte is the make code for that key. Break + codes for extended keys are usually three bytes long where the first two +bytes are E0h, F0h, and the last byte is the last byte of that key's make +code. As an example, I have listed below a the set two make codes and +break codes for a few keys: </p> + + +<blockquote> + <blockquote> + + <blockquote> + + <table border="1" cols="3" width="300"> + <tbody> + <tr> + <td> + + + <center>Key</center> + </td> + <td> + + + <center>(Set 2) <br> + + Make Code</center> + </td> + <td> + + + <center>(Set 2) <br> + Break Code</center> + </td> + </tr> + <tr> + + <td> + + + <center>"A"</center> + </td> + <td> + + + <center>1C</center> + </td> + <td> + + + <center>F0,1C</center> + </td> + + </tr> + <tr> + <td> + + + <center>"5"</center> + </td> + <td> + + + <center>2E</center> + </td> + <td> + + + <center>F0,2E</center> + + </td> + </tr> + <tr> + <td> + + + <center>"F10"</center> + </td> + <td> + + + <center>09</center> + </td> + + <td> + + + <center>F0,09</center> + </td> + </tr> + <tr> + <td> + + + <center>Right Arrow</center> + </td> + <td> + + + <center>E0, 74</center> + + </td> + <td> + + + <center>E0, F0, 74</center> + </td> + </tr> + <tr> + <td> + + + <center>Right "Ctrl"</center> + </td> + + <td> + + + <center>E0, 14</center> + </td> + <td> + + + <center>E0, F0, 14</center> + </td> + </tr> + + + </tbody> + + </table> + + </blockquote> + </blockquote> + Example: What sequence of make codes and break codes should + be sent to your computer for the character "G" to appear in a word processor? + Since this is an upper-case letter, the sequence of events that need to + take place are: press the "Shift" key, press the "G" key, release the "G" + key, release the "Shift" key. The scan codes associated with these + events are the following: make code for the "Shift" key (12h), make + code for the "G" key (34h), break code for the "G" key(F0h,34h), break code + for the "Shift" key (F0h,12h). Therefore, the data sent to your computer + would be: 12h, 34h, F0h, 34h, F0h, 12h.</blockquote> + + If you press a key, its make code is sent to the computer. +When you press and hold down a key, that key becomes <i>typematic</i>, +which means the keyboard will keep sending that key's make code until the +key is released or another key is pressed. To verify this, open a text +editor and hold down the "A" key. When you first press the key, the +character "a" immediately appears on your screen. After a short delay, +another "a" will appear followed by a whole stream of "a"s until you release +the "A" key. There are two important parameters here: the <i>typematic + delay</i>, which is the short delay between the first and second "a", +and the <i>typematic rate</i>, which is how many characters per second +will appear on your screen after the typematic delay. The typematic +delay can range from 0.25 seconds to 1.00 second and the typematic rate +can range from 2.0 cps (characters per second) to 30.0 cps. You may +change the typematic rate and delay using the "Set Typematic Rate/Delay" +(0xF3) command. + +<p>Typematic data is not buffered within the keyboard. In the case + where more than one key is held down, only the last key pressed becomes + typematic. Typematic repeat then stops when that key is released, + even though other keys may be held down. </p> + +<p><a name="MakeBreakTypematic FN"></a> <br> + <i>Footnote 1) Actually, the "Pause/Break" key does not have + a break code in scan code sets one and two. When this key is pressed, + its make code is sent; when it's released, it doesn't send anything. So + how do you tell when this key has been released? You can't.</i> </p> + + +<p><b>Reset:</b> </p> + +<p>At power-on or software reset (see the "Reset" command) the keyboard + performs a diagnostic self-test referred to as BAT (Basic Assurance Test) + and loads the following default values: </p> + +<ul> + <li> Typematic delay 500 ms.</li> + <li> Typematic rate 10.9 cps.</li> + + <li> Scan code set 2.</li> + <li> Set all keys typematic/make/break.</li> + +</ul> + +<p>When entering BAT, the keyboard enables its three LED indicators, and + turns them off when BAT has completed. At this time, a BAT completion + code of either 0xAA (BAT successful) or 0xFC (Error) is sent to the host. + This BAT completion code must be sent 500~750 milliseconds after +power-on. </p> + + +<p>Many of the keyboards I've tested ignore their CLOCK and DATA lines until +<i>after</i> the BAT completion code has been sent. Therefore, an +"Inhibit" condition (CLOCK line low) may not prevent the keyboard from + sending its BAT completion code. </p> + +<p><b>Command Set:</b> </p> + +<p>A few notes regarding commands the host can issue to the keyboard:<br> + </p> + + +<ul> + <li>The keyboard clears its output buffer when it recieves any command.</li> + <li>If the keyboard receives an invalid command or argument, it must +respond with "resend" (0xFE).</li> + <li>The keyboard must not send any scancodes while processing a command.</li> + <li>If the keyboard is waiting for an argument byte and it instead +receives a command, it should discard the previous command and process this + new one.</li> + +</ul> + Below are all the commands the host may send to the keyboard:<br> + + +<ul> + <li> 0xFF (Reset) - Keyboard responds with "ack" (0xFA), then enters + "Reset" mode. (See "Reset" section.)</li> + <li> 0xFE (Resend) - Keyboard responds by resending the last-sent byte. + The exception to this is if the last-sent byte was "resend" (0xFE). + If this is the case, the keyboard resends the last non-0xFE byte. + This command is used by the host to indicate an error in reception.</li> + +</ul> + + +<blockquote>The next six commands can be issued when the keyboard is in any +mode, but it only effects the behavior of the keyboard when in "mode 3" +(ie, set to scan code set 3.) <br> + </blockquote> + +<ul> + <li> *0xFD (Set Key Type Make) - Disable break codes and typematic repeat + for specified keys. Keyboard responds with "ack" (0xFA), then disables + scanning (if enabled) and reads a list of keys from the host. These + keys are specified by their set 3 make codes. Keyboard responds to + each make code with "ack". Host terminates this list by sending an +invalid set 3 make code (eg, a valid command.) The keyboard then re-enables + scanning (if previously disabled).</li> + <li> *0xFC (Set Key Type Make/Break) - Similar to previous command, + except this one only disables typematic repeat.</li> + + <li> *0xFB (Set Key Type Typematic) - Similar to previous two, except + this one only disables break codes.</li> + <li> *0xFA (Set All Keys Typematic/Make/Break) - Keyboard responds with + "ack" (0xFA). Sets all keys to their normal setting (generate scan +codes on make, break, and typematic repeat)</li> + <li> *0xF9 (Set All Keys Make) - Keyboard responds with "ack" (0xFA). + Similar to 0xFD, except applies to all keys.</li> + <li> *0xF8 (Set All Keys Make/Break) - Keyboard responds with "ack" + (0xFA). Similar to 0xFC, except applies to all keys.</li> + + <li> *0xF7 (Set All Keys Typematic) - Keyboard responds with "ack" (0xFA). + Similar to 0xFB, except applies to all keys.</li> + <li> 0xF6 (Set Default) - Load default typematic rate/delay (10.9cps + / 500ms), key types (all keys typematic/make/break), and scan code set (2).</li> + <li> 0xF5 (Disable) - Keyboard stops scanning, loads default values + (see "Set Default" command), and waits further instructions.</li> + <li> 0xF4 (Enable) - Re-enables keyboard after disabled using previous + command.</li> + + <li> 0xF3 (Set Typematic Rate/Delay) - Host follows this command with + one argument byte that defines the typematic rate and delay as follows:</li> + <br> + . + <center><b>Repeat Rate</b></center> + + <center> + <table border="1" cellspacing="0" cellpadding="0" width="90%"> + <tbody> + <tr> + + <td> + + <center>Bits 0-4</center> + </td> + <td> + + <center>Rate(cps)</center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center>Bits 0-4</center> + + </td> + <td> + + <center>Rate(cps)</center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center>Bits 0-4</center> + </td> + <td> + + <center>Rate(cps)</center> + + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center>Bits 0-4</center> + </td> + <td> + + <center>Rate(cps)</center> + </td> + </tr> + + <tr> + <td> + + <center><tt>00h</tt></center> + </td> + <td> + + <center><tt>30.0</tt></center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>08h</tt></center> + + </td> + <td> + + <center><tt>15.0</tt></center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>10h</tt></center> + </td> + <td> + + <center><tt>7.5</tt></center> + + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>18h</tt></center> + </td> + <td> + + <center><tt>3.7</tt></center> + </td> + </tr> + + <tr> + <td> + + <center><tt>01h</tt></center> + </td> + <td> + + <center><tt>26.7</tt></center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>09h</tt></center> + + </td> + <td> + + <center><tt>13.3</tt></center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>11h</tt></center> + </td> + <td> + + <center><tt>6.7</tt></center> + + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>19h</tt></center> + </td> + <td> + + <center><tt>3.3</tt></center> + </td> + </tr> + + <tr> + <td> + + <center><tt>02h</tt></center> + </td> + <td> + + <center><tt>24.0</tt></center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>0Ah</tt></center> + + </td> + <td> + + <center><tt>12.0</tt></center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>12h</tt></center> + </td> + <td> + + <center><tt>6.0</tt></center> + + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>1Ah</tt></center> + </td> + <td> + + <center><tt>3.0</tt></center> + </td> + </tr> + + <tr> + <td> + + <center><tt>03h</tt></center> + </td> + <td> + + <center><tt>21.8</tt></center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>0Bh</tt></center> + + </td> + <td> + + <center><tt>10.9</tt></center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>13h</tt></center> + </td> + <td> + + <center><tt>5.5</tt></center> + + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>1Bh</tt></center> + </td> + <td> + + <center><tt>2.7</tt></center> + </td> + </tr> + + <tr> + <td> + + <center><tt>04h</tt></center> + </td> + <td> + + <center><tt>20.7</tt></center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>0Ch</tt></center> + + </td> + <td> + + <center><tt>10.0</tt></center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>14h</tt></center> + </td> + <td> + + <center><tt>5.0</tt></center> + + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>1Ch</tt></center> + </td> + <td align="center"> + <font face="Courier New, Courier, monospace"><small>2.5</small></font><br> + </td> + </tr> + + <tr> + <td> + + <center><tt>05h</tt></center> + </td> + <td> + + <center><tt>18.5</tt></center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>0Dh</tt></center> + + </td> + <td> + + <center><tt>9.2</tt></center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>15h</tt></center> + </td> + <td> + + <center><tt>4.6</tt></center> + + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>1Dh</tt></center> + </td> + <td> + + <center><tt>2.3</tt></center> + </td> + </tr> + + <tr> + <td> + + <center><tt>06h</tt></center> + </td> + <td> + + <center><tt>17.1</tt></center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>0Eh</tt></center> + + </td> + <td> + + <center><tt>8.6</tt></center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>16h</tt></center> + </td> + <td> + + <center><tt>4.3</tt></center> + + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>1Eh</tt></center> + </td> + <td> + + <center><tt>2.1</tt></center> + </td> + </tr> + + <tr> + <td> + + <center><tt>07h</tt></center> + </td> + <td> + + <center><tt>16.0</tt></center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>0Fh</tt></center> + + </td> + <td> + + <center><tt>8.0</tt></center> + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>17h</tt></center> + </td> + <td> + + <center><tt>4.0</tt></center> + + </td> + <td bgcolor="#cccccc"> </td> + <td> + + <center><tt>1Fh</tt></center> + </td> + <td align="center"> + <small><font face="Courier New, Courier, monospace">2.0</font></small><br> + </td> + </tr> + + + + </tbody> + </table> + + <div align="center"> </div> + </center> + + <center> + <p><b>Delay</b></p> + </center> + + <center> + <table border="1" cellspacing="0" cellpadding="0" cols="2" width="217"> + + <tbody> + <tr> + <td> + + <center>Bits 5-6</center> + </td> + <td> + + <center>Delay (seconds)</center> + </td> + </tr> + + <tr> + <td> + + <center>00b</center> + </td> + <td> + + <center>0.25</center> + </td> + </tr> + <tr> + + <td> + + <center>01b</center> + </td> + <td> + + <center>0.50</center> + </td> + </tr> + <tr> + <td> + + <center>10b</center> + + </td> + <td> + + <center>0.75</center> + </td> + </tr> + <tr> + <td> + + <center>11b</center> + </td> + + <td> + + <center>1.00</center> + </td> + </tr> + + + </tbody> + </table> + </center> + <br> + <li> *0xF2 (Read ID) - The keyboard responds by sending a +two-byte device ID of 0xAB, 0x83. (0xAB is sent first, followed by 0x83.)</li> + + <li> *0xF0 (Set Scan Code Set) - Keyboard responds with "ack", + then reads argument byte from the host. This argument byte may be 0x01, + 0x02, or 0x03 to select scan code set 1, 2, or 3, respectively. The + keyboard responds to this argument byte with "ack". If the argument + byte is 0x00, the keyboard responds with "ack" followed by the current scan + code set.</li> + <li> 0xEE (Echo) - The keyboard responds with "Echo" (0xEE).</li> + <li> 0xED (Set/Reset LEDs) - The host follows this command with one + argument byte, that specifies the state of the keyboard's Num Lock, Caps + Lock, and Scroll Lock LEDs. This argument byte is defined as follows:</li> + + +</ul> + +<center> +<table border="0" cellspacing="0" cellpadding="3" cols="8" width="400"> + <tbody> + <tr align="center" valign="CENTER"> + <td>MSb</td> + <td><br> + </td> + <td><br> + + </td> + <td><br> + </td> + <td><br> + </td> + <td><br> + </td> + <td><br> + </td> + + <td>LSb</td> + </tr> + + </tbody> +</table> + </center> + +<center> +<table border="1" cellspacing="0" cellpadding="2" cols="8" width="400"> + <tbody> + <tr align="center" valign="CENTER"> + + <td>Always 0</td> + <td>Always 0</td> + <td>Always 0</td> + <td>Always 0</td> + <td>Always 0</td> + <td>Caps Lock</td> + + <td>Num Lock</td> + <td>Scroll Lock</td> + </tr> + + </tbody> +</table> + </center> + +<blockquote> + <blockquote> + + <blockquote> + + <ul> + + + <ul> + <li> "Scroll Lock" - Scroll Lock LED off(0)/on(1)</li> + <li> "Num Lock" - Num Lock LED off(0)/on(1)</li> + <li> "Caps Lock" - Caps Lock LED off(0)/on(1)</li> + + </ul> + + </ul> + + </blockquote> + </blockquote> + </blockquote> + *Originally available in PS/2 keyboards only. + +<p><b>Emulation:</b> </p> + +<ul> + Click here for keyboard/mouse routines. Source in MPASM for + PIC microcontrollers. + +</ul> + <b>The i8042 Keyboard Controller:</b> + +<p>Up to this point in the article, all information has been presented +from a hardware point-of-view. However, if you're writing low-level + keyboard-related software for the host PC, you won't be communicating +directly with the keyboard. Instead, a keyboard controller provides +an interface between the keyboard and the peripheral bus. This controller +takes care of all the signal-level and protocol details, as well as providing + some conversion, interpretation, and handling of scan codes and commands. + </p> + +<p>An Intel 8042/compatible microcontroller is used as the PC's keyboard + controller. In modern computers, this microcontroller is hidden within + the motherboard's chipset, which integrates many controllers in a single + package. Nonetheless, this device is still there, and the keyboard + controller is still commonly referred to as "the 8042". </p> + + +<p>Depending on the motherboard, the keyboard controller may operate in + one of two modes: "AT-compatible" mode, or "PS/2-compatible" mode. + The latter is used if a PS/2 mouse is supported by the motherboard. + If this is the case, the 8042 acts as the keyboard controller and the +mouse controller. The keyboard controller auto-detects which mode +it is to use according to how it's wired to the keyboard port. </p> + +<p>The 8042 contains the following registers: </p> + +<ul> + <li> A one-byte input buffer - contains byte read from keyboard; read-only</li> + + <li> A one-byte output buffer - contains byte to-be-written to keyboard; + write-only</li> + <li> A one-byte status register - 8 status flags; read-only</li> + <li> A one-byte control register - 7 control flags; read/write </li> + +</ul> + The first three registers (input, output, status) are directly accessible + via ports 0x60 and 0x64. The last register (control) is read using + the "Read Command Byte" command, and written using the "Write Command Byte" + command. The following table shows how the peripheral ports are +used to interface the 8042: <br> + + +<center> +<table border="1" cellspacing="0" cellpadding="3"> + <tbody> + <tr> + <td> + + <center>Port</center> + </td> + <td> + + <center>Read / <br> + + Write</center> + </td> + <td> + + <center>Function</center> + </td> + </tr> + <tr> + <td>0x60</td> + + <td>Read</td> + <td>Read Input Buffer</td> + </tr> + <tr> + <td>0x60</td> + <td>Write</td> + <td>Write Output Buffer</td> + + </tr> + <tr> + <td>0x64</td> + <td>Read</td> + <td>Read Status Register</td> + </tr> + <tr> + + <td>0x64</td> + <td>Write</td> + <td>Send Command</td> + </tr> + + </tbody> +</table> + </center> + + +<p>Writing to port 0x64 doesn't write to any specific register, but sends + a command for the 8042 to interpret. If the command accepts a parameter, + this parameter is sent to port 0x60. Likewise, any results returned + by the command may be read from port 0x60. </p> + +<p>When describing the 8042, I may occasionally refer to its physical I/O + pins. These pins are defined below: </p> + +<p><u>AT-compatible mode</u> </p> + +<center> + +<table border="0" cellspacing="0" cellpadding="5"> + <tbody> + <tr> + <td>Port 1 (Input Port): + + <center> + + <table border="1" cellspacing="0" cellpadding="2"> + <tbody> + <tr> + <td>Pin</td> + <td>Name</td> + + <td>Function</td> + </tr> + <tr> + <td>0</td> + <td>P10</td> + <td> <br> + Undefined <br> + + .</td> + </tr> + <tr> + <td>1</td> + <td>P11</td> + <td> <br> + Undefined <br> + + .</td> + </tr> + <tr> + <td>2</td> + <td>P12</td> + <td> <br> + Undefined <br> + + .</td> + </tr> + <tr> + <td>3</td> + <td>P13</td> + <td> <br> + Undefined <br> + + .</td> + </tr> + <tr> + <td>4</td> + <td>P14</td> + <td>External RAM <br> + 1: Enable external RAM <br> + + 0: Disable external RAM</td> + </tr> + <tr> + <td>5</td> + <td>P15</td> + <td>Manufacturing Setting <br> + 1: Setting enabled <br> + + 0: Setting disabled</td> + </tr> + <tr> + <td>6</td> + <td>P16</td> + <td>Display Type Switch <br> + 1: Color display <br> + + 0: Monochrome</td> + </tr> + <tr> + <td>7</td> + <td>P17</td> + <td>Keyboard Inhibit Switch <br> + 1: Keyboard enabled <br> + + 0: Keyboard inhibited</td> + </tr> + + + </tbody> + + </table> + </center> + </td> + <td>Port 2 (Output Port): + + <table border="1" cellspacing="0" cellpadding="2"> + <tbody> + + <tr> + <td>Pin</td> + <td>Name</td> + <td>Function</td> + </tr> + <tr> + <td>0</td> + + <td>P20</td> + <td>System Reset <br> + 1: Normal <br> + 0: Reset computer</td> + </tr> + <tr> + <td>1</td> + + <td>P21</td> + <td> <br> + Gate A20 <br> + .</td> + </tr> + <tr> + <td>2</td> + + <td>P22</td> + <td> <br> + Undefined <br> + .</td> + </tr> + <tr> + <td>3</td> + + <td>P23</td> + <td> <br> + Undefined <br> + .</td> + </tr> + <tr> + <td>4</td> + + <td>P24</td> + <td> <br> + Input Buffer Full <br> + .</td> + </tr> + <tr> + <td>5</td> + + <td>P25</td> + <td> <br> + Output Buffer Empty <br> + .</td> + </tr> + <tr> + <td>6</td> + + <td>P26</td> + <td>Keyboard Clock <br> + 1: Pull Clock low <br> + 0: High-Z</td> + </tr> + <tr> + <td>7</td> + + <td>P27</td> + <td>Keyboard Data: <br> + 1: Pull Data low <br> + 0: High-Z</td> + </tr> + + + </tbody> + + </table> + + </td> + <td>Port 3 (Test Port): + + <center> + + <table border="1" cellspacing="0" cellpadding="2"> + <tbody> + <tr> + <td>Pin</td> + <td>Name</td> + <td>Function</td> + + </tr> + <tr> + <td>0</td> + <td>T0</td> + <td>Keyboard Clock <br> + (Input) <br> + + .</td> + </tr> + <tr> + <td>1</td> + <td>T1</td> + <td>Keyboard Data <br> + (Input) <br> + + .</td> + </tr> + <tr> + <td>2</td> + <td>--</td> + <td> <br> + Undefined <br> + + .</td> + </tr> + <tr> + <td>3</td> + <td>--</td> + <td> <br> + Undefined <br> + + .</td> + </tr> + <tr> + <td>4</td> + <td>--</td> + <td> <br> + Undefined <br> + + .</td> + </tr> + <tr> + <td>5</td> + <td>--</td> + <td> <br> + Undefined <br> + + .</td> + </tr> + <tr> + <td>6</td> + <td>--</td> + <td> <br> + Undefined <br> + + .</td> + </tr> + <tr> + <td>7</td> + <td>--</td> + <td> <br> + Undefined <br> + + .</td> + </tr> + + + </tbody> + + </table> + </center> + </td> + </tr> + + </tbody> +</table> + + </center> + +<p><u>PS/2-compatible mode</u> </p> + +<center> +<table border="0" cellspacing="0" cellpadding="5"> + <tbody> + <tr> + <td>Port 1 (Input Port): + + <center> + + <table border="1" cellspacing="0" cellpadding="2"> + + <tbody> + <tr> + <td>Pin</td> + <td>Name</td> + <td>Function</td> + </tr> + <tr> + + <td>0</td> + <td>P10</td> + <td>Keyboard Data <br> + (Input) <br> + .</td> + </tr> + + <tr> + <td>1</td> + <td>P11</td> + <td>Mouse Data <br> + (Input) <br> + .</td> + + </tr> + <tr> + <td>2</td> + <td>P12</td> + <td> <br> + Undefined <br> + .</td> + + </tr> + <tr> + <td>3</td> + <td>P13</td> + <td> <br> + Undefined <br> + .</td> + + </tr> + <tr> + <td>4</td> + <td>P14</td> + <td>External RAM <br> + 1: Enable external RAM <br> + 0: Disable external RAM</td> + + </tr> + <tr> + <td>5</td> + <td>P15</td> + <td>Manufacturing Setting <br> + 1: Setting enabled <br> + 0: Setting disabled</td> + + </tr> + <tr> + <td>6</td> + <td>P16</td> + <td>Display Type Switch <br> + 1: Color display <br> + 0: Monochrome</td> + + </tr> + <tr> + <td>7</td> + <td>P17</td> + <td>Keyboard Inhibit Switch <br> + 1: Keyboard enabled <br> + 0: Keyboard disabled</td> + + </tr> + + + </tbody> + + </table> + </center> + </td> + <td>Port 2 (Output Port): + + <center> + + <table border="1" cellspacing="0" cellpadding="2"> + <tbody> + <tr> + + <td>Pin</td> + <td>Name</td> + <td>Function</td> + </tr> + <tr> + <td>0</td> + <td>P20</td> + + <td>System Reset <br> + 1: Normal <br> + 0: Reset computer</td> + </tr> + <tr> + <td>1</td> + <td>P21</td> + + <td> <br> + Gate A20 <br> + .</td> + </tr> + <tr> + <td>2</td> + <td>P22</td> + + <td>Mouse Data: <br> + 1: Pull Data low <br> + 0: High-Z</td> + </tr> + <tr> + <td>3</td> + <td>P23</td> + + <td>Mouse Clock: <br> + 1: Pull Clock low <br> + 0: High-Z</td> + </tr> + <tr> + <td>4</td> + <td>P24</td> + + <td>Keyboard IBF interrupt: <br> + 1: Assert IRQ 1 <br> + 0: De-assert IRQ 1</td> + </tr> + <tr> + <td>5</td> + <td>P25</td> + + <td>Mouse IBF interrupt: <br> + 1: Assert IRQ 12 <br> + 0: De-assert IRQ 12</td> + </tr> + <tr> + <td>6</td> + <td>P26</td> + + <td>Keyboard Clock: <br> + 1: Pull Clock low <br> + 0: High-Z</td> + </tr> + <tr> + <td>7</td> + <td>P27</td> + + <td>Keyboard Data: <br> + 1: Pull Data low <br> + 0: High-Z</td> + </tr> + + + </tbody> + + </table> + </center> + </td> + + <td>Port 3 (Test Port): + + <center> + + <table border="1" cellspacing="0" cellpadding="2"> + <tbody> + <tr> + <td>Pin</td> + <td>Name</td> + <td>Function</td> + + </tr> + <tr> + <td>0</td> + <td>T0</td> + <td>Keyboard Clock <br> + (Input) <br> + .</td> + + </tr> + <tr> + <td>1</td> + <td>T1</td> + <td>Mouse Clock <br> + (Input) <br> + .</td> + + </tr> + <tr> + <td>2</td> + <td>--</td> + <td> <br> + Undefined <br> + .</td> + + </tr> + <tr> + <td>3</td> + <td>--</td> + <td> <br> + Undefined <br> + .</td> + + </tr> + <tr> + <td>4</td> + <td>--</td> + <td> <br> + Undefined <br> + .</td> + + </tr> + <tr> + <td>5</td> + <td>--</td> + <td> <br> + Undefined <br> + .</td> + + </tr> + <tr> + <td>6</td> + <td>--</td> + <td> <br> + Undefined <br> + .</td> + + </tr> + <tr> + <td>7</td> + <td>--</td> + <td> <br> + Undefined <br> + .</td> + + </tr> + + + </tbody> + + </table> + </center> + </td> + </tr> + + </tbody> +</table> + </center> + + +<p>(Note: Reading keyboard controller datasheets can be confusing--it will + refer to the "input buffer" as the "output buffer" and vice versa. + This makes sense from the point-of-view of someone writing firmware for + the controller, but for somebody used to interfacing the controller, this + can cause problems. Throughout this document, I only refer to the +"input buffer" as the one containing input from the keyboard, and the "output + buffer" as the one that contains output to be sent to the keyboard.) +</p> + +<p><i>Status Register:</i> </p> + +<p>The 8042's status flags are read from port 0x64. They contain +error information, status information, and indicate whether or not data +is present in the input and output buffers. The flags are defined as + follows: <br> + + </p> + +<center> +<table border="0" cellspacing="0" cellpadding="0"> + <tbody> + <tr> + <td><br> + </td> + <td> + + <center> + + <table border="0" cellspacing="0" cellpadding="3" cols="8" + width="400"> + + <tbody> + <tr> + <td>MSb</td> + <td><br> + </td> + <td><br> + </td> + <td><br> + + </td> + <td><br> + </td> + <td><br> + </td> + <td><br> + </td> + <td> + + + <div align="right">LSb</div> + + </td> + </tr> + + + </tbody> + + </table> + </center> + </td> + </tr> + <tr> + <td>AT-compatible mode:</td> + + <td> + + <center> + + <table border="1" cellspacing="0" cellpadding="2" cols="8" + width="400"> + <tbody> + <tr> + <td> + + + <center>PERR</center> + </td> + <td> + + + <center>RxTO</center> + + </td> + <td> + + + <center>TxTO</center> + </td> + <td> + + + <center>INH</center> + </td> + <td> + + + <center>A2</center> + + </td> + <td> + + + <center>SYS</center> + </td> + <td> + + + <center>IBF</center> + </td> + <td> + + + <center>OBF</center> + + </td> + </tr> + + + </tbody> + + </table> + </center> + </td> + </tr> + <tr> + <td>PS/2-compatible mode: </td> + + <td> + + <center> + + <table border="1" cellspacing="0" cellpadding="2" cols="8" + width="400"> + <tbody> + <tr> + <td> + + + <center>PERR</center> + </td> + <td> + + + <center>TO</center> + + </td> + <td> + + + <center>MOBF</center> + </td> + <td> + + + <center>INH</center> + </td> + <td> + + + <center>A2</center> + + </td> + <td> + + + <center>SYS</center> + </td> + <td> + + + <center>IBF</center> + </td> + <td> + + + <center>OBF</center> + + </td> + </tr> + + + </tbody> + + </table> + </center> + </td> + </tr> + + </tbody> +</table> + </center> + + +<ul> + <li> OBF (Output Buffer Full) - Indicates when it's okay to write to + output buffer.</li> + <br> + 0: Output buffer empty - Okay to write to port 0x60 <br> + 1: Output buffer full - Don't write to port 0x60 <li> IBF (Input +Buffer Full) - Indicates when input is available in the input buffer.</li> + <br> + + 0: Input buffer empty - No unread input at port 0x60 <br> + 1: Input buffer full - New input can be read from port 0x60 <li> +SYS (System flag) - Post reads this to determine if power-on reset, or +software reset.</li> + <br> + 0: Power-up value - System is in power-on reset. <br> + 1: BAT code received - System has already beed initialized. <li> +A2 (Address line A2) - Used internally by the keyboard controller</li> + + <br> + 0: A2 = 0 - Port 0x60 was last written to <br> + 1: A2 = 1 - Port 0x64 was last written to <li> INH (Inhibit flag) +- Indicates whether or not keyboard communication is inhibited.</li> + <br> + 0: Keyboard Clock = 0 - Keyboard is inhibited <br> + 1: Keyboard Clock = 1 - Keyboard is not inhibited <li> TxTO (Transmit + Timeout) - Indicates keyboard isn't accepting input (kbd may not be plugged + in).</li> + + <br> + 0: No Error - Keyboard accepted the last byte written to it. <br> + 1: Timeout error - Keyboard didn't generate clock signals within +15 ms of "request-to-send". <li> RxTO (Receive Timeout) - Indicates keyboard + didn't respond to a command (kbd probably broke)</li> + <br> + 0: No Error - Keyboard responded to last byte. <br> + 1: Timeout error - Keyboard didn't generate clock signals within +20 ms of command reception. <li> PERR (Parity Error) - Indicates communication + error with keyboard (possibly noisy/loose connection)</li> + + <br> + 0: No Error - Odd parity received and proper command response recieved. + <br> + 1: Parity Error - Even parity received or 0xFE received as command + response. <li> MOBF (Mouse Output Buffer Full) - Similar to OBF, + except for PS/2 mouse.</li> + <br> + 0: Output buffer empty - Okay to write to auxillary device's output + buffer <br> + 1: Output buffer full - Don't write to port auxillary device's output + buffer <li> TO (General Timout) - Indicates timeout during command + write or response. (Same as TxTO + RxTO.)</li> + + <br> + 0: No Error - Keyboard received and responded to last command. <br> + 1: Timeout Error - See TxTO and RxTO for more information. + +</ul> + [EG: On my PC, the normal value of the 8042's "Status" register +is 14h = 00010100b. This indicates keyboard communication is not +inhibited, and the 8042 has already completed its self-test ("BAT"). +The "Status" register is accessed by reading from port 64h ("IN AL, 64h")] + +<p><i>Reading keyboard input:</i> </p> + + +<p>When the 8042 recieves a valid scan code from the keyboard, it is converted + to its set 1 equivalent. The converted scan code is then placed in + the input buffer, the IBF (Input Buffer Full) flag is set, and IRQ 1 is asserted. + Furthermore, when any byte is received from the keyboard, the 8042 inhibits + further reception (by pulling the "Clock" line low), so no other scan codes + will be received until the input buffer is emptied. </p> + +<p>If enabled, IRQ 1 will activate the keyboard driver, pointed to by interrupt + vector 0x09. The driver reads the scan code from port 0x60, which causes + the 8042 to de-assert IRQ 1 and reset the IBF flag. The scan code +is then processed by the driver, which responds to special key combinations +and updates an area of the system RAM reserved for keyboard input. </p> + +<p>If you don't want to patch into interrupt 0x09, you may poll the keyboard + controller for input. This is accomplished by disabling the 8042's + IBF Interrupt and polling the IBF flag. This flag is set (1) when + data is available in the input buffer, and is cleared (0) when data is read + from the input buffer. Reading the input buffer is accomplished + by reading from port 0x60, and the IBF flag is at port 0x64, bit 1. + The following assembly code illustrates this: </p> + + +<p><tt>kbRead:</tt> <br> + <tt>WaitLoop: in +al, 64h ; Read Status byte</tt> <br> + <tt> + and al, 10b ; Test IBF flag +(Status<1>)</tt> <br> + + <tt> + jz WaitLoop ; Wait for IBF = + 1</tt> <br> + <tt> + in al, 60h ; Read input + buffer</tt> </p> + + +<p><i>Writing to keyboard:</i> </p> + +<p>When you write to the 8042's output buffer (via port 0x60), the controller + sets the OBF ("Output Buffer Full") flag and processes the data. The + 8042 will send this data to the keyboard and wait for a response. +If the keyboard does not accept or generate a response within a given amount + of time, the appropriate timeout flag will be set (see Status register + definition for more info.) If an incorrect parity bit is read, the + 8042 will send the "Resend" (0xFE) command to the keyboard. If the + keyboard continues to send erroneous bytes, the "Parity Error" flag is set + in the Status register. If no errors occur, the response byte is +placed in the input buffer, the IBF ("Input Buffer Full") flag is set, and +IRQ 1 is activated, signaling the keyboard driver. </p> + + +<p>The following assembly code shows how to write to the output buffer. + (Remember, after you write to the output buffer, you should use int 9h + or poll port 64h to get the keyboard's response.) </p> + +<p><tt>kbWrite:</tt> <br> + <tt>WaitLoop: in +al, 64h ; Read Status byte</tt> <br> + + <tt> + and al, 01b ; Test OBF flag +(Status<0>)</tt> <br> + <tt> + jnz WaitLoop ; Wait for OBF = 0</tt> + <br> + + <tt> + out 60h, cl ; Write data to +output buffer</tt> </p> + +<p><i>Keyboard Controller Commands:</i> </p> + +<p>Commands are sent to the keyboard controller by writing to port 0x64. + Command parameters are written to port 0x60 after teh command is sent. + Results are returned on port 0x60. Always test the OBF ("Output Buffer + Full") flag before writing commands or parameters to the 8042. </p> + + +<ul> + <li> 0x20 (Read Command Byte) - Returns command byte. (See "Write + Command Byte" below).</li> + <li> 0x60 (Write Command Byte) - Stores parameter as command byte. + Command byte defined as follows:</li> + +</ul> + + +<center> +<table border="0" cellspacing="0" cellpadding="0"> + <tbody> + <tr> + <td><br> + </td> + <td> + + <center> + + <table border="0" cellspacing="0" cellpadding="3" cols="8" + width="400"> + <tbody> + + <tr> + <td>MSb</td> + <td><br> + </td> + <td><br> + </td> + <td><br> + </td> + + <td><br> + </td> + <td><br> + </td> + <td><br> + </td> + <td> + + + <div align="right">LSb</div> + </td> + + </tr> + + + </tbody> + + </table> + </center> + </td> + </tr> + <tr> + <td>AT-compatible mode:</td> + <td> + + <center> + + <table border="1" cellspacing="0" cellpadding="2" cols="8" + width="400"> + + <tbody> + <tr> + <td> + + + <center>--</center> + </td> + <td> + + + <center>XLAT</center> + </td> + <td> + + + <center>PC</center> + + </td> + <td> + + + <center>_EN</center> + </td> + <td> + + + <center>OVR</center> + </td> + <td> + + + <center>SYS</center> + + </td> + <td> + + + <center>--</center> + </td> + <td> + + + <center>INT</center> + </td> + </tr> + + + </tbody> + + </table> + + </center> + </td> + </tr> + <tr> + <td>PS/2-compatible mode: </td> + <td> + + <center> + + <table border="1" cellspacing="0" cellpadding="2" cols="8" + width="400"> + <tbody> + + <tr> + <td> + + + <center>--</center> + </td> + <td> + + + <center>XLAT</center> + </td> + <td> + + + <center>_EN2</center> + + </td> + <td> + + + <center>_EN</center> + </td> + <td> + + + <center>--</center> + </td> + <td> + + + <center>SYS</center> + + </td> + <td> + + + <center>INT2</center> + </td> + <td> + + + <center>INT</center> + </td> + </tr> + + + </tbody> + + </table> + + </center> + </td> + </tr> + + </tbody> +</table> + </center> + +<ul> + + <ul> + <li> INT (Input Buffer Full Interrupt) - When set, IRQ 1 is generated + when data is available in the input buffer.</li> + + <br> + 0: IBF Interrupt Disabled - You must poll STATUS<IBF> to read + input. <br> + 1: IBF Interrupt Enabled - Keyboard driver at software int 0x09 handles + input. <li> SYS (System Flag) - Used to manually set/clear SYS + flag in Status register.</li> + <br> + 0: Power-on value - Tells POST to perform power-on tests/initialization. + <br> + + 1: BAT code received - Tells POST to perform "warm boot" tests/initiailization. + <li> OVR (Inhibit Override) - Overrides keyboard's "inhibit" + switch on older motherboards.</li> + <br> + 0: Inhibit switch enabled - Keyboard inhibited if pin P17 is high. + <br> + 1: Inhibit switch disabled - Keyboard not inhibited even if P17 = +high. <li> _EN (Disable keyboard) - Disables/enables keyboard +interface.</li> + <br> + + 0: Enable - Keyboard interface enabled. <br> + 1: Disable - All keyboard communication is disabled. <li> PC ("PC +Mode") - ???Enables keyboard interface somehow???</li> + <br> + 0: Disable - ??? <br> + 1: Enable - ??? <li> XLAT (Translate Scan Codes) - Enables/disables + translation to set 1 scan codes.</li> + + <br> + 0: Translation disabled - Data appears at input buffer exactly as +read from keyboard <br> + 1: Translation enabled - Scan codes translated to set 1 before put + in input buffer <li> INT2 (Mouse Input Buffer Full Interrupt) - When set, + IRQ 12 is generated when mouse data is available.</li> + <br> + 0: Auxillary IBF Interrupt Disabled - <br> + 1: Auxillary IBF Interrupt Enabled - <li> _EN2 (Disable Mouse) + - Disables/enables mouse interface.</li> + + <br> + 0: Enable - Auxillary PS/2 device interface enabled <br> + 1: Disable - Auxillary PS/2 device interface disabled + + </ul> + +</ul> + +<ul> + <li> ?0x90-0x9F (Write to output port) - Writes command's lower nibble + to lower nibble of output port (see Output Port definition.)</li> + <li> ?0xA1 (Get version number) - Returns firmware version number.</li> + + <li> ?0xA4 (Get password) - Returns 0xFA if password exists; otherwise, + 0xF1.</li> + <li> ?0xA5 (Set password) - Set the new password by sending a null-terminated + string of scan codes as this command's parameter.</li> + <li> ?0xA6 (Check password) - Compares keyboard input with current password.</li> + <li> 0xA7 (Disable mouse interface) - PS/2 mode only. Similar + to "Disable keyboard interface" (0xAD) command.</li> + + <li> 0xA8 (Enable mouse interface) - PS/2 mode only. Similar to + "Enable keyboard interface" (0xAE) command.</li> + <li> 0xA9 (Mouse interface test) - Returns 0x00 if okay, 0x01 if Clock + line stuck low, 0x02 if clock line stuck high, 0x03 if data line stuck +low, and 0x04 if data line stuck high.</li> + <li> 0xAA (Controller self-test) - Returns 0x55 if okay.</li> + <li> 0xAB (Keyboard interface test) - Returns 0x00 if okay, 0x01 if + Clock line stuck low, 0x02 if clock line stuck high, 0x03 if data line +stuck low, and 0x04 if data line stuck high.</li> + + <li> 0xAD (Disable keyboard interface) - Sets bit 4 of command byte + and disables all communication with keyboard.</li> + <li> 0xAE (Enable keyboard interface) - Clears bit 4 of command byte + and re-enables communication with keyboard.</li> + <li> 0xAF (Get version)</li> + <li> 0xC0 (Read input port) - Returns values on input port (see Input + Port definition.)</li> + <li> 0xC1 (Copy input port LSn) - PS/2 mode only. Copy input port's + low nibble to Status register (see Input Port definition)</li> + + <li> 0xC2 (Copy input port MSn) - PS/2 mode only. Copy input port's + high nibble to Status register (see Input Port definition.)</li> + <li> 0xD0 (Read output port) - Returns values on output port (see Output + Port definition.) </li> + <li> 0xD1 (Write output port) - Write parameter to output port (see + Output Port definition.)</li> + <li> 0xD2 (Write keyboard buffer) - Parameter written to input buffer + as if received from keyboard.</li> + <li> 0xD3 (Write mouse buffer) - Parameter written to input buffer as + if received from mouse.</li> + + <li> 0xD4 (Write mouse Device) - Sends parameter to the auxillary PS/2 + device.</li> + <li> 0xE0 (Read test port) - Returns values on test port (see Test Port + definition.)</li> + <li> 0xF0-0xFF (Pulse output port) - Pulses command's lower nibble onto + lower nibble of output port (see Output Port definition.)</li> + +</ul> + +<p><br> + <i>Modern Keyboard Controllers:</i> </p> + + +<p>So far, I've only discussed the 8042 keyboard controller. Although + modern keyboard controllers remain compatible with the original device, compatibility + is their only requirement (and their goal.) </p> + +<p>My motherboard's keyboard controller is a great example of this. + I connected a microcontroller+LCD in parallel to my keyboard to see what + data is sent by the keyboard controller. At power-up, the keyboard + controller sent the "Set LED state" command to turn off all LEDs, then reads + the keyboard's ID. When I tried writing data to the output buffer, + I found the keyboard controller only forwards the "Set LED state" command + and "Set Typematic Rate/Delay" command. It does not allow any other + commands to be sent to the keyboard. However, it does emulate the +keyboard's response by placing "acknowledge" (0xFA) in the input buffer +when appropriate (or 0xEE in response to the "Echo" command.) Furthermore, +if the keyboard sends it an erroneous byte, the keyboard controller takes +care of error handling (sends the "Retry" command; if byte still erroneous; +sends error code to keyboard and places error code in input buffer.) </p> + + +<p>Once again, keep in mind chipset designers are more interested in compatibility + than standardization. </p> + +<p><b>Initialization:</b> </p> + +<p>The following is the communication between my computer and keyboard +when it boots-up. I beleive the first three commands were initiated + by the keyboad controller, the next command (which enables Num lock LED) + was sent by the BIOS, then the rest of the commands were sent my the OS + (Win98SE). Remember, these results are specific to my computer, but + it should give you a general idea as to what happens at startup. </p> + +<blockquote><tt>Keyboard: AA Self-test passed + ;Keyboard controller init</tt> <br> + + <tt>Host: ED Set/Reset Status + Indicators </tt> <br> + <tt>Keyboard: FA Acknowledge</tt> <br> + <tt>Host: 00 Turn off all LEDs</tt> + <br> + + <tt>Keyboard: FA Acknowledge</tt> <br> + <tt>Host: F2 Read ID</tt> <br> + <tt>Keyboard: FA Acknowledge</tt> <br> + + <tt>Keyboard: AB First byte of ID</tt> <br> + <tt>Host: ED Set/Reset Status + Indicators ;BIOS init</tt> <br> + <tt>Keyboard: FA Acknowledge</tt> <br> + + <tt>Host: 02 Turn on Num Lock + LED</tt> <br> + <tt>Keyboard: FA Acknowledge</tt> <br> + <tt>Host: F3 Set Typematic +Rate/Delay ;Windows init</tt> + + <br> + <tt>Keyboard: FA Acknowledge</tt> <br> + <tt>Host: 20 500 ms / 30.0 +reports/sec</tt> <br> + <tt>Keyboard: FA Acknowledge</tt> <br> + + <tt>Host: F4 Enable</tt> <br> + <tt>Keyboard: FA Acknowledge</tt> <br> + <tt>Host: F3 Set Typematic +Rate/delay</tt> <br> + + <tt>Keyboard: FA Acknowledge</tt> <br> + <tt>Host: 00 250 ms / 30.0 +reports/sec</tt> <br> + <tt>Keyboard: FA Acknowledge</tt></blockquote> + + <br> + <br> + +</body> +</html> |