|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1991,1990,1989 Carnegie Mellon University ! 4: * All Rights Reserved. ! 5: * ! 6: * Permission to use, copy, modify and distribute this software and its ! 7: * documentation is hereby granted, provided that both the copyright ! 8: * notice and this permission notice appear in all copies of the ! 9: * software, derivative works or modified versions, and any portions ! 10: * thereof, and that both notices appear in supporting documentation. ! 11: * ! 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 15: * ! 16: * Carnegie Mellon requests users of this software to return to ! 17: * ! 18: * Software Distribution Coordinator or [email protected] ! 19: * School of Computer Science ! 20: * Carnegie Mellon University ! 21: * Pittsburgh PA 15213-3890 ! 22: * ! 23: * any improvements or extensions that they make and grant Carnegie Mellon ! 24: * the rights to redistribute these changes. ! 25: */ ! 26: /* ! 27: * File: lk201.c ! 28: * Author: Alessandro Forin, Carnegie Mellon University ! 29: * Date: 9/90 ! 30: * ! 31: * Routines for the LK201 Keyboard Driver ! 32: */ ! 33: ! 34: #include <lk.h> ! 35: #if NLK > 0 ! 36: #include <bm.h> ! 37: ! 38: #include <mach_kdb.h> ! 39: ! 40: #include <mach/std_types.h> ! 41: #include <device/device_types.h> ! 42: #include <machine/machspl.h> /* spl definitions */ ! 43: #include <sys/ioctl.h> ! 44: #include <machine/machspl.h> ! 45: #include <chips/lk201.h> ! 46: #include <chips/serial_defs.h> ! 47: #include <chips/screen_defs.h> ! 48: ! 49: ! 50: /* ! 51: * Structures describing the keyboard status ! 52: */ ! 53: typedef struct { ! 54: unsigned short kbd_flags; ! 55: unsigned short kbd_previous; ! 56: char kbd_gen_shift; ! 57: char kbd_ctrl; ! 58: char kbd_lock; ! 59: char kbd_meta; ! 60: char kbd_shift; ! 61: } lk201_kbd_state_t; ! 62: ! 63: #define mapLOCKtoCNTRL 0x1 /* flags */ ! 64: ! 65: typedef struct { ! 66: char led_active; ! 67: char led_pattern; ! 68: char led_increasing; ! 69: char led_lights; ! 70: int led_interval; ! 71: int led_light_count; ! 72: } lk201_led_state_t; ! 73: ! 74: ! 75: /* ! 76: * Keyboard state ! 77: */ ! 78: ! 79: struct lk201_softc { ! 80: lk201_kbd_state_t kbd; ! 81: lk201_led_state_t led; ! 82: int sl_unit; ! 83: } lk201_softc_data[NLK]; ! 84: ! 85: typedef struct lk201_softc *lk201_softc_t; ! 86: ! 87: lk201_softc_t lk201_softc[NLK]; ! 88: ! 89: /* ! 90: * Forward decls ! 91: */ ! 92: io_return_t ! 93: lk201_translation( ! 94: int key, ! 95: char c, ! 96: int tabcode ); ! 97: ! 98: int ! 99: lk201_input( ! 100: int unit, ! 101: unsigned short data); ! 102: ! 103: ! 104: /* ! 105: * Autoconf (sort-of) ! 106: */ ! 107: lk201_probe( ! 108: int unit) ! 109: { ! 110: lk201_softc[unit] = &lk201_softc_data[unit]; ! 111: return 1; ! 112: } ! 113: ! 114: void lk201_attach( ! 115: int unit, ! 116: int sl_unit) ! 117: { ! 118: lk201_softc[unit]->sl_unit = sl_unit; ! 119: lk201_selftest(unit); ! 120: } ! 121: ! 122: /* ! 123: * Keyboard initialization ! 124: */ ! 125: ! 126: static unsigned char lk201_reset_string[] = { ! 127: LK_CMD_LEDS_ON, LK_PARAM_LED_MASK(0xf), /* show we are resetting */ ! 128: LK_CMD_SET_DEFAULTS, ! 129: LK_CMD_MODE(LK_MODE_RPT_DOWN,1), ! 130: LK_CMD_MODE(LK_MODE_RPT_DOWN,2), ! 131: LK_CMD_MODE(LK_MODE_RPT_DOWN,3), ! 132: LK_CMD_MODE(LK_MODE_RPT_DOWN,4), ! 133: LK_CMD_MODE(LK_MODE_DOWN_UP,5), ! 134: LK_CMD_MODE(LK_MODE_DOWN_UP,6), ! 135: LK_CMD_MODE(LK_MODE_RPT_DOWN,7), ! 136: LK_CMD_MODE(LK_MODE_RPT_DOWN,8), ! 137: LK_CMD_MODE(LK_MODE_RPT_DOWN,9), ! 138: LK_CMD_MODE(LK_MODE_RPT_DOWN,10), ! 139: LK_CMD_MODE(LK_MODE_RPT_DOWN,11), ! 140: LK_CMD_MODE(LK_MODE_RPT_DOWN,12), ! 141: LK_CMD_MODE(LK_MODE_DOWN,13), ! 142: LK_CMD_MODE(LK_MODE_RPT_DOWN,14), ! 143: LK_CMD_ENB_RPT, ! 144: /* LK_CMD_ENB_KEYCLK, LK_PARAM_VOLUME(4), */ ! 145: LK_CMD_DIS_KEYCLK, ! 146: LK_CMD_RESUME, ! 147: LK_CMD_ENB_BELL, LK_PARAM_VOLUME(4), ! 148: LK_CMD_LEDS_OFF, LK_PARAM_LED_MASK(0xf) ! 149: }; ! 150: ! 151: void ! 152: lk201_reset( ! 153: int unit) ! 154: { ! 155: register int i, sl; ! 156: register spl_t s; ! 157: lk201_softc_t lk; ! 158: ! 159: lk = lk201_softc[unit]; ! 160: sl = lk->sl_unit; ! 161: s = spltty(); ! 162: for (i = 0; i < sizeof(lk201_reset_string); i++) { ! 163: (*console_putc)(sl, ! 164: SCREEN_LINE_KEYBOARD, ! 165: lk201_reset_string[i]); ! 166: delay(100); ! 167: } ! 168: /* zero any state associated with previous keypresses */ ! 169: bzero(lk, sizeof(*lk)); ! 170: lk->sl_unit = sl; ! 171: splx(s); ! 172: } ! 173: ! 174: lk201_selftest( ! 175: int unit) ! 176: { ! 177: int messg[4], sl; ! 178: spl_t s; ! 179: ! 180: sl = lk201_softc[unit]->sl_unit; ! 181: s = spltty(); ! 182: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_REQ_ID); ! 183: delay(10000);/* arbitrary */ ! 184: messg[0] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE); ! 185: messg[1] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE); ! 186: splx(s); ! 187: ! 188: printf("( lk201 id %x.%x", messg[0], messg[1]); ! 189: ! 190: s = spltty(); ! 191: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_POWER_UP); ! 192: ! 193: /* cannot do this, waiting too long might cause receiver overruns */ ! 194: /* delay(80000);/* spec says 70 msecs or less */ ! 195: ! 196: messg[0] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE); ! 197: messg[1] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE); ! 198: messg[2] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE); ! 199: messg[3] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE); ! 200: splx(s); ! 201: ! 202: printf(", self-test "); ! 203: if (messg[0] != 0x01 || messg[1] || messg[2] || messg[3]) ! 204: printf("bad [%x %x %x %x]", ! 205: messg[0], messg[1], messg[2], messg[3]); ! 206: else ! 207: printf("ok )"); ! 208: ! 209: lk201_reset(unit); ! 210: } ! 211: ! 212: /* ! 213: * Tinkerbell ! 214: */ ! 215: void ! 216: lk201_ring_bell( ! 217: int unit) ! 218: { ! 219: spl_t s = spltty(); ! 220: (*console_putc)(lk201_softc[unit]->sl_unit, SCREEN_LINE_KEYBOARD, LK_CMD_BELL); ! 221: splx(s); ! 222: } ! 223: ! 224: /* ! 225: * Here is your LED toy, Bob ! 226: */ ! 227: void ! 228: lk201_lights( ! 229: int unit, ! 230: boolean_t on) ! 231: { ! 232: unsigned int sl; ! 233: spl_t s; ! 234: ! 235: sl = lk201_softc[unit]->sl_unit; ! 236: s = spltty(); ! 237: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_OFF); ! 238: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(0xf)); ! 239: if (on < 16 && on > 0) { ! 240: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_ON); ! 241: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(on)); ! 242: } ! 243: splx(s); ! 244: } ! 245: ! 246: ! 247: lk201_led( ! 248: int unit) ! 249: { ! 250: lk201_led_state_t *leds = &lk201_softc[unit]->led; ! 251: unsigned int sl; ! 252: spl_t s; ! 253: ! 254: sl = lk201_softc[unit]->sl_unit; ! 255: if (leds->led_interval) { /* leds are on */ ! 256: if (leds->led_light_count <= 0) { /* hit this lights */ ! 257: ! 258: if (leds->led_lights <= 0) leds->led_lights= 1; /* sanity */ ! 259: if (leds->led_lights > 16) leds->led_lights = 16;/* sanity */ ! 260: leds->led_light_count = leds->led_interval; /* reset */ ! 261: s = spltty(); ! 262: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_OFF); ! 263: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(leds->led_lights)); ! 264: switch (leds->led_pattern) { ! 265: case LED_OFF: ! 266: leds->led_interval = 0; /* since you can now set */ ! 267: break; /* the interval even if off */ ! 268: case LED_COUNT: ! 269: leds->led_lights++; ! 270: if (leds->led_lights > 16) leds->led_lights = 1; ! 271: break; ! 272: case LED_ROTATE: ! 273: leds->led_lights <<= 1; ! 274: if (leds->led_lights > 8) leds->led_lights = 1; ! 275: break; ! 276: case LED_CYLON: ! 277: if (leds->led_increasing) { ! 278: leds->led_lights <<= 1; ! 279: if (leds->led_lights > 8) { ! 280: leds->led_lights >>= 2; ! 281: leds->led_increasing = 0; ! 282: } ! 283: } else { ! 284: leds->led_lights >>= 1; ! 285: if (leds->led_lights <= 0) { ! 286: leds->led_lights = 2; ! 287: leds->led_increasing = 1; ! 288: } ! 289: } ! 290: break; ! 291: } ! 292: (*console_putc)( sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_ON); ! 293: (*console_putc)( sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(leds->led_lights)); ! 294: splx(s); ! 295: } ! 296: leds->led_light_count--; ! 297: } else { ! 298: if (leds->led_lights) { ! 299: s = spltty(); ! 300: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_OFF); ! 301: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(0xf)); ! 302: leds->led_lights = 0; ! 303: splx(s); ! 304: } ! 305: leds->led_active = 0; ! 306: #if NBM > 0 ! 307: screen_enable_vretrace(unit, 0); /* interrupts off */ ! 308: #endif ! 309: } ! 310: } ! 311: ! 312: ! 313: /* ! 314: * Special user-visible ops ! 315: */ ! 316: io_return_t ! 317: lk201_set_status( ! 318: int unit, ! 319: dev_flavor_t flavor, ! 320: dev_status_t status, ! 321: natural_t status_count) ! 322: { ! 323: lk201_led_state_t *leds = &lk201_softc[unit]->led; ! 324: lk201_kbd_state_t *kbd = &lk201_softc[unit]->kbd; ! 325: ! 326: switch( flavor ) { ! 327: case LK201_SEND_CMD:{ ! 328: register lk201_cmd_t *cmd = (lk201_cmd_t*)status; ! 329: unsigned int cnt, s, sl; ! 330: ! 331: if ((status_count < (sizeof(*cmd)/sizeof(int))) || ! 332: ((cnt = cmd->len) > 2)) ! 333: return D_INVALID_SIZE; ! 334: ! 335: if (cnt == 0) ! 336: cmd->command |= LK_PARAM; ! 337: else ! 338: cmd->params[cnt-1] |= LK_PARAM; ! 339: sl = lk201_softc[unit]->sl_unit; ! 340: s = spltty(); ! 341: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, cmd->command); ! 342: if (cnt > 0) ! 343: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, cmd->params[0]); ! 344: if (cnt > 1) ! 345: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, cmd->params[1]); ! 346: splx(s); ! 347: return D_SUCCESS; ! 348: } ! 349: case LK201_LED_PATTERN:{ ! 350: register int ptn = * (int *) status; ! 351: if (ptn != LED_OFF && ptn != LED_COUNT && ! 352: ptn != LED_ROTATE && ptn != LED_CYLON ) { ! 353: return -1; ! 354: } else { ! 355: leds->led_pattern = ptn; ! 356: } ! 357: break; ! 358: } ! 359: case LK201_LED_INTERVAL:{ ! 360: register int lcnt = * (int *) status; ! 361: if (lcnt < 0) ! 362: lcnt = 1; ! 363: leds->led_interval = lcnt; ! 364: break; ! 365: } ! 366: case LK201_mapLOCKtoCNTRL:{ ! 367: boolean_t enable = * (boolean_t*) status; ! 368: if (enable) ! 369: kbd->kbd_flags |= mapLOCKtoCNTRL; ! 370: else ! 371: kbd->kbd_flags &= ~mapLOCKtoCNTRL; ! 372: return D_SUCCESS; ! 373: } ! 374: case LK201_REMAP_KEY:{ ! 375: register KeyMap *k = (KeyMap *) status; ! 376: int mode; ! 377: ! 378: if (status_count < (sizeof(KeyMap)/sizeof(int))) ! 379: return D_INVALID_SIZE; ! 380: ! 381: mode = k->shifted ? 1 : 0; ! 382: if (k->meta) mode += 2; ! 383: return lk201_translation( k->in_keyval, ! 384: k->out_keyval, ! 385: mode ); ! 386: } ! 387: default: ! 388: return D_INVALID_OPERATION; ! 389: } ! 390: leds->led_lights = 1; ! 391: leds->led_active = 1; ! 392: #if NBM > 0 ! 393: screen_enable_vretrace(unit, 1); /* interrupts on */ ! 394: #endif ! 395: return D_SUCCESS; ! 396: } ! 397: ! 398: /* ! 399: * Keycode translation tables ! 400: * ! 401: * NOTE: these tables have been compressed a little bit ! 402: * because the lk201 cannot generate very small codes. ! 403: */ ! 404: ! 405: unsigned char lk201_xlate_key[] = { ! 406: /* 86 */ 0 ,0 ! 407: /* 88 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 408: /* 96 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 409: /* 104 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 410: /* 112 */ ,0 ,0x1b ,0x08 ,'\n' ,0 ,0 ,0 ,0 ! 411: /* 120 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 412: /* 128 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 413: /* 136 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 414: /* 144 */ ,0 ,0 ,'0',0 ,'.','\r','1','2' ! 415: /* 152 */ ,'3','4','5','6',',','7','8','9' ! 416: /* 160 */ ,'-',0 ,0 ,0 ,0 ,0 ,0 ,0 ! 417: /* 168 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 418: /* 176 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 419: /* 184 */ ,0 ,0 ,0 ,0 ,0x7f,'\r','\t','`' ! 420: /* 192 */ ,'1' ,'q' ,'a' ,'z' ,0 ,'2' ,'w' ,'s' ! 421: /* 200 */ ,'x' ,'<' ,0 ,'3' ,'e' ,'d' ,'c' ,0 ! 422: /* 208 */ ,'4' ,'r' ,'f' ,'v' ,' ' ,0 ,'5' ,'t' ! 423: /* 216 */ ,'g' ,'b' ,0 ,'6' ,'y' ,'h' ,'n' ,0 ! 424: /* 224 */ ,'7' ,'u' ,'j' ,'m' ,0 ,'8' ,'i' ,'k' ! 425: /* 232 */ ,',' ,0 ,'9' ,'o' ,'l' ,'.' ,0 ,'0' ! 426: /* 240 */ ,'p' ,0 ,';' ,'/' ,0 ,'=' ,']' ,'\\' ! 427: /* 248 */ ,0 ,'-' ,'[' ,'\'' ,0 ,0 ,0 ,0 ! 428: }; ! 429: ! 430: unsigned char lk201_xlate_shifted[] = { ! 431: /* 86 */ 0 ,0 ! 432: /* 88 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 433: /* 96 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 434: /* 104 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 435: /* 112 */ ,0 ,0x1b ,0x08 ,'\n' ,0 ,0 ,0 ,0 ! 436: /* 120 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 437: /* 128 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 438: /* 136 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 439: /* 144 */ ,0 ,0 ,'0',0 ,'.','\r','1','2' ! 440: /* 152 */ ,'3','4','5','6',',','7','8','9' ! 441: /* 160 */ ,'-',0 ,0 ,0 ,0 ,0 ,0 ,0 ! 442: /* 168 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 443: /* 176 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 444: /* 184 */ ,0 ,0 ,0 ,0 ,0x7f ,'\r' ,'\t' ,'~' ! 445: /* 192 */ ,'!' ,'Q' ,'A' ,'Z' ,0 ,'@' ,'W' ,'S' ! 446: /* 200 */ ,'X' ,'>' ,0 ,'#' ,'E' ,'D' ,'C' ,0 ! 447: /* 208 */ ,'$' ,'R' ,'F' ,'V' ,' ' ,0 ,'%' ,'T' ! 448: /* 216 */ ,'G' ,'B' ,0 ,'^' ,'Y' ,'H' ,'N' ,0 ! 449: /* 224 */ ,'&' ,'U' ,'J' ,'M' ,0 ,'*' ,'I' ,'K' ! 450: /* 232 */ ,'<' ,0 ,'(' ,'O' ,'L' ,'>' ,0 ,')' ! 451: /* 240 */ ,'P' ,0 ,':' ,'?' ,0 ,'+' ,'}' ,'|' ! 452: /* 248 */ ,0 ,'_' ,'{' ,'"' ,0 ,0 ,0 ,0 ! 453: }; ! 454: ! 455: unsigned char lk201_xlate_meta[] = { ! 456: /* 86 */ 0 ,0 ! 457: /* 88 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 458: /* 96 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 459: /* 104 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 460: /* 112 */ ,0 ,0x1b ,0x08 ,'\n' ,0 ,0 ,0 ,0 ! 461: /* 120 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 462: /* 128 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 463: /* 136 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 464: /* 144 */ ,0 ,0 ,'0',0 ,'.','\r','1','2' ! 465: /* 152 */ ,'3','4','5','6',',','7','8','9' ! 466: /* 160 */ ,'-',0 ,0 ,0 ,0 ,0 ,0 ,0 ! 467: /* 168 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 468: /* 176 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 469: /* 184 */ ,0 ,0 ,0 ,0 ,0x7f ,'\r' ,'\t' ,'~' ! 470: /* 192 */ ,'!' ,'Q' ,'A' ,'Z' ,0 ,'@' ,'W' ,'S' ! 471: /* 200 */ ,'X' ,'>' ,0 ,'#' ,'E' ,'D' ,'C' ,0 ! 472: /* 208 */ ,'$' ,'R' ,'F' ,'V' ,' ' ,0 ,'%' ,'T' ! 473: /* 216 */ ,'G' ,'B' ,0 ,'^' ,'Y' ,'H' ,'N' ,0 ! 474: /* 224 */ ,'&' ,'U' ,'J' ,'M' ,0 ,'*' ,'I' ,'K' ! 475: /* 232 */ ,'<' ,0 ,'(' ,'O' ,'L' ,'>' ,0 ,')' ! 476: /* 240 */ ,'P' ,0 ,':' ,'?' ,0 ,'+' ,'}' ,'|' ! 477: /* 248 */ ,0 ,'_' ,'{' ,'"' ,0 ,0 ,0 ,0 ! 478: }; ! 479: ! 480: unsigned char lk201_xlate_shifted_meta[] = { ! 481: /* 86 */ 0 ,0 ! 482: /* 88 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 483: /* 96 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 484: /* 104 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 485: /* 112 */ ,0 ,0x1b ,0x08 ,'\n' ,0 ,0 ,0 ,0 ! 486: /* 120 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 487: /* 128 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 488: /* 136 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 489: /* 144 */ ,0 ,0 ,'0',0 ,'.','\r','1','2' ! 490: /* 152 */ ,'3','4','5','6',',','7','8','9' ! 491: /* 160 */ ,'-',0 ,0 ,0 ,0 ,0 ,0 ,0 ! 492: /* 168 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 493: /* 176 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ! 494: /* 184 */ ,0 ,0 ,0 ,0 ,0x7f ,'\r' ,'\t' ,'~' ! 495: /* 192 */ ,'!' ,'Q' ,'A' ,'Z' ,0 ,'@' ,'W' ,'S' ! 496: /* 200 */ ,'X' ,'>' ,0 ,'#' ,'E' ,'D' ,'C' ,0 ! 497: /* 208 */ ,'$' ,'R' ,'F' ,'V' ,' ' ,0 ,'%' ,'T' ! 498: /* 216 */ ,'G' ,'B' ,0 ,'^' ,'Y' ,'H' ,'N' ,0 ! 499: /* 224 */ ,'&' ,'U' ,'J' ,'M' ,0 ,'*' ,'I' ,'K' ! 500: /* 232 */ ,'<' ,0 ,'(' ,'O' ,'L' ,'>' ,0 ,')' ! 501: /* 240 */ ,'P' ,0 ,':' ,'?' ,0 ,'+' ,'}' ,'|' ! 502: /* 248 */ ,0 ,'_' ,'{' ,'"' ,0 ,0 ,0 ,0 ! 503: }; ! 504: ! 505: ! 506: io_return_t ! 507: lk201_translation( ! 508: int key, ! 509: char c, ! 510: int tabcode ) ! 511: { ! 512: unsigned char *table; ! 513: ! 514: if ((key &= 0xff) < LK_MINCODE) ! 515: return D_INVALID_OPERATION; ! 516: ! 517: switch (tabcode) { ! 518: case 3: ! 519: table = lk201_xlate_shifted_meta; ! 520: break; ! 521: case 2: ! 522: table = lk201_xlate_meta; ! 523: break; ! 524: case 1: ! 525: table = lk201_xlate_shifted; ! 526: break; ! 527: case 0: ! 528: default: ! 529: table = lk201_xlate_key; ! 530: break; ! 531: } ! 532: table[key - LK_MINCODE] = c; ! 533: return D_SUCCESS; ! 534: } ! 535: ! 536: /* ! 537: * Input character processing ! 538: */ ! 539: ! 540: lk201_rint( ! 541: int unit, ! 542: unsigned short data, ! 543: boolean_t handle_shift, ! 544: boolean_t from_kernel) ! 545: { ! 546: int c; ! 547: lk201_kbd_state_t *kbd = &lk201_softc[unit]->kbd; ! 548: ! 549: /* ! 550: * Keyboard touched, clean char to 8 bits. ! 551: */ ! 552: #if NBM > 0 ! 553: ssaver_bump(unit); ! 554: #endif ! 555: ! 556: data &= 0xff; ! 557: ! 558: /* Translate keycode into ASCII */ ! 559: if ((c = lk201_input(unit, data)) == -1) ! 560: return -1; ! 561: ! 562: #if NBM > 0 ! 563: /* ! 564: * Notify X, unless we are called from inside kernel ! 565: */ ! 566: if (!from_kernel && ! 567: screen_keypress_event(unit, DEV_KEYBD, data, EVT_BUTTON_RAW)) ! 568: return -1; ! 569: #endif ! 570: ! 571: /* Handle shifting if need to */ ! 572: if (kbd->kbd_gen_shift) ! 573: return (handle_shift) ? cngetc() : -1; ! 574: ! 575: return c; ! 576: } ! 577: ! 578: /* ! 579: * Routine to grock a character from LK201 ! 580: */ ! 581: #if MACH_KDB ! 582: int lk201_allow_kdb = 1; ! 583: #endif ! 584: ! 585: int lk201_debug = 0; ! 586: ! 587: lk201_input( ! 588: int unit, ! 589: unsigned short data) ! 590: { ! 591: int c, sl; ! 592: lk201_kbd_state_t *kbd = &lk201_softc[unit]->kbd; ! 593: ! 594: kbd->kbd_gen_shift = 0; ! 595: ! 596: #if MACH_KDB ! 597: if (lk201_allow_kdb && (data == LK_DO)) { ! 598: kdb_kintr(); ! 599: return -2; ! 600: } ! 601: #endif ! 602: ! 603: /* ! 604: * Sanity checks ! 605: */ ! 606: ! 607: if (data == LK_INPUT_ERR || data == LK_OUTPUT_ERR) { ! 608: printf(" Keyboard error, code = %x\n",data); ! 609: return -1; ! 610: } ! 611: if (data < LK_MINCODE) ! 612: return -1; ! 613: ! 614: /* ! 615: * Check special keys: shifts, ups, .. ! 616: */ ! 617: ! 618: if (data == LK_LOCK && (kbd->kbd_flags&mapLOCKtoCNTRL)) ! 619: data = LK_CNTRL; ! 620: ! 621: switch (data) { ! 622: case LK_LOCK: ! 623: kbd->kbd_lock ^= 1; ! 624: kbd->kbd_gen_shift = 1; ! 625: sl = lk201_softc[unit]->sl_unit; ! 626: /* called from interrupt, no need for spl */ ! 627: if (kbd->kbd_lock) ! 628: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_ON); ! 629: else ! 630: (*console_putc)(sl,SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_OFF); ! 631: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(0x4)); ! 632: return 0; ! 633: ! 634: case LK_ALT: ! 635: case LK_L_ALT: ! 636: case LK_R_ALT: ! 637: case LK_R_COMPOSE: ! 638: kbd->kbd_meta ^= 1; ! 639: kbd->kbd_gen_shift = 1; ! 640: return 0; ! 641: ! 642: case LK_SHIFT: ! 643: case LK_R_SHIFT: ! 644: kbd->kbd_shift ^= 1; ! 645: kbd->kbd_gen_shift = 1; ! 646: return 0; ! 647: ! 648: case LK_CNTRL: ! 649: kbd->kbd_ctrl ^= 1; ! 650: kbd->kbd_gen_shift = 1; ! 651: return 0; ! 652: ! 653: case LK_ALLUP: ! 654: kbd->kbd_ctrl = 0; ! 655: kbd->kbd_shift = 0; ! 656: kbd->kbd_meta = 0; ! 657: kbd->kbd_gen_shift = 1; ! 658: return 0; ! 659: ! 660: case LK_REPEAT: ! 661: c = kbd->kbd_previous; ! 662: break; ! 663: ! 664: default: ! 665: ! 666: /* ! 667: * Do the key translation to ASCII ! 668: */ ! 669: if (kbd->kbd_ctrl || kbd->kbd_lock || kbd->kbd_shift) { ! 670: c = ((kbd->kbd_meta) ? ! 671: lk201_xlate_shifted_meta : lk201_xlate_shifted) ! 672: [data - LK_MINCODE]; ! 673: if (kbd->kbd_ctrl) ! 674: c &= 0x1f; ! 675: } else ! 676: c = ((kbd->kbd_meta) ? ! 677: lk201_xlate_meta : lk201_xlate_key) ! 678: [data-LK_MINCODE]; ! 679: break; ! 680: ! 681: } ! 682: ! 683: kbd->kbd_previous = c; ! 684: ! 685: /* ! 686: * DEBUG code DEBUG ! 687: */ ! 688: if (lk201_debug && (c == 0)) { ! 689: printf("lk201: [%x]\n", data); ! 690: } ! 691: ! 692: return c; ! 693: } ! 694: ! 695: #endif /* NLK > 0 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.