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