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