00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <isa/atkbd.h>
00031 #include <isa/8259.h>
00032 #include <sys/video.h>
00033 #include <sys/idt.h>
00034 #include <sys/gdt.h>
00035 #include <sys/io.h>
00036 #include <lib/kmalloc.h>
00037 #include <lib/kprintf.h>
00038 #include <ubixos/types.h>
00039 #include <ubixos/sched.h>
00040 #include <ubixos/endtask.h>
00041 #include <ubixos/tty.h>
00042 #include <ubixos/spinlock.h>
00043 #include <ubixos/kpanic.h>
00044 #include <ubixos/vitals.h>
00045
00046 static int atkbd_scan();
00047
00048 static unsigned int keyMap = 0x0;
00049 static unsigned int ledStatus = 0x0;
00050 static char stdinBuffer[512];
00051 static uInt16 stdinSize;
00052 static uInt32 controlKeys = 0x0;
00053
00054 static spinLock_t atkbdSpinLock = SPIN_LOCK_INITIALIZER;
00055
00056 static unsigned int keyboardMap[255][8] = {
00057
00058 { 0, 0, 0, 0, 0, 0, 0, 0},
00059 { 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B},
00060 { 0x31, 0x21, 0, 0, 0x31, 0x31, 0x21, 0x21},
00061 { 0x32, 0x40, 0, 0, 0x32, 0x32, 0x40, 0x40},
00062 { 0x33, 0x23, 0, 0, 0x33, 0x33, 0x23, 0x23},
00063 { 0x34, 0x24, 0, 0, 0x34, 0x34, 0x24, 0x24},
00064 { 0x35, 0x25, 0, 0, 0x35, 0x35, 0x25, 0x25},
00065 { 0x36, 0x5E, 0, 0, 0x36, 0x36, 0x5E, 0x5E},
00066 { 0x37, 0x26, 0, 0, 0x37, 0x37, 0x26, 0x26},
00067 { 0x38, 0x2A, 0, 0, 0x38, 0x38, 0x2A, 0x2A},
00068 { 0x39, 0x28, 0, 0, 0x39, 0x39, 0x28, 0x28},
00069 { 0x30, 0x29, 0, 0, 0x30, 0x30, 0x29, 0x29},
00070 { 0x2D, 0x5F, 0, 0, 0x2D, 0x2D, 0x5F, 0x5F},
00071 { 0x3D, 0x2B, 0, 0, 0x3D, 0x3D, 0x2B, 0x2B},
00072 { 0x08, 0x08, 0x8, 0x8, 0x08, 0x08, 0x08, 0x08},
00073 { 0x09, 0, 0, 0, 0, 0, 0, 0},
00074 { 0x71, 0x51, 0, 0, 0, 0, 0, 0},
00075 { 0x77, 0x57, 0, 0, 0, 0, 0, 0},
00076 { 0x65, 0x45, 0, 0, 0, 0, 0, 0},
00077 { 0x72, 0x52, 0, 0, 0, 0, 0, 0},
00078 { 0x74, 0x54, 0, 0, 0, 0, 0, 0},
00079 { 0x79, 0x59, 0, 0, 0, 0, 0, 0},
00080 { 0x75, 0x55, 0, 0, 0, 0, 0, 0},
00081 { 0x69, 0x49, 0, 0, 0, 0, 0, 0},
00082 { 0x6F, 0x4F, 0, 0, 0, 0, 0, 0},
00083 { 0x70, 0x50, 0, 0, 0, 0, 0, 0},
00084 { 0x5B, 0x7B, 0, 0, 0, 0, 0, 0},
00085 { 0x5D, 0x7D, 0, 0, 0, 0, 0, 0},
00086 { 0x0A, 0, 0, 0, 0, 0, 0, 0},
00087 { 0, 0, 0, 0, 0, 0, 0, 0},
00088 { 0x61, 0x41, 0x41, 0, 0, 0, 0, 0},
00089 { 0x73, 0x53, 0, 0, 0, 0, 0, 0},
00090 { 0x64, 0x44, 0, 0, 0, 0, 0, 0},
00091 { 0x66, 0x46, 0, 0, 0, 0, 0, 0},
00092 { 0x67, 0x47, 0, 0, 0, 0, 0, 0},
00093 { 0x68, 0x48, 0, 0, 0, 0, 0, 0},
00094 { 0x6A, 0x4A, 0, 0, 0, 0, 0, 0},
00095 { 0x6B, 0x4B, 0, 0, 0, 0, 0, 0},
00096 { 0x6C, 0x4C, 0, 0, 0, 0, 0, 0},
00097 { 0x3B, 0x3A, 0, 0, 0, 0, 0, 0},
00098 { 0x27, 0x22, 0, 0, 0, 0, 0, 0},
00099 { 0x60, 0x7E, 0, 0, 0, 0, 0, 0},
00100 { 0x2A, 0x0, 0, 0, 0, 0, 0, 0},
00101 { 0x5C, 0x3C, 0, 0, 0, 0, 0, 0},
00102 { 0x7A, 0x5A, 0, 0, 0, 0, 0, 0},
00103 { 0x78, 0x58, 0, 0, 0, 0, 0, 0},
00104 { 0x63, 0x43, 0x3, 0x9, 0, 0, 0, 0},
00105 { 0x76, 0x56, 0, 0, 0, 0, 0, 0},
00106 { 0x62, 0x42, 0, 0, 0, 0, 0, 0},
00107 { 0x6E, 0x4E, 0, 0, 0, 0, 0, 0},
00108 { 0x6D, 0x4D, 0, 0, 0, 0, 0, 0},
00109 { 0x2C, 0x3C, 0, 0, 0, 0, 0, 0},
00110 { 0x2E, 0x3E, 0, 0, 0, 0, 0, 0},
00111 { 0x2F, 0x3F, 0, 0, 0, 0, 0, 0},
00112 { 0, 0, 0, 0, 0, 0, 0, 0},
00113 { 0, 0, 0, 0, 0, 0, 0, 0},
00114 { 0, 0, 0, 0, 0, 0, 0, 0},
00115 { 0x20, 0, 0, 0, 0, 0, 0, 0},
00116 { 0, 0, 0, 0, 0, 0, 0, 0},
00117 { 0x3000, 0, 0, 0x3000, 0, 0, 0, 0},
00118 { 0x3001, 0, 0, 0x3001, 0, 0, 0, 0},
00119 { 0x3002, 0, 0, 0x3002, 0, 0, 0, 0},
00120 { 0x3003, 0, 0, 0x3003, 0, 0, 0, 0},
00121 { 0x3004, 0, 0, 0x3004, 0, 0, 0, 0},
00122 { 0x4000, 0, 0, 0, 0, 0, 0, 0},
00123 { 0x4100, 0, 0, 0, 0, 0, 0, 0},
00124 { 0x4200, 0, 0, 0, 0, 0, 0, 0},
00125 { 0x4300, 0, 0, 0, 0, 0, 0, 0},
00126 { 0x4400, 0, 0, 0, 0, 0, 0, 0},
00127 { 0, 0, 0, 0, 0, 0, 0, 0},
00128 { 0, 0, 0, 0, 0, 0, 0, 0},
00129 { 0x4700, 0, 0, 0, 0, 0, 0, 0},
00130 { 0x4800, 0, 0, 0, 0, 0, 0, 0},
00131 { 0x4900, 0, 0, 0, 0, 0, 0, 0},
00132 { 0x2D, 0, 0, 0, 0, 0, 0, 0},
00133 { 0x4B00, 0, 0, 0, 0, 0, 0, 0},
00134 { 0x4C00, 0, 0, 0, 0, 0, 0, 0},
00135 { 0x4D00, 0, 0, 0, 0, 0, 0, 0},
00136 { 0x2B, 0, 0, 0, 0, 0, 0, 0},
00137 { 0x4F00, 0, 0, 0, 0, 0, 0, 0},
00138 { 0x5000, 0, 0, 0, 0, 0, 0, 0},
00139 { 0x5100, 0, 0, 0, 0, 0, 0, 0},
00140 { 0x5200, 0, 0, 0, 0, 0, 0, 0},
00141 { 0x5300, 0, 0, 0, 0, 0, 0, 0},
00142 { 0, 0, 0, 0, 0, 0, 0, 0},
00143 { 0, 0, 0, 0, 0, 0, 0, 0}
00144 };
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 int atkbd_init() {
00158
00159 setVector(&atkbd_isr, mVec+0x1, dPresent + dInt + dDpl0);
00160
00161
00162 setLED();
00163
00164
00165 atkbd_scan();
00166
00167
00168 irqEnable(0x1);
00169
00170
00171 kprintf("atkbd0 - Address: [0x%X], Keyboard Buffer: [0x%X], Buffer Size [%i]\n",&atkbd_isr,&stdinBuffer,512);
00172
00173
00174 return(0x0);
00175 }
00176
00177
00178
00179
00180
00181 asm(
00182 ".globl atkbd_isr \n"
00183 "atkbd_isr: \n"
00184 " pusha \n"
00185 " push %ss \n"
00186 " push %ds \n"
00187 " push %es \n"
00188 " push %fs \n"
00189 " push %gs \n"
00190 " call keyboardHandler \n"
00191 " mov $0x20,%dx \n"
00192 " mov $0x20,%ax \n"
00193 " outb %al,%dx \n"
00194 " pop %gs \n"
00195 " pop %fs \n"
00196 " pop %es \n"
00197 " pop %ds \n"
00198 " pop %ss \n"
00199 " popa \n"
00200 " iret \n"
00201 );
00202
00203 static int atkbd_scan() {
00204 int code = 0x0;
00205 int val = 0x0;
00206
00207 code = inportByte(0x60);
00208 val = inportByte(0x61);
00209
00210 outportByte(0x61,val | 0x80);
00211 outportByte(0x61,val);
00212
00213 return(code);
00214 }
00215
00216 void keyboardHandler() {
00217 int key = 0x0;
00218
00219 if (!spinTryLock(&atkbdSpinLock))
00220 return;
00221
00222 key = atkbd_scan();
00223
00224 if (key > 255)
00225 return;
00226
00227
00228 if (key == 0x1D && !(controlKeys & controlKey)) {
00229 controlKeys |= controlKey;
00230 }
00231 if (key == 0x80 + 0x1D) {
00232 controlKeys &= (0xFF - controlKey);
00233 }
00234
00235 if (key == 0x38 && !(controlKeys & altKey)) {
00236 controlKeys |= altKey;
00237 }
00238 if (key == 0x80 + 0x38) {
00239 controlKeys &= (0xFF - altKey);
00240 }
00241
00242 if ((key == 0x2A || key == 0x36) && !(controlKeys & shiftKey)) {
00243 controlKeys |= shiftKey;
00244 }
00245 if ((key == 0x80 + 0x2A) || (key == 0x80 + 0x36)) {
00246 controlKeys &= (0xFF - shiftKey);
00247 }
00248
00249 if (key == 0x3A) {
00250 ledStatus ^= ledCapslock;
00251 setLED();
00252 }
00253
00254 if (key == 0x45) {
00255 ledStatus ^= ledNumlock;
00256 setLED();
00257 }
00258
00259 if (key == 0x46) {
00260 ledStatus ^= ledScrolllock;
00261 setLED();
00262 }
00263
00264 if (controlKeys == 0) { keyMap = 0; }
00265 else if (controlKeys == 1) { keyMap = 1; }
00266 else if (controlKeys == 2) { keyMap = 2; }
00267 else if (controlKeys == 4) { keyMap = 3; }
00268
00269 if (((uInt)(keyboardMap[key][keyMap]) > 0) && ((uInt32)(keyboardMap[key][keyMap]) < 0xFF)) {
00270 switch ((uInt32)keyboardMap[key][keyMap]) {
00271 case 8:
00272 backSpace();
00273 if (tty_foreground == 0x0) {
00274 stdinBuffer[stdinSize] = keyboardMap[key][keyMap];
00275 stdinSize++;
00276 }
00277 else {
00278 tty_foreground->stdin[tty_foreground->stdinSize] = keyboardMap[key][keyMap];
00279 tty_foreground->stdinSize++;
00280 }
00281 break;
00282 case 0x3:
00283
00284
00285 K_PANIC("CTRL-C pressed\n");
00286 kprintf("FreePages: [0x%X]\n",systemVitals->freePages);
00287 break;
00288 case 0x9:
00289 kprintf("REBOOTING");
00290 while(inportByte(0x64) & 0x02);
00291 outportByte(0x64, 0xFE);
00292 break;
00293 default:
00294 if (tty_foreground == 0x0) {
00295 stdinBuffer[stdinSize] = keyboardMap[key][keyMap];
00296 stdinSize++;
00297 }
00298 else {
00299 tty_foreground->stdin[tty_foreground->stdinSize] = keyboardMap[key][keyMap];
00300 tty_foreground->stdinSize++;
00301 }
00302 break;
00303 }
00304 }
00305 else {
00306 switch ((keyboardMap[key][keyMap] >> 8)) {
00307 case 0x30:
00308 tty_change(keyboardMap[key][keyMap] & 0xFF);
00309
00310 break;
00311 default:
00312 break;
00313 }
00314 }
00315
00316
00317 spinUnlock(&atkbdSpinLock);
00318 return;
00319 }
00320
00321 void setLED() {
00322 outportByte(0x60, 0xED);
00323 while(inportByte(0x64) & 2);
00324 outportByte(0x60, ledStatus);
00325 while(inportByte(0x64) & 2);
00326 }
00327
00328
00329 unsigned char getch() {
00330 uInt8 retKey = 0x0;
00331 uInt32 i = 0x0;
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 if (tty_foreground == 0x0) {
00348 if (stdinSize == 0x0) {
00349
00350 return(0x0);
00351 }
00352
00353 retKey = stdinBuffer[0];
00354 stdinSize--;
00355
00356 for (i=0x0;i<stdinSize;i++) {
00357 stdinBuffer[i] = stdinBuffer[i+0x1];
00358 }
00359 }
00360 else {
00361 if (tty_foreground->stdinSize == 0x0) {
00362
00363 return(0x0);
00364 }
00365
00366 retKey = tty_foreground->stdin[0];
00367 tty_foreground->stdinSize--;
00368
00369 for (i=0x0;i<tty_foreground->stdinSize;i++) {
00370 tty_foreground->stdin[i] = tty_foreground->stdin[i+0x1];
00371 }
00372 }
00373
00374 return(retKey);
00375 }
00376
00377
00378
00379