A project to implement a console using the Mbed using VGA for video output and a PS/2 keyboard for the input. The eventual goal is to also include tools for managing SD cards, and a semi-self-hosting programming environment.
Dependencies: PS2_MbedConsole fastlib SDFileSystem vga640x480g_mbedconsole lightvm mbed
keyboard.cpp
00001 /* 00002 <Copyright Header> 00003 Copyright (c) 2012 Jordan "Earlz" Earls <http://lastyearswishes.com> 00004 All rights reserved. 00005 00006 Redistribution and use in source and binary forms, with or without 00007 modification, are permitted provided that the following conditions 00008 are met: 00009 00010 1. Redistributions of source code must retain the above copyright 00011 notice, this list of conditions and the following disclaimer. 00012 2. Redistributions in binary form must reproduce the above copyright 00013 notice, this list of conditions and the following disclaimer in the 00014 documentation and/or other materials provided with the distribution. 00015 3. The name of the author may not be used to endorse or promote products 00016 derived from this software without specific prior written permission. 00017 00018 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 00019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 00020 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 00021 THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00022 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00023 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 00024 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00025 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00026 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 00027 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00028 00029 This file is part of the MbedConsole project 00030 */ 00031 00032 #include "mbedconsole.h" 00033 #include "keyboard.h" 00034 /**This is basically a straight rip off of my x86 OS project AlloyOS. I just ported the keyboard driver from it cause it always treated me well**/ 00035 00036 00037 const char kbdus[0x84] = 00038 { 00039 0, 00040 0, //1 F9 00041 0, //2 ? 00042 0, //3 f5 00043 0, //4 f3 00044 0, //5 F1 00045 0, //6 F2 00046 0, //7 F12 00047 0, //8 ? 00048 0, //9 F10 00049 0, //A F8 00050 0, //B F6 00051 0, //C F4 00052 '\t', 00053 '`', 00054 0, //F ? 00055 0, //10 ? 00056 0, //11 L alt 00057 0, //L shift 00058 0, //13 ? 00059 0, //14 L CTRL 00060 'q', '1', 00061 0, 0, 0, //17-19 ? 00062 'z', 's', 'a', 'w', '2', 00063 0, 0, //1F-20 ? 00064 'c', 'x', 'd', 'e', '4', '3', 00065 0, 0, //27-28 ? 00066 ' ', 'v', 'f', 't', 'r', '5', 00067 0, 0, //2F-30 ? 00068 'n', 'b', 'h', 'g', 'y', '6', 00069 0, 0, 0, //37-39 ? 00070 'm','j', 'u', '7', '8', 00071 0, 0, //3F-40 ? 00072 ',', 'k', 'i', 'o', '0', '9', 00073 0, 0, //47-48 ? 00074 '.', '/', 'l', ';', 'p', '-', 00075 0, 0, 0, //4f-51 ? 00076 '\'', 00077 0, //53 ? 00078 '[', '=', 00079 0, 0, //56-57 ? 00080 0, //58 caplock 00081 0, //59 R shift 00082 '\n', //5A enter 00083 ']', 00084 0, //5C ? 00085 '\\', 00086 0, 0, 0, 0, 0, 0, 0, 0, //5E-65 ? 00087 '\b', //backspace 00088 0, 0, //67-68 00089 0, //69 End 1 00090 0, //6a ? 00091 '4', //6b left 4 00092 0, //6c home 7 00093 0, 0, 0, //6d-6f ? 00094 '0', //70 ins 0 00095 0, //71 del . 00096 '2', //72 down 2 00097 '5', //73 5 00098 '6', //74 right 6 00099 '8', //75 up 8 00100 27, //76 esc 00101 0, //77 numlock 00102 0, //78 f11 00103 '+', //79 + 00104 '3', //7A pagedown 3 00105 '-', //7B 00106 '*', //7C 00107 '9', //7D pageup 9 00108 '0', //7E scroll lock 00109 0, 0, 0, 0, //7F-82 ? 00110 0, //83 F7 00111 }; 00112 00113 00114 const char kbdus_caps[0x84] = 00115 { 00116 0, 00117 0, //1 F9 00118 0, //2 ? 00119 0, //3 f5 00120 0, //4 f3 00121 0, //5 F1 00122 0, //6 F2 00123 0, //7 F12 00124 0, //8 ? 00125 0, //9 F10 00126 0, //A F8 00127 0, //B F6 00128 0, //C F4 00129 '\t', 00130 '~', 00131 0, //F ? 00132 0, //10 ? 00133 0, //11 L alt 00134 0, //L shift 00135 0, //13 ? 00136 0, //14 L CTRL 00137 'Q', '!', 00138 0, 0, 0, //17-19 ? 00139 'Z', 'S', 'A', 'W', '@', 00140 0, 0, //1F-20 ? 00141 'C', 'X', 'D', 'E', '#', '$', 00142 0, 0, //27-28 ? 00143 ' ', 'V', 'F', 'T', 'R', '%', 00144 0, 0, //2F-30 ? 00145 'N', 'B', 'H', 'G', 'Y', '^', 00146 0, 0, 0, //37-39 ? 00147 'M','J', 'U', '&', '*', 00148 0, 0, //3F-40 ? 00149 '<', 'K', 'I', 'O', ')', '(', 00150 0, 0, //47-48 ? 00151 '>', '?', 'L', ':', 'P', '_', 00152 0, 0, 0, //4f-51 ? 00153 '\"', 00154 0, //53 ? 00155 '{', '+', 00156 0, 0, //56-57 ? 00157 0, //58 caplock 00158 0, //59 R shift 00159 '\n', //5A enter 00160 '}', 00161 0, //5C ? 00162 '|', 00163 0, 0, 0, 0, 0, 0, 0, 0, //5E-65 ? 00164 '\b', //backspace 00165 0, 0, //67-68 00166 0, //69 End 1 00167 0, //6a ? 00168 '4', //6b left 4 00169 0, //6c home 7 00170 0, 0, 0, //6d-6f ? 00171 '0', //70 ins 0 00172 0, //71 del . 00173 '2', //72 down 2 00174 '5', //73 5 00175 '6', //74 right 6 00176 '8', //75 up 8 00177 27, //76 esc 00178 0, //77 numlock 00179 0, //78 f11 00180 '+', //79 + 00181 '3', //7A pagedown 3 00182 '-', //7B 00183 '*', //7C 00184 '9', //7D pageup 9 00185 '0', //7E scroll lock 00186 0, 0, 0, 0, //7F-82 ? 00187 0, //83 F7 00188 }; 00189 00190 PS2KB_INIT *ps2_kb_init; 00191 PS2KB *ps2_kb; 00192 00193 volatile kbd_key *keys; 00194 volatile uint8_t current_key=0; 00195 volatile uint8_t key_got=0; 00196 volatile char pending_key=0; 00197 volatile uint8_t led_status=0; 00198 00199 void keyboard_init() 00200 { 00201 keys=(kbd_key*)malloc(256*sizeof(kbd_key)); 00202 kbd_shifts.shift=0; 00203 kbd_shifts.caps=0; 00204 kbd_shifts.num=0; 00205 kbd_shifts.scroll=0; 00206 kbd_shifts.ctrl=0; 00207 kbd_shifts.alt=0; 00208 ps2_kb_init=new PS2KB_INIT(KEYBOARD_CLOCKPIN, KEYBOARD_DATAPIN); 00209 ps2_kb=new PS2KB(KEYBOARD_CLOCKPIN, KEYBOARD_DATAPIN, (KeyboardCallback) &keyboard_callback); 00210 } 00211 00212 00213 00214 volatile shift_locks kbd_shifts; 00215 00216 00217 00218 /**The way the keyboard driver works is this: 00219 the buffer is 256 elements big. key_got and current_key are both 00220 bytes. Rather than setting current_key to 0, the entire buffer is constantly 00221 in use. when a key is pushed, current key is incremented. when a key is got(with safety checks) 00222 key_got is incremented. Also, when it reaches the end of the buffer, it simply wraps around 00223 to the beginning due to byte overflow. The worst that can happen is if 256 bytes get 00224 built up, in which case everything will be screwed up.. I should eventually controlt he capture 00225 of these keys to where not all of them are stored, and they are only stored when needed**/ 00226 00227 int kbd_PutBuffer(uint16_t scan,uint8_t asci){ 00228 keys[current_key].scancode=scan; 00229 keys[current_key].asci=asci; 00230 current_key++; 00231 pending_key++;; 00232 return 0; 00233 } 00234 00235 kbd_key kbd_PopBuffer(){ 00236 kbd_key k; 00237 while(pending_key==0){ 00238 //hlt(); 00239 //fill in busy code here 00240 } 00241 00242 k.scancode=keys[key_got].scancode; 00243 k.asci=keys[key_got].asci; 00244 pending_key--; 00245 key_got++; 00246 return k; 00247 } 00248 00249 uint8_t kbd_GetKey(){ //this will just return the asci code 00250 kbd_key k; 00251 k.asci=0; 00252 while(k.asci==0){ 00253 k=kbd_PopBuffer(); 00254 } 00255 return k.asci; 00256 } 00257 00258 00259 void kbd_update_leds(uint8_t status){ 00260 uint8_t tmp; 00261 //TODO 00262 /*while((inportb(0x64)&2)!=0){} 00263 outportb(0x60,0xED); 00264 00265 while((inportb(0x64)&2)!=0){} 00266 outportb(0x60,status); 00267 */ 00268 } 00269 00270 00271 00272 int kbd_DoShifts(uint8_t scan){ 00273 switch(scan){ 00274 case RSHIFT_KEY: 00275 kbd_shifts.shift++; 00276 break; 00277 case LSHIFT_KEY: 00278 kbd_shifts.shift++; 00279 break; 00280 case CTRL_KEY: 00281 kbd_shifts.ctrl++; 00282 break; 00283 case ALT_KEY: 00284 kbd_shifts.alt++; 00285 break; 00286 case CAPS_KEY: 00287 led_status^=CAPS_LED; 00288 kbd_update_leds(led_status); 00289 kbd_shifts.caps^=1; 00290 break; 00291 case NUM_KEY: 00292 led_status^=NUM_LED; 00293 kbd_update_leds(led_status); 00294 kbd_shifts.num^=1; 00295 break; 00296 case SCROLL_KEY: 00297 led_status^=SCROLL_LED; 00298 kbd_update_leds(led_status); 00299 kbd_shifts.scroll^=1; 00300 break; 00301 default: 00302 return 0; 00303 break; 00304 } 00305 return 1; 00306 } 00307 00308 int kbd_DoUnshifts(uint8_t scan){ 00309 switch(scan){ 00310 case RSHIFT_KEY: 00311 kbd_shifts.shift--; 00312 break; 00313 case LSHIFT_KEY: 00314 kbd_shifts.shift--; 00315 break; 00316 case CTRL_KEY: 00317 kbd_shifts.ctrl--; 00318 break; 00319 case ALT_KEY: 00320 kbd_shifts.alt--; 00321 break; 00322 case CAPS_KEY: 00323 //kbd_shifts.caps=0; 00324 break; 00325 case NUM_KEY: 00326 //kbd_shifts.num=0; 00327 break; 00328 case SCROLL_KEY: 00329 //kbd_shifts.scroll=0; 00330 break; 00331 default: 00332 return 0; 00333 break; 00334 } 00335 return 1; 00336 } 00337 volatile bool expecting_break=false; 00338 void keyboard_callback(PS2KB kb, uint8_t val) //this is called from interrupt! Must be fast 00339 { 00340 //stopints(); 00341 if(expecting_break){ 00342 //val^=0xF0; 00343 kbd_DoUnshifts(val); 00344 expecting_break=false; 00345 }else{ 00346 if(val>=0xF0){ 00347 expecting_break=true; 00348 }else{ 00349 //add check for 0x84 to make sure we don't go over our keymap 00350 if(val<=0x84 && kbd_DoShifts(val)==0){ //if not a shift-type key 00351 00352 if ((kbd_shifts.caps^kbd_shifts.shift)==1) { 00353 kbd_PutBuffer(val,kbdus_caps[val]); 00354 }else{ 00355 kbd_PutBuffer(val,kbdus[val]); 00356 } 00357 } 00358 } 00359 } 00360 } 00361 00362 00363 00364
Generated on Sun Jul 17 2022 09:10:09 by 1.7.2