1 /************** 3-20-07 : KCW *************************
2 To demo a simple KBD driver: handle lower case ASCII key press only
5 handle shift keys; handle esc keys; add function keys
6 *********************************************************/
8 #define KEYBD 0x60 /* I/O port for keyboard data */
9 #define PORT_B 0x61 /* port_B of 8255 */
10 #define KBIT 0x80 /* bit used to ack characters to keyboard */
12 #define KBN 64 // size of input buffer in bytes
13 #define N_SCAN 105 /* Number of scan codes */
15 /* Scan codes to ASCII for unshifted keys; unused keys are left out */
16 char unshift
[N_SCAN
] = {
17 0,033,'1','2','3','4','5','6', '7','8','9','0','-','=','\b','\t',
18 'q','w','e','r','t','y','u','i', 'o','p','[',']', '\r', 0,'a','s',
19 'd','f','g','h','j','k','l',';', 0, 0, 0, 0,'z','x','c','v',
20 'b','n','m',',','.','/', 0,'*', 0, ' '
23 /* Scan codes to ASCII for shifted keys; unused keys are left out */
24 char shift
[N_SCAN
] = {
25 0,033,'!','@','#','$','%','^', '&','*','(',')','_','+','\b','\t',
26 'Q','W','E','R','T','Y','U','I', 'O','P','{','}', '\r', 0,'A','S',
27 'D','F','G','H','J','K','L',':', 0,'~', 0,'|','Z','X','C','V',
28 'B','N','M','<','>','?',0,'*', 0, ' '
32 int kbdata
= 0; // has KBD input flag
33 char kbc
; // data char
42 printf("kbinit done\n\r");
44 /************************************************************************
45 kbhandler() is the kbd interrupt handler. The kbd generates 2 interrupts
46 for each key typed; one when the key is pressed and another one when the
47 key is released. Each key generates a scan code. The scan code of a key
48 release is 0x80 + the scan code of key pressed. When the kbd interrupts,
49 the scan code is in the data port (0x60) of the KBD interface. First,
50 read the scan code from the data port. Then ack the key input by strobing
52 Some special keys generate ESC key sequences,e.g. arrow keys
53 Then process the scan code:
54 1. Normal key releases are ignored except for the spcecial keys of
55 0xE0, CAPLOCK, CONTROL, ALT, SHIFTs, which are used to set or clear
56 the status variables esc, control, alt, shift
58 2. For normal keys: translate into ASCII, depending on shifted or not.
59 3. ASCII keys are entered into a circular input buffer.
60 4. Sync between upper routines and lower routines is by P/V on semaphores
62 5. The input buffer contains RAW keys (may have \b). kgets()/ugets() cooks
63 the keys to weed out specail keys such as \b. So far only \b is handled.
64 Arrow keys are used only by sh for history. Each arrow key is immediately
65 made into a line to allow sh to get a line of inputs.
66 **************************************************************************/
72 /* Fetch the character from the keyboard hardware and acknowledge it. */
73 scode
= in_byte(KEYBD
); /* get the scan code of the key struck */
74 value
= in_byte(PORT_B
); /* strobe the keyboard to ack the char */
75 out_byte(PORT_B
, value
| KBIT
); /* first, strobe the bit high */
76 out_byte(PORT_B
, value
); /* then strobe it low */
78 //printf("kb interrupt %x\n", scode);
80 if (scode
& 0x80) // ignore key release
83 kbc
= unshift
[scode
]; // translate scan code into ASCII char
91 /********************** upper half rotuine ***********************/
101 unlock(); // mask in interrupt before looping
103 while(kbdata
==0); // busy loop waiting for kbdata = 1
112 /************************* KBD scan code info *****************************
114 US 104-key keyboard, set 1 scancodes
116 "Make" code is generated when key is pressed.
117 "Break" code is generated when key is released.
118 Hex value of make code for each key is shown.
121 one-byte make code = nn
122 one-byte repeat code = nn
123 one-byte break code = 80h + nn
125 "Gray" keys (not on original 84-key keyboard):
126 two-byte make code = E0nn
127 two-byte repeat code = E0nn
128 two-byte break code = E0 followed by 80h + nn
130 "Gray" keys noted by [1] are NumLock-sensitive.
131 When the keyboard's internal NumLock is active:
132 four-byte make code = E02AE0nn
133 two-byte repeat code = E0nn
134 four-byte break code = E0 followed by 80h + nn followed by E0AA
136 ____ ___________________ ___________________ ___________________
137 | | | | | | | | | | | | | | | | |
138 |Esc | |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10 |F11 |F12 |
139 | | | | | | | | | | | | | | | | |
140 | 01| | 3B| 3C| 3D| 3E| | 3F| 40| 41| 42| | 43| 44| 57| 58|
141 |____| |____|____|____|____| |____|____|____|____| |____|____|____|____|
143 __________________________________________________________________________
144 | | | | | | | | | | | | | | | |
145 |~ |! |@ |# |$ |% |^ |& |* |( |) |_ |+ || |bksp|
146 |` |1 |2 |3 |4 |5 |6 |7 |8 |9 |0 |- |= |\ | |
147 | 29| 02| 03| 04| 05| 06| 07| 08| 09| 0A| 0B| 0C| 0D| 2B| 0E|
148 |____|____|____|____|____|____|____|____|____|____|____|____|____|____|____|
149 | | | | | | | | | | | | | | |
150 |Tab |Q |W |E |R |T |Y |U |I |O |P |{ |} | |
151 | | | | | | | | | | | |[ |] | |
152 | 0F| 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 1A| 1B| |
153 |____|____|____|____|____|____|____|____|____|____|____|____|____| |
154 | | | | | | | | | | | | | |
155 |Caps|A |S |D |F |G |H |J |K |L |: |" | Enter |
156 | | | | | | | | | | |; |' | |
157 | 3A| 1E| 1F| 20| 21| 22| 23| 24| 25| 26| 27| 28| 1C|
158 |____|____|____|____|____|____|____|____|____|____|____|____|______________|
159 | | | | | | | | | | | | |
160 | L Shift |Z |X |C |V |B |N |M |< |> |? | R Shift |
161 | | | | | | | | |, |. |/ | |
162 | 2A| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 34| 35| 36|
163 |_________|____|____|____|____|____|____|____|____|____|____|______________|
165 |L Ctrl | L win | L Alt | space | R Alt | R win | menu |R Ctrl |
166 | |[1] | | | |[1] |[1] | |
167 | 1D| E05B| 38| 39| E038| E05C| E05D| E01D|
168 |_______|_______|_______|__________________|_______|_______|_______|_______|
171 [2] For PrintScreen/SysRq key: make code = E02AE037,
172 repeat code = E037, break code = E0B7E0AA
174 [3] The Pause/Break key does not repeat, and it does not
175 generate a break code. Its make code is E11D45E19DC5
184 ____ ____ ____ ____ ____ ____ ____
186 |Ins |Home|PgUp| |Num |/ |* |- |
187 |[1] |[1] |[1] | |Lock| | | |
188 |E052|E047|E049| | 45|E035| 37| 4A|
189 |____|____|____| |____|____|____|____|
191 |Del |End |PgDn| |7 |8 |9 | |
192 |[1] |[1] |[1] | |Home|(U) |PgUp| |
193 |E053|E04F|E051| | 47| 48| 49| |
194 |____|____|____| |____|____|____| |
199 ____ |____|____|____|____|
202 |[1] | |End |(D) |PgDn| |
203 |E048| | 4F| 50| 51|Ent |
204 ____|____|____ |____|____|____| |
206 |(L) |(D) |(R) | |0 |. | |
207 |[1] |[1] |[1] | |Ins |Del | |
208 |E04B|E050|E04D| | 52| 53|E01C|
209 |____|____|____| |_________|____|____|
212 code key code key code key code key
213 ---- --- ---- --- ---- --- ---- ---
214 01 Esc 0F Tab 1D L Ctrl 2B \|
222 09 8* 17 I 25 K 33 ,<
223 0A 9( 18 O 26 L 34 .>
224 0B 0) 19 P 27 ;: 35 /?
225 0C -_ 1A [{ 28 '" 36 R Shift
226 0D =+ 1B ]} 29 `~ 37 *
227 0E BackSpace 1C Enter 2A L Shift 38 L Alt
229 code key code key code key code key
230 ---- --- ---- --- ---- --- ---- ---
231 39 Space 41 F7 49 PageUp 9 51 PageDown 3
232 3A CapsLock 42 F8 4A - 52 Insert 0
233 3B F1 43 F9 4B (left) 4 53 Del .
235 3D F3 45 NumLock 4D (right) 6 57 F11
236 3E F4 46 ScrollLock 4E + 58 F12
237 3F F5 47 Home 7 4F End 1
238 40 F6 48 (up) 8 50 (down) 2
243 E01C Enter (on numeric keypad)
245 E02A make code prefix for keyboard internal numlock
246 E02AE037 PrintScreen make code
248 E037 PrintScreen repeat code
263 E0AA break code suffix for keyboard internal numlock
264 E0B7E0AA PrintScreen break code
266 *****************************************************************************/