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