|
|
1.1 ! root 1: /* ! 2: * Keyboard/display driver for German keyboard. ! 3: * Coherent, IBM PC/XT/AT (286 and 386). ! 4: */ ! 5: #include <sys/coherent.h> ! 6: #ifdef _I386 ! 7: #include <sys/reg.h> ! 8: #else ! 9: #include <sys/i8086.h> ! 10: #endif ! 11: #include <sys/con.h> ! 12: #include <sys/devices.h> ! 13: #include <errno.h> ! 14: #include <sys/stat.h> ! 15: #include <sys/tty.h> ! 16: #include <signal.h> ! 17: #include <sys/sched.h> ! 18: #include <sys/silo.h> ! 19: ! 20: #define SPC 0376 /* Special encoding */ ! 21: #define XXX 0377 /* Non-character */ ! 22: #define KBDATA 0x60 /* Keyboard data */ ! 23: #define KBCTRL 0x61 /* Keyboard control */ ! 24: #define KBFLAG 0x80 /* Keyboard reset flag */ ! 25: #define LEDCMD 0xED /* status indicator command */ ! 26: #define KBACK 0xFA /* status indicator acknowledge */ ! 27: #define EXTENDED0 0xE0 /* extended key seq initiator */ ! 28: #define EXTENDED1 0xE1 /* extended key seq initiator */ ! 29: ! 30: #define KEYUP 0x80 /* Key up change */ ! 31: #define KEYSC 0x7F /* Key scan code mask */ ! 32: #define LSHIFT 0x2A-1 /* Left shift key */ ! 33: #define LSHIFTA 0x2B-1 /* Alternate left-shift key */ ! 34: #define RSHIFT 0x36-1 /* Right shift key */ ! 35: #define CTRL 0x1D-1 /* Control key */ ! 36: /*-- #define CAPLOCK 0x1D-1 --*/ /* Control key */ ! 37: #define ALT 0x38-1 /* Alt key or ALT GR */ ! 38: #define CAPLOCK 0x3A-1 /* Caps lock key */ ! 39: /*-- #define CTRL 0x3A-1 --*/ /* Caps lock key */ ! 40: #define NUMLOCK 0x45-1 /* Numeric lock key */ ! 41: #define DELETE 0x53-1 /* Del, as in CTRL-ALT-DEL */ ! 42: #define BACKSP 0x0E-1 /* Back space */ ! 43: #define SCRLOCK 0x46-1 /* Scroll lock */ ! 44: ! 45: /* Shift flags */ ! 46: #define SRS 0x01 /* Right shift key on */ ! 47: #define SLS 0x02 /* Left shift key on */ ! 48: #define CTS 0x04 /* Ctrl key on */ ! 49: #define ALS 0x08 /* Alt key on */ ! 50: #define CPLS 0x10 /* Caps lock on */ ! 51: #define NMLS 0x20 /* Num lock on */ ! 52: #define AKPS 0x40 /* Alternate keypad shift */ ! 53: #define SHFT 0x80 /* Shift key flag */ ! 54: #define AGS 0x100 /* Alt Graphics on */ ! 55: ! 56: /* Function key information */ ! 57: #define NFKEY 20 /* Number of settable functions */ ! 58: #define NFCHAR 150 /* Number of characters settable */ ! 59: #define NFBUF (NFKEY*2+NFCHAR+1) /* Size of buffer */ ! 60: ! 61: /* ! 62: * Functions. ! 63: */ ! 64: int isrint(); ! 65: int istime(); ! 66: void isbatch(); ! 67: int mmstart(); ! 68: int isopen(); ! 69: int isclose(); ! 70: int isread(); ! 71: int mmwrite(); ! 72: int isioctl(); ! 73: void mmwatch(); ! 74: int isload(); ! 75: int isuload(); ! 76: int ispoll(); ! 77: int nulldev(); ! 78: int nonedev(); ! 79: ! 80: static int isioctl0(); ! 81: ! 82: /* ! 83: * Configuration table. ! 84: */ ! 85: CON iscon ={ ! 86: DFCHR|DFPOL, /* Flags */ ! 87: KB_MAJOR, /* Major index */ ! 88: isopen, /* Open */ ! 89: isclose, /* Close */ ! 90: nulldev, /* Block */ ! 91: isread, /* Read */ ! 92: mmwrite, /* Write */ ! 93: #ifdef _I386 ! 94: isioctl0, /* Ioctl */ ! 95: #else ! 96: isioctl, /* Ioctl */ ! 97: #endif ! 98: nulldev, /* Powerfail */ ! 99: mmwatch, /* Timeout */ ! 100: isload, /* Load */ ! 101: isuload, /* Unload */ ! 102: ispoll /* Poll */ ! 103: }; ! 104: ! 105: /* ! 106: * Flag indicating turbo machine. ! 107: */ ! 108: int isturbo = 0; ! 109: ! 110: /* ! 111: * Terminal structure. ! 112: */ ! 113: TTY istty = { ! 114: {0}, {0}, 0, mmstart, NULL, 0, 0 ! 115: }; ! 116: ! 117: static silo_t in_silo; ! 118: ! 119: /* ! 120: * State variables. ! 121: */ ! 122: int islock; /* Keyboard locked flag */ ! 123: int isbusy; /* Raw input conversion busy */ ! 124: static short shift; /* Overall shift state */ ! 125: static char scroll; /* Scroll lock state */ ! 126: static char lshift = LSHIFT; /* Left shift alternate state */ ! 127: static char isfbuf[NFBUF]; /* Function key values */ ! 128: static char *isfval[NFKEY]; /* Function key string pointers */ ! 129: static int ledcmd; /* LED update command flag */ ! 130: static int extended; /* extended key scan count */ ! 131: static char extmode; /* use extended mode for this key */ ! 132: static char ext0seen; /* 0xE0 prefix seen */ ! 133: ! 134: /* ! 135: * Tables for converting key code to ASCII. ! 136: * lmaptab specifies unshifted conversion, ! 137: * umaptab specifies shifted conversion, ! 138: * smaptab specifies the shift states which are active. ! 139: * An entry of XXX says the key is dead. ! 140: * An entry of SPC requires further processing. ! 141: * ! 142: * Key codes: ! 143: * ESC .. <- == 1 .. 14 ! 144: * -> .. \n == 15 .. 28 ! 145: * CTRL .. ` == 29 .. 41 ! 146: * ^Shift .. PrtSc == 42 .. 55 ! 147: * ALT .. CapsLock == 56 .. 58 ! 148: * F1 .. F10 == 59 .. 68 ! 149: * NumLock .. Del == 69 .. 83 ! 150: * ISO, F11, F12 == 86 .. 88 ! 151: */ ! 152: unsigned char agmaptab[] ={ /* Alt Gr */ ! 153: XXX, XXX,'\375','\374',XXX, XXX, XXX, /* 1 - 7 */ ! 154: '{', '[', ']', '}', '\\', XXX, XXX, XXX, /* 8 - 15 */ ! 155: '@', XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 16 - 23 */ ! 156: XXX, XXX, XXX, '~', XXX, XXX, XXX, XXX, /* 24 - 31 */ ! 157: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 32 - 39 */ ! 158: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 40 - 47 */ ! 159: XXX, XXX,'\346', XXX, XXX, XXX, XXX, XXX, /* 48 - 55 */ ! 160: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 56 - 63 */ ! 161: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 64 - 71 */ ! 162: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 72 - 79 */ ! 163: XXX, XXX, XXX, XXX, XXX, XXX, '|', XXX, /* 80 - 87 */ ! 164: XXX /* 88 */ ! 165: }; ! 166: ! 167: static unsigned char lmaptab[] ={ ! 168: '\33', '1', '2', '3', '4', '5', '6', /* 1 - 7 */ ! 169: '7', '8', '9', '0','\341','\'', '\b', '\t', /* 8 - 15 */ ! 170: 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* 16 - 23 */ ! 171: 'o', 'p','\201', '+', '\r', XXX, 'a', 's', /* 24 - 31 */ ! 172: 'd', 'f', 'g', 'h', 'j', 'k', 'l','\224', /* 32 - 39 */ ! 173: '\204','^', XXX, '#', 'y', 'x', 'c', 'v', /* 40 - 47 */ ! 174: 'b', 'n', 'm', ',', '.', SPC, XXX, SPC, /* 48 - 55 */ ! 175: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */ ! 176: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */ ! 177: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */ ! 178: SPC, SPC, SPC, SPC, XXX, XXX, '<', XXX, /* 80 - 87 */ ! 179: XXX /* 88 */ ! 180: }; ! 181: ! 182: static unsigned char umaptab[] ={ ! 183: '\33', '!', '"','\025', '$', '%', '&', /* 1 - 7 */ ! 184: '/', '(', ')', '=', '?', '`', '\b', SPC, /* 8 - 15 */ ! 185: 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', /* 16 - 23 */ ! 186: 'O', 'P','\232', '*', '\r', XXX, 'A', 'S', /* 24 - 31 */ ! 187: 'D', 'F', 'G', 'H', 'J', 'K', 'L','\231', /* 32 - 39 */ ! 188: '\216','\370',XXX,'\'', 'Y', 'X', 'C', 'V', /* 40 - 47 */ ! 189: 'B', 'N', 'M', ';', ':', SPC, XXX, SPC, /* 48 - 55 */ ! 190: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */ ! 191: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */ ! 192: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */ ! 193: SPC, SPC, SPC, SPC, XXX, XXX, '>', XXX, /* 80 - 87 */ ! 194: XXX /* 88 */ ! 195: }; ! 196: ! 197: #define SS0 0 /* No shift */ ! 198: #define SS1 (SLS|SRS|CTS) /* Shift, Ctrl */ ! 199: #define SES (SLS|SRS) /* Shift */ ! 200: #define LET (SLS|SRS|CPLS|CTS) /* Shift, Caps, Ctrl */ ! 201: #define KEY (SLS|SRS|NMLS|AKPS) /* Shift, Num, Alt keypad */ ! 202: ! 203: static unsigned char smaptab[] ={ ! 204: SS0, SES, SS1, SES, SES, SES, SS1, /* 1 - 7 */ ! 205: SES, SES, SES, SES, SS1, SES, CTS, SES, /* 8 - 15 */ ! 206: LET, LET, LET, LET, LET, LET, LET, LET, /* 16 - 23 */ ! 207: LET, LET, SS1, SS1, CTS, SHFT, LET, LET, /* 24 - 31 */ ! 208: LET, LET, LET, LET, LET, LET, LET, SES, /* 32 - 39 */ ! 209: SES, SS1, SHFT, SS1, LET, LET, LET, LET, /* 40 - 47 */ ! 210: LET, LET, LET, SES, SES, SES, SHFT, SES, /* 48 - 55 */ ! 211: SHFT, SS1, SHFT, SS0, SS0, SS0, SS0, SS0, /* 56 - 63 */ ! 212: SS0, SS0, SS0, SS0, SS0, SHFT, KEY, KEY, /* 64 - 71 */ ! 213: KEY, KEY, SS0, KEY, KEY, KEY, SS0, KEY, /* 72 - 79 */ ! 214: KEY, KEY, KEY, KEY, SS0, SS0, SES, SS0, /* 80 - 87 */ ! 215: SS0 ! 216: }; ! 217: ! 218: /* ! 219: * Load entry point. ! 220: * Do reset the keyboard because it gets terribly munged ! 221: * if you type during the boot. ! 222: */ ! 223: isload() ! 224: { ! 225: register short i;/* was: int i .. the loop below is hardly portable */ ! 226: ! 227: /* ! 228: * Reset keyboard if NOT an XT turbo. ! 229: */ ! 230: if ( ! isturbo ) { ! 231: outb(KBCTRL, 0x0C); /* Clock low */ ! 232: for (i = 10582; --i >= 0; ); /* For 20ms */ ! 233: outb(KBCTRL, 0xCC); /* Clock high */ ! 234: for (i = 0; --i != 0; ) ! 235: ; ! 236: i = inb(KBDATA); ! 237: outb(KBCTRL, 0xCC); /* Clear keyboard */ ! 238: outb(KBCTRL, 0x4D); /* Enable keyboard */ ! 239: } ! 240: ! 241: /* ! 242: * Enable mmwatch() invocation every second. ! 243: */ ! 244: drvl[KB_MAJOR].d_time = 1; ! 245: ! 246: /* ! 247: * Seize keyboard interrupt. ! 248: */ ! 249: setivec(1, isrint); ! 250: ! 251: /* ! 252: * Initialize video display. ! 253: */ ! 254: mmstart( &istty ); ! 255: } ! 256: ! 257: /* ! 258: * Unload entry point. ! 259: */ ! 260: isuload() ! 261: { ! 262: clrivec(1); ! 263: } ! 264: ! 265: /* ! 266: * Default function key strings (terminated by -1 [\377]) ! 267: */ ! 268: static char *deffuncs[] = { ! 269: "\33[1x\377", /* F1 */ ! 270: "\33[2x\377", /* F2 */ ! 271: "\33[3x\377", /* F3 */ ! 272: "\33[4x\377", /* F4 */ ! 273: "\33[5x\377", /* F5 */ ! 274: "\33[6x\377", /* F6 */ ! 275: "\33[7x\377", /* F7 */ ! 276: "\33[8x\377", /* F8 */ ! 277: "\33[9x\377", /* F9 */ ! 278: "\33[0x\377", /* F10 - historical value */ ! 279: "\33[1y\377", /* F11 */ ! 280: "\33[2y\377", /* F12 */ ! 281: "\33[3y\377", /* F13 */ ! 282: "\33[4y\377", /* F14 */ ! 283: "\33[5y\377", /* F15 */ ! 284: "\33[6y\377", /* F16 */ ! 285: "\33[7y\377", /* F17 */ ! 286: "\33[8y\377", /* F18 */ ! 287: "\33[9y\377", /* F19 */ ! 288: "\33[0y\377" /* F20 */ ! 289: }; ! 290: ! 291: /* ! 292: * Open routine. ! 293: */ ! 294: isopen(dev, mode) ! 295: dev_t dev; ! 296: unsigned int mode; ! 297: { ! 298: register int s; ! 299: ! 300: if (minor(dev) != 0) { ! 301: u.u_error = ENXIO; ! 302: return; ! 303: } ! 304: if ((istty.t_flags&T_EXCL)!=0 && super()==0) { ! 305: u.u_error = ENODEV; ! 306: return; ! 307: } ! 308: ttsetgrp(&istty, dev, mode); ! 309: ! 310: s = sphi(); ! 311: if (istty.t_open++ == 0) ! 312: { initkeys(); /* init function keys */ ! 313: istty.t_flags = T_CARR; /* indicate "carrier" */ ! 314: ttopen(&istty); ! 315: } ! 316: spl(s); ! 317: updleds(); /* update keyboard status LEDS */ ! 318: } ! 319: ! 320: /* Init function keys */ ! 321: initkeys() ! 322: { register int i; ! 323: register char *cp1, *cp2; ! 324: ! 325: for (i=0; i<NFKEY; i++) ! 326: isfval[i] = 0; /* clear function key buffer */ ! 327: cp2 = isfbuf; /* pointer to key buffer */ ! 328: for (i=0; i<NFKEY; i++) ! 329: { isfval[i] = cp2; /* save pointer to key string */ ! 330: cp1 = deffuncs[i]; /* get init string pointer */ ! 331: while ((*cp2++ = *cp1++) != -1) /* copy key data */ ! 332: if (cp2 >= &isfbuf[NFBUF-3]) /* overflow? */ ! 333: return; ! 334: } ! 335: } ! 336: ! 337: /* ! 338: * Close a tty. ! 339: */ ! 340: isclose(dev) ! 341: { ! 342: register int s; ! 343: ! 344: s = sphi(); ! 345: if (--istty.t_open == 0) ! 346: { s = sphi(); ! 347: ttclose(&istty); ! 348: spl(s); ! 349: } ! 350: } ! 351: ! 352: /* ! 353: * Read routine. ! 354: */ ! 355: isread(dev, iop) ! 356: dev_t dev; ! 357: IO *iop; ! 358: { ! 359: ttread(&istty, iop, 0); ! 360: if (istty.t_oq.cq_cc) ! 361: mmtime(&istty); ! 362: } ! 363: ! 364: /* ! 365: * Ioctl routine. ! 366: */ ! 367: #ifdef _I386 ! 368: isioctl0(dev, com, vec) ! 369: dev_t dev; ! 370: struct sgttyb *vec; ! 371: { ! 372: tioc286(dev, com, vec, isioctl); ! 373: } ! 374: #endif ! 375: ! 376: isioctl(dev, com, vec) ! 377: dev_t dev; ! 378: struct sgttyb *vec; ! 379: { ! 380: register int s; ! 381: ! 382: switch(com) { ! 383: case TIOCSETF: ! 384: case TIOCGETF: ! 385: isfunction(com, (char *)vec); ! 386: goto ioc_done;; ! 387: case TIOCSHIFT: /* switch left-SHIFT and "\" */ ! 388: lshift = LSHIFTA; /* alternate values */ ! 389: lmaptab[41] = '\\'; ! 390: lmaptab[42] = XXX; ! 391: umaptab[41] = '|'; ! 392: umaptab[42] = XXX; ! 393: smaptab[41] = SS1; ! 394: smaptab[42] = SHFT; ! 395: goto ioc_done;; ! 396: case TIOCCSHIFT: /* normal (default) left-SHIFT and "\" */ ! 397: lshift = LSHIFT; /* normal values */ ! 398: lmaptab[41] = XXX; ! 399: lmaptab[42] = '\\'; ! 400: umaptab[41] = XXX; ! 401: umaptab[42] = '|'; ! 402: smaptab[41] = SHFT; ! 403: smaptab[42] = SS1; ! 404: goto ioc_done;; ! 405: } ! 406: s = sphi(); ! 407: ttioctl(&istty, com, vec); ! 408: spl(s); ! 409: ! 410: ioc_done: ! 411: return; ! 412: } ! 413: ! 414: /* ! 415: * Set and receive the function keys. ! 416: */ ! 417: isfunction(c, v) ! 418: int c; ! 419: char *v; ! 420: { ! 421: register char *cp; ! 422: register int i; ! 423: ! 424: if (c == TIOCGETF) { ! 425: for (cp = isfbuf; cp < &isfbuf[NFBUF]; cp++) ! 426: putubd(v++, *cp); ! 427: } else { ! 428: for (i=0; i<NFKEY; i++) /* zap current settings */ ! 429: isfval[i] = 0; ! 430: cp = isfbuf; /* pointer to key buffer */ ! 431: for (i=0; i<NFKEY; i++) { ! 432: isfval[i] = cp; /* save pointer to key string */ ! 433: while ((*cp++ = getubd(v++)) != -1) /* copy key data */ ! 434: if (cp >= &isfbuf[NFBUF-3]) /* overflow? */ ! 435: return; ! 436: } ! 437: } ! 438: } ! 439: ! 440: ! 441: /* ! 442: * Poll routine. ! 443: */ ! 444: ispoll( dev, ev, msec ) ! 445: dev_t dev; ! 446: int ev; ! 447: int msec; ! 448: { ! 449: return ttpoll(&istty, ev, msec); ! 450: } ! 451: ! 452: /* ! 453: * Receive interrupt. ! 454: */ ! 455: isrint() ! 456: { ! 457: register int c; ! 458: register int s; ! 459: register int r; ! 460: int savests; ! 461: int update_leds = 0; ! 462: ! 463: /* ! 464: * Schedule raw input handler if not already active. ! 465: */ ! 466: if ( isbusy == 0 ) { ! 467: isbusy = 1; ! 468: defer( isbatch, &istty ); ! 469: } ! 470: ! 471: /* ! 472: * Pull character from the data ! 473: * port. Pulse the KBFLAG in the control ! 474: * port to reset the data buffer. ! 475: */ ! 476: r = inb(KBDATA) & 0xFF; ! 477: c = inb(KBCTRL); ! 478: outb(KBCTRL, c|KBFLAG); ! 479: outb(KBCTRL, c); ! 480: #if KBDEBUG ! 481: printf("kbd: 0x%x ", r); /* print scan code/direction */ ! 482: #endif ! 483: if (ledcmd) { ! 484: ledcmd = 0; ! 485: if (r == KBACK) { /* output to status LEDS */ ! 486: c = scroll & 1; ! 487: if (shift & NMLS) ! 488: c |= 2; ! 489: if (shift & CPLS) ! 490: c |= 4; ! 491: outb(KBDATA, c); ! 492: } ! 493: return; ! 494: } ! 495: if (extended > 0) { /* if multi-character seq, */ ! 496: --extended; /* ... ignore this char */ ! 497: return; ! 498: } ! 499: switch (r) { ! 500: case EXTENDED0: /* 0xE0 prefix found */ ! 501: ext0seen = 1; ! 502: return; ! 503: case EXTENDED1: /* ignore extended sequences */ ! 504: extended = 5; ! 505: return; ! 506: case 0xFF: /* Overrun */ ! 507: return; ! 508: } ! 509: ! 510: if (ext0seen) { ! 511: ext0seen = 0; ! 512: extmode = 1; ! 513: } else ! 514: extmode = 0; ! 515: ! 516: c = (r & KEYSC) - 1; ! 517: /* ! 518: * Check for reset. ! 519: */ ! 520: if ((r&KEYUP) == 0 && c == DELETE && (shift&(CTS|ALS)) == (CTS|ALS)) ! 521: boot(); ! 522: ! 523: /* ! 524: * Track "shift" keys. ! 525: */ ! 526: s = smaptab[c]; ! 527: if (s&SHFT) { ! 528: if (r&KEYUP) { /* "shift" released */ ! 529: if (c == RSHIFT) ! 530: shift &= ~SRS; ! 531: else if (c == lshift) ! 532: shift &= ~SLS; ! 533: else if (c == CTRL) ! 534: shift &= ~CTS; ! 535: else if (c == ALT) ! 536: shift &= extmode ? ~AGS : ~ALS; ! 537: } else { /* "shift" pressed */ ! 538: if (c == lshift) ! 539: shift |= SLS; ! 540: else if (c == RSHIFT) ! 541: shift |= SRS; ! 542: else if (c == CTRL) ! 543: shift |= CTS; ! 544: else if (c == ALT) ! 545: shift |= extmode ? AGS : ALS; ! 546: else if (c == CAPLOCK) { ! 547: shift ^= CPLS; /* toggle cap lock */ ! 548: updleds(); ! 549: } else if (c == NUMLOCK) { ! 550: shift ^= NMLS; /* toggle num lock */ ! 551: updleds(); ! 552: } ! 553: } ! 554: return; ! 555: } ! 556: ! 557: /* ! 558: * No other key up codes of interest. ! 559: */ ! 560: if (r&KEYUP) ! 561: return; ! 562: ! 563: /* ! 564: * If the tty is not open the character is ! 565: * just tossed away. ! 566: */ ! 567: if (istty.t_open == 0) ! 568: return; ! 569: ! 570: /* ! 571: * Map character, based on the ! 572: * current state of the shift, control, alt graphics, ! 573: * meta (ALT) and lock flags. ! 574: */ ! 575: if (shift & AGS) /* Alt Graphics ? */ ! 576: c = agmaptab[c]; ! 577: else if (shift & CTS) { ! 578: if (s == CTS) /* Map Ctrl (BS | NL) */ ! 579: c = (c == BACKSP) ? 0x7F : 0x0A; ! 580: else if (s==SS1 || s==LET) /* Normal Ctrl map */ ! 581: c = umaptab[c]&0x1F; /* Clear bits 5-6 */ ! 582: else ! 583: return; /* Ignore this char */ ! 584: } else if (s &= shift) { ! 585: if (shift & SES) { /* if shift on */ ! 586: if (s & (CPLS|NMLS)) /* if caps/num lock */ ! 587: c = lmaptab[c]; /* use unshifted */ ! 588: else ! 589: c = umaptab[c]; /* use shifted */ ! 590: } else { /* if shift not on */ ! 591: if (s & (CPLS|NMLS)) /* if caps/num lock */ ! 592: c = umaptab[c]; /* use shifted */ ! 593: else ! 594: c = lmaptab[c]; /* use unshifted */ ! 595: } ! 596: } else ! 597: c = lmaptab[c]; /* use unshifted */ ! 598: ! 599: /* ! 600: * Act on character. ! 601: */ ! 602: if (c == XXX) ! 603: return; /* char to ignore */ ! 604: ! 605: if (c != SPC) { /* not special char? */ ! 606: if (shift & ALS) /* ALT (meta bit)? */ ! 607: c |= 0x80; /* set meta */ ! 608: isin(c); /* send the char */ ! 609: } else ! 610: update_leds += isspecial(r); /* special chars */ ! 611: if (update_leds) { ! 612: savests = sphi(); ! 613: outb(KBDATA, LEDCMD); ! 614: ledcmd = 1; ! 615: spl(savests); ! 616: } ! 617: } ! 618: ! 619: /* ! 620: * Handle special input sequences. ! 621: * The character passed is the key number. ! 622: * ! 623: * The keypad is translated by the following table, ! 624: * the first entry is the normal sequence, the second the shifted, ! 625: * and the third the alternate keypad sequence. ! 626: */ ! 627: static char *keypad[][3] = { ! 628: { "\33[H", "7", "\33?w" }, /* 71 */ ! 629: { "\33[A", "8", "\33?x" }, /* 72 */ ! 630: { "\33[V", "9", "\33?y" }, /* 73 */ ! 631: { "\33[D", "4", "\33?t" }, /* 75 */ ! 632: { "\0337", "5", "\33?u" }, /* 76 */ ! 633: { "\33[C", "6", "\33?v" }, /* 77 */ ! 634: { "\33[24H","1", "\33?q" }, /* 79 */ ! 635: { "\33[B", "2", "\33?r" }, /* 80 */ ! 636: { "\33[U", "3", "\33?s" }, /* 81 */ ! 637: { "\33[@", "0", "\33?p" }, /* 82 */ ! 638: { "\33[P", ".", "\33?n" } /* 83 */ ! 639: }; ! 640: ! 641: isspecial(c) ! 642: int c; ! 643: { ! 644: register char *cp; ! 645: register int s; ! 646: int update_leds = 0; ! 647: ! 648: cp = 0; ! 649: ! 650: switch (c) { ! 651: case 15: /* cursor back tab */ ! 652: cp = "\033[Z"; ! 653: break; ! 654: case 53: ! 655: if (extmode) ! 656: cp = "/"; ! 657: else if (shift & SES) ! 658: cp = "_"; ! 659: else ! 660: cp = "-"; ! 661: break; ! 662: case 55: /* ignore PrtScr */ ! 663: if (!extmode) ! 664: cp = "*"; ! 665: break; ! 666: case 59: case 60: case 61: case 62: case 63: /* Function keys */ ! 667: case 64: case 65: case 66: case 67: case 68: ! 668: /* offset to function string */ ! 669: if ( shift & ALS ) ! 670: cp = isfval[c-49]; ! 671: else ! 672: cp = isfval[c-59]; ! 673: break; ! 674: ! 675: case 70: /* Scroll Lock -- stop/start output */ ! 676: { ! 677: static char cbuf[2]; ! 678: ! 679: cp = &cbuf[0]; /* working buffer */ ! 680: if (!(istty.t_sgttyb.sg_flags&RAWIN)) { /* not if in RAW mode */ ! 681: ++update_leds; ! 682: if (istty.t_flags & T_STOP) { /* output stopped? */ ! 683: cbuf[0] = istty.t_tchars.t_startc; /* start it */ ! 684: scroll = 0; ! 685: } else { ! 686: cbuf[0] = istty.t_tchars.t_stopc; /* stop output */ ! 687: scroll = 1; ! 688: } ! 689: } ! 690: break; ! 691: } ! 692: ! 693: case 79: /* 1/End */ ! 694: case 80: /* 2/DOWN */ ! 695: case 81: /* 3/PgDn */ ! 696: case 82: /* 0/Ins */ ! 697: case 83: /* ./Del */ ! 698: --c; /* adjust code */ ! 699: case 75: /* 4/LEFT */ ! 700: case 76: /* 5 */ ! 701: case 77: /* 6/RIGHT */ ! 702: --c; /* adjust code */ ! 703: case 71: /* 7/Home/Clear */ ! 704: case 72: /* 8/UP */ ! 705: case 73: /* 9/PgUp */ ! 706: s = 0; /* start off with normal keypad */ ! 707: if (shift & NMLS) /* num lock? */ ! 708: s = 1; /* set shift pad */ ! 709: if (shift & SES) /* shift? */ ! 710: s ^= 1; /* toggle shift pad */ ! 711: if (shift & AKPS) /* alternate pad? */ ! 712: s = 2; /* set alternate pad */ ! 713: if (extmode) /* not from keypad? */ ! 714: s = 0; /* force normal sequence */ ! 715: cp = keypad[c-71][s]; /* get keypad value */ ! 716: break; ! 717: } ! 718: if (cp) /* send string */ ! 719: while ((*cp != 0) && (*cp != -1)) ! 720: isin( *cp++ & 0377 ); ! 721: return update_leds; ! 722: } ! 723: ! 724: /** ! 725: * ! 726: * void ! 727: * ismmfunc( c ) -- process keyboard related output escape sequences ! 728: * char c; ! 729: */ ! 730: void ! 731: ismmfunc(c) ! 732: register int c; ! 733: { ! 734: switch (c) { ! 735: case 't': /* Enter numlock */ ! 736: shift |= NMLS; ! 737: updleds(); /* update LED status */ ! 738: break; ! 739: case 'u': /* Leave numlock */ ! 740: shift &= ~NMLS; ! 741: updleds(); /* update LED status */ ! 742: break; ! 743: case '=': /* Enter alternate keypad */ ! 744: shift |= AKPS; ! 745: break; ! 746: case '>': /* Exit alternate keypad */ ! 747: shift &= ~AKPS; ! 748: break; ! 749: case 'c': /* Reset terminal */ ! 750: islock = 0; ! 751: shift = 0; ! 752: initkeys(); ! 753: updleds(); /* update LED status */ ! 754: break; ! 755: } ! 756: } ! 757: ! 758: /** ! 759: * ! 760: * void ! 761: * isin( c ) -- append character to raw input silo ! 762: * char c; ! 763: */ ! 764: static ! 765: isin( c ) ! 766: register int c; ! 767: { ! 768: int cache_it = 1; ! 769: TTY * tp = &istty; ! 770: ! 771: /* ! 772: * If using software incoming flow control, process and ! 773: * discard t_stopc and t_startc. ! 774: */ ! 775: if (!ISRIN) { ! 776: if (ISSTOP) { ! 777: if ((tp->t_flags&T_STOP) == 0) ! 778: tp->t_flags |= T_STOP; ! 779: cache_it = 0; ! 780: } ! 781: if (ISSTART) { ! 782: tp->t_flags &= ~T_STOP; ! 783: ttstart(tp); ! 784: cache_it = 0; ! 785: } ! 786: } ! 787: ! 788: /* ! 789: * Cache received character. ! 790: */ ! 791: if (cache_it) { ! 792: in_silo.si_buf[ in_silo.si_ix ] = c; ! 793: ! 794: if ( ++in_silo.si_ix >= sizeof(in_silo.si_buf) ) ! 795: in_silo.si_ix = 0; ! 796: } ! 797: } ! 798: ! 799: /** ! 800: * ! 801: * void ! 802: * isbatch() -- raw input conversion routine ! 803: * ! 804: * Action: Enable the video display. ! 805: * Canonize the raw input silo. ! 806: * ! 807: * Notes: isbatch() was scheduled as a deferred process by isrint(). ! 808: */ ! 809: static void ! 810: isbatch( tp ) ! 811: register TTY * tp; ! 812: { ! 813: register int c; ! 814: static int lastc; ! 815: ! 816: /* ! 817: * Ensure video display is enabled. ! 818: */ ! 819: mm_von(); ! 820: ! 821: isbusy = 0; ! 822: ! 823: /* ! 824: * Process all cached characters. ! 825: */ ! 826: while ( in_silo.si_ix != in_silo.si_ox ) { ! 827: ! 828: /* ! 829: * Get next cached char. ! 830: */ ! 831: c = in_silo.si_buf[ in_silo.si_ox ]; ! 832: ! 833: if ( in_silo.si_ox >= sizeof(in_silo.si_buf) - 1 ) ! 834: in_silo.si_ox = 0; ! 835: else ! 836: in_silo.si_ox++; ! 837: ! 838: if ( (islock == 0) || ISINTR || ISQUIT ) { ! 839: ttin( tp, c ); ! 840: } ! 841: ! 842: else if ( (c == 'b') && (lastc == '\033') ) { ! 843: islock = 0; ! 844: ttin( tp, lastc ); ! 845: ttin( tp, c ); ! 846: } ! 847: ! 848: else if ( (c == 'c') && (lastc == '\033') ) { ! 849: ttin( tp, lastc ); ! 850: ttin( tp, c ); ! 851: } ! 852: ! 853: else ! 854: putchar('\007'); ! 855: ! 856: lastc = c; ! 857: } ! 858: } ! 859: ! 860: /* ! 861: * update the keyboard status LEDS ! 862: */ ! 863: updleds() ! 864: { ! 865: int s; ! 866: ! 867: s = sphi(); ! 868: outb(KBDATA, LEDCMD); ! 869: ledcmd = 1; ! 870: spl(s); ! 871: } ! 872: ! 873: /* ! 874: * unlock the scroll in case an interrupt character is received ! 875: */ ! 876: kbunscroll() ! 877: { ! 878: scroll = 0; ! 879: updleds(); ! 880: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.