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 */ 243