1309 lines
47 KiB
Plaintext
1309 lines
47 KiB
Plaintext
Wout Mertens' Guide To Keyboard Programming v1.1
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
23 may 94
|
||
|
||
Table of Contents
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
0 Legal Info
|
||
0.1 Preface
|
||
|
||
1 Overall Information
|
||
1.1 Extended ASCII
|
||
1.2 Special Functions
|
||
|
||
2 DOS Interfacing
|
||
2.1 Functions
|
||
|
||
3 BIOS Interfacing
|
||
3.1 Functions
|
||
3.2 Keyboard Flags
|
||
3.3 Keyboard Buffer
|
||
|
||
4 Low-Level Interfacing
|
||
4.1 Interfacing And Configuring
|
||
4.2 Lay-Out
|
||
4.3 Scancodes
|
||
4.4 Int 9
|
||
|
||
5 Tech Stuff
|
||
|
||
A Acknowledgments
|
||
B How To Contact Me
|
||
C The Answer To Life, The Universe And All The Rest
|
||
D History
|
||
|
||
|
||
0. Legal Info
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
This "Keyboard Guide" is (C) Copyright 1994 Wout Mertens.
|
||
All rights reserved.
|
||
|
||
THIS DOCUMENT AND THE ACCOMPANYING SOURCE CODE FILES ARE PROVIDED "AS
|
||
IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING ANY
|
||
WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. WOUT
|
||
MERTENS WILL NOT BE HELD LIABLE FOR ANY DAMAGES OR LOSSES OF ANY KIND
|
||
THAT RESULT FROM THE USE OR THE INABILITY TO USE THE INFORMATION
|
||
PROVIDED IN THIS DOCUMENT OR THIS SOURCE CODE FILE, INCLUDING, BUT NOT
|
||
LIMITED TO, LOSS OF PROPERTY OR INCOME.
|
||
|
||
This document and its accompanying source code files are freeware, not
|
||
public domain. They may be distributed freely provided that neither
|
||
file is modified, and that they are distributed together along with
|
||
FILE_ID.DIZ in their entirety, including the legal notice, and that:
|
||
If they are distributed by a third party vendor, no more than $5 U.S. is
|
||
charged for the disk on which the archive, containing this document and
|
||
the accompanying source code files, is stored, except when distributed
|
||
on CD-ROM.
|
||
This legal information supersedes all previous notices.
|
||
|
||
|
||
0.1. Preface
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
I wrote this document because I needed info, and thought I could get it
|
||
this way. Boy was I wrong! I ended up finding it all by myself. Anyway,
|
||
I hope you can use it. It is meant for people who know what interrupts
|
||
are and that 0ah equals 10. Enjoy.
|
||
|
||
Oh, almost forgot. I didn't give this text any page formatting (aside
|
||
from spaces before and room after for ease of reading) because:
|
||
|
||
- I read ALL my documents on-line
|
||
- People have differing page sizes and then it would look like
|
||
shit for some people and too short for others.
|
||
|
||
If you want to print this, well, go ahead and format it, BUT DON'T EVEN
|
||
*THINK* OF SPREADING IT !!! (Except when you ask my permission)
|
||
|
||
Everytime you see something like d9h or 65h, it is a hexadecimal
|
||
number. No trailing 0 was added for ease of typing.
|
||
|
||
|
||
1. Overall Information
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
On the IBM, there are three ways, all alike, to access the keyboard.
|
||
Via the operating system, via BIOS or via low-level access. Which way
|
||
you use depends very much on the application you are writing. Games do
|
||
not use DOS functions, for example. And a file-compressor is really not
|
||
interested wether you are actually pressing 'Y' or not. Or how long.
|
||
|
||
This is the way it works:
|
||
|
||
Hardware ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ BIOS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ÃÄÄÄÄ DOS ÄÄÄ´
|
||
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||
Ú´Keyboard DataÃÄÄÄÄÄ¿
|
||
³ÀÄÄÄÄÄÄÄÄÄÄÄÄÒÙ ³
|
||
ÚÄÄÄÄÄ¿ ÚÄÄÄÄÄ¿³ ÚÄÄÄÄÄÄÄÄ¿ º ÚÄÄÄÄÁÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||
³key- ÃÄÒÄ´int 9ÃÁÄÄ´keyboardÃÄÄÄ´BIOS keyboardÃÄÄÄ´DOS keyboard³
|
||
³board³ º ÀÄÄÄÄÄÙ ³buffer ³ º ³functions ³ ³functions ³
|
||
ÀÄÄÄÄÄÙ º ÀÄÄÄÒÄÄÄÄÙ º ÀÄÄÄÄÄÄÒÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÒÄÄÄÄÄÙ
|
||
º º º º º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÊËÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
º
|
||
|
||
Possible tap points
|
||
|
||
The keyboard triggers IRQ 1 (Interrupt Request), also known as int 9.
|
||
Int 9 then translates the keyboard codes into ASCII, or when necessary,
|
||
extended ASCII, and places it into the keyboard buffer. Also, the shift
|
||
and lock states are saved in the BIOS Data Area (seg 40h). The keyboard
|
||
buffer is then used by the BIOS functions to interface with programs.
|
||
The DOS functions use the BIOS keyboard functions to interface with
|
||
programs as well, but on a higher and more protected (Ctrl-Brk etc)
|
||
level.
|
||
|
||
|
||
1.1. Extended ASCII
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
Extended ASCII is IBM's way of letting non-ASCII keys be recognized by
|
||
programs. The BIOS will first send 0 and then the extended ASCII code.
|
||
|
||
Here is the table:
|
||
ÖÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ·
|
||
ºKey Hex DecºKey Hex DecºKey Hex DecºKey Hex Decº
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
ºF1 3B 59ºShift-F1 54 84ºCtrl-F1 5E 94ºAlt-F1 68 104º
|
||
ºF2 3C 60ºShift-F2 55 85ºCtrl-F2 5F 95ºAlt-F2 69 105º
|
||
ºF3 3D 61ºShift-F3 56 86ºCtrl-F3 60 96ºAlt-F3 6A 106º
|
||
ºF4 3E 62ºShift-F4 57 87ºCtrl-F4 61 97ºAlt-F4 6B 107º
|
||
ºF5 3F 63ºShift-F5 58 88ºCtrl-F5 62 98ºAlt-F5 6C 108º
|
||
ºF6 40 64ºShift-F6 59 89ºCtrl-F6 63 99ºAlt-F6 6D 109º
|
||
ºF7 41 65ºShift-F7 5A 90ºCtrl-F7 64 100ºAlt-F7 6E 110º
|
||
ºF8 42 66ºShift-F8 5B 91ºCtrl-F8 65 101ºAlt-F8 6F 111º
|
||
ºF9 43 67ºShift-F9 5C 92ºCtrl-F9 66 102ºAlt-F9 70 112º
|
||
ºF10 44 68ºShift-F10 5D 93ºCtrl-F10 67 103ºAlt-F10 71 113º
|
||
ÓÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĽ
|
||
ÖÄÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ·
|
||
ºKey Hex DecºKey Hex DecºKey Hex DecºKey Hex Decº
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
ºAlt-A 1E 30ºAlt-P 19 25ºAlt-3 7A 122ºdown 50 80º
|
||
ºAlt-B 30 48ºAlt-Q 10 16ºAlt-4 7B 123ºleft 4B 75º
|
||
ºAlt-C 2E 46ºAlt-R 13 19ºAlt-5 7C 124ºright 4D 77º
|
||
ºAlt-D 20 32ºAlt-S 1F 31ºAlt-6 7D 125ºup 48 72º
|
||
ºAlt-E 12 18ºAlt-T 14 20ºAlt-7 7E 126ºEnd 4F 79º
|
||
ºAlt-F 21 33ºAlt-U 16 22ºAlt-8 7F 127ºHome 47 71º
|
||
ºAlt-G 22 34ºAlt-V 2F 47ºAlt-9 80 128ºPgDn 51 81º
|
||
ºAlt-H 23 35ºAlt-W 11 17ºAlt-- 82 130ºPgUp 49 73º
|
||
ºAlt-I 17 23ºAlt-X 2D 45ºAlt-= 83 131º º
|
||
ºAlt-J 24 36ºAlt-Y 15 21º º^left 73 115º
|
||
ºAlt-K 25 37ºAlt-Z 2C 44ºNUL 03 3º^right 74 116º
|
||
ºAlt-L 26 38º ºShift-Tab 0F 15º^End 75 117º
|
||
ºAlt-M 32 50ºAlt-0 81 129ºIns 52 82º^Home 77 119º
|
||
ºAlt-N 31 49ºAlt-1 78 120ºDel 53 83º^PgDn 76 118º
|
||
ºAlt-O 18 24ºAlt-2 79 121º^PrtSc 72 114º^PgUp 84 132º
|
||
ÓÄÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĽ
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º 101-key Keyboard Extensions Supported by BIOS º
|
||
ÖÄÄÄÄÄÄÐÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÄÄ·
|
||
ºKey Hex DecºKey Hex DecºKey Hex Decº
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
ºF11 85 133ºAlt-Bksp 0E 14ºAlt - K / A4 164º
|
||
ºF12 86 134ºAlt-Enter 1C 28ºAlt - K * 37 55º
|
||
ºShft-F11 87 135ºAlt-Esc 01 1ºAlt - K - 4A 74º
|
||
ºShft-F12 88 136ºAlt-Tab A5 165ºAlt - K + 4E 78º
|
||
ºCtrl-F11 89 137ºCtrl-Tab 94 148ºAlt - K Enter A6 166º
|
||
ºCtrl-F12 8A 138º º º
|
||
ºAlt-F11 8B 139ºAlt-up 98 152ºCtrl- K / 95 149º
|
||
ºAlt-F12 8C 140ºAlt-down A0 160ºCtrl- K * 96 150º
|
||
ºAlt-[ 1A 26ºAlt-left 9B 155ºCtrl- K - 8E 142º
|
||
ºAlt-] 1B 27ºAlt-right 9D 157ºCtrl- K + 90 144º
|
||
ºAlt-; 27 39º º º
|
||
ºAlt-' 28 40ºAlt-Delete A3 163ºCtrl- K Up [8] 8D 141º
|
||
ºAlt-` 29 41ºAlt-End 9F 159ºCtrl- K Cn [5] 8F 143º
|
||
ºAlt-\ 2B 43ºAlt-Home 97 151ºCtrl- K Dw [2] 91 145º
|
||
ºAlt-, 33 51ºAlt-Insert A2 162ºCtrl- K Ins[0] 92 146º
|
||
ºAlt-. 34 52ºAlt-PageUp 99 153ºCtrl- K Del[.] 93 147º
|
||
ºAlt-/ 35 53ºAlt-PageDown A1 161º º
|
||
ÓÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĽ
|
||
K indicates a key on the numeric keypad (when not in NumLock mode)
|
||
|
||
|
||
1.2. Special Functions
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
There are a few functions and interrupts invoked by int 9:
|
||
|
||
int 5 - Print Screen Handler
|
||
|
||
int 15h
|
||
fns 4fh - Check Scancode
|
||
(See int 9)
|
||
|
||
85h - System Request
|
||
Normally IRET
|
||
|
||
int 23h - Ctrl-Break handler
|
||
|
||
Feel free to revector any of them.
|
||
|
||
|
||
2. DOS Interfacing
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
One of the ways to use the keyboard is to let DOS handle it.
|
||
|
||
Pro:
|
||
- The keyboard lay-out is unimportant
|
||
- You can even do strings
|
||
- The user doesn't actually have to type
|
||
|
||
Contra:
|
||
- You don't know if you are actually accessing the keyboard (like
|
||
in "Really format drive C: ? Y/N" :-)
|
||
- The functions are quite slow
|
||
|
||
|
||
2.1. Functions
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
DOS provides a set of 7 functions to handle the keyboard:
|
||
|
||
01h Keyboard Input
|
||
06h Console I/O
|
||
07h No Echo Unfiltered Input
|
||
08h No Echo Filtered Input
|
||
0Ah Buffered Input
|
||
0Bh Input Status
|
||
0Ch Clear Keyboard Buffer & Input
|
||
|
||
They all expect the keyboard to be file handle 0. If you want to let a
|
||
program think you are typing something, you can replace this handle
|
||
with a file containing the keystrokes it must read. This is what
|
||
happens when you 'pipe' something in DOS. (Don't forget to change the
|
||
handle back to the old one!)
|
||
|
||
This also means you can use:
|
||
|
||
3Fh Read bytes from handle
|
||
|
||
Fn 01h: Keyboard Input
|
||
----------------------
|
||
Expects: AH 01h
|
||
|
||
Returns: AL Character fetched from the Standard Input
|
||
|
||
Description: Reads (waits for) a character from the Standard Input
|
||
Device. Echoes that character to the Standard Output
|
||
Device. If Ctrl-Break is detected, INT 23h is executed.
|
||
|
||
Notes: Extended ASCII keystrokes (ie, F1-F12, PgUp, cursor, etc)
|
||
will require two calls to this function. The first call
|
||
will return AL=0. The second will return AL with the
|
||
extended ASCII code.
|
||
|
||
Fn 06h: Console I/O
|
||
-------------------
|
||
Expects: AH 06h
|
||
DL 0 to 0FEh Character to send to the Standard Output
|
||
0FFh Request for input from the Standard Input
|
||
|
||
Returns: ZF Clear (NZ) if character is ready \ on input requests
|
||
AL Character read, if ZF is clear / (when DL=0FFh)
|
||
|
||
Description: If DL is 0FFh, this performs a "no wait" console input,
|
||
returning the Zero Flag (ZF) set (ZR) if there is no
|
||
character ready. If a character is ready, returns ZF
|
||
cleared (NZ) with the character that was read in AL.
|
||
|
||
If DL is anything but 0FFh, DL is sent to the Standard
|
||
Output.
|
||
|
||
Notes: Does not check for Ctrl-Break. Call twice for Extended
|
||
ASCII.
|
||
|
||
Fn 07h: No Echo Unfiltered Console Input
|
||
----------------------------------------
|
||
Expects: AH 07h
|
||
|
||
Returns: AL Character fetched from the Standard Input
|
||
|
||
Description: Reads (waits for) a character from the Standard Input
|
||
Device, returning that character in AL.
|
||
|
||
Unfiltered: Does not detect Ctrl-Break, backspace, etc.
|
||
|
||
Notes: Call twice for Extended ASCII character input.
|
||
Use Fn 0Bh to check status (if you don't want to wait for
|
||
a key).
|
||
|
||
Fn 08h: No Echo Console Input
|
||
-----------------------------
|
||
Expects: AH 08h
|
||
|
||
Returns: AL Character fetched from the Standard Input
|
||
|
||
Description: Reads (waits for) a character from the Standard Input
|
||
Device, returning that character in AL.
|
||
|
||
If Ctrl-Break is detected, INT 23h is executed.
|
||
|
||
Notes: Call twice for Extended ASCII character input.
|
||
|
||
Fn 0Ah: Buffered String Input
|
||
-----------------------------
|
||
Expects: AH 0Ah
|
||
DS:DX Address of an input buffer (see below)
|
||
|
||
Returns: Buffer contains input terminated with CR (ASCII 13h)
|
||
|
||
Description: On entry, the buffer at DS:DX must be set up as:
|
||
ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄ Ä Ä
|
||
³max³ ? ³ ? ? ? ? ? max is maximum acceptable
|
||
ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁ Ä Ä input (range: 1 to 254)
|
||
On exit, the buffer is filled:
|
||
ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄ Ä Ä len is actual length of
|
||
³max³len³ T E X T 0Dh input, less the termina-
|
||
ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁ Ä Ä ting CR (eg, 4).
|
||
|
||
Characters are read from the Standard Input up to a CR
|
||
(ASCII 13) or up to the value of max-1. If max-1 is
|
||
reached, the console bell rings (beeps) for each character
|
||
until Enter (CR) is read.
|
||
|
||
The second byte of the buffer is filled with the actual
|
||
length of the input, less the terminating CR. The final
|
||
character in the buffer is always CR (which is not counted
|
||
in the length byte).
|
||
|
||
The characters in the buffer (including the len) before
|
||
the call are used as a "template" and the DOS editing keys
|
||
are in effect: [Esc] displays "\" and restarts the edit,
|
||
[F3] displays to the end of the template, [F5] displays
|
||
"@" and stores the current line as the template, etc.
|
||
Most Extended ASCII keystrokes are ignored.
|
||
|
||
If Ctrl-Break is detected, INT 23h is executed and the
|
||
buffer is left unchanged.
|
||
|
||
Fn 0Bh: Check Input Status
|
||
--------------------------
|
||
Expects: AH 0Bh
|
||
|
||
Returns: AL 0FFh if a character is available from the Standard Input
|
||
0 if no character is available
|
||
|
||
Description: Checks the status of the Standard Input.
|
||
|
||
If Ctrl-Break is detected, INT 23h is executed.
|
||
|
||
Notes: Use before Fns 01h, 07h and 08h to avoid having DOS wait
|
||
for a key.
|
||
|
||
This is a simple, non-destructive way to check for
|
||
Ctrl-Break during long calculations or other processing
|
||
that does not normally look for input. It lets the user
|
||
abort from such a sequence.
|
||
|
||
Fn 0Ch: Clear & Input
|
||
---------------------
|
||
Expects: AH 0Ch
|
||
AL DOS input function number (01h, 06h, 07h, 08h, or 0Ah)
|
||
|
||
Returns: none
|
||
|
||
Description: Clears the Standard Input type-ahead buffer then invokes
|
||
the DOS input function specified by AL. This forces the
|
||
system to wait for a character to be typed.
|
||
|
||
These values are allowed for AL:
|
||
01h Keyboard Input
|
||
06h Console I/O
|
||
07h No Echo Unfiltered Input
|
||
08h No Echo Filtered Input
|
||
0Ah Buffered Input
|
||
|
||
|
||
In addition to these functions, it is also possible to read a selected
|
||
amount of characters from the keyboard, using DOS's File Handle
|
||
functions, as the Keyboard, aka Standard Input, has a pre-set handle of
|
||
0000h:
|
||
|
||
Fn 3Fh: Read from keyboard via Handle
|
||
-------------------------------------
|
||
Expects: AH 3Fh
|
||
BX 0000h - Handle for Standard Input (Keyboard)
|
||
DS:DX Address of buffer to receive data
|
||
CX Number of bytes to read
|
||
|
||
Returns: AX Error code if CF is set to CY
|
||
AX Number of bytes actually read
|
||
|
||
Description: CX bytes of data are read from the keyboard. The data is
|
||
placed into the caller's buffer pointed to by DS:DX.
|
||
|
||
Notes: It is handy to use this function for reading default
|
||
handles such as the Standard I/O handles, instead of the
|
||
buffered input or character-by-character input functions.
|
||
|
||
When you read from a device, AX returns the length of the
|
||
line up to and including the termination CR (ASCII 13h).
|
||
|
||
|
||
3. BIOS Interfacing
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
Pro:
|
||
- You get to know all the statusses and such
|
||
- It's a tad bit faster than DOS
|
||
- You can only read the keyboard
|
||
- It's easier than the really hardcore low level, and the keys
|
||
are translated
|
||
|
||
Contra:
|
||
- It is still to slow for games or demos
|
||
- You don't have bulk access, like strings
|
||
|
||
The BIOS has 3 different ways of reading (parts of) the keyboard:
|
||
- functions
|
||
- keyboard flags
|
||
- keyboard buffer
|
||
|
||
This part describes all of them.
|
||
|
||
|
||
3.1. Functions
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
These functions can be accessed through int 16h.
|
||
|
||
Fn 00h: Read (wait for) next keystroke
|
||
--------------------------------------
|
||
Expects: AH 0
|
||
|
||
Returns: AL ASCII character (if AL=0, AH is an Extended ASCII key-
|
||
stroke)
|
||
AH Scan Code or Extended ASCII keystroke
|
||
|
||
Fn 01h: Check if a keystroke is ready (and preview it if so)
|
||
------------------------------------------------------------
|
||
Expects: AH 1
|
||
|
||
Returns: ZF ZR or 1 if no key is ready
|
||
ZF NZ or 0 if a key is ready.
|
||
AX is set as for Fn 00h (but the keystroke has not been
|
||
removed from the queue).
|
||
|
||
Fn 02h: Read the shift-key status
|
||
---------------------------------
|
||
Expects: AH 2
|
||
|
||
Returns: AL shift key and 'lock' status as in 83-keyboard flags
|
||
|
||
Description: Determine which shift keys are currently being pressed and
|
||
whether the keyboard is in NumLock state, etc.
|
||
|
||
Fn 03h Set keyboard typeamatic rate and delay. (11/15/85 BIOS)
|
||
--------------------------------------------------------------
|
||
Expects: AH 3
|
||
AL 05h (eg, AX = 0305h)
|
||
BL Typeamatic Rate
|
||
0: 30 keys/sec 10: 10
|
||
1: 26.7 13: 9
|
||
2: 24 16: 7.5
|
||
4: 20 20: 5
|
||
8: 15 31: 2
|
||
BH Delay: 0=250ms 1=500ms 2=750ms 3=1 second)
|
||
|
||
Returns: none
|
||
|
||
Description: when a key is pressed, the keyboard will wait during Delay
|
||
before it starts repeating at Typematic Rate.
|
||
|
||
Fn 05h Place a keystroke into the keyboard buffer. (11/15/85 BIOS)
|
||
------------------------------------------------------------------
|
||
Expects: AH 5
|
||
CL ASCII character.
|
||
CH Scan Code byte (or 0 if you don't care)
|
||
|
||
Returns: AL Status: 0=success; 1=buffer full
|
||
|
||
Fn 10h Read (wait for) a keystroke; 101-keyboard only (11/15/85 BIOS)
|
||
---------------------------------------------------------------------
|
||
Expects: AH 10h
|
||
|
||
Returns: AL ASCII character (if AL=0, AH is an Extended ASCII key-
|
||
stroke)
|
||
AH Scan Code or Extended ASCII keystroke
|
||
|
||
Fn 11h Preview keystroke; same as 01; 101-keyboard only (11/15/85 BIOS)
|
||
-----------------------------------------------------------------------
|
||
Expects: AH 11h
|
||
|
||
Returns: ZF ZR or 1 if no key is ready
|
||
ZF NZ or 0 if a key is ready.
|
||
AX set as for Fn 10 but keystroke is still in the buffer.
|
||
|
||
12h Read shift-key status; same as 02; 101-keyboard only (11/15/85 BIOS)
|
||
------------------------------------------------------------------------
|
||
Expects: AH 12H
|
||
Returns: AL shift key and 'lock' status as in 101-keyboard flags
|
||
|
||
|
||
3.2. Keyboard Flags
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
The keyboard flags are found in the BIOS Data Area: segment 40h.
|
||
|
||
17h: 83-keyboard flags 0=Off, 1=On
|
||
---------------------------------------
|
||
bit 0: Right shift
|
||
1: Left shift
|
||
2: Ctrl, either side
|
||
3: Alt, either side
|
||
4: Scroll Lock
|
||
5: Num Lock
|
||
6: Caps Lock
|
||
7: Insert state
|
||
|
||
Do NOT just change one of these and then hope the keyboard follows. The
|
||
LEDs will definitely get out of sync.
|
||
|
||
18h: 101-keyboard flags 0=Off, 1=On
|
||
---------------------------------------
|
||
bit 0¿ : Left ctrl
|
||
1ÃÄAt keyb. only : Left Alt
|
||
2Ù : Sys Req
|
||
3: Pause state
|
||
4: Scroll Lock ¿
|
||
5: Num Lock ÃÄBeing pressed
|
||
6: Caps Lock ³
|
||
7: Insert Ù
|
||
|
||
Do NOT just change one of these and then hope the keyboard follows. The
|
||
LEDs will definitely get out of sync.
|
||
|
||
19h: Pseudokey value
|
||
--------------------
|
||
This is the accumulating value of the key being made with Alt+numeric
|
||
keypad. Normally 0
|
||
|
||
71h: Ctrl-break flag 0=Off, 1=On
|
||
---------------------------------------
|
||
bit 7: Ctrl-Break was pressed. Never gets reset, unless you do.
|
||
|
||
96h: AT only - keyboard ? 0=Off, 1=On
|
||
---------------------------------------
|
||
bit 4: 101/102 keyboard is attached
|
||
|
||
97h: AT only - lock LEDs 0=Off, 1=On
|
||
---------------------------------------
|
||
bit 0: ScrollLock ¿
|
||
1: NumLock ÃÄ keyboard LED is turned on
|
||
2: CapsLock Ù
|
||
|
||
Do NOT just change one of these and then hope the keyboard follows.
|
||
The LEDs will definitely get out of sync.
|
||
|
||
|
||
3.3. Keyboard Buffer
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
The keyboard buffer is a circular data area. This means that when a
|
||
pointer in the buffer gets one larger than the buffer, it is wrapped
|
||
around to the beginning.
|
||
|
||
The keyboard buffer is fed by int 9 and function 5 of int 16h. It is
|
||
found at the BIOS data segment, 40h. It is pointed to by 4 variables in
|
||
the BDA: The head (1ah), the tail (1ch), the Beginning (80h) and the
|
||
End (82h). They are all words, pointing at locations in the BDA.
|
||
|
||
The latter two are only available on ATs and PSs. They are used to
|
||
enlarge the keyboard buffer by mapping it to another spot in the BIOS
|
||
data area. Normally, that spot is 32 bytes long starting from 1eh.
|
||
|
||
The head is the pointer to the next word. The tail is the pointer to
|
||
the next available word. Each code is two bytes, the scan code and the
|
||
ASCII value.
|
||
|
||
The buffer is empty if the Head = the Tail and it is full if the Tail
|
||
is two smaller than the Head, both counted circularly. This means that
|
||
the storage space equals (length buffer/2)-1.
|
||
|
||
|
||
4. Low-Level Interfacing
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
Pro:
|
||
- Fast
|
||
- Complete control
|
||
|
||
Contra:
|
||
- Hard to code
|
||
- Totally NO functions at all. It's Handyman work here...
|
||
|
||
The interfacing is split in two items:
|
||
- Just changing something, such as the LED's
|
||
- Reading out codes: int 9
|
||
|
||
|
||
4.1. Interfacing And Configuring
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
The computer and the AT or MF II interface through I/O ports 60h and
|
||
64h, controlled by a programmable Intel 8042 (old ATs), 8741 or 8742
|
||
(newer, allow two input devices (like the PS/2 mouse)) microprocessor
|
||
or compatible, which allows typematic rate programming, LEDs lighting
|
||
and some other stuff. It also has a +-20 byte output buffer for smooth
|
||
operation and long scancodes.
|
||
|
||
The old XT keyboard has a 8048, which is in essence just a very
|
||
primitive one-way serial interface, so all used is port 61h, to disable
|
||
and reenable the keyboard on every scancode.
|
||
|
||
Port 60h: Input & output
|
||
------------------------
|
||
Read: Scancodes and keyboarddata
|
||
--------------------------------
|
||
This port gives the following output codes:
|
||
|
||
00h: Keyboard error, too many keys are being pressed at once
|
||
aah: Basic Assurance Test (BAT) end
|
||
abh 41h: The result of requesting keyboard ID on a MF II keyboard
|
||
eeh: The result of the echo command
|
||
fah: ACK(noledge). Sent by every command, except eeh and feh
|
||
fch: BAT failed
|
||
feh: Resend your data please
|
||
ffh: Keyboard error
|
||
|
||
All the rest are make (press) and break (release) codes of the keys.
|
||
|
||
Write: Command data
|
||
-------------------
|
||
This is the place where command data has to be sent. If the command
|
||
consists of two bytes, you must wait until the outputbuffer is sent to
|
||
the keyboard. Check on it via bit 1 of port 64h. When you send a
|
||
command, the outputbuffer is cleared, so pending results may not come.
|
||
During transmission of a two-byte command, the keyboard stops scanning.
|
||
When you send something out of range or so, the keyboard will react
|
||
with feh (resend). All commands, except echo (eeh) and resend (feh)
|
||
result in ACK (fah) to be sent.
|
||
|
||
Commands:
|
||
|
||
edh: Set keyboard LEDs
|
||
Send a second byte with:
|
||
|
||
bit 0 = Scroll Lock 0=Off 1=On
|
||
1 = Num Lock
|
||
2 = Caps Lock
|
||
rest = 0
|
||
|
||
Do make an effort to keep the BIOS keyboard flags in sync.
|
||
|
||
eeh: Great fun. Send it, and get 0eeh right back! :-]
|
||
(Diagnostics)
|
||
|
||
f0h: Select scancode set.
|
||
|
||
0: return current set number: 1:'C', 2:'A', 3:'?'
|
||
1: set scancode set no 1
|
||
2: set scancode set no 2 -> standard
|
||
3: set scancode set no 3
|
||
|
||
f2h: Identify keyboard
|
||
XT: nothing (that is, time-out error :-) (see port 64h)
|
||
AT: ACK
|
||
MF II: ACK abh 41h
|
||
|
||
f3h: Typematic rate programming
|
||
Send a second byte with:
|
||
|
||
bit 0 -> 4: rate. Timings:
|
||
|
||
0: 30 keys/sec 10: 10
|
||
1: 26.7 13: 9
|
||
2: 24 16: 7.5
|
||
4: 20 20: 5
|
||
8: 15 31: 2
|
||
|
||
bit 5 & 6: pause before repeat:
|
||
|
||
0: 250 ms
|
||
1: 500
|
||
2: 750
|
||
4: 1000
|
||
|
||
bit 7: Always 0
|
||
|
||
The next three are doubtfull, since one of my sources say they don't
|
||
exist and another says they do. I leave it up to you :)
|
||
|
||
f4h: Enable keyboard. It clears its buffer and starts scanning.
|
||
f5h: Reset keyboard, disable scanning
|
||
f6h: Reset keyboard, enable scanning
|
||
|
||
feh: Resend last transmission. I really don't know what it does, since
|
||
it sends something incomprehesible.
|
||
|
||
ffh: Internal diagnostics: Sends aah if successfull. Warning! The
|
||
keyboard reacts with ACK and then you have to set the data and
|
||
clock pins high, DURING AT LEAST 500 SECONDS!. Do this via the
|
||
outputport (see 64h). After that, the BAT (Basic Assurance Test)
|
||
starts. This sends aah on success and fch on failure.
|
||
|
||
Example: Set the keyboard LEDs
|
||
|
||
start:
|
||
in al, 64h \It would be good
|
||
and al, 02h ;Test if command buffer is empty |to put this in a
|
||
jnz start /macro...
|
||
|
||
mov al, edh
|
||
out 60h, al ;Write outputport
|
||
|
||
wait:
|
||
in al, 64h
|
||
and al, 02h ;Test if command came through
|
||
jnz wait
|
||
|
||
mov al, 0111b
|
||
out 60h, al ;Set all LED's to ON.
|
||
|
||
|
||
Port 61h
|
||
--------
|
||
This port is used to acknoledge the receival of a scancode, by
|
||
disabling the keyboard and immediately reenabling it. This also means
|
||
that you can read a scancode as many times as you like, until you
|
||
acknoledge the receival.
|
||
|
||
bit 0 -> 5: Nothing to do with keyboard, but with the Programmable
|
||
Peripheral Interface (PPI) -> save them!
|
||
bit 6: Hold keyboard clock low -> Keyboard can't send any data.
|
||
bit 7: 0=Enable keyboard; 1=Disable keyboard
|
||
|
||
Example:
|
||
|
||
in al, 61h
|
||
mov ah, al ;Save keyboard status
|
||
or al, 80h ;Disable
|
||
out 61h, al
|
||
mov al, ah ;Enable (If it was disabled at first, you wouldn't
|
||
out 61h, al ; be doing this anyway :-)
|
||
|
||
|
||
Port 64h: Interface: data and control
|
||
-------------------------------------
|
||
Read: Statusport
|
||
----------------
|
||
bit 0: 1: Keyboard data is in buffer
|
||
0: Output buffer empty -> use it to check for results
|
||
1: 1: User data is in buffer
|
||
0: Command buffer is empty -> time to send a command
|
||
2: 1: Selftest successful
|
||
0: Reset (?)
|
||
3: 1: 64h was last accessed port
|
||
0: 60h was last accessed port
|
||
4: 1: Keyboard enabled
|
||
0: Keyboard locked
|
||
5: PS/2: Mouse interface
|
||
6: 1: Time-out error occurred: Keyboard or PS/2 mouse didn't
|
||
react. Use the Resend command to retry fetching the data
|
||
byte. This could happen when trying to get a XT keyboard
|
||
to do something :).
|
||
7: 1: Last transmission had a parity error
|
||
|
||
Write: Control register
|
||
-----------------------
|
||
This is the control room of the keyboard interface. If additional data
|
||
is required, send it to port 60h after writing the command to 64h.
|
||
Also, check 61h bit 2 before sending anything.
|
||
|
||
Commands:
|
||
|
||
aah: Keyboard self test. Sends 55h if successfull.
|
||
|
||
abh: Test interface. Sends:
|
||
|
||
00h: No error
|
||
01h: Clock low
|
||
02h: Clock high
|
||
03h: Data low
|
||
04h: Data high
|
||
ffh: Total Error
|
||
|
||
adh: Deactivate keyboard
|
||
|
||
aeh: Activate keyboard
|
||
|
||
c0h: Read inputport. This is some highly specialized stuff and I wonder
|
||
why I am typing this. Ok. The inputport is that what the keyboard
|
||
is sending and some more. Layout:
|
||
|
||
bit 0: Keyboard data in pin
|
||
1: PS/2 mouse in pin
|
||
2->5: reserved
|
||
6: Wether you have a color or mono screen
|
||
7: 1: Keyboard not locked
|
||
0: Keyboard locked
|
||
|
||
When you issue this command, the inputport is put on the
|
||
outputbuffer, so you have the great priviledge of reading it at
|
||
port 60h.
|
||
|
||
c1h: Puts the low nibble of the input port over bits 4-7 of the
|
||
statusport, so you can read them out continuously. This lasts
|
||
until bit 2 of the statusport gets set, meaning you are sending
|
||
data to the keyboard.
|
||
|
||
c2h: Ditto, but it puts the high nibble over bits 0-3 of the
|
||
statusport. Lifespan is the same.
|
||
|
||
d0h: Puts the outputport on the buffer. Layout:
|
||
|
||
bit 0: 1: Reset processor
|
||
1: 1: A20 gate enable
|
||
2: PS/2 mouse data out
|
||
3: PS/2 mouse clock signal
|
||
4: 1: Output buffer full
|
||
5: 1: Output buffer PS/2 mouse full
|
||
6: Keyboard clock signal
|
||
7: Keyboard data out
|
||
|
||
Bit 0 and 1 are quite important for high memory and
|
||
286-extended-memory access.
|
||
|
||
d1h: Write the following data byte to the outputport
|
||
|
||
d2h: Write the following data byte to the keyboardbuffer. This is VERY
|
||
handy for TSRs that need to read codes that start with e0h. This
|
||
way, they don't have to pass through the e0h, unless they know for
|
||
sure it isn't their code, which results in correct functioning
|
||
shift keys etc. At least, if it does what I think it
|
||
does... [UNTESTED]
|
||
|
||
d3h: Ditto, for PS/2 mouse.
|
||
|
||
d4h: Write byte to PS/2 mouse.
|
||
|
||
e0h: Reads the keyboards testinputs, T0 and T1. T0 goes to bit 0 and T1
|
||
to bit 1 of the byte that is put on the outputbuffer.
|
||
|
||
fxh: I think it sends x to the low nibble of the output port. It does
|
||
reset my computer when I send feh, but that doesn't mean anything
|
||
:-). The official explanation says that it keeps the corresponding
|
||
bits in the output port low for 6ms...
|
||
|
||
Example: Send something to the outputport
|
||
|
||
start:
|
||
in al, 64h \It would be good
|
||
and al, 02h ;Test if command buffer is empty|to put this in a
|
||
jnz start /macro...
|
||
|
||
mov al, d1h
|
||
out 64h, al ;Write outputport
|
||
|
||
wait:
|
||
in al, 64h
|
||
and al, 02h ;Test if command came through
|
||
jnz wait
|
||
|
||
mov al, 01h
|
||
out 60h, al
|
||
|
||
|
||
4.2. Lay-Out
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
The keyboard first consisted of 83 keys, which is now known as the XT
|
||
keyboard. Then came along the AT-keyboard, which has 84 keys, a
|
||
slightly different layout and an extra SysReq key. The next keyboard is
|
||
the MF II keyboard. This one has 101 or 102 keys, and this is the one
|
||
this section will be babbling about.
|
||
|
||
The keycaps change, but the most popular settings are QWERTY and
|
||
AZERTY. Also popular is the Dvorak lay-out, made by what's-his-name
|
||
Dvorak, who made the lay-out so that both hands did not have to move
|
||
that much, resulting in fast (up to double) typing speed. This is it,
|
||
should you be interested (slight modifications by me, because it
|
||
actually requires a 12x4 keyboard):
|
||
|
||
101 - key 102 - key
|
||
|
||
~ ! @ # $ % ^ & * ( ) [ + ü ! @ # $ % ^ & * ( ) [ +
|
||
` 1 2 3 4 5 6 7 8 9 0 ] = ý 1 2 3 4 5 6 7 8 9 0 ] =
|
||
|
||
" , . P Y F G C R L ? { | " , . P Y F G C R L ? {
|
||
' , . p y f g c r l / } \ ' , . p y f g c r l / }
|
||
|
||
A O E U I D H T N S _ < A O E U I D H T N S _ ~
|
||
a o e u i d h t n s - > a o e u i d h t n s - `
|
||
|
||
: Q J K X B M W V Z > : Q J K X B M W V Z
|
||
; q j k x b m w v z < ; q j k x b m w v z
|
||
|
||
|
||
The key lay-out is as follows: (The numbers are internal to the
|
||
keyboard)
|
||
|
||
US-English Keyboard: 101 keys
|
||
-----------------------------
|
||
ÚÄÄ¿ÚÄÄÂÄÄÂÄÄÂÄÄ¿ÚÄÄÂÄÄÂÄÄÂÄÄ¿ÚÄÄÂÄÄÂÄÄÂÄÄ¿ÚÄÄÂÄÄÂÄÄ¿
|
||
³10³³12³13³14³15³³16³17³18³19³³20³21³22³23³³24³25³26³ <ÄÄ Add 100 to the
|
||
ÀÄÄÙÀÄÄÁÄÄÁÄÄÁÄÄÙÀÄÄÁÄÄÁÄÄÁÄÄÙÀÄÄÁÄÄÁÄÄÁÄÄÙÀÄÄÁÄÄÁÄÄÙ keycodes on
|
||
this line
|
||
ÚÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÄ¿ÚÄÄÂÄÄÂÄÄ¿ÚÄÄÂÄÄÂÄÄÄÂÄÄÄ¿
|
||
³1³ 2³ 3³ 4³ 5³ 6³ 7³ 8³ 9³10³11³12³13³ 15³³75³80³85³³90³95³100³105³
|
||
ÃÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÄ´ÃÄÄÅÄÄÅÄÄ´ÃÄÄÅÄÄÅÄÄÄÅÄÄÄ´
|
||
³16³17³18³19³20³21³22³23³24³25³26³27³28³29³³76³81³86³³91³96³101³ ³
|
||
ÃÄÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÄÄ´ÀÄÄÁÄÄÁÄÄÙÃÄÄÅÄÄÅÄÄÄ´ ³
|
||
³30 ³31³32³33³34³35³36³37³38³39³40³41³ 43 ³ ³92³97³102³106³
|
||
ÃÄÄÄÁÄÂÁÄÂÁÄÂÁÄÂÁÄÂÁÄÂÁÄÂÁÄÂÁÄÂÁÄÂÁÄÂÁÄÄÄÄ´ ÚÄÄ¿ ÃÄÄÅÄÄÅÄÄÄÅÄÄÄ´
|
||
³ 44 ³46³47³48³49³50³51³52³53³54³55³ 57 ³ ³83³ ³93³98³103³ ³
|
||
ÃÄÄÄÂÄÅÄÄÁÂÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÂÁÄÄÅÄÂÄÄÄ´ÚÄÄÅÄÄÅÄÄ¿ÃÄÄÁÄÄÅÄÄÄ´ ³
|
||
³58 ³ ³60 ³ 61 ³ 62³ ³ 64³³79³84³89³³ 99 ³104³108³
|
||
ÀÄÄÄÙ ÀÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÙ ÀÄÄÄÙÀÄÄÁÄÄÁÄÄÙÀÄÄÄÄÄÁÄÄÄÁÄÄÄÙ
|
||
|
||
|
|
||
This has the extra 29 key, or \
|
||
|
||
Other Countries: 102 keys
|
||
-------------------------
|
||
ÚÄÄ¿ÚÄÄÂÄÄÂÄÄÂÄÄ¿ÚÄÄÂÄÄÂÄÄÂÄÄ¿ÚÄÄÂÄÄÂÄÄÂÄÄ¿ÚÄÄÂÄÄÂÄÄ¿
|
||
³10³³12³13³14³15³³16³17³18³19³³20³21³22³23³³24³25³26³ <ÄÄ Add 100 to the
|
||
ÀÄÄÙÀÄÄÁÄÄÁÄÄÁÄÄÙÀÄÄÁÄÄÁÄÄÁÄÄÙÀÄÄÁÄÄÁÄÄÁÄÄÙÀÄÄÁÄÄÁÄÄÙ keycodes on
|
||
this line
|
||
ÚÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÄ¿ÚÄÄÂÄÄÂÄÄ¿ÚÄÄÂÄÄÂÄÄÄÂÄÄÄ¿
|
||
³1³ 2³ 3³ 4³ 5³ 6³ 7³ 8³ 9³10³11³12³13³ 15³³75³80³85³³90³95³100³105³
|
||
ÃÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÄ´ÃÄÄÅÄÄÅÄÄ´ÃÄÄÅÄÄÅÄÄÄÅÄÄÄ´
|
||
³16³17³18³19³20³21³22³23³24³25³26³27³28³43³³76³81³86³³91³96³101³ ³
|
||
ÃÄÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁÂÄÁ¿ ³ÀÄÄÁÄÄÁÄÄÙÃÄÄÅÄÄÅÄÄÄ´ ³
|
||
³30 ³31³32³33³34³35³36³37³38³39³40³41³42³ ³ ³92³97³102³106³
|
||
ÃÄÄÂÁÄÂÁÄÂÁÄÂÁÄÂÁÄÂÁÄÂÁÄÂÁÄÂÁÄÂÁÄÂÁÄÂÁÄÄÁÄ´ ÚÄÄ¿ ÃÄÄÅÄÄÅÄÄÄÅÄÄÄ´
|
||
³44³45³46³47³48³49³50³51³52³53³54³55³ 57 ³ ³83³ ³93³98³103³ ³
|
||
ÃÄÄÁÂÄÅÄÄÁÂÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÂÁÄÄÅÄÂÄÄÄ´ÚÄÄÅÄÄÅÄÄ¿ÃÄÄÁÄÄÅÄÄÄ´ ³
|
||
³58 ³ ³60 ³ 61 ³ 62³ ³ 64³³79³84³89³³ 99 ³104³108³
|
||
ÀÄÄÄÙ ÀÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÙ ÀÄÄÄÙÀÄÄÁÄÄÁÄÄÙÀÄÄÄÄÄÁÄÄÄÁÄÄÄÙ
|
||
|
||
This has the extra 42 and 45 keys. Their characters change from
|
||
country to country.
|
||
|
||
|
||
4.3. Scancodes
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
The AT-keyboard has 3 separate scancode settings: One as we know it,
|
||
(83 key-mapping, and added codes have an extra e0h added), one (almost)
|
||
sequential and one with ONE byte codes! Problem with the latter is that
|
||
only for lshift, caps, lctrl and lalt breakcodes are sent :-(. The
|
||
keyboard starts up in set 2, the set can be changed via port 64h (see
|
||
above).
|
||
|
||
In set 1 and 2, there are special codes, namely e0h and e1h. They are
|
||
used for keys that have the same function. An example: 1dh for the
|
||
left control key and e0h 1dh for the right one. This is done for
|
||
lowlevel compatibility with XT programs. Notice that the only time e1h
|
||
is used, is when it represents a temporary control key, which also has
|
||
a e0h version.
|
||
|
||
e0h 2ah is a temporary shift function, used by for example PrtScr,
|
||
which is in reality shift-numkeypad-*, like on the XT keyboard. See
|
||
below for further information.
|
||
|
||
The code will be sent as shown further. The codes listed are the make
|
||
codes. They are sent when a key is pressed. Upon release, the keyboard
|
||
sends a break code. It is the make code, but ORed with 80h. The only
|
||
exception to this are the codes e0h and e1h, which remain the same. So
|
||
for example pressing and releasing the right ctrl key would give e0h
|
||
1dh and e0h 9dh. I only give the codes for set 2 because the rest would
|
||
be too much work and stupid. If you want them, look them up yourself.
|
||
Modify any of the accompanying source codes or so...
|
||
|
||
ø Only on US-English keyboards
|
||
øø Only on other country versions
|
||
|
||
Scancodes are in hex.
|
||
|
||
Key Scan Key Scan Key Scan Key Scan Key Scan Key Scan
|
||
no. code no. code no. code no. code no. code no. code
|
||
ÄÄÄÄÂÄÄÄÄÄÒÄÄÄÄÂÄÄÄÄÄÒÄÄÄÄÂÄÄÄÄÄÒÄÄÄÄÂÄÄÄÄÄÒÄÄÄÄÂÄÄÄÄÄÒÄÄÄÄÂÄÄÄÄÄ
|
||
1 ³29 º19 ³12 º36 ³23 º53 ³33 º86 ³e0 51º106 ³4e
|
||
2 ³02 º20 ³13 º37 ³24 º54 ³34 º89 ³e0 4dº108 ³e0 1c
|
||
3 ³03 º21 ³14 º38 ³25 º55 ³35 º90 ³45 º110 ³01
|
||
4 ³04 º22 ³15 º39 ³26 º57 ³36 º91 ³47 º112 ³3b
|
||
5 ³05 º23 ³16 º40 ³27 º58 ³1d º92 ³4b º113 ³3c
|
||
6 ³06 º24 ³17 º41 ³28 º60 ³38 º93 ³4f º114 ³3d
|
||
7 ³07 º25 ³18 º42øø³2b º61 ³39 º95 ³e0 35º115 ³3e
|
||
8 ³08 º26 ³19 º43 ³1c º62 ³e0 38º96 ³48 º116 ³3f
|
||
9 ³09 º27 ³1a º44 ³2a º64 ³e0 1dº97 ³4c º117 ³40
|
||
10 ³0a º28 ³1b º45øø³56 º75 ³e0 52º98 ³50 º118 ³41
|
||
11 ³0b º29ø ³2b º46 ³2c º76 ³e0 53º99 ³52 º119 ³42
|
||
12 ³0c º30 ³3a º47 ³2d º79 ³e0 4bº100 ³37 º120 ³43
|
||
13 ³0d º31 ³1e º48 ³2e º80 ³e0 47º101 ³49 º121 ³44
|
||
15 ³0e º32 ³1f º49 ³2f º81 ³e0 4fº102 ³4d º122 ³57
|
||
16 ³0f º33 ³20 º50 ³30 º83 ³e0 48º103 ³51 º123 ³58
|
||
17 ³10 º34 ³21 º51 ³31 º84 ³e0 50º104 ³53 º124 ³(*)
|
||
18 ³11 º35 ³22 º52 ³32 º85 ³e0 49º105 ³4a º125 ³46
|
||
º126 ³(*)
|
||
|
||
(*)
|
||
Key 124, AKA PrtScr/SysRq, is both. When pressed normally, it will send
|
||
(hex) e0 2a e0 37. This is in fact a special shift-*, or the original
|
||
place of that code on the XT keyboard.
|
||
|
||
Used in conjuction with:
|
||
|
||
Normal: e0 2a e0 37
|
||
Shift : e0 37
|
||
Ctrl : e0 37
|
||
Alt : e0 54
|
||
|
||
Key 126: Pause/Break. On the XT keyboard, this used to be ctrl-NumLock
|
||
and ctrl-ScrollLock. Now guess the codes... Very special is that the
|
||
break codes are sent immediately after the make codes. I think that is
|
||
because the codes have odd length.
|
||
|
||
Normal: e1 1d 45 (e0 1d is already used by rightctrl)
|
||
Ctrl : e0 46 (46 is the code for ScrollLock...)
|
||
|
||
|
||
4.4. Int 9
|
||
ÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
When a key is pressed or released, or when the 8042 sends an ACK or NAK
|
||
the keyboard triggers IRQ1, or int 9. This can be masked by setting
|
||
bit 1 on port 21h, the interrupt controller. Int 9 gets the scancode,
|
||
translates it and puts it in the keyboard buffer.
|
||
|
||
BEWARE: When a scancode consists of more than 1 byte, it should be read
|
||
------ one byte per call. (Took me quite long to find out...)
|
||
|
||
Translating:
|
||
-----------
|
||
Int 9 will first call int 15h, subfunction 4fh, with the scancode in
|
||
al. If the scancode is legitimate, the carry flag is set, and al
|
||
contains the scancode. If not, the carry flag is reset, and int 9
|
||
stops. (The carries are picked so that if int 9 thinks the BIOS
|
||
supports the call and it doesn't, the carry is set by the BIOS, and the
|
||
scancode can always be used). This allows the keyboard to be redefined,
|
||
by taking over the function and replacing scancodes.
|
||
|
||
If you want to take over int 9, you must remember to let the interrupt
|
||
controller know when you are finished, by writing 20h to port 20h,
|
||
since this is a hardware interrupt. You should also disable and then
|
||
reenable the keyboard (see port 61h), so the keyboard knows you got the
|
||
code. The codes come in one byte per IRQ, so save e0hs.
|
||
|
||
The key will be translated by int 9, with the following special cases:
|
||
|
||
00h:
|
||
User is pressing too many keys at once: beep or something
|
||
|
||
aah, bah 41h, eeh, fah, feh:
|
||
Ignore it. Someone is playing with port 60h
|
||
|
||
fch, ffh:
|
||
Ditto, but now you know the keyboard is screwed up :)
|
||
|
||
e0h 2ah:
|
||
Well. If you let the keyboard decide what the NumLock state is
|
||
(nothing to do with the LED), use it to see how the code must be
|
||
translated (e0h 2ah: NumLock is on). Else, ignore. (Most Smart)
|
||
|
||
Ctrl-NumLock or Pause:
|
||
Place system in a tight wait loop until next key pressed. It would
|
||
be friendly to allow hardware IRQ's... (clock, comms etc) (I think)
|
||
|
||
Ctrl-Break:
|
||
Clear keyboard buffer (=Equal Head and Tail), place word 0000h in
|
||
buffer, invoke int 23h, and set flag at 0040h:0071h (bit 7=1).
|
||
|
||
Shift-PrtScr:
|
||
Invoke int 5
|
||
|
||
Ctrl-PrtScr:
|
||
redirect CON to PRN. (Teletype mode)
|
||
Never used it, perhaps never will. Doesn't work on my keyboard
|
||
driver... (DOS) Don't know how to stop it. Perhaps rehitting
|
||
Ctrl-PrtScr... This is from hearsay.
|
||
|
||
SysRq:
|
||
Invoke int 15 subfunction 85h. al->0 when pressed, 1 when released.
|
||
|
||
Ctrl-Alt-Del:
|
||
Reboot. Here's a sample of how to reboot:
|
||
|
||
mov ah,0Dh ; Disk Reset
|
||
int 21h ; causes SmartDrv 4.x to write cache
|
||
mov ax, 40h ; set up segment addressing
|
||
mov ds,ax
|
||
or byte ptr ds:[17h],0Ch ; equivalent of pressing CTRL+ALT
|
||
mov ax,4F53h ; Issue a "DEL" (53h = DEL scan code)
|
||
int 15h ; EMM386 sees this & shuts down
|
||
mov word ptr ds:[72h],1234h ; Set REBOOT flag to Warm-Boot (0=cold)
|
||
db 0EAh,0h,0h,0FFh,0FFh ; JMP FFFF:0000
|
||
|
||
Of course, the int 15h call should already have been done by the
|
||
handler. It is also used by other caches to flush.
|
||
|
||
Shift-numkeypad:
|
||
Temporarily reverse the NumLock state, e.g. 8 becomes arrow up and
|
||
vice versa.
|
||
|
||
Alt+numkeypad:
|
||
Make the pseudokey in BDA byte 19h until the alt is released, then
|
||
put it in the keyboard buffer. How? Well, everytime an extra number
|
||
comes in, multiply BDA:19h with 10 and add the new number.
|
||
|
||
Alt release:
|
||
See above. Just making sure it is implemented ;-)
|
||
|
||
Ctrl+a->z:
|
||
Send bytes 1 through 27
|
||
|
||
Foreign keyboards:
|
||
Some keys are accents, to be placed on the next key.
|
||
|
||
Right alt:
|
||
Some keys have three keys on it. To access them, the right alt is
|
||
pressed. So remember to send the right ASCII code...
|
||
|
||
NumLock:
|
||
Switch numkeypad on/off and light/switch off LED
|
||
|
||
CapsLock:
|
||
Translate normal letters to caps or vice versa and light/switch off
|
||
LED. A nice touch would be to have a distinction between CapsLock
|
||
and Ctrl-CapsLock. The former would shift alfabetic
|
||
keys only and the latter all keys...
|
||
|
||
ScrollLock:
|
||
Light/sw. off LED
|
||
|
||
Int 9 also has to adjust the BDA flags and keyboard buffer. In
|
||
addition, the driver should warn when the keyboard buffer is full.
|
||
|
||
|
||
5. Tech Stuff
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
Interface:
|
||
Bidirectional, serial synchronous. The keyboard communicates via
|
||
clock and data line with the system. The data comes in 11 bit
|
||
packets, namely start-data-parity-stop. Parity is uneven.
|
||
=1 8bit 1bit =0
|
||
Also, see further.
|
||
|
||
Data Format:
|
||
Data transfer to and from the keyboard in IBM-compatible format:
|
||
AT-, PS/2-mode: Idle state - "Data & Clock" high.
|
||
PC mode: Idle state - "Data" low, "Clock" high.
|
||
|
||
Data Output:
|
||
Open drain.
|
||
|
||
Keyboard Sequence:
|
||
Alpha-N-key-rollover.
|
||
|
||
Automatic repeat function:
|
||
All keys have auto repeat. Delay and repeat sequence can be
|
||
modified through the system, but is fixed for PC-mode. (10Hz after
|
||
500ms)
|
||
|
||
Keyboard Self-diagnostic test:
|
||
After "Power-On" or upon request, the keyboard carries out a
|
||
self-diagnostic test. After positive test, the keyboard sends AAh.
|
||
Any other is a failure.
|
||
|
||
Pin assignment:
|
||
___ 1 Clock
|
||
/524\ 2 Data
|
||
|3 1|Ä¿ 3 Not used
|
||
\_ï_/ ³chassis gnd 4 Gnd
|
||
- 5 +5V (This is the place to tap from :-)
|
||
|
||
PS/2 adaptor: 1 Data
|
||
_ _ 2 Not used
|
||
/5U6\ 3 Gnd
|
||
|3 4|Ä¿ 4 +5V
|
||
\1_2/ ³chassis gnd 5 Clock
|
||
- 6 Not used
|
||
|
||
The PC-XT keyboard communication protocol
|
||
-----------------------------------------
|
||
Below is a drawing of the timing of the data, send to the PC. The upper
|
||
line shows the clock line, the lower the data line. The text above
|
||
indicates the position of the start, data and stop bits (clocked on the
|
||
negative edge of the clock line).
|
||
|
||
|
||
Start 1 2 3 4 5 6 7 8 Stop
|
||
³ ³ ³ ³ ³ ³ ³ ³ ³ ³
|
||
ÄÄÄ¿ ÚÄÄ¿ ÚÄÄ¿ ÚÄÄ¿ ÚÄÄ¿ ÚÄÄ¿ ÚÄÄ¿ ÚÄÄ¿ ÚÄÄ¿ ÚÄÄ¿ ÚÄÄÄ
|
||
clkÀÄÄÙ ÀÄÄÙ ÀÄÄÙ ÀÄÄÙ ÀÄÄÙ ÀÄÄÙ ÀÄÄÙ ÀÄÄÙ ÀÄÄÙ ÀÄÄÙ
|
||
ÄÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄ¿ ÚÄ
|
||
dta ÀÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÙ
|
||
|
||
The communication abides to the following rules:
|
||
|
||
- On power up or reset, the PC pulls the clock line (normally high)
|
||
low for at least 20 ms. When it is released (goes high again),
|
||
the keyboard should send the code 0AAh to the PC to indicate its
|
||
existance.
|
||
|
||
- The data is clocked in on the negative edge of the clock signal.
|
||
The clock line must normally be high, the data line can be
|
||
anything between transmissions. The clock line is delayed two PC
|
||
clock cycles in the PC, so data changes and the negative clock
|
||
edge may take place at the same time. It is safer, however, to
|
||
build in a bigger delay.
|
||
|
||
- A transmission starts with a start bit (high). Then follow eight
|
||
data bits, of witch bit 7 (MSB) indicates the release of the key.
|
||
After that normally follows a stop bit (low), but that may be
|
||
left out. In fact, due to the shift register hardware inside the
|
||
PC, any number of stop bits could be send, as long as they are
|
||
low. Not 100% hardware compatibles, however, may get confused
|
||
then.
|
||
|
||
- After a transmission, the PC pulls the data line low until it is
|
||
ready processing the data. The keyboard should wait with sending
|
||
any more data until the PC releases the data line again.
|
||
|
||
|
||
A. Acknowledgments
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
This text was made by Wout Mertens, with the help of Tech Help of
|
||
Flambeaux software, the tech spex of Cherry and some texts I found.
|
||
|
||
Information on the PC-XT keyboard communication protocol and the
|
||
kbfunc.c file by Gertjan Klein (Floating somewhere in cyberspace).
|
||
|
||
Cherry is the registered trademark of Cherry Microschalter Gmbh etc.
|
||
IBM is the registered trademark of the IBM corporation
|
||
Mertens is the registered trademark of the Mertens Family ;-)
|
||
|
||
Improved copyright notice, thanks & greetings to:
|
||
Emil Gilliam (Floating in cyberspace as well)
|
||
Kip Cooley at the Diamond Bar BBS (909) 923-1031 (1:218/101).
|
||
Ian Remmler at the DownTown BBS (210) 625-4479 (1:387/1001).
|
||
|
||
|
||
B. How To Contact Me
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
Please let me know if something is inaccurate or missing etc. Also, I
|
||
would like some feedback on the quality and usability of this text.
|
||
(Keeps me writing...) If you think this text is very usefull, you can
|
||
always send me a nice postcard from where you live to thank me... I will
|
||
then try to notify you when a new version arrives.
|
||
|
||
I am usually reachable through the Fido 80XXX echo, but you can also
|
||
reach me at the following addresses:
|
||
|
||
Fido 2:292/805.1
|
||
SBC 14:1900/457
|
||
DGI 68:320/1.3
|
||
CDN 94:810/1104
|
||
CIN 112:913/101.4
|
||
|
||
SnailMail: Wout Mertens
|
||
Jozef de Bomstr 62
|
||
2018 Antwerp
|
||
Belgium - Europe
|
||
|
||
|
||
C. The Answer To Life, The Universe And All The Rest
|
||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
42.
|
||
|
||
PS: Could anyone tell me the Question?
|
||
|
||
(With thanks to Douglas Adams :-)
|
||
|
||
|
||
D. History
|
||
ÄÄÄÄÄÄÄÄÄÄ
|
||
|
||
20 feb 94: release of v1.0
|
||
5 apr 94: changed info on rebooting in int 9
|
||
added info about XT protocol, by Gertjan Klein
|
||
added C program to interface with keyboard, by Gertjan Klein
|
||
removed a bug in the copyright: Emil Gilliam was not to be
|
||
held liable :-):-):-)
|
||
removed some general typing errors
|
||
9 apr 94: removed bug in keyboard buffer info: Head and Tail do not
|
||
point to a location relative to Beginning, but instead
|
||
directly to the keyboardbuffer
|
||
23 may 94: v1.1
|
||
|
||
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||
³File passed thru : [ E X T A S Y ] ³ +49-(0)30-341-2912 ³
|
||
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ USR DUAL HST 16.8 ³
|
||
³ [x] Files passed CRC Test ³ ONLiNE 24 HOURS ³
|
||
³ [x] Files passed ViRUS Test ³ SYSOP : NIGHTHAWK ³
|
||
³ ³ /\/\/\/\/\/\/\/\/\/\/\/ ³
|
||
³ DIZ IZ AN -$CiENCE FRONTiER$- TOOL ³ MORE THAN 5 GiGS OF IBM ³
|
||
³ [ ADVANCED CHECKER GOLD ] ³ PUBLiC DOMAiN, SHARE- ³
|
||
³ written 1993/94 by Alien / SF ³ FREEWARE & SEXGiFS !!!! ³
|
||
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||
|
||
|