OSDN Git Service

modified: Project 16.bfproject
[proj16/16.git] / 16 / PCGPE10 / KEYBOARD.TXT
1 \r
2                      ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\r
3                      ³ Programming the Keyboard ³\r
4                      ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
5 \r
6                  Written for the PC-GPE by Mark Feldman\r
7               e-mail address : u914097@student.canberra.edu.au\r
8                                myndale@cairo.anu.edu.au\r
9 \r
10              ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\r
11              ³      THIS FILE MAY NOT BE DISTRIBUTED     ³\r
12              ³ SEPARATE TO THE ENTIRE PC-GPE COLLECTION. ³\r
13              ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
14  \r
15 \r
16 ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
17 ³ Disclaimer ³\r
18 ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
19 \r
20 I assume no responsibility whatsoever for any effect that this file, the\r
21 information contained therein or the use thereof has on you, your sanity,\r
22 computer, spouse, children, pets or anything else related to you or your\r
23 existance. No warranty is provided nor implied with this information.\r
24 \r
25 ÚÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
26 ³ Overview ³\r
27 ÀÄÄÄÄÄÄÄÄÄÄÙ\r
28 \r
29 The operation of the keyboard is really quite simple. Every time a key\r
30 is pressed or released an interrupt 9 is generated, and reading the value\r
31 from port 60h tells you what happened.\r
32 \r
33 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
34 ³ Decoding the Keyboard Byte ³\r
35 ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
36 \r
37 So let's say you've installed an interrupt handler to handle all keyboard\r
38 events and when an interrupt is generated your handler reads the byte from\r
39 port 60h. What now?\r
40 \r
41 Well..each key on the keyboard has an associated scan code which is contained\r
42 in the lower 7 bits of the byte. The most significant bit (ie bit 7) tells\r
43 you what was actually done, 0 = key was just pressed, 1 = key was just\r
44 released. If someone had just pressed the ESC key for instance, the port will\r
45 show a value of 1 (1 is the ESC key's scan code). If they hold their finger\r
46 on the button the keyboard will keep generating interrupt 9's and each\r
47 time the port will still show a value of 1. When the person releases the key\r
48 a final interrupt will be generated and the port will return 129 (1 + 128,\r
49 since the high bit will be set indicating the person has released the key).\r
50 \r
51 Well...it's almost this simple. Some keys are "extended" keys. When an\r
52 extended key is pressed an interrupt is generated and the keyboard port\r
53 will return a value of 224 (E0h). This means that an extended key was pressed\r
54 and it's *extended* scan code will be available during the *next* interrupt.\r
55 Note that the left control key has a scan code of 29, while the *right*\r
56 control key has an *extended* scan code of 29. The same applies to the alt\r
57 keys and the arrow keys (keypad arrows vs the other ones).\r
58 \r
59 It would be nice if all keys were created equal and we could just throw away\r
60 the 224 extended bytes and handle all the other bytes normally. Unfortunately\r
61 there are two buttons which on my machine at least (and others I have tested)\r
62 do some really weird stuff:\r
63 \r
64 PrtScn\r
65 ÄÄÄÄÄÄ\r
66 Pressing this button will send *2* extended characters to the handler, 42\r
67 and 55, so the actual byte sequence will be 224, 42, 224, 55. (Also note\r
68 that the left shift key has a regular scan code of 42, so there goes our\r
69 idea of just throwing 224's away). Only the extended 55's are sent during\r
70 auto-repeat. When the key is released, the two are sent again with the high\r
71 bits set (224, 170, 224, and 183). If any of the shift or control keys are\r
72 being held down when the PrtScn button is pressed then only the (224, 55) is\r
73 sent when the key is pressed and only the (224, 183) is sent when it's\r
74 released. If the alt key is being held down (System Request) then the key\r
75 behaves like an ordinary key with scan code 84. The practical upshot of all\r
76 this is that the handlers you write to handle normal keys and extended keys\r
77 will work fine with all the different PrtScn combinations (although a program\r
78 would have to check normal key 84 *AND* extended key 55 in order to determine\r
79 if the key is currently being pressed).\r
80 \r
81 Pause/Break\r
82 ÄÄÄÄÄÄÄÄÄÄÄ\r
83 Welcome to hell. If you press this key while either of the the control keys\r
84 are being held down, it will behave like extended key 70, at all other times\r
85 it will send the following bytes: (225, 29, 69, 225, 157, 197). Holding the\r
86 key down does not result in autorepeat. Taking your finger off the key does\r
87 not send any extra bytes, they appear to be sent after the "key down" bytes\r
88 when you first press the key. Notice that 225 isn't 224, so our normal\r
89 extended character handler will not take care of this. My personal theory is\r
90 that while a scan code of 224 (E0h) means there is 1 more character\r
91 following, a scan code of 225 (E1h) means there are *2* more following. I've\r
92 seen a number of keyboard handler libraries and they all seem to overlook\r
93 this key. So why not be the first kid on your block to have a keyboard\r
94 handler which properly supports the Pause/Break key? CHECK IT OUT!!\r
95 \r
96 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
97 ³ Writing a Handler ³\r
98 ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
99 \r
100 Writing a keyboard handler is fairly straightforward. This section will\r
101 show how to do it in Pascal (you C and asm programmers would probably already\r
102 know this stuff anyway).\r
103 \r
104 First we'll declare a few things we'll need:\r
105 \r
106 const KEYBOARDINTR = 9;\r
107       KEYBOARDPORT = $60;\r
108 \r
109 var BIOSKeyboardHandler : procedure;\r
110     CallBIOSHandler : boolean;\r
111 \r
112 The CallBIOSHandler variable will be initialised by the calling program. If\r
113 we also want the BIOS handler to process all keystrokes then this variable\r
114 must be set to true.\r
115 \r
116 Next we need to store the value of the current handler and set up own our\r
117 own one. We'll use a procedure called KeyboardHandler to handle the actual\r
118 interrupt.\r
119 \r
120 CallBIOSHandler := false; { ...or set it to true if you want. }\r
121 GetIntVec(KEYBOARDINTR, @BIOSKeyboardHandler);\r
122 SetIntVec(KEYBOARDINTR, Addr(KeyboardHandler));\r
123 \r
124 Ok, so everything is now set up and our handler will now be able to process\r
125 all keyboard events. The actual interrupt handler could look like this:\r
126 \r
127 {$F+}\r
128 procedure KeyboardHandler(Flags, CS, IP, AX, BX, CX, DX,\r
129                           SI, DI, DS, ES, BP: Word);\r
130 interrupt;\r
131 var key : byte;\r
132 begin\r
133 \r
134   key := Port[KEYBOARDPORT];\r
135 \r
136   { PROCESS THE KEYSTROKE HERE }\r
137 \r
138   if CallBIOSHandler then\r
139 \r
140   { Call the BIOS keyboard handler if the calling program wants us to }\r
141     begin\r
142       asm pushf end;\r
143       BIOSKeyboardHandler;\r
144     end\r
145 \r
146   { Otherwise just acknowledge the interrupt }\r
147   else Port[$20] := $20;\r
148 end;\r
149 {$F-}\r
150 \r
151 \r
152 When the program is finished we can set the old keyboard handler again:\r
153 \r
154 SetIntVec(KEYBOARDINTR, @BIOSKeyboardHandler);\r
155 \r
156 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
157 ³ A Word of Warning ³\r
158 ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
159 \r
160 When I was writing a simple handler to test the info in this file I did\r
161 something REALLY stoopid which I would like to share with the world. I\r
162 thought that my program was stuffing the keyboard up because when I exited\r
163 the program my editor (Borland Pascal 7.0) would act as though the control\r
164 button was being held down (I'm sure some of you have already started\r
165 laughing by now). I had to press it after each time I ran the program\r
166 just to sort it out. After spending a few hours looking all over the place\r
167 for info on what could possibly be wrong I realised what I was doing. I was\r
168 pressing CTRL-F9 to compile the program which would also immediately make it\r
169 run and I was releasing the control key when my program was running, ie the\r
170 regular BIOS handler was not getting the control key's "key up" command and\r
171 still thought it was being held down when my program returned control to\r
172 it. Moron.....\r
173 \r
174 ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
175 ³ Scan Codes ³\r
176 ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
177 \r
178 The following is a list of all the regular key scan codes in numerical\r
179 order:\r
180 \r
181 Scan                                   Scan\r
182 Code Key                               Code Key\r
183 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ             ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
184  1   ESC                               44   Z\r
185  2   1                                 45   X\r
186  3   2                                 46   C\r
187  4   3                                 47   V\r
188  5   4                                 48   B\r
189  6   5                                 49   N\r
190  7   6                                 50   M\r
191  8   7                                 51   , <\r
192  9   8                                 52   . >\r
193 10   9                                 53   / ?\r
194 11   0                                 54   RIGHT SHIFT\r
195 12   - _                               55   *            (KEYPAD)\r
196 13   = +                               56   LEFT ALT\r
197 14   BACKSPACE                         57   SPACEBAR\r
198 15   TAB                               58   CAPSLOCK\r
199 16   Q                                 59   F1\r
200 17   W                                 60   F2\r
201 18   E                                 61   F3\r
202 19   R                                 62   F4\r
203 20   T                                 63   F5\r
204 21   Y                                 64   F6\r
205 22   U                                 65   F7\r
206 23   I                                 66   F8\r
207 24   O                                 67   F9\r
208 25   P                                 68   F10\r
209 26   [ {                               69   NUMLOCK      (KEYPAD)\r
210 27   ] }                               70   SCROLL LOCK\r
211 28   ENTER (RETURN)                    71   7 HOME       (KEYPAD)\r
212 29   LEFT CONTROL                      72   8 UP         (KEYPAD)\r
213 30   A                                 73   9 PGUP       (KEYPAD)\r
214 31   S                                 74   -            (KEYPAD)\r
215 32   D                                 75   4 LEFT       (KEYPAD)\r
216 33   F                                 76   5            (KEYPAD)\r
217 34   G                                 77   6 RIGHT      (KEYPAD)\r
218 35   H                                 78   +            (KEYPAD)\r
219 36   J                                 79   1 END        (KEYPAD)\r
220 37   K                                 80   2 DOWN       (KEYPAD)\r
221 38   L                                 81   3 PGDN       (KEYPAD)\r
222 39   ; :                               82   0 INSERT     (KEYPAD)\r
223 40   ' "                               83   . DEL        (KEYPAD)\r
224 41   ` ~                               87   F11\r
225 42   LEFT SHIFT                        88   F12\r
226 \r
227 \r
228 The following is a list of all the extended key scan codes in numerical\r
229 order:\r
230 \r
231 Scan                                   Scan\r
232 Code Key                               Code Key\r
233 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ        ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
234 28   ENTER        (KEYPAD)              75   LEFT         (NOT KEYPAD)\r
235 29   RIGHT CONTROL                      77   RIGHT        (NOT KEYPAD)\r
236 42   PRINT SCREEN (SEE TEXT)            79   END          (NOT KEYPAD)\r
237 53   /            (KEYPAD)              80   DOWN         (NOT KEYPAD)\r
238 55   PRINT SCREEN (SEE TEXT)            81   PAGE DOWN    (NOT KEYPAD)\r
239 56   RIGHT ALT                          82   INSERT       (NOT KEYPAD)\r
240 71   HOME         (NOT KEYPAD)          83   DELETE       (NOT KEYPAD)\r
241 72   UP           (NOT KEYPAD)         111   MACRO\r
242 73   PAGE UP      (NOT KEYPAD)\r
243 \r