|
|
1.1 ! root 1: /* ! 2: * io.386/kb_d.c ! 3: * ! 4: * Keyboard driver, no virtual consoles, no loadable tables, German. ! 5: * ! 6: * Revised: Fri Jul 16 08:39:12 1993 CDT ! 7: */ ! 8: ! 9: #include <sys/coherent.h> ! 10: #include <sys/reg.h> ! 11: #include <sys/con.h> ! 12: #include <sys/devices.h> ! 13: #include <sys/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 50 /* Number of settable functions */ ! 58: #define NFCHAR 150 /* Number of characters settable */ ! 59: #define NFBUF (NFKEY*2+NFCHAR+1) /* Size of buffer */ ! 60: ! 61: #define ESCAPE_CHAR '\x1B' ! 62: #define ESCAPE_STRING "\x1B" ! 63: #define HEXFF_STRING "\xFF" ! 64: #define DELETE_STRING "\x7F" ! 65: ! 66: /* ! 67: * Functions. ! 68: */ ! 69: int isrint(); ! 70: int istime(); ! 71: void isbatch(); ! 72: int mmstart(); ! 73: int isopen(); ! 74: int isclose(); ! 75: int isread(); ! 76: int mmwrite(); ! 77: int isioctl(); ! 78: void mmwatch(); ! 79: int isload(); ! 80: int isuload(); ! 81: int ispoll(); ! 82: int nulldev(); ! 83: int nonedev(); ! 84: ! 85: /* ! 86: * Configuration table. ! 87: */ ! 88: CON iscon ={ ! 89: DFCHR|DFPOL, /* Flags */ ! 90: KB_MAJOR, /* Major index */ ! 91: isopen, /* Open */ ! 92: isclose, /* Close */ ! 93: nulldev, /* Block */ ! 94: isread, /* Read */ ! 95: mmwrite, /* Write */ ! 96: isioctl, /* Ioctl */ ! 97: nulldev, /* Powerfail */ ! 98: mmwatch, /* Timeout */ ! 99: isload, /* Load */ ! 100: isuload, /* Unload */ ! 101: ispoll /* Poll */ ! 102: }; ! 103: ! 104: /* ! 105: * Flag indicating turbo machine. ! 106: */ ! 107: int isturbo = 0; ! 108: ! 109: /* ! 110: * Terminal structure. ! 111: */ ! 112: TTY istty = { ! 113: {0}, {0}, 0, mmstart, NULL, 0, 0 ! 114: }; ! 115: ! 116: static silo_t in_silo; ! 117: ! 118: /* ! 119: * State variables. ! 120: */ ! 121: int islock; /* Keyboard locked flag */ ! 122: int isbusy; /* Raw input conversion busy */ ! 123: static short shift; /* Overall shift state */ ! 124: static char scroll; /* Scroll lock state */ ! 125: static char lshift = LSHIFT; /* Left shift alternate state */ ! 126: static char isfbuf[NFBUF]; /* Function key values */ ! 127: static char *isfval[NFKEY]; /* Function key string pointers */ ! 128: static int ledcmd; /* LED update command flag */ ! 129: static int extended; /* extended key scan count */ ! 130: static char extmode; /* use extended mode for this key */ ! 131: static char ext0seen; /* 0xE0 prefix seen */ ! 132: static int xlate = 1; /* scan code translation flag */ ! 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: ESCAPE_CHAR, '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: ESCAPE_CHAR, '!', '"','\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, SS1, SS1, SS1, SS1, SS1, /* 56 - 63 */ ! 212: SS1, SS1, SS1, SS1, SS1, 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: /* Normal keypresses */ ! 270: ESCAPE_STRING "[M" HEXFF_STRING, /* F1 */ ! 271: ESCAPE_STRING "[N" HEXFF_STRING, /* F2 */ ! 272: ESCAPE_STRING "[O" HEXFF_STRING, /* F3 */ ! 273: ESCAPE_STRING "[P" HEXFF_STRING, /* F4 */ ! 274: ESCAPE_STRING "[Q" HEXFF_STRING, /* F5 */ ! 275: ESCAPE_STRING "[R" HEXFF_STRING, /* F6 */ ! 276: ESCAPE_STRING "[S" HEXFF_STRING, /* F7 */ ! 277: ESCAPE_STRING "[T" HEXFF_STRING, /* F8 */ ! 278: ESCAPE_STRING "[U" HEXFF_STRING, /* F9 */ ! 279: ESCAPE_STRING "[V" HEXFF_STRING, /* F10 - historical value */ ! 280: ! 281: /* Shifted keypresses */ ! 282: ESCAPE_STRING "[Y" HEXFF_STRING, /* sF1 */ ! 283: ESCAPE_STRING "[Z" HEXFF_STRING, /* sF2 */ ! 284: ESCAPE_STRING "[a" HEXFF_STRING, /* sF3 */ ! 285: ESCAPE_STRING "[b" HEXFF_STRING, /* sF4 */ ! 286: ESCAPE_STRING "[c" HEXFF_STRING, /* sF5 */ ! 287: ESCAPE_STRING "[d" HEXFF_STRING, /* sF6 */ ! 288: ESCAPE_STRING "[e" HEXFF_STRING, /* sF7 */ ! 289: ESCAPE_STRING "[f" HEXFF_STRING, /* sF8 */ ! 290: ESCAPE_STRING "[g" HEXFF_STRING, /* sF9 */ ! 291: ESCAPE_STRING "[h" HEXFF_STRING, /* sF10 */ ! 292: ! 293: /* Ctrl-ed keypresses */ ! 294: ESCAPE_STRING "[k" HEXFF_STRING, /* cF1 */ ! 295: ESCAPE_STRING "[l" HEXFF_STRING, /* cF2 */ ! 296: ESCAPE_STRING "[m" HEXFF_STRING, /* cF3 */ ! 297: ESCAPE_STRING "[n" HEXFF_STRING, /* cF4 */ ! 298: ESCAPE_STRING "[o" HEXFF_STRING, /* cF5 */ ! 299: ESCAPE_STRING "[p" HEXFF_STRING, /* cF6 */ ! 300: ESCAPE_STRING "[q" HEXFF_STRING, /* cF7 */ ! 301: ESCAPE_STRING "[r" HEXFF_STRING, /* cF8 */ ! 302: ESCAPE_STRING "[s" HEXFF_STRING, /* cF9 */ ! 303: ESCAPE_STRING "[t" HEXFF_STRING, /* cF10 */ ! 304: ! 305: /* Ctrl-Shift-ed Keypresses ;) */ ! 306: ESCAPE_STRING "[w" HEXFF_STRING, /* csF1 */ ! 307: ESCAPE_STRING "[x" HEXFF_STRING, /* csF2 */ ! 308: ESCAPE_STRING "[y" HEXFF_STRING, /* csF3 */ ! 309: ESCAPE_STRING "[z" HEXFF_STRING, /* csF4 */ ! 310: ESCAPE_STRING "[@" HEXFF_STRING, /* csF5 */ ! 311: ESCAPE_STRING "[[" HEXFF_STRING, /* csF6 */ ! 312: ESCAPE_STRING "[\\" HEXFF_STRING, /* csF7 */ ! 313: ESCAPE_STRING "[]" HEXFF_STRING, /* csF8 */ ! 314: ESCAPE_STRING "[^" HEXFF_STRING, /* csF9 */ ! 315: ESCAPE_STRING "[_" HEXFF_STRING, /* csF10 */ ! 316: ! 317: /* Alt keys -- use original 83 key settings since these ! 318: are not defined with a default for virtual terminals */ ! 319: ESCAPE_STRING "[1y" HEXFF_STRING, /* aF1 */ ! 320: ESCAPE_STRING "[2y" HEXFF_STRING, /* aF2 */ ! 321: ESCAPE_STRING "[3y" HEXFF_STRING, /* aF3 */ ! 322: ESCAPE_STRING "[4y" HEXFF_STRING, /* aF4 */ ! 323: ESCAPE_STRING "[5y" HEXFF_STRING, /* aF5 */ ! 324: ESCAPE_STRING "[6y" HEXFF_STRING, /* aF6 */ ! 325: ESCAPE_STRING "[7y" HEXFF_STRING, /* aF7 */ ! 326: ESCAPE_STRING "[8y" HEXFF_STRING, /* aF8 */ ! 327: ESCAPE_STRING "[9y" HEXFF_STRING, /* aF9 */ ! 328: ESCAPE_STRING "[0y" HEXFF_STRING /* aF10 */ ! 329: }; ! 330: ! 331: /* ! 332: * Open routine. ! 333: */ ! 334: isopen(dev, mode) ! 335: dev_t dev; ! 336: unsigned int mode; ! 337: { ! 338: register int s; ! 339: ! 340: if (minor(dev) != 0) { ! 341: u.u_error = ENXIO; ! 342: return; ! 343: } ! 344: if ((istty.t_flags&T_EXCL)!=0 && super()==0) { ! 345: u.u_error = ENODEV; ! 346: return; ! 347: } ! 348: ttsetgrp(&istty, dev, mode); ! 349: ! 350: s = sphi(); ! 351: if (istty.t_open++ == 0) ! 352: { initkeys(); /* init function keys */ ! 353: istty.t_flags = T_CARR; /* indicate "carrier" */ ! 354: ttopen(&istty); ! 355: } ! 356: spl(s); ! 357: updleds(); /* update keyboard status LEDS */ ! 358: } ! 359: ! 360: /* Init function keys */ ! 361: initkeys() ! 362: { register int i; ! 363: register char *cp1, *cp2; ! 364: ! 365: for (i=0; i<NFKEY; i++) ! 366: isfval[i] = 0; /* clear function key buffer */ ! 367: cp2 = isfbuf; /* pointer to key buffer */ ! 368: for (i=0; i<NFKEY; i++) ! 369: { isfval[i] = cp2; /* save pointer to key string */ ! 370: cp1 = deffuncs[i]; /* get init string pointer */ ! 371: while ((*cp2++ = *cp1++) != -1) /* copy key data */ ! 372: if (cp2 >= &isfbuf[NFBUF-3]) /* overflow? */ ! 373: return; ! 374: } ! 375: } ! 376: ! 377: /* ! 378: * Close a tty. ! 379: */ ! 380: isclose(dev) ! 381: { ! 382: register int s; ! 383: ! 384: s = sphi(); ! 385: if (--istty.t_open == 0) ! 386: { s = sphi(); ! 387: ttclose(&istty); ! 388: spl(s); ! 389: } ! 390: } ! 391: ! 392: /* ! 393: * Read routine. ! 394: */ ! 395: isread(dev, iop) ! 396: dev_t dev; ! 397: IO *iop; ! 398: { ! 399: ttread(&istty, iop, 0); ! 400: if (istty.t_oq.cq_cc) ! 401: mmtime(&istty); ! 402: } ! 403: ! 404: /* ! 405: * Ioctl routine. ! 406: */ ! 407: /* ! 408: * special struct for the KDMAPDISP call ! 409: */ ! 410: ! 411: #define KDMAPDISP (('K' << 8) | 2) /* map display into user space */ ! 412: #define KDSKBMODE (('K' << 8) | 6) /* turn scan code xlate on/off */ ! 413: #define KDMEMDISP (('K' << 8) | 7) /* dump byte of virt/phys mem */ ! 414: #define KDENABIO (('K' << 8) | 60) /* enable IO */ ! 415: #define KIOCSOUND (('K' << 8) | 63) /* start sound generation */ ! 416: #define KDSETLED (('K' << 8) | 66) /* set leds */ ! 417: ! 418: #define TIMER_CTL 0x43 /* Timer control */ ! 419: #define TIMER_CNT 0x42 /* Timer counter */ ! 420: #define SPEAKER_CTL 0x61 /* Speaker control */ ! 421: ! 422: struct kd_memloc { ! 423: char *vaddr; /* virtual address to map to */ ! 424: char *physaddr; /* physical address to map to */ ! 425: long length; /* size in bytes to map */ ! 426: long ioflg; /* enable I/O addresses if non-zero */ ! 427: }; ! 428: ! 429: static TIM tp; ! 430: int ! 431: kbstate(action) ! 432: int action; ! 433: { ! 434: int i; ! 435: if (action == 1) { ! 436: timeout(&tp,20,kbstate,2); ! 437: outb(KBCTRL, 0xCC); /* Clock high */ ! 438: } ! 439: if (action == 2) { ! 440: i = inb(KBDATA); ! 441: outb(KBCTRL, 0xCC); /* Clear keyboard */ ! 442: outb(KBCTRL, 0x4D); /* Enable keyboard */ ! 443: } ! 444: } ! 445: ! 446: static int X11led; ! 447: ! 448: isioctl(dev, com, vec) ! 449: dev_t dev; ! 450: struct sgttyb *vec; ! 451: { ! 452: register int s; ! 453: ! 454: switch(com) { ! 455: #define KDDEBUG 0 ! 456: #if KDDEBUG ! 457: case KDMEMDISP: ! 458: { ! 459: struct kd_memloc* mem; ! 460: unsigned char ub, pb; ! 461: mem = vec; ! 462: pxcopy( mem->physaddr, &pb, 1, SEG_386_KD ); ! 463: ub = getubd( mem->vaddr ); ! 464: printf( "User's byte %x(%x), Physical byte %x, Addresses %x %x\n", ! 465: mem->ioflg, ub, pb, mem->vaddr, mem->physaddr ); ! 466: goto ioc_done;; ! 467: } ! 468: #endif ! 469: case KDMAPDISP: ! 470: { ! 471: struct kd_memloc* mem; ! 472: mem = vec; ! 473: #if KDDEBUG ! 474: printf( "mapPhysUser(%x, %x, %x) = %d\n", ! 475: mem->vaddr, mem->physaddr, mem->length, ! 476: #endif ! 477: mapPhysUser(mem->vaddr, mem->physaddr, mem->length) ! 478: #if KDDEBUG ! 479: ) ! 480: #endif ! 481: ; ! 482: } ! 483: case KDENABIO: ! 484: { ! 485: int i; ! 486: for (i = 0 ; i < 64 ; i++ ) ! 487: iomapAnd(0,i); ! 488: goto ioc_done;; ! 489: } ! 490: case KIOCSOUND: ! 491: { ! 492: if (vec) { ! 493: outb(TIMER_CTL, 0xB6); ! 494: outb(TIMER_CNT, (int)vec&0xFF); ! 495: outb(TIMER_CNT, (int)vec>>8); ! 496: outb(SPEAKER_CTL, inb(SPEAKER_CTL) | 03); /* Turn speaker on */ ! 497: } ! 498: else ! 499: outb(SPEAKER_CTL, inb(SPEAKER_CTL) & ~03 ); /* speaker off */ ! 500: goto ioc_done;; ! 501: } ! 502: case KDSKBMODE: ! 503: { ! 504: outb(KBCTRL, 0x0C); /* Clock low */ ! 505: timeout(&tp,3,kbstate,1); /* wait about 20-30ms */ ! 506: xlate = (int)vec; ! 507: goto ioc_done;; ! 508: } ! 509: case KDSETLED: ! 510: { ! 511: X11led = (int)vec; ! 512: updleds(); ! 513: goto ioc_done;; ! 514: } ! 515: ! 516: case TIOCSETF: ! 517: case TIOCGETF: ! 518: isfunction(com, (char *)vec); ! 519: goto ioc_done;; ! 520: case TIOCSHIFT: /* switch left-SHIFT and "\" */ ! 521: lshift = LSHIFTA; /* alternate values */ ! 522: lmaptab[41] = '\\'; ! 523: lmaptab[42] = XXX; ! 524: umaptab[41] = '|'; ! 525: umaptab[42] = XXX; ! 526: smaptab[41] = SS1; ! 527: smaptab[42] = SHFT; ! 528: goto ioc_done;; ! 529: case TIOCCSHIFT: /* normal (default) left-SHIFT and "\" */ ! 530: lshift = LSHIFT; /* normal values */ ! 531: lmaptab[41] = XXX; ! 532: lmaptab[42] = '\\'; ! 533: umaptab[41] = XXX; ! 534: umaptab[42] = '|'; ! 535: smaptab[41] = SHFT; ! 536: smaptab[42] = SS1; ! 537: goto ioc_done;; ! 538: } ! 539: s = sphi(); ! 540: ttioctl(&istty, com, vec); ! 541: spl(s); ! 542: ! 543: ioc_done: ! 544: return; ! 545: } ! 546: ! 547: /* ! 548: * Set and receive the function keys. ! 549: */ ! 550: isfunction(c, v) ! 551: int c; ! 552: char *v; ! 553: { ! 554: register char *cp; ! 555: register int i; ! 556: ! 557: if (c == TIOCGETF) { ! 558: for (cp = isfbuf; cp < &isfbuf[NFBUF]; cp++) ! 559: putubd(v++, *cp); ! 560: } else { ! 561: for (i=0; i<NFKEY; i++) /* zap current settings */ ! 562: isfval[i] = 0; ! 563: cp = isfbuf; /* pointer to key buffer */ ! 564: for (i=0; i<NFKEY; i++) { ! 565: isfval[i] = cp; /* save pointer to key string */ ! 566: while ((*cp++ = getubd(v++)) != -1) /* copy key data */ ! 567: if (cp >= &isfbuf[NFBUF-3]) /* overflow? */ ! 568: return; ! 569: } ! 570: } ! 571: } ! 572: ! 573: ! 574: /* ! 575: * Poll routine. ! 576: */ ! 577: ispoll( dev, ev, msec ) ! 578: dev_t dev; ! 579: int ev; ! 580: int msec; ! 581: { ! 582: return ttpoll(&istty, ev, msec); ! 583: } ! 584: ! 585: /* ! 586: * Receive interrupt. ! 587: */ ! 588: isrint() ! 589: { ! 590: register int c; ! 591: register int s; ! 592: register int r; ! 593: int savests; ! 594: int update_leds = 0; ! 595: ! 596: /* ! 597: * Schedule raw input handler if not already active. ! 598: */ ! 599: if ( isbusy == 0 ) { ! 600: isbusy = 1; ! 601: defer( isbatch, &istty ); ! 602: } ! 603: ! 604: /* ! 605: * Pull character from the data ! 606: * port. Pulse the KBFLAG in the control ! 607: * port to reset the data buffer. ! 608: */ ! 609: r = inb(KBDATA) & 0xFF; ! 610: c = inb(KBCTRL); ! 611: outb(KBCTRL, c|KBFLAG); ! 612: outb(KBCTRL, c); ! 613: if (!xlate) { ! 614: if (ledcmd) { ! 615: ledcmd = 0; ! 616: if (r == KBACK) { /* output to status LEDS */ ! 617: outb(KBDATA, X11led); ! 618: return; ! 619: } ! 620: } ! 621: isin(r); ! 622: return; ! 623: } ! 624: ! 625: #if KBDEBUG ! 626: printf("kbd: 0x%x ", r); /* print scan code/direction */ ! 627: #endif ! 628: if (ledcmd) { ! 629: ledcmd = 0; ! 630: if (r == KBACK) { /* output to status LEDS */ ! 631: c = scroll & 1; ! 632: if (shift & NMLS) ! 633: c |= 2; ! 634: if (shift & CPLS) ! 635: c |= 4; ! 636: outb(KBDATA, c); ! 637: } ! 638: return; ! 639: } ! 640: if (extended > 0) { /* if multi-character seq, */ ! 641: --extended; /* ... ignore this char */ ! 642: return; ! 643: } ! 644: switch (r) { ! 645: case EXTENDED0: /* 0xE0 prefix found */ ! 646: ext0seen = 1; ! 647: return; ! 648: case EXTENDED1: /* ignore extended sequences */ ! 649: extended = 5; ! 650: return; ! 651: case 0xFF: /* Overrun */ ! 652: return; ! 653: } ! 654: ! 655: if (ext0seen) { ! 656: ext0seen = 0; ! 657: extmode = 1; ! 658: } else ! 659: extmode = 0; ! 660: ! 661: c = (r & KEYSC) - 1; ! 662: /* ! 663: * Check for reset. ! 664: */ ! 665: if ((r&KEYUP) == 0 && c == DELETE && (shift&(CTS|ALS)) == (CTS|ALS)) ! 666: boot(); ! 667: ! 668: /* ! 669: * Track "shift" keys. ! 670: */ ! 671: s = smaptab[c]; ! 672: if (s&SHFT) { ! 673: if (r&KEYUP) { /* "shift" released */ ! 674: if (c == RSHIFT) ! 675: shift &= ~SRS; ! 676: else if (c == lshift) ! 677: shift &= ~SLS; ! 678: else if (c == CTRL) ! 679: shift &= ~CTS; ! 680: else if (c == ALT) ! 681: shift &= extmode ? ~AGS : ~ALS; ! 682: } else { /* "shift" pressed */ ! 683: if (c == lshift) ! 684: shift |= SLS; ! 685: else if (c == RSHIFT) ! 686: shift |= SRS; ! 687: else if (c == CTRL) ! 688: shift |= CTS; ! 689: else if (c == ALT) ! 690: shift |= extmode ? AGS : ALS; ! 691: else if (c == CAPLOCK) { ! 692: shift ^= CPLS; /* toggle cap lock */ ! 693: updleds(); ! 694: } else if (c == NUMLOCK) { ! 695: shift ^= NMLS; /* toggle num lock */ ! 696: updleds(); ! 697: } ! 698: } ! 699: return; ! 700: } ! 701: ! 702: /* ! 703: * No other key up codes of interest. ! 704: */ ! 705: if (r&KEYUP) ! 706: return; ! 707: ! 708: /* ! 709: * If the tty is not open the character is ! 710: * just tossed away. ! 711: */ ! 712: if (istty.t_open == 0) ! 713: return; ! 714: ! 715: /* ! 716: * Map character, based on the ! 717: * current state of the shift, control, alt graphics, ! 718: * meta (ALT) and lock flags. ! 719: */ ! 720: if (shift & AGS) /* Alt Graphics ? */ ! 721: c = agmaptab[c]; ! 722: else if (shift & CTS) { ! 723: if (s == CTS) /* Map Ctrl (BS | NL) */ ! 724: c = (c == BACKSP) ? 0x7F : 0x0A; ! 725: else if (s==SS1 || s==LET) { /* Normal Ctrl map */ ! 726: if((c = umaptab[c]) != SPC) ! 727: c &= 0x1F; /* Clear bits 5-6 */ ! 728: } else ! 729: return; /* Ignore this char */ ! 730: } else if (s &= shift) { ! 731: if (shift & SES) { /* if shift on */ ! 732: if (s & (CPLS|NMLS)) /* if caps/num lock */ ! 733: c = lmaptab[c]; /* use unshifted */ ! 734: else ! 735: c = umaptab[c]; /* use shifted */ ! 736: } else { /* if shift not on */ ! 737: if (s & (CPLS|NMLS)) /* if caps/num lock */ ! 738: c = umaptab[c]; /* use shifted */ ! 739: else ! 740: c = lmaptab[c]; /* use unshifted */ ! 741: } ! 742: } else ! 743: c = lmaptab[c]; /* use unshifted */ ! 744: ! 745: /* ! 746: * Act on character. ! 747: */ ! 748: if (c == XXX) ! 749: return; /* char to ignore */ ! 750: ! 751: if (c != SPC) { /* not special char? */ ! 752: if (shift & ALS) /* ALT (meta bit)? */ ! 753: c |= 0x80; /* set meta */ ! 754: isin(c); /* send the char */ ! 755: } else ! 756: update_leds += isspecial(r); /* special chars */ ! 757: if (update_leds) { ! 758: savests = sphi(); ! 759: outb(KBDATA, LEDCMD); ! 760: ledcmd = 1; ! 761: spl(savests); ! 762: } ! 763: } ! 764: ! 765: /* ! 766: * Handle special input sequences. ! 767: * The character passed is the key number. ! 768: * ! 769: * The keypad is translated by the following table, ! 770: * the first entry is the normal sequence, the second the shifted, ! 771: * and the third the alternate keypad sequence. ! 772: */ ! 773: static char *keypad[][3] = { ! 774: { ESCAPE_STRING "[H", "7", ESCAPE_STRING "?w" }, /* 71 */ ! 775: { ESCAPE_STRING "[A", "8", ESCAPE_STRING "?x" }, /* 72 */ ! 776: { ESCAPE_STRING "[I", "9", ESCAPE_STRING "?y" }, /* 73 */ ! 777: { ESCAPE_STRING "[D", "4", ESCAPE_STRING "?t" }, /* 75 */ ! 778: { ESCAPE_STRING "7", "5", ESCAPE_STRING "?u" }, /* 76 */ ! 779: { ESCAPE_STRING "[C", "6", ESCAPE_STRING "?v" }, /* 77 */ ! 780: { ESCAPE_STRING "[F", "1", ESCAPE_STRING "?q" }, /* 79 */ ! 781: { ESCAPE_STRING "[B", "2", ESCAPE_STRING "?r" }, /* 80 */ ! 782: { ESCAPE_STRING "[G", "3", ESCAPE_STRING "?s" }, /* 81 */ ! 783: { ESCAPE_STRING "[L", "0", ESCAPE_STRING "?p" }, /* 82 */ ! 784: { DELETE_STRING , ".", ESCAPE_STRING "?n" } /* 83 */ ! 785: }; ! 786: ! 787: isspecial(c) ! 788: int c; ! 789: { ! 790: register char *cp; ! 791: register int s; ! 792: int update_leds = 0; ! 793: ! 794: cp = 0; ! 795: ! 796: switch (c) { ! 797: case 15: /* cursor back tab */ ! 798: cp = ESCAPE_STRING "[Z"; ! 799: break; ! 800: case 53: ! 801: if (extmode) ! 802: cp = "/"; ! 803: else if (shift & SES) ! 804: cp = "_"; ! 805: else ! 806: cp = "-"; ! 807: break; ! 808: case 55: /* ignore PrtScr */ ! 809: if (!extmode) ! 810: cp = "*"; ! 811: break; ! 812: case 59: case 60: case 61: case 62: case 63: /* Function keys */ ! 813: case 64: case 65: case 66: case 67: case 68: ! 814: /* offset to function string */ ! 815: if (shift & ALS) ! 816: cp = isfval[c-19]; /* alt-Fx */ ! 817: else { if ((shift & (SES)) && (shift & CTS)) /* CTRL-Shift-Fx */ ! 818: cp = isfval[c-29]; ! 819: else { if (shift & CTS) /* CTRL-Fx */ ! 820: cp = isfval[c-39]; ! 821: else { if(shift & (SES)) /* Shift-Fx */ ! 822: cp = isfval[c-49]; ! 823: else cp = isfval[c-59]; /* Plain Fx */ ! 824: } ! 825: } ! 826: } ! 827: break; ! 828: ! 829: case 70: /* Scroll Lock -- stop/start output */ ! 830: { ! 831: static char cbuf[2]; ! 832: ! 833: cp = &cbuf[0]; /* working buffer */ ! 834: if (!(istty.t_sgttyb.sg_flags&RAWIN)) { /* not if in RAW mode */ ! 835: ++update_leds; ! 836: if (istty.t_flags & T_STOP) { /* output stopped? */ ! 837: cbuf[0] = istty.t_tchars.t_startc; /* start it */ ! 838: scroll = 0; ! 839: } else { ! 840: cbuf[0] = istty.t_tchars.t_stopc; /* stop output */ ! 841: scroll = 1; ! 842: } ! 843: } ! 844: break; ! 845: } ! 846: ! 847: case 79: /* 1/End */ ! 848: case 80: /* 2/DOWN */ ! 849: case 81: /* 3/PgDn */ ! 850: case 82: /* 0/Ins */ ! 851: case 83: /* ./Del */ ! 852: --c; /* adjust code */ ! 853: case 75: /* 4/LEFT */ ! 854: case 76: /* 5 */ ! 855: case 77: /* 6/RIGHT */ ! 856: --c; /* adjust code */ ! 857: case 71: /* 7/Home/Clear */ ! 858: case 72: /* 8/UP */ ! 859: case 73: /* 9/PgUp */ ! 860: s = 0; /* start off with normal keypad */ ! 861: if (shift & NMLS) /* num lock? */ ! 862: s = 1; /* set shift pad */ ! 863: if (shift & SES) /* shift? */ ! 864: s ^= 1; /* toggle shift pad */ ! 865: if (shift & AKPS) /* alternate pad? */ ! 866: s = 2; /* set alternate pad */ ! 867: if (extmode) /* not from keypad? */ ! 868: s = 0; /* force normal sequence */ ! 869: cp = keypad[c-71][s]; /* get keypad value */ ! 870: break; ! 871: } ! 872: if (cp) /* send string */ ! 873: while ((*cp != 0) && (*cp != -1)) ! 874: isin( *cp++ & 0377 ); ! 875: return update_leds; ! 876: } ! 877: ! 878: /** ! 879: * ! 880: * void ! 881: * ismmfunc( c ) -- process keyboard related output escape sequences ! 882: * char c; ! 883: */ ! 884: void ! 885: ismmfunc(c) ! 886: register int c; ! 887: { ! 888: switch (c) { ! 889: case 't': /* Enter numlock */ ! 890: shift |= NMLS; ! 891: updleds(); /* update LED status */ ! 892: break; ! 893: case 'u': /* Leave numlock */ ! 894: shift &= ~NMLS; ! 895: updleds(); /* update LED status */ ! 896: break; ! 897: case '=': /* Enter alternate keypad */ ! 898: shift |= AKPS; ! 899: break; ! 900: case '>': /* Exit alternate keypad */ ! 901: shift &= ~AKPS; ! 902: break; ! 903: case 'c': /* Reset terminal */ ! 904: islock = 0; ! 905: shift = 0; ! 906: initkeys(); ! 907: updleds(); /* update LED status */ ! 908: break; ! 909: } ! 910: } ! 911: ! 912: /** ! 913: * ! 914: * void ! 915: * isin( c ) -- append character to raw input silo ! 916: * char c; ! 917: */ ! 918: static ! 919: isin( c ) ! 920: register int c; ! 921: { ! 922: int cache_it = 1; ! 923: TTY * tp = &istty; ! 924: ! 925: /* ! 926: * If using software incoming flow control, process and ! 927: * discard t_stopc and t_startc. ! 928: */ ! 929: if (_IS_IXON_MODE (tp)) { ! 930: #if _I386 ! 931: if (_IS_START_CHAR (tp, c) || ! 932: (_IS_IXANY_MODE (tp) && (tp->t_flags & T_STOP) != 0)) { ! 933: tp->t_flags &= ~(T_STOP | T_XSTOP); ! 934: ttstart(tp); ! 935: cache_it = 0; ! 936: } else if (_IS_STOP_CHAR (tp, c)) { ! 937: if ((tp->t_flags&T_STOP) == 0) ! 938: tp->t_flags |= (T_STOP | T_XSTOP); ! 939: cache_it = 0; ! 940: } ! 941: #else ! 942: if (_IS_STOP_CHAR (tp, c)) { ! 943: if ((tp->t_flags&T_STOP) == 0) ! 944: tp->t_flags |= T_STOP; ! 945: cache_it = 0; ! 946: } ! 947: if (_IS_START_CHAR (tp, c)) { ! 948: tp->t_flags &= ~T_STOP; ! 949: ttstart (tp); ! 950: cache_it = 0; ! 951: } ! 952: #endif ! 953: } ! 954: ! 955: /* ! 956: * Cache received character. ! 957: */ ! 958: if (cache_it) { ! 959: in_silo.si_buf[ in_silo.si_ix ] = c; ! 960: ! 961: if ( ++in_silo.si_ix >= sizeof(in_silo.si_buf) ) ! 962: in_silo.si_ix = 0; ! 963: } ! 964: } ! 965: ! 966: /** ! 967: * ! 968: * void ! 969: * isbatch() -- raw input conversion routine ! 970: * ! 971: * Action: Enable the video display. ! 972: * Canonize the raw input silo. ! 973: * ! 974: * Notes: isbatch() was scheduled as a deferred process by isrint(). ! 975: */ ! 976: static void ! 977: isbatch( tp ) ! 978: register TTY * tp; ! 979: { ! 980: register int c; ! 981: static int lastc; ! 982: ! 983: /* ! 984: * Ensure video display is enabled. ! 985: */ ! 986: mm_von(); ! 987: ! 988: isbusy = 0; ! 989: ! 990: /* ! 991: * Process all cached characters. ! 992: */ ! 993: while ( in_silo.si_ix != in_silo.si_ox ) { ! 994: ! 995: /* ! 996: * Get next cached char. ! 997: */ ! 998: c = in_silo.si_buf[ in_silo.si_ox ]; ! 999: ! 1000: if ( in_silo.si_ox >= sizeof(in_silo.si_buf) - 1 ) ! 1001: in_silo.si_ox = 0; ! 1002: else ! 1003: in_silo.si_ox++; ! 1004: ! 1005: if (islock == 0 || _IS_INTERRUPT_CHAR (tp, c) || ! 1006: _IS_QUIT_CHAR (tp, c)) { ! 1007: ttin (tp, c); ! 1008: } else if (c == 'b' && lastc == ESCAPE_CHAR) { ! 1009: islock = 0; ! 1010: ttin (tp, lastc); ! 1011: ttin (tp, c); ! 1012: } else if (c == 'c' && lastc == ESCAPE_CHAR) { ! 1013: ttin (tp, lastc); ! 1014: ttin (tp, c); ! 1015: } else ! 1016: putchar ('\a'); ! 1017: ! 1018: lastc = c; ! 1019: } ! 1020: } ! 1021: ! 1022: /* ! 1023: * update the keyboard status LEDS ! 1024: */ ! 1025: updleds() ! 1026: { ! 1027: int s; ! 1028: ! 1029: s = sphi(); ! 1030: outb(KBDATA, LEDCMD); ! 1031: ledcmd = 1; ! 1032: spl(s); ! 1033: } ! 1034: ! 1035: /* ! 1036: * unlock the scroll in case an interrupt character is received ! 1037: */ ! 1038: kbunscroll() ! 1039: { ! 1040: scroll = 0; ! 1041: updleds(); ! 1042: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.