📄 the ps-2 keyboard interface.htm
字号:
<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 cellSpacing=0 cols=8 cellPadding=2 width=400 border=1>
<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. <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. <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. <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 <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. <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). <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) <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) <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.
<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.) <BR>0: No Error - Keyboard received and responded to
last command. <BR>1: Timeout Error - See TxTO and RxTO for more information.
</LI></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>0x60 (Write Command Byte) - Stores parameter as command byte.
Command byte defined as follows: </LI></UL>
<CENTER>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD><BR></TD>
<TD>
<CENTER>
<TABLE cellSpacing=0 cols=8 cellPadding=3 width=400 border=0>
<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 cellSpacing=0 cols=8 cellPadding=2 width=400 border=1>
<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 cellSpacing=0 cols=8 cellPadding=2 width=400 border=1>
<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. <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. <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. <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. <BR>0:
Enable - Keyboard interface enabled. <BR>1: Disable - All keyboard
communication is disabled.
<LI>PC ("PC Mode") - ???Enables keyboard interface somehow??? <BR>0: Disable
- ??? <BR>1: Enable - ???
<LI>XLAT (Translate Scan Codes) - Enables/disables translation to set 1 scan
codes. <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. <BR>0: Auxillary IBF Interrupt Disabled
- <BR>1: Auxillary IBF Interrupt Enabled -
<LI>_EN2 (Disable Mouse) - Disables/enables mouse interface. <BR>0: Enable -
Auxillary PS/2 device interface enabled <BR>1: Disable - Auxillary PS/2
device interface disabled </LI></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>?0xA1 (Get version number) - Returns firmware version number.
<LI>?0xA4 (Get password) - Returns 0xFA if password exists; otherwise, 0xF1.
<LI>?0xA5 (Set password) - Set the new password by sending a null-terminated
string of scan codes as this command's parameter.
<LI>?0xA6 (Check password) - Compares keyboard input with current password.
<LI>0xA7 (Disable mouse interface) - PS/2 mode only. Similar to "Disable
keyboard interface" (0xAD) command.
<LI>0xA8 (Enable mouse interface) - PS/2 mode only. Similar to "Enable
keyboard interface" (0xAE) command.
<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>0xAA (Controller self-test) - Returns 0x55 if okay.
<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>0xAD (Disable keyboard interface) - Sets bit 4 of command byte and
disables all communication with keyboard.
<LI>0xAE (Enable keyboard interface) - Clears bit 4 of command byte and
re-enables communication with keyboard.
<LI>0xAF (Get version)
<LI>0xC0 (Read input port) - Returns values on input port (see Input Port
definition.)
<LI>0xC1 (Copy input port LSn) - PS/2 mode only. Copy input port's low nibble
to Status register (see Input Port definition)
<LI>0xC2 (Copy input port MSn) - PS/2 mode only. Copy input port's high nibble
to Status register (see Input Port definition.)
<LI>0xD0 (Read output port) - Returns values on output port (see Output Port
definition.)
<LI>0xD1 (Write output port) - Write parameter to output port (see Output Port
definition.)
<LI>0xD2 (Write keyboard buffer) - Parameter written to input buffer as if
received from keyboard.
<LI>0xD3 (Write mouse buffer) - Parameter written to input buffer as if
received from mouse.
<LI>0xD4 (Write mouse Device) - Sends parameter to the auxillary PS/2 device.
<LI>0xE0 (Read test port) - Returns values on test port (see Test Port
definition.)
<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>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -