]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/drivers/keyb-pc.cpp
update
[l4.git] / kernel / fiasco / src / drivers / keyb-pc.cpp
1 INTERFACE:
2
3 /**
4  * Implementation for PC keyboards.
5  */
6 EXTENSION class Keyb
7 {
8 private:
9
10   enum {
11     /*
12      * Keyboard I/O ports.
13      */
14     K_RDWR          =0x60, /* keyboard data & cmds (read/write) */
15     K_STATUS        =0x64, /* keybd status (read-only) */
16     K_CMD           =0x64, /* keybd ctlr command (write-only) */
17     
18     /*
19      * Bit definitions for K_STATUS port.
20      */
21     K_OBUF_FUL      =0x01, /* output (from keybd) buffer full */
22     K_IBUF_FUL      =0x02, /* input (to keybd) buffer full */
23     K_SYSFLAG       =0x04, /* "System Flag" */
24     K_CMD_DATA      =0x08, /* 1 = input buf has cmd, 0 = data */
25     K_KBD_INHIBIT   =0x10, /* 0 if keyboard inhibited */
26     K_AUX_OBUF_FUL  =0x20, /* 1 = obuf holds aux device data */
27     K_TIMEOUT       =0x40, /* timout error flag */
28     K_PARITY_ERROR  =0x80, /* parity error flag */
29     
30     /* 
31      * Keyboard controller commands (sent to K_CMD port).
32      */
33     KC_CMD_READ     =0x20, /* read controller command byte */
34     KC_CMD_WRITE    =0x60, /* write controller command byte */
35     KC_CMD_DIS_AUX  =0xa7, /* disable auxiliary device */
36     KC_CMD_ENB_AUX  =0xa8, /* enable auxiliary device */
37     KC_CMD_TEST_AUX =0xa9, /* test auxiliary device interface */
38     KC_CMD_SELFTEST =0xaa, /* keyboard controller self-test */
39     KC_CMD_TEST     =0xab, /* test keyboard interface */
40     KC_CMD_DUMP     =0xac, /* diagnostic dump */
41     KC_CMD_DISABLE  =0xad, /* disable keyboard */
42     KC_CMD_ENABLE   =0xae, /* enable keyboard */
43     KC_CMD_RDKBD    =0xc4, /* read keyboard ID */
44     KC_CMD_WIN      =0xd0, /* read  output port */
45     KC_CMD_WOUT     =0xd1, /* write output port */
46     KC_CMD_ECHO     =0xee, /* used for diagnostic testing */
47     KC_CMD_PULSE    =0xff, /* pulse bits 3-0 based on low nybble */
48     
49     /* 
50      * Keyboard commands (send to K_RDWR).
51      */
52     K_CMD_LEDS      =0xed, /* set status LEDs (caps lock, etc.) */
53     
54     /* 
55      * Bit definitions for controller command byte (sent following 
56      * K_CMD_WRITE command).
57      */
58     K_CB_ENBLIRQ    =0x01, /* enable data-ready intrpt */
59     K_CB_SETSYSF    =0x04, /* Set System Flag */
60     K_CB_INHBOVR    =0x08, /* Inhibit Override */
61     K_CB_DISBLE     =0x10, /* disable keyboard */
62     
63     /* 
64      * Bit definitions for "Indicator Status Byte" (sent after a 
65      * K_CMD_LEDS command).  If the bit is on, the LED is on.  Undefined 
66      * bit positions must be 0.
67      */
68     K_LED_SCRLLK    =0x1, /* scroll lock */
69     K_LED_NUMLK     =0x2, /* num lock */
70     K_LED_CAPSLK    =0x4, /* caps lock */
71     
72     /* 
73      * Bit definitions for "Miscellaneous port B" (K_PORTB).
74      */
75     /* read/write */
76     K_ENABLETMR2    =0x01, /* enable output from timer 2 */
77     K_SPKRDATA      =0x02, /* direct input to speaker */
78     K_ENABLEPRTB    =0x04, /* "enable" port B */
79     K_EIOPRTB       =0x08, /* enable NMI on parity error */
80     /* read-only */
81     K_REFRESHB      =0x10, /* refresh flag from INLTCONT PAL */
82     K_OUT2B         =0x20, /* timer 2 output */
83     K_ICKB          =0x40, /* I/O channel check (parity error) */
84     
85     /*
86      * Bit definitions for the keyboard controller's output port.
87      */
88     KO_SYSRESET     =0x01, /* processor reset */
89     KO_GATE20       =0x02, /* A20 address line enable */
90     KO_AUX_DATA_OUT =0x04, /* output data to auxiliary device */
91     KO_AUX_CLOCK    =0x08, /* auxiliary device clock */
92     KO_OBUF_FUL     =0x10, /* keyboard output buffer full */
93     KO_AUX_OBUF_FUL =0x20, /* aux device output buffer full */
94     KO_CLOCK        =0x40, /* keyboard clock */
95     KO_DATA_OUT     =0x80, /* output data to keyboard */
96   };
97   
98
99 };
100
101 IMPLEMENTATION[pc]:
102
103 #include "processor.h"
104 #include "io.h"
105
106 enum {
107   SHIFT = 0xff,
108 };
109
110 static const unsigned char keymap[][2] = {
111   {0       },           /* 0 */
112   {27,  27 },           /* 1 - ESC */
113   {'1', '!'},           /* 2 */
114   {'2', '@'},
115   {'3', '#'},
116   {'4', '$'},
117   {'5', '%'},
118   {'6', '^'},
119   {'7', '&'},
120   {'8', '*'},
121   {'9', '('},
122   {'0', ')'},
123   {'-', '_'},
124   {'=', '+'},
125   {8,   8  },           /* 14 - Backspace */
126   {'\t','\t'},          /* 15 */
127   {'q', 'Q'},
128   {'w', 'W'},
129   {'e', 'E'},
130   {'r', 'R'},
131   {'t', 'T'},
132   {'y', 'Y'},
133   {'u', 'U'},
134   {'i', 'I'},
135   {'o', 'O'},
136   {'p', 'P'},
137   {'[', '{'},
138 // {']','}'},           /* 27 */
139   {'+', '*'},           /* 27 */
140   {'\r','\r'},          /* 28 - Enter */
141   {0,   0  },           /* 29 - Ctrl */
142   {'a', 'A'},           /* 30 */
143   {'s', 'S'},
144   {'d', 'D'},
145   {'f', 'F'},
146   {'g', 'G'},
147   {'h', 'H'},
148   {'j', 'J'},
149   {'k', 'K'},
150   {'l', 'L'},
151   {';', ':'},
152   {'\'','"'},           /* 40 */
153   {'`', '~'},           /* 41 */
154   {SHIFT, SHIFT},       /* 42 - Left Shift */
155   {'\\','|'},           /* 43 */
156   {'z', 'Z'},           /* 44 */
157   {'x', 'X'},
158   {'c', 'C'},
159   {'v', 'V'},
160   {'b', 'B'},
161   {'n', 'N'},
162   {'m', 'M'},
163   {',', '<'},
164   {'.', '>'},
165 // {'/', '?'},          /* 53 */
166   {'-', '_'},           /* 53 */
167   {SHIFT, SHIFT},       /* 54 - Right Shift */
168   {0,    0},            /* 55 - Print Screen */
169   {0,    0},            /* 56 - Alt */
170   {' ',' '},            /* 57 - Space bar */
171   {0,    0},            /* 58 - Caps Lock */
172   {0,    0},            /* 59 - F1 */
173   {0,    0},            /* 60 - F2 */
174   {0,    0},            /* 61 - F3 */
175   {0,    0},            /* 62 - F4 */
176   {0,    0},            /* 63 - F5 */
177   {0,    0},            /* 64 - F6 */
178   {0,    0},            /* 65 - F7 */
179   {0,    0},            /* 66 - F8 */
180   {0,    0},            /* 67 - F9 */
181   {0,    0},            /* 68 - F10 */
182   {0,    0},            /* 69 - Num Lock */
183   {0,    0},            /* 70 - Scroll Lock */
184   {0xb7,0xb7},          /* 71 - Numeric keypad 7 */
185   {0xb8,0xb8},          /* 72 - Numeric keypad 8 */
186   {0xb9,0xb9},          /* 73 - Numeric keypad 9 */
187   {'-', '-'},           /* 74 - Numeric keypad '-' */
188   {0xb4,0xb4},          /* 75 - Numeric keypad 4 */
189   {0xb5,0xb5},          /* 76 - Numeric keypad 5 */
190   {0xb6,0xb6},          /* 77 - Numeric keypad 6 */
191   {'+', '+'},           /* 78 - Numeric keypad '+' */
192   {0xb1,0xb1},          /* 79 - Numeric keypad 1 */
193   {0xb2,0xb2},          /* 80 - Numeric keypad 2 */
194   {0xb3,0xb3},          /* 81 - Numeric keypad 3 */
195   {0xb0,0xb0},          /* 82 - Numeric keypad 0 */
196   {0xae,0xae},          /* 83 - Numeric keypad '.' */
197 };
198
199
200 IMPLEMENT
201 int Keyb::getchar(bool wait)
202 {
203   static unsigned shift_state;
204   unsigned status, scan_code, ch;
205   Proc::Status old_s = Proc::cli_save();
206
207   for (;;)
208     {
209       /* Wait until a scan code is ready and read it. */
210       status = Io::in8(0x64);
211       if ((status & K_OBUF_FUL) == 0)
212         {
213           if (wait)
214             continue;
215           Proc::sti_restore(old_s);
216           return -1;
217         }
218       scan_code = Io::in8(0x60);
219
220       /* Drop mouse events */
221       if ((status & K_AUX_OBUF_FUL) != 0)
222         {
223           if (wait)
224             continue;
225           Proc::sti_restore(old_s);
226           return -1;
227         }
228
229       if ((scan_code & 0x7f) >= sizeof(keymap)/sizeof(keymap[0]))
230         continue;
231
232       /* Handle key releases - only release of SHIFT is important. */
233       if (scan_code & 0x80)
234         {
235           scan_code &= 0x7f;
236           if (keymap[scan_code][0] == SHIFT)
237             shift_state = 0;
238           continue;
239         }
240
241       /* Translate the character through the keymap. */
242       ch = keymap[scan_code][shift_state];
243       if (ch == (unsigned)SHIFT)
244         {
245           shift_state = 1;
246           continue;
247         }
248       if (ch == 0)
249         continue;
250       
251       Proc::sti_restore(old_s);
252       return ch;
253     }
254 }