2 * this is the program that i don't wanna write most.
3 * there are even some mistakes, such as when CAPS_LOCK
4 * is on, i just put it in the SHIFT case, so mistakes
5 * happens, saying i press the 1 he will put the '!',
6 * yeah, that's realy and simply equal to the SHIFT case.
8 * what it can't do also is it can't handle when the CAPS
9 * Lock and SHIFT key press both present. And we only can ues
10 * the PAD key by CAPS_LOCK or by SHIFT key. Really ugly. but
11 * i don't wanna do any work on it.
13 * Maybe i will correct it in furture when i'm free and
14 * with the passion that swearing to correct it or even re-
19 * Aleaxander, 2007-2008
20 * Aleaxander@gmail.com
25 * Altough it makes mistakes, but i am happy that it can handle
26 * the regular things like move the cursor left,right..., it also
27 * can move the start of line (HOME) or the end of a line(END).
28 * and what the most important is you can move it anywhere you like.
33 #include <asm/system.h>
38 static unsigned char scancode
;
39 //static unsigned char brkflag;
40 static unsigned char mode
= 0;
41 static unsigned char e0
= 2; /* num lock is opened by default */
42 static unsigned char key
;
43 static unsigned char leds
;
44 //static unsigned char shift;
46 static void kb_wait(void);
47 extern void con_write(char *, int);
51 static unsigned char normal_map
[256] =
53 NO
, 0x1B, '1', '2', '3', '4', '5', '6', // 0x00
54 '7', '8', '9', '0', '-', '=', '\b', '\t',
55 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', // 0x10
56 'o', 'p', '[', ']', '\n', NO
, 'a', 's',
57 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', // 0x20
58 '\'', '`', NO
, '\\', 'z', 'x', 'c', 'v',
59 'b', 'n', 'm', ',', '.', '/', NO
, '*', // 0x30
60 NO
, ' ', NO
, NO
, NO
, NO
, NO
, NO
,
61 NO
, NO
, NO
, NO
, NO
, NO
, NO
, HOME
, // 0x40
62 UP
, PGUP
, '-', LF
, '5', RT
, '+', END
,
63 DN
, PGDN
, INS
, DEL
, NO
, NO
, NO
, NO
, // 0x50
65 [0x9C] '\n', // KP_Enter
78 static unsigned char shift_map
[256] = {
79 NO
, 033, '!', '@', '#', '$', '%', '^', // 0x00
80 '&', '*', '(', ')', '_', '+', '\b', '\t',
81 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', // 0x10
82 'O', 'P', '{', '}', '\n', NO
, 'A', 'S',
83 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', // 0x20
84 '"', '~', NO
, '|', 'Z', 'X', 'C', 'V',
85 'B', 'N', 'M', '<', '>', '?', NO
, '*', // 0x30
86 NO
, ' ', NO
, NO
, NO
, NO
, NO
, NO
,
87 NO
, NO
, NO
, NO
, NO
, NO
, NO
, '7', // 0x40
88 '8', '9', '-', '4', '5', '6', '+', '1',
89 '2', '3', '0', '.', NO
, NO
, NO
, NO
, // 0x50
91 [0x9C] '\n', // KP_Enter
104 #define C(x) (x - '@')
106 static unsigned char ctl_map
[256] = {
107 NO
, NO
, NO
, NO
, NO
, NO
, NO
, NO
,
108 NO
, NO
, NO
, NO
, NO
, NO
, NO
, NO
,
109 C('Q'), C('W'), C('E'), C('R'), C('T'), C('Y'), C('U'), C('I'),
110 C('O'), C('P'), NO
, NO
, '\r', NO
, C('A'), C('S'),
111 C('D'), C('F'), C('G'), C('H'), C('J'), C('K'), C('L'), NO
,
112 NO
, NO
, NO
, C('\\'), C('Z'), C('X'), C('C'), C('V'),
113 C('B'), C('N'), C('M'), NO
, NO
, C('/'), NO
, NO
,
115 [0xB5] C('/'), // KP_Div
128 extern void parse_command (char *);
129 static int index
= 0;
130 char command_buffer
[512] = {'\0',};
134 static void pln(void)
143 if ((mode
& (RSHIFT
| LSHIFT
)) || (leds
& CAPS_LOCK
))
147 key
= *(map
+ scancode
);
149 /* I have no meaning of the following code, so just ignore it */
151 if (mode
& (LCTRL
| RCTRL
| CAPS_STATE
))
152 if (key
>= 'a' && key
<= '}')
154 if (mode
& (LCTRL
| RCTRL
))
155 if (key
>= 64 && key
<= 64 + 26)
162 command_buffer
[index
] = '\0';
175 command_buffer
[index
] = (char)key
;
179 con_write((char *)&key
,1);
186 parse_command (command_buffer
);
187 memset(command_buffer
, '\0', index
);
195 static void unp(void)
197 /* Just do nothing */
200 static void ctl(void)
211 static void alt(void)
222 static void sft(void)
225 if (scancode
== 0x36)
229 static void unshift(void)
231 if (scancode
== 0xAA)
233 else if (scancode
== 0xB6)
237 static void cur(void)
239 /*Not implemented yet*/
242 static void set_leds(void)
245 outb(0xed, 0x60); /* set leds command */
247 outb(leds
, 0x60); /* send param */
250 static void sroll(void)
256 static void num_lock(void)
262 static void cap(void)
268 static void kb_wait(void)
270 while (inb(0x64) & 0x02)
274 static void fun(void)
296 void (*kfun_table
[0x80])(void) = {
297 /* 0/8 1/9 2/a 3/b 4/c 5/d 6/e 7/f */
298 /*00*/unp
, unp
, pln
, pln
, pln
, pln
, pln
, pln
,
299 /* */pln
, pln
, pln
, pln
, pln
, pln
, pln
, pln
,
300 /*10*/pln
, pln
, pln
, pln
, pln
, pln
, pln
, pln
,
301 /* */pln
, pln
, pln
, pln
, pln
, ctl
, pln
, pln
,
302 /*20*/pln
, pln
, pln
, pln
, pln
, pln
, pln
, pln
,
303 /* */pln
, pln
, sft
, pln
, pln
, pln
, pln
, pln
,
304 /*30*/pln
, pln
, pln
, pln
, pln
, pln
, sft
, pln
,
305 /* */alt
, pln
, cap
, fun
, fun
, fun
, fun
, fun
,
306 /*40*/fun
, fun
, fun
, fun
, fun
, unp
, unp
, pln
,
307 /* */pln
, pln
, pln
, unp
, pln
, pln
, pln
, pln
,
308 /*50*/pln
, pln
, pln
, pln
, unp
, unp
, unp
, fun
,
309 /* */fun
, unp
, unp
, unp
, unp
, unp
, unp
, unp
,
310 /*60*/unp
, unp
, unp
, unp
, unp
, unp
, unp
, unp
,
311 /* */unp
, unp
, unp
, unp
, unp
, unp
, unp
, unp
,
312 /*70*/unp
, unp
, unp
, unp
, unp
, unp
, unp
, unp
,
313 /* */unp
, unp
, unp
, unp
, unp
, unp
, unp
, unp
,
318 /* looks like not works */
319 void wait_for_keypress()
325 while ( (code
== '\0') || (code
& 0x80) )
329 void keyboard_interrupt ()
336 scancode
= inb(0x60);
340 if (scancode
== 0xAA || scancode
== 0xB6) {
345 if (scancode
== 0x2A || scancode
== 0x36) {
350 if (scancode
== 0x3A || scancode
== 0xB6) {
356 * I don't know why i need hanle the left move here,
357 * may just because i don't know why the origin handle
358 * can't work! what a sham day
360 * And what make happy is that it works now! greate work.
362 if (scancode
== 0x4b) {
364 con_write((char *)&scancode
, 1);
369 /* we haven't implenmented the ESC codes now */
371 if (scancode
== 0xe0) {
375 /* we must reset the e0 later */
376 if (e0
== 1 && scancode
& 0x80) {
384 (*kfun_table
[scancode
&0x7f])();
385 /* key stroke has been handled */
388 outb((com
=inb(0x61))|0x80, 0x61); /* disable it */
389 outb(com
&0x7f, 0x61); /* enable it again */
390 outb(0x20, 0x20); /* EOI */
394 void keyboard_init ()
396 set_trap_gate(0x21,keyboard_interrupt
);
397 outb(inb(0x21)&0xfd, 0x21);