xref: /reactos/boot/armllb/hw/keyboard.c (revision 9393fc32)
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
LlbKbdTranslateScanCode(IN USHORT ScanCode,IN PUCHAR KeyCode)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
LlbKeyboardGetChar(VOID)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 */
243