Sync trunk.
[reactos.git] / boot / armllb / hw / keyboard.c
1 /*
2 * PROJECT: ReactOS Boot Loader
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: boot/armllb/hw/keyboard.c
5 * PURPOSE: LLB Keyboard Routines
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 #include "precomp.h"
10
11 #define E0_KPENTER 96
12 #define E0_RCTRL 97
13 #define E0_KPSLASH 98
14 #define E0_PRSCR 99
15 #define E0_RALT 100
16 #define E0_BREAK 101
17 #define E0_HOME 102
18 #define E0_UP 103
19 #define E0_PGUP 104
20 #define E0_LEFT 105
21 #define E0_RIGHT 106
22 #define E0_END 107
23 #define E0_DOWN 108
24 #define E0_PGDN 109
25 #define E0_INS 110
26 #define E0_DEL 111
27 #define E1_PAUSE 119
28 #define E0_MACRO 112
29 #define E0_F13 113
30 #define E0_F14 114
31 #define E0_HELP 115
32 #define E0_DO 116
33 #define E0_F17 117
34 #define E0_KPMINPLUS 118
35 #define E0_OK 124
36 #define E0_MSLW 125
37 #define E0_MSRW 126
38 #define E0_MSTM 127
39
40 /* US 101 KEYBOARD LAYOUT *****************************************************/
41
42 CHAR LlbHwScanCodeToAsciiTable[58][2] =
43 {
44 { 0,0 } ,
45 { 27, 27 } ,
46 { '1','!' } ,
47 { '2','@' } ,
48 { '3','#' } ,
49 { '4','$' } ,
50 { '5','%' } ,
51 { '6','^' } ,
52 { '7','&' } ,
53 { '8','*' } ,
54 { '9','(' } ,
55 { '0',')' } ,
56 { '-','_' } ,
57 { '=','+' } ,
58 { 8,8 } ,
59 { 9,9 } ,
60 { 'q','Q' } ,
61 { 'w','W' } ,
62 { 'e','E' } ,
63 { 'r','R' } ,
64 { 't','T' } ,
65 { 'y','Y' } ,
66 { 'u','U' } ,
67 { 'i','I' } ,
68 { 'o','O' } ,
69 { 'p','P' } ,
70 { '[','{' } ,
71 { ']','}' } ,
72 { 13,13 } ,
73 { 0,0 } ,
74 { 'a','A' } ,
75 { 's','S' } ,
76 { 'd','D' } ,
77 { 'f','F' } ,
78 { 'g','G' } ,
79 { 'h','H' } ,
80 { 'j','J' } ,
81 { 'k','K' } ,
82 { 'l','L' } ,
83 { ';',':' } ,
84 { 39,34 } ,
85 { '`','~' } ,
86 { 0,0 } ,
87 { '\\','|'} ,
88 { 'z','Z' } ,
89 { 'x','X' } ,
90 { 'c','C' } ,
91 { 'v','V' } ,
92 { 'b','B' } ,
93 { 'n','N' } ,
94 { 'm','M' } ,
95 { ',','<' } ,
96 { '.','>' } ,
97 { '/','?' } ,
98 { 0,0 } ,
99 { 0,0 } ,
100 { 0,0 } ,
101 { ' ',' ' } ,
102 };
103
104 /* EXTENDED KEY TABLE *********************************************************/
105
106 UCHAR LlbHwExtendedScanCodeTable[128] =
107 {
108 0, 0, 0, 0,
109 0, 0, 0, 0,
110 0, 0, 0, 0,
111 0, 0, 0, 0,
112 0, 0, 0, 0,
113 0, 0, 0, 0,
114 0, 0, 0, 0,
115 E0_KPENTER, E0_RCTRL, 0, 0,
116 0, 0, 0, 0,
117 0, 0, 0, 0,
118 0, 0, 0, 0,
119 0, 0, 0, 0,
120 0, 0, 0, 0,
121 0, E0_KPSLASH, 0, E0_PRSCR,
122 E0_RALT, 0, 0, 0,
123 0, E0_F13, E0_F14, E0_HELP,
124 E0_DO, E0_F17, 0, 0,
125 0, 0, E0_BREAK, E0_HOME,
126 E0_UP, E0_PGUP, 0, E0_LEFT,
127 E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,
128 E0_DOWN, E0_PGDN, E0_INS, E0_DEL,
129 0, 0, 0, 0,
130 0, 0, 0, E0_MSLW,
131 E0_MSRW, E0_MSTM, 0, 0,
132 0, 0, 0, 0,
133 0, 0, 0, 0,
134 0, 0, 0, 0,
135 0, 0, 0, E0_MACRO,
136 0, 0, 0, 0,
137 0, 0, 0, 0,
138 0, 0, 0, 0,
139 0, 0, 0, 0
140 };
141
142
143 /* FUNCTIONS ******************************************************************/
144
145 USHORT LlbKbdLastScanCode;
146
147 UCHAR
148 NTAPI
149 LlbKbdTranslateScanCode(IN USHORT ScanCode,
150 IN PUCHAR KeyCode)
151 {
152 ULONG LastScanCode;
153
154 /* Check for extended scan codes */
155 if ((ScanCode == 0xE0) || (ScanCode == 0xE1))
156 {
157 /* We'll get these on the next scan */
158 LlbKbdLastScanCode = ScanCode;
159 return 0;
160 }
161
162 /* Check for bogus scan codes */
163 if ((ScanCode == 0x00) || (ScanCode == 0xFF))
164 {
165 /* Reset */
166 LlbKbdLastScanCode = 0;
167 return 0;
168 }
169
170 /* Only act on the break, not the make */
171 if (ScanCode > 0x80) return 0;
172
173 /* Keep only simple scan codes */
174 ScanCode &= 0x7F;
175
176 /* Check if this was part of an extended sequence */
177 if (LlbKbdLastScanCode)
178 {
179 /* Save the last scan code and clear it, since we've consumed it now */
180 LastScanCode = LlbKbdLastScanCode;
181 LlbKbdLastScanCode = 0;
182 switch (LastScanCode)
183 {
184 /* E0 extended codes */
185 case 0xE0:
186
187 /* Skip bogus codes */
188 if ((ScanCode == 0x2A) || (ScanCode == 0x36)) return 0;
189
190 /* Lookup the code for it */
191 if (!LlbHwExtendedScanCodeTable[ScanCode]) return 0;
192 *KeyCode = LlbHwExtendedScanCodeTable[ScanCode];
193 break;
194
195 /* E1 extended codes */
196 case 0xE1:
197
198 /* Only recognize one (the SYSREQ/PAUSE sequence) */
199 if (ScanCode != 0x1D) return 0;
200 LlbKbdLastScanCode = 0x100;
201 break;
202
203 /* PAUSE sequence */
204 case 0x100:
205
206 /* Make sure it's the one */
207 if (ScanCode != 0x45) return 0;
208 *KeyCode = E1_PAUSE;
209 break;
210 }
211 }
212 else
213 {
214 /* Otherwise, the scancode is the key code */
215 LlbKbdLastScanCode = 0;
216 *KeyCode = ScanCode;
217 }
218
219 /* Translation success */
220 return 1;
221 }
222
223 CHAR
224 NTAPI
225 LlbKeyboardGetChar(VOID)
226 {
227 UCHAR ScanCode, KeyCode;
228
229 do
230 {
231 /* Read the scan code and convert it to a virtual key code */
232 ScanCode = LlbHwKbdRead();
233 } while (!LlbKbdTranslateScanCode(ScanCode, &KeyCode));
234
235 /* Is this ASCII? */
236 if (KeyCode > 96) return ScanCode;
237
238 /* Return the ASCII character */
239 return LlbHwScanCodeToAsciiTable[KeyCode][0];
240 }
241
242 /* EOF */