|
|
1.1 ! root 1: /* ! 2: * io.386/vtkb_d.c ! 3: * ! 4: * Keyboard driver, 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: #include <sys/kb.h> ! 20: #include <sys/vt.h> ! 21: ! 22: #define ISVEC 1 /* Keyboard interrupt vector */ ! 23: #define DEBUG 0 ! 24: ! 25: #define SPC 0376 /* Special encoding */ ! 26: #define XXX 0377 /* Non-character */ ! 27: #define KBDATA 0x60 /* Keyboard data */ ! 28: #define KBCTRL 0x61 /* Keyboard control */ ! 29: #define KBFLAG 0x80 /* Keyboard reset flag */ ! 30: #define LEDCMD 0xED /* status indicator command */ ! 31: #define KBACK 0xFA /* status indicator acknowledge */ ! 32: #define EXTENDED0 0xE0 /* extended key seq initiator */ ! 33: #define EXTENDED1 0xE1 /* extended key seq initiator */ ! 34: ! 35: #define KEYUP 0x80 /* Key up change */ ! 36: #define KEYSC 0x7F /* Key scan code mask */ ! 37: #define LSHIFT 0x2A-1 /* Left shift key */ ! 38: #define LSHIFTA 0x2B-1 /* Alternate left-shift key */ ! 39: #define RSHIFT 0x36-1 /* Right shift key */ ! 40: #define CTRLkb 0x1D-1 /* Control key */ ! 41: /*-- #define CAPLOCK 0x1D-1 --*/ /* Control key */ ! 42: #define ALTkb 0x38-1 /* Alt key or ALT GR */ ! 43: #define CAPLOCK 0x3A-1 /* Caps lock key */ ! 44: /*-- #define CTRL 0x3A-1 --*/ /* Caps lock key */ ! 45: #define NUMLOCK 0x45-1 /* Numeric lock key */ ! 46: #define DELETE 0x53-1 /* Del, as in CTRL-ALT-DEL */ ! 47: #define BACKSP 0x0E-1 /* Back space */ ! 48: #define SCRLOCK 0x46-1 /* Scroll lock */ ! 49: ! 50: /* Shift flags */ ! 51: #define SRS 0x01 /* Right shift key on */ ! 52: #define SLS 0x02 /* Left shift key on */ ! 53: #define CTS 0x04 /* Ctrl key on */ ! 54: #define ALS 0x08 /* Alt key on */ ! 55: #define CPLS 0x10 /* Caps lock on */ ! 56: #define NMLS 0x20 /* Num lock on */ ! 57: #define AKPS 0x40 /* Alternate keypad shift */ ! 58: #define SHFT 0x80 /* Shift key flag */ ! 59: #define AGS 0x100 /* Alt Graphics on */ ! 60: ! 61: /* Function key information */ ! 62: #define NFKEY 50 /* Number of settable functions */ ! 63: #define NFCHAR 150 /* Number of characters settable */ ! 64: #define NFBUF (NFKEY*2+NFCHAR+1) /* Size of buffer */ ! 65: ! 66: #define ESCAPE_CHAR '\x1B' ! 67: #define ESCAPE_STRING "\x1B" ! 68: #define HEXFF_STRING "\xFF" ! 69: #define DELETE_STRING "\x7F" ! 70: ! 71: /* ! 72: * Functions. ! 73: */ ! 74: int isrint(); ! 75: int istime(); ! 76: void isbatch(); ! 77: int mmstart(); ! 78: int isopen(); ! 79: int isclose(); ! 80: int isread(); ! 81: int mmwrite(); ! 82: int isioctl(); ! 83: void mmwatch(); ! 84: int isload(); ! 85: int isuload(); ! 86: int ispoll(); ! 87: int nulldev(); ! 88: int nonedev(); ! 89: ! 90: /* ! 91: * Configuration table. ! 92: */ ! 93: CON iscon ={ ! 94: DFCHR|DFPOL, /* Flags */ ! 95: KB_MAJOR, /* Major index */ ! 96: isopen, /* Open */ ! 97: isclose, /* Close */ ! 98: nulldev, /* Block */ ! 99: isread, /* Read */ ! 100: mmwrite, /* Write */ ! 101: isioctl, /* Ioctl */ ! 102: nulldev, /* Powerfail */ ! 103: mmwatch, /* Timeout */ ! 104: isload, /* Load */ ! 105: isuload, /* Unload */ ! 106: ispoll /* Poll */ ! 107: }; ! 108: ! 109: /* ! 110: * Flag indicating turbo machine. ! 111: */ ! 112: int isturbo = 0; ! 113: ! 114: /* ! 115: ============================================================================== ! 116: ============================================================================== ! 117: */ ! 118: /* constants for vtdata[] */ ! 119: #define VT_VGAPORT 0x3D4 ! 120: #define VT_MONOPORT 0x3B4 ! 121: ! 122: #define VT_MONOBASE (SEG_VIDEOa|DPL_1) ! 123: #define VT_VGABASE (SEG_VIDEOb|DPL_1) ! 124: ! 125: /* ! 126: Patchable table entrys, ! 127: we go indirect in order to produce a label which can be addressed ! 128: */ ! 129: HWentry VTVGA = { 4, 0, VT_VGAPORT, { 0, VT_VGABASE }, { 25, 80 } }; ! 130: HWentry VTMONO = { 4, 0, VT_MONOPORT, { 0, VT_MONOBASE }, { 25, 80 } }; ! 131: ! 132: HWentry *vtHWtable[] = { ! 133: VTVGA, /* VGA followed by MONO is compatible to DOS */ ! 134: VTMONO, ! 135: 0 /* MUST STAY AS LAST ELEMENT !!! */ ! 136: }; ! 137: ! 138: extern int mminit(); ! 139: static VTDATA const_vtdata = { ! 140: mminit, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 23, 24, 0, 0, 0, 23, 0, 0, 1 ! 141: }; ! 142: ! 143: /* later this should be dynamic */ ! 144: VTDATA *vtconsole, **vtdata; ! 145: ! 146: int vtcount, vtmax; ! 147: extern int vtactive; ! 148: int vt_verbose = { 0 }; ! 149: int vt_opened = { 0 }; ! 150: ! 151: /* Terminal structure. */ ! 152: TTY **vttty; ! 153: ! 154: /* ! 155: ============================================================================== ! 156: ============================================================================== ! 157: */ ! 158: ! 159: static silo_t in_silo; ! 160: ! 161: /* ! 162: * State variables. ! 163: */ ! 164: int islock; /* Keyboard locked flag */ ! 165: int isbusy; /* Raw input conversion busy */ ! 166: static unsigned shift; /* Overall shift state */ ! 167: static char scrollkb; /* Scroll lock state */ ! 168: static char lshiftkb = LSHIFT; /* Left shift alternate state */ ! 169: static char isfbuf[NFBUF]; /* Function key values */ ! 170: static char *isfval[NFKEY]; /* Function key string pointers */ ! 171: static int ledcmd; /* LED update command flag */ ! 172: static int extended; /* extended key scan count */ ! 173: static char extmode; /* use extended mode for this key */ ! 174: static char ext0seen; /* 0xE0 prefix seen */ ! 175: static char fk_loaded; /* true == funcion keys resident */ ! 176: static int xlate =1; /* scan code translation flag */ ! 177: ! 178: /* ! 179: * Tables for converting key code to ASCII. ! 180: * lmaptab specifies unshifted conversion, ! 181: * umaptab specifies shifted conversion, ! 182: * smaptab specifies the shift states which are active. ! 183: * An entry of XXX says the key is dead. ! 184: * An entry of SPC requires further processing. ! 185: * ! 186: * Key codes: ! 187: * ESC .. <- == 1 .. 14 ! 188: * -> .. \n == 15 .. 28 ! 189: * CTRL .. ` == 29 .. 41 ! 190: * ^Shift .. PrtSc == 42 .. 55 ! 191: * ALT .. CapsLock == 56 .. 58 ! 192: * F1 .. F10 == 59 .. 68 ! 193: * NumLock .. Del == 69 .. 83 ! 194: * ISO, F11, F12 == 86 .. 88 ! 195: */ ! 196: unsigned char agmaptab[] ={ /* Alt Gr */ ! 197: XXX, XXX,'\375','\374',XXX, XXX, XXX, /* 1 - 7 */ ! 198: '{', '[', ']', '}', '\\', XXX, XXX, XXX, /* 8 - 15 */ ! 199: '@', XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 16 - 23 */ ! 200: XXX, XXX, XXX, '~', XXX, XXX, XXX, XXX, /* 24 - 31 */ ! 201: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 32 - 39 */ ! 202: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 40 - 47 */ ! 203: XXX, XXX,'\346', XXX, XXX, XXX, XXX, XXX, /* 48 - 55 */ ! 204: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 56 - 63 */ ! 205: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 64 - 71 */ ! 206: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 72 - 79 */ ! 207: XXX, XXX, XXX, XXX, XXX, XXX, '|', XXX, /* 80 - 87 */ ! 208: XXX /* 88 */ ! 209: }; ! 210: ! 211: static unsigned char lmaptab[] ={ ! 212: ESCAPE_CHAR, '1', '2', '3', '4', '5', '6', /* 1 - 7 */ ! 213: '7', '8', '9', '0','\341','\'', '\b', '\t', /* 8 - 15 */ ! 214: 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* 16 - 23 */ ! 215: 'o', 'p','\201', '+', '\r', XXX, 'a', 's', /* 24 - 31 */ ! 216: 'd', 'f', 'g', 'h', 'j', 'k', 'l','\224', /* 32 - 39 */ ! 217: '\204','^', XXX, '#', 'y', 'x', 'c', 'v', /* 40 - 47 */ ! 218: 'b', 'n', 'm', ',', '.', SPC, XXX, SPC, /* 48 - 55 */ ! 219: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */ ! 220: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */ ! 221: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */ ! 222: SPC, SPC, SPC, SPC, XXX, XXX, '<', XXX, /* 80 - 87 */ ! 223: XXX /* 88 */ ! 224: }; ! 225: ! 226: static unsigned char umaptab[] ={ ! 227: ESCAPE_CHAR, '!', '"','\025', '$', '%', '&', /* 1 - 7 */ ! 228: '/', '(', ')', '=', '?', '`', '\b', SPC, /* 8 - 15 */ ! 229: 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', /* 16 - 23 */ ! 230: 'O', 'P','\232', '*', '\r', XXX, 'A', 'S', /* 24 - 31 */ ! 231: 'D', 'F', 'G', 'H', 'J', 'K', 'L','\231', /* 32 - 39 */ ! 232: '\216','\370',XXX,'\'', 'Y', 'X', 'C', 'V', /* 40 - 47 */ ! 233: 'B', 'N', 'M', ';', ':', SPC, XXX, SPC, /* 48 - 55 */ ! 234: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */ ! 235: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */ ! 236: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */ ! 237: SPC, SPC, SPC, SPC, XXX, XXX, '>', XXX, /* 80 - 87 */ ! 238: XXX /* 88 */ ! 239: }; ! 240: ! 241: #define SS0 0 /* No shift */ ! 242: #define SS1 (SLS|SRS|CTS) /* Shift, Ctrl */ ! 243: #define SES (SLS|SRS) /* Shift */ ! 244: #define LET (SLS|SRS|CPLS|CTS) /* Shift, Caps, Ctrl */ ! 245: #define KEY (SLS|SRS|NMLS|AKPS) /* Shift, Num, Alt keypad */ ! 246: ! 247: static unsigned char smaptab[] ={ ! 248: SS0, SES, SS1, SES, SES, SES, SS1, /* 1 - 7 */ ! 249: SES, SES, SES, SES, SS1, SES, CTS, SES, /* 8 - 15 */ ! 250: LET, LET, LET, LET, LET, LET, LET, LET, /* 16 - 23 */ ! 251: LET, LET, SS1, SS1, CTS, SHFT, LET, LET, /* 24 - 31 */ ! 252: LET, LET, LET, LET, LET, LET, LET, SES, /* 32 - 39 */ ! 253: SES, SS1, SHFT, SS1, LET, LET, LET, LET, /* 40 - 47 */ ! 254: LET, LET, LET, SES, SES, SES, SHFT, SES, /* 48 - 55 */ ! 255: SHFT, SS1, SHFT, SS1, SS1, SS1, SS1, SS1, /* 56 - 63 */ ! 256: SS1, SS1, SS1, SS1, SS1, SHFT, KEY, KEY, /* 64 - 71 */ ! 257: KEY, KEY, SS0, KEY, KEY, KEY, SS0, KEY, /* 72 - 79 */ ! 258: KEY, KEY, KEY, KEY, SS0, SS0, SES, SS0, /* 80 - 87 */ ! 259: SS0 ! 260: }; ! 261: ! 262: /* ! 263: * Load entry point. ! 264: * Do reset the keyboard because it gets terribly munged ! 265: * if you type during the boot. ! 266: */ ! 267: isload() ! 268: { ! 269: register short i; /* was: int i */ ! 270: register HWentry **hw; ! 271: register VTDATA *vp; ! 272: ! 273: /* ! 274: * Reset keyboard if NOT an XT turbo. ! 275: */ ! 276: if ( ! isturbo ) { ! 277: outb(KBCTRL, 0x0C); /* Clock low */ ! 278: for (i = 10582; --i >= 0; ); /* For 20ms */ ! 279: outb(KBCTRL, 0xCC); /* Clock high */ ! 280: for (i = 0; --i != 0; ) ! 281: ; ! 282: i = inb(KBDATA); ! 283: outb(KBCTRL, 0xCC); /* Clear keyboard */ ! 284: outb(KBCTRL, 0x4D); /* Enable keyboard */ ! 285: } ! 286: ! 287: PRINTV("vtload:\n"); ! 288: fk_loaded = 0; ! 289: ! 290: /* figure out what our current max is */ ! 291: for( vtmax = 0, hw = vtHWtable; *hw; ++hw ) { ! 292: vtmax += (*hw)->count; ! 293: (*hw)->found = 0; /* assume non-exist */ ! 294: } ! 295: PRINTV( "vtload: %d screens possible\n", vtmax ); ! 296: ! 297: vtdata = (VTDATA **) kalloc( vtmax * sizeof( *vtdata ) ); ! 298: if( vtdata == NULL ) { ! 299: printf( "vtload: unable to obtain vtdata[%d]\n", vtmax ); ! 300: u.u_error = -1; ! 301: return; ! 302: } ! 303: PRINTV( "vtload: obtained vtdata[%d] @%x\n", vtmax, vtdata ); ! 304: ! 305: vttty = (TTY **) kalloc( vtmax * sizeof( *vttty ) ); ! 306: if( vttty == NULL ) { ! 307: printf( "vtload: unable to obtain vttty[%d]\n", vtmax ); ! 308: u.u_error = -1; ! 309: return; ! 310: } ! 311: PRINTV( "vtload: obtained vttty[%d] @%x\n", vtmax, vttty ); ! 312: ! 313: /* determine which video adaptors are present */ ! 314: for( vtcount = 0, hw = vtHWtable; *hw; ++hw ) { ! 315: /* remember our logical start */ ! 316: (*hw)->start = vtcount; ! 317: PRINTV( ", start %d\n", vtcount ); ! 318: ! 319: /* allocate the necessary memory */ ! 320: for ( i = 0; i < (*hw)->count; ++i ) { ! 321: vp = vtdata[vtcount] = kalloc( sizeof(VTDATA) ); ! 322: PRINTV( " vtdata[%d] = @%x\n", vtcount, vp ); ! 323: if( vp == NULL || !VTttyinit(vtcount) ) { ! 324: printf("not enough memory for VTDATA\n" ); ! 325: break; ! 326: } ! 327: ! 328: /* fill in appropriately */ ! 329: *vp = const_vtdata; ! 330: vp->vmm_port = (*hw)->port; ! 331: vp->vmm_vseg = (*hw)->vidmemory.seg; ! 332: vp->vmm_voff = (*hw)->vidmemory.off; ! 333: ! 334: vp->vt_ind = vtcount; ! 335: vtdatainit(vp); ! 336: if (i == 0 ) { ! 337: vp->vmm_visible = VNKB_TRUE; ! 338: vp->vmm_seg = vp->vmm_vseg; ! 339: vp->vmm_off = vp->vmm_voff; ! 340: updscreen(vtcount); ! 341: } ! 342: (*hw)->found++; ! 343: vtcount++; ! 344: } ! 345: } ! 346: ! 347: /* ! 348: * initialize vtconsole ! 349: */ ! 350: vtconsole = vtdata[vtactive = 0]; ! 351: vtconsole->vmm_invis = 0; /* vtconsole cursor visible */ ! 352: ! 353: /* ! 354: * Seize keyboard interrupt. ! 355: */ ! 356: #ifdef _I386 ! 357: setivec(ISVEC, isrint); ! 358: #else ! 359: #if VT_MAJOR == KB_MAJOR ! 360: setivec(1, isrint); ! 361: #else ! 362: ! 363: /* ! 364: * Map table and vector to us ! 365: */ ! 366: i = sphi(); ! 367: PRINTV( "VTload: unload old vector\n" ); ! 368: kcall( Kclrivec, 1 ); ! 369: setivec(1, isrint); ! 370: spl( i ); ! 371: #endif ! 372: #endif /* _I386 */ ! 373: ! 374: /* ! 375: * Enable mmwatch() invocation every second. ! 376: */ ! 377: drvl[VT_MAJOR].d_time = 1; ! 378: ! 379: /* ! 380: * Initialize video display. ! 381: */ ! 382: for ( i = 0; i < vtcount; ++i ) ! 383: mmstart( vttty[i] ); ! 384: } ! 385: ! 386: /* ! 387: * Unload entry point. ! 388: */ ! 389: isuload() ! 390: { ! 391: register int i; ! 392: register level = sphi(); ! 393: ! 394: clrivec(ISVEC); ! 395: #ifndef _I386 ! 396: #if VT_MAJOR != KB_MAJOR ! 397: kcall( Ksetivec, ISVEC, &Kisrint ); ! 398: #endif ! 399: #endif ! 400: spl( level ); ! 401: ! 402: /* Restore pointers to original state. */ ! 403: vtconsole = vtdata[0]; ! 404: vtconsole->vmm_invis = 0; ! 405: vtconsole->vmm_visible = VNKB_TRUE; ! 406: ! 407: if( vt_opened ) ! 408: printf( "VTclose with %d open screens\n", vt_opened ); ! 409: ! 410: #ifndef _I386 ! 411: for( i = 0; i < vtcount; ++i ) { ! 412: PRINTV( "VTuload: free far %x:%x, tty %x\n", ! 413: vttty[i]->t_buffer->s_faddr, vttty[i] ); ! 414: sfree( vttty[i]->t_buffer ); ! 415: kfree( vttty[i] ); ! 416: sfree( vtdata[i].vt_buffer ); ! 417: } ! 418: #endif ! 419: } ! 420: ! 421: /* ! 422: * Default function key strings (terminated by -1 [\377]) ! 423: */ ! 424: ! 425: static char *deffuncs[] = { ! 426: /* Normal function keys */ ! 427: ESCAPE_STRING "[M" HEXFF_STRING, /* F1 */ ! 428: ESCAPE_STRING "[N" HEXFF_STRING, /* F2 */ ! 429: ESCAPE_STRING "[O" HEXFF_STRING, /* F3 */ ! 430: ESCAPE_STRING "[P" HEXFF_STRING, /* F4 */ ! 431: ESCAPE_STRING "[Q" HEXFF_STRING, /* F5 */ ! 432: ESCAPE_STRING "[R" HEXFF_STRING, /* F6 */ ! 433: ESCAPE_STRING "[S" HEXFF_STRING, /* F7 */ ! 434: ESCAPE_STRING "[T" HEXFF_STRING, /* F8 */ ! 435: ESCAPE_STRING "[U" HEXFF_STRING, /* F9 */ ! 436: ESCAPE_STRING "[V" HEXFF_STRING, /* F10 - historical value */ ! 437: /* No F11 or F12 on these keyboards */ ! 438: ! 439: /* Shifted function keys */ ! 440: ESCAPE_STRING "[Y" HEXFF_STRING, /* sF1 */ ! 441: ESCAPE_STRING "[Z" HEXFF_STRING, /* sF2 */ ! 442: ESCAPE_STRING "[a" HEXFF_STRING, /* sF3 */ ! 443: ESCAPE_STRING "[b" HEXFF_STRING, /* sF4 */ ! 444: ESCAPE_STRING "[c" HEXFF_STRING, /* sF5 */ ! 445: ESCAPE_STRING "[d" HEXFF_STRING, /* sF6 */ ! 446: ESCAPE_STRING "[e" HEXFF_STRING, /* sF7 */ ! 447: ESCAPE_STRING "[f" HEXFF_STRING, /* sF8 */ ! 448: ESCAPE_STRING "[g" HEXFF_STRING, /* sF9 */ ! 449: ESCAPE_STRING "[h" HEXFF_STRING, /* sF10 */ ! 450: ! 451: /* Ctrl-ed function keys */ ! 452: ESCAPE_STRING "[k" HEXFF_STRING, /* cF1 */ ! 453: ESCAPE_STRING "[l" HEXFF_STRING, /* cF2 */ ! 454: ESCAPE_STRING "[m" HEXFF_STRING, /* cF3 */ ! 455: ESCAPE_STRING "[n" HEXFF_STRING, /* cF4 */ ! 456: ESCAPE_STRING "[o" HEXFF_STRING, /* cF5 */ ! 457: ESCAPE_STRING "[p" HEXFF_STRING, /* cF6 */ ! 458: ESCAPE_STRING "[q" HEXFF_STRING, /* cF7 */ ! 459: ESCAPE_STRING "[r" HEXFF_STRING, /* cF8 */ ! 460: ESCAPE_STRING "[s" HEXFF_STRING, /* cF9 */ ! 461: ESCAPE_STRING "[t" HEXFF_STRING, /* cF10 */ ! 462: ! 463: /* Ctrl-shifted function keys */ ! 464: ESCAPE_STRING "[w" HEXFF_STRING, /* csF1 */ ! 465: ESCAPE_STRING "[x" HEXFF_STRING, /* csF2 */ ! 466: ESCAPE_STRING "[y" HEXFF_STRING, /* csF3 */ ! 467: ESCAPE_STRING "[z" HEXFF_STRING, /* csF4 */ ! 468: ESCAPE_STRING "[@" HEXFF_STRING, /* csF5 */ ! 469: ESCAPE_STRING "[[" HEXFF_STRING, /* csF6 */ ! 470: ESCAPE_STRING "[\\" HEXFF_STRING, /* csF7 */ ! 471: ESCAPE_STRING "[]" HEXFF_STRING, /* csF8 */ ! 472: ESCAPE_STRING "[^" HEXFF_STRING, /* csF9 */ ! 473: ESCAPE_STRING "[_" HEXFF_STRING, /* csF10 */ ! 474: ! 475: /* Alt keys -- use original 83 key setting since these are ! 476: * not defined for virtual terms; actually, many will never ! 477: * be used since intercepted by virtual term code, but ! 478: * should be here in case someone defines like 1 virtual term ! 479: * so the keys return something semi-useful */ ! 480: ESCAPE_STRING "[1y" HEXFF_STRING, /* aF1 */ ! 481: ESCAPE_STRING "[2y" HEXFF_STRING, /* aF2 */ ! 482: ESCAPE_STRING "[3y" HEXFF_STRING, /* aF3 */ ! 483: ESCAPE_STRING "[4y" HEXFF_STRING, /* aF4 */ ! 484: ESCAPE_STRING "[5y" HEXFF_STRING, /* aF5 */ ! 485: ESCAPE_STRING "[6y" HEXFF_STRING, /* aF6 */ ! 486: ESCAPE_STRING "[7y" HEXFF_STRING, /* aF7 */ ! 487: ESCAPE_STRING "[8y" HEXFF_STRING, /* aF8 */ ! 488: ESCAPE_STRING "[9y" HEXFF_STRING, /* aF9 */ ! 489: ESCAPE_STRING "[0y" HEXFF_STRING /* aF10 */ ! 490: }; ! 491: ! 492: /* ! 493: * Open routine. ! 494: */ ! 495: isopen(dev, mode) ! 496: dev_t dev; ! 497: unsigned int mode; ! 498: { ! 499: register int s; ! 500: register TTY *tp; ! 501: int index = vtindex(dev); ! 502: ! 503: PRINTV("isopen: %x\n", dev); ! 504: if (index < 0 || index >= vtcount) { ! 505: u.u_error = ENXIO; ! 506: return; ! 507: } ! 508: ! 509: tp = vttty[index]; ! 510: if ((tp->t_flags&T_EXCL) != 0 && !super()) { ! 511: u.u_error = ENODEV; ! 512: return; ! 513: } ! 514: ttsetgrp(tp, dev, mode); ! 515: ! 516: s = sphi(); ! 517: if (tp->t_open++ == 0) { ! 518: initkeys(); /* init function keys */ ! 519: tp->t_flags = T_CARR; /* indicate "carrier" */ ! 520: ttopen(tp); ! 521: } ! 522: spl(s); ! 523: #if 0 ! 524: updleds(); /* update keyboard status LEDS */ ! 525: #endif ! 526: } ! 527: ! 528: /* Init function keys */ ! 529: initkeys() ! 530: { register int i; ! 531: register char *cp1, *cp2; ! 532: ! 533: for (i=0; i<NFKEY; i++) ! 534: isfval[i] = 0; /* clear function key buffer */ ! 535: cp2 = isfbuf; /* pointer to key buffer */ ! 536: for (i=0; i<NFKEY; i++) ! 537: { isfval[i] = cp2; /* save pointer to key string */ ! 538: cp1 = deffuncs[i]; /* get init string pointer */ ! 539: while ((*cp2++ = *cp1++) != -1) /* copy key data */ ! 540: if (cp2 >= &isfbuf[NFBUF-3]) /* overflow? */ ! 541: return; ! 542: } ! 543: } ! 544: ! 545: void isvtswitch(); /* deferred virtual terminal switch */ ! 546: ! 547: /* ! 548: * Close a tty. ! 549: */ ! 550: isclose(dev) ! 551: { ! 552: register int s; ! 553: int index = vtindex(dev); ! 554: register TTY *tp = vttty[index]; ! 555: ! 556: if (--tp->t_open == 0) ! 557: ttclose(tp); ! 558: ! 559: } ! 560: ! 561: /* ! 562: * Read routine. ! 563: */ ! 564: isread(dev, iop) ! 565: dev_t dev; ! 566: IO *iop; ! 567: { ! 568: int index = vtindex(dev); ! 569: register TTY *tp = vttty[index]; ! 570: ! 571: ttread(tp, iop, 0); ! 572: if (tp->t_oq.cq_cc) ! 573: mmtime(tp); ! 574: } ! 575: ! 576: /* ! 577: * Ioctl routine. ! 578: */ ! 579: /* ! 580: * special struct for the KDMAPDISP call ! 581: */ ! 582: ! 583: #define KDMAPDISP (('K' << 8) | 2) /* map display into user space */ ! 584: #define KDSKBMODE (('K' << 8) | 6) /* turn scan code xlate on/off */ ! 585: #define KDMEMDISP (('K' << 8) | 7) /* dump byte of virt/phys mem */ ! 586: #define KDENABIO (('K' << 8) | 60) /* enable IO */ ! 587: #define KIOCSOUND (('K' << 8) | 63) /* start sound generation */ ! 588: #define KDSETLED (('K' << 8) | 66) /* set leds */ ! 589: ! 590: #define TIMER_CTL 0x43 /* Timer control */ ! 591: #define TIMER_CNT 0x42 /* Timer counter */ ! 592: #define SPEAKER_CTL 0x61 /* Speaker control */ ! 593: ! 594: struct kd_memloc { ! 595: char *vaddr; /* virtual address to map to */ ! 596: char *physaddr; /* physical address to map to */ ! 597: long length; /* size in bytes to map */ ! 598: long ioflg; /* enable I/O addresses if non-zero */ ! 599: }; ! 600: ! 601: static TIM tp; ! 602: int ! 603: kbstate(action) ! 604: int action; ! 605: { ! 606: int i; ! 607: if (action == 1) { ! 608: timeout(&tp,20,kbstate,2); ! 609: outb(KBCTRL, 0xCC); /* Clock high */ ! 610: } ! 611: if (action == 2) { ! 612: i = inb(KBDATA); ! 613: outb(KBCTRL, 0xCC); /* Clear keyboard */ ! 614: outb(KBCTRL, 0x4D); /* Enable keyboard */ ! 615: } ! 616: } ! 617: ! 618: ! 619: static int X11led; ! 620: ! 621: ! 622: isioctl(dev, com, vec) ! 623: dev_t dev; ! 624: struct sgttyb *vec; ! 625: { ! 626: register int s; ! 627: ! 628: switch(com) { ! 629: #define KDDEBUG 0 ! 630: #if KDDEBUG ! 631: case KDMEMDISP: ! 632: { ! 633: struct kd_memloc* mem; ! 634: unsigned char ub, pb; ! 635: mem = vec; ! 636: pxcopy( mem->physaddr, &pb, 1, SEG_386_KD ); ! 637: ub = getubd( mem->vaddr ); ! 638: printf( "User's byte %x(%x), Physical byte %x, Addresses %x %x\n", ! 639: mem->ioflg, ub, pb, mem->vaddr, mem->physaddr ); ! 640: goto ioc_done;; ! 641: } ! 642: #endif ! 643: case KDMAPDISP: ! 644: { ! 645: struct kd_memloc* mem; ! 646: mem = vec; ! 647: #if KDDEBUG ! 648: printf( "mapPhysUser(%x, %x, %x) = %d\n", ! 649: mem->vaddr, mem->physaddr, mem->length, ! 650: #endif ! 651: mapPhysUser(mem->vaddr, mem->physaddr, mem->length) ! 652: #if KDDEBUG ! 653: ) ! 654: #endif ! 655: ; ! 656: } ! 657: case KDENABIO: ! 658: { ! 659: int i; ! 660: for (i = 0 ; i < 64 ; i++ ) ! 661: iomapAnd(0,i); ! 662: goto ioc_done;; ! 663: } ! 664: case KIOCSOUND: ! 665: { ! 666: if (vec) { ! 667: outb(TIMER_CTL, 0xB6); ! 668: outb(TIMER_CNT, (int)vec&0xFF); ! 669: outb(TIMER_CNT, (int)vec>>8); ! 670: outb(SPEAKER_CTL, inb(SPEAKER_CTL) | 03); /* Turn speaker on */ ! 671: } ! 672: else ! 673: outb(SPEAKER_CTL, inb(SPEAKER_CTL) & ~03 ); /* speaker off */ ! 674: goto ioc_done;; ! 675: } ! 676: case KDSKBMODE: ! 677: { ! 678: outb(KBCTRL, 0x0C); /* Clock low */ ! 679: timeout(&tp,3,kbstate,1); /* wait about 20-30ms */ ! 680: xlate = (int)vec; ! 681: goto ioc_done;; ! 682: } ! 683: case KDSETLED: ! 684: { ! 685: X11led = (int)vec; ! 686: updleds(); ! 687: goto ioc_done;; ! 688: } ! 689: ! 690: case TIOCSETF: ! 691: case TIOCGETF: ! 692: isfunction(com, (char *)vec); ! 693: goto ioc_done;; ! 694: case TIOCSHIFT: /* switch left-SHIFT and "\" */ ! 695: lshiftkb = LSHIFTA; /* alternate values */ ! 696: lmaptab[41] = '\\'; ! 697: lmaptab[42] = XXX; ! 698: umaptab[41] = '|'; ! 699: umaptab[42] = XXX; ! 700: smaptab[41] = SS1; ! 701: smaptab[42] = SHFT; ! 702: goto ioc_done;; ! 703: case TIOCCSHIFT: /* normal (default) left-SHIFT and "\" */ ! 704: lshiftkb = LSHIFT; /* normal values */ ! 705: lmaptab[41] = XXX; ! 706: lmaptab[42] = '\\'; ! 707: umaptab[41] = XXX; ! 708: umaptab[42] = '|'; ! 709: smaptab[41] = SHFT; ! 710: smaptab[42] = SS1; ! 711: goto ioc_done;; ! 712: } ! 713: s = sphi(); ! 714: ttioctl(vttty[vtindex(dev)], com, vec); ! 715: spl(s); ! 716: ! 717: ioc_done: ! 718: return; ! 719: } ! 720: ! 721: /* ! 722: * Set and receive the function keys. ! 723: */ ! 724: isfunction(c, v) ! 725: int c; ! 726: char *v; ! 727: { ! 728: register char *cp; ! 729: register int i; ! 730: ! 731: if (c == TIOCGETF) { ! 732: for (cp = isfbuf; cp < &isfbuf[NFBUF]; cp++) ! 733: putubd(v++, *cp); ! 734: } else { ! 735: for (i=0; i<NFKEY; i++) /* zap current settings */ ! 736: isfval[i] = 0; ! 737: cp = isfbuf; /* pointer to key buffer */ ! 738: for (i=0; i<NFKEY; i++) { ! 739: isfval[i] = cp; /* save pointer to key string */ ! 740: while ((*cp++ = getubd(v++)) != -1) /* copy key data */ ! 741: if (cp >= &isfbuf[NFBUF-3]) /* overflow? */ ! 742: return; ! 743: } ! 744: } ! 745: } ! 746: ! 747: ! 748: /* ! 749: * Poll routine. ! 750: */ ! 751: ispoll( dev, ev, msec ) ! 752: dev_t dev; ! 753: int ev; ! 754: int msec; ! 755: { ! 756: register TTY *tp = vttty[vtindex(dev)]; ! 757: ! 758: return ttpoll(tp, ev, msec); ! 759: } ! 760: ! 761: /* ! 762: * Receive interrupt. ! 763: */ ! 764: isrint() ! 765: { ! 766: register int c; ! 767: register int s; ! 768: register int r; ! 769: int savests; ! 770: int update_leds = 0; ! 771: ! 772: /* ! 773: * Schedule raw input handler if not already active. ! 774: */ ! 775: if ( isbusy == 0 ) { ! 776: isbusy = 1; ! 777: defer(isbatch, vttty[vtactive]); ! 778: } ! 779: ! 780: /* ! 781: * Pull character from the data ! 782: * port. Pulse the KBFLAG in the control ! 783: * port to reset the data buffer. ! 784: */ ! 785: r = inb(KBDATA) & 0xFF; ! 786: c = inb(KBCTRL); ! 787: outb(KBCTRL, c|KBFLAG); ! 788: outb(KBCTRL, c); ! 789: if (!xlate) { ! 790: if (ledcmd) { ! 791: ledcmd = 0; ! 792: if (r == KBACK) { /* output to status LEDS */ ! 793: outb(KBDATA, X11led); ! 794: return; ! 795: } ! 796: } ! 797: isin(r); ! 798: return; ! 799: } ! 800: ! 801: #if KBDEBUG ! 802: printf("kbd: %d\n", r); /* print scan code/direction */ ! 803: #endif ! 804: if (ledcmd) { ! 805: ledcmd = 0; ! 806: if (r == KBACK) { /* output to status LEDS */ ! 807: c = scrollkb & 1; ! 808: if (shift & NMLS) ! 809: c |= 2; ! 810: if (shift & CPLS) ! 811: c |= 4; ! 812: outb(KBDATA, c); ! 813: } ! 814: return; ! 815: } ! 816: if (extended > 0) { /* if multi-character seq, */ ! 817: --extended; /* ... ignore this char */ ! 818: return; ! 819: } ! 820: switch (r) { ! 821: case EXTENDED0: /* 0xE0 prefix found */ ! 822: ext0seen = 1; ! 823: return; ! 824: case EXTENDED1: /* ignore extended sequences */ ! 825: extended = 5; ! 826: return; ! 827: case 0xFF: /* Overrun */ ! 828: return; ! 829: } ! 830: ! 831: if (ext0seen) { ! 832: ext0seen = 0; ! 833: extmode = 1; ! 834: } else ! 835: extmode = 0; ! 836: ! 837: c = (r & KEYSC) - 1; ! 838: /* ! 839: * Check for reset. ! 840: */ ! 841: if ((r&KEYUP) == 0 && c == DELETE && (shift&(CTS|ALS)) == (CTS|ALS)) ! 842: boot(); ! 843: ! 844: /* ! 845: * Track "shift" keys. ! 846: */ ! 847: s = smaptab[c]; ! 848: if (s&SHFT) { ! 849: if (r&KEYUP) { /* "shift" released */ ! 850: if (c == RSHIFT) ! 851: shift &= ~SRS; ! 852: else if (c == lshiftkb) ! 853: shift &= ~SLS; ! 854: else if (c == CTRLkb) ! 855: shift &= ~CTS; ! 856: else if (c == ALTkb) ! 857: shift &= extmode ? ~AGS : ~ALS; ! 858: } else { /* "shift" pressed */ ! 859: if (c == lshiftkb) ! 860: shift |= SLS; ! 861: else if (c == RSHIFT) ! 862: shift |= SRS; ! 863: else if (c == CTRLkb) ! 864: shift |= CTS; ! 865: else if (c == ALTkb) ! 866: shift |= extmode ? AGS : ALS; ! 867: else if (c == CAPLOCK) { ! 868: shift ^= CPLS; /* toggle cap lock */ ! 869: updleds(); ! 870: } else if (c == NUMLOCK) { ! 871: shift ^= NMLS; /* toggle num lock */ ! 872: updleds(); ! 873: } ! 874: } ! 875: return; ! 876: } ! 877: ! 878: /* ! 879: * No other key up codes of interest. ! 880: */ ! 881: if (r&KEYUP) ! 882: return; ! 883: ! 884: /* ! 885: * Map character, based on the ! 886: * current state of the shift, control, alt graphics, ! 887: * meta (ALT) and lock flags. ! 888: */ ! 889: if (shift & AGS) /* Alt Graphics ? */ ! 890: c = agmaptab[c]; ! 891: else if (shift & CTS) { ! 892: if (s == CTS) /* Map Ctrl (BS | NL) */ ! 893: c = (c == BACKSP) ? 0x7F : 0x0A; ! 894: else if (s==SS1 || s==LET) { ! 895: if((c = umaptab[c]) != SPC) /* Normal Ctrl map */ ! 896: c &= 0x1F; /* Clear bits 5-6 */ ! 897: } else { if (s==KEY || s==SS0) ! 898: vtnumeric(r); ! 899: return; /* Ignore this char */ ! 900: } ! 901: } else if (s &= shift) { ! 902: if (shift & SES) { /* if shift on */ ! 903: if (s & (CPLS|NMLS)) /* if caps/num lock */ ! 904: c = lmaptab[c]; /* use unshifted */ ! 905: else ! 906: c = umaptab[c]; /* use shifted */ ! 907: } else { /* if shift not on */ ! 908: if (s & (CPLS|NMLS)) /* if caps/num lock */ ! 909: c = umaptab[c]; /* use shifted */ ! 910: else ! 911: c = lmaptab[c]; /* use unshifted */ ! 912: } ! 913: } else ! 914: c = lmaptab[c]; /* use unshifted */ ! 915: ! 916: /* ! 917: * Act on character. ! 918: */ ! 919: if (c == XXX) ! 920: return; /* char to ignore */ ! 921: ! 922: if (c != SPC) { /* not special char? */ ! 923: if (shift & ALS) /* ALT (meta bit)? */ ! 924: c |= 0x80; /* set meta */ ! 925: isin(c); /* send the char */ ! 926: } else ! 927: update_leds += isspecial(r); /* special chars */ ! 928: if (update_leds) { ! 929: savests = sphi(); ! 930: outb(KBDATA, LEDCMD); ! 931: ledcmd = 1; ! 932: spl(savests); ! 933: } ! 934: } ! 935: ! 936: /* ! 937: * Process numeric keypad for virtual terminals. ! 938: */ ! 939: vtnumeric(c) ! 940: int c; ! 941: { ! 942: switch (c) { ! 943: case 71: /* ctrl-7 */ ! 944: defer(isvtswitch, vt7); ! 945: break; ! 946: case 72: /* ctrl-8 */ ! 947: defer(isvtswitch, vt8); ! 948: break; ! 949: case 73: /* ctrl-9 */ ! 950: defer(isvtswitch, vt9); ! 951: break; ! 952: case 74: /* ctrl - */ ! 953: defer(isvtswitch, vtp); ! 954: break; ! 955: case 75: /* ctrl-4 */ ! 956: defer(isvtswitch, vt4); ! 957: break; ! 958: case 76: /* ctrl-5 */ ! 959: defer(isvtswitch, vt5); ! 960: break; ! 961: case 77: /* ctrl-6 */ ! 962: defer(isvtswitch, vt6); ! 963: break; ! 964: case 78: /* ctrl + */ ! 965: defer(isvtswitch, vtn); ! 966: break; ! 967: case 79: /* ctrl-1 */ ! 968: defer(isvtswitch, vt1); ! 969: break; ! 970: case 80: /* ctrl-2 */ ! 971: defer(isvtswitch, vt2); ! 972: break; ! 973: case 81: /* ctrl-3 */ ! 974: defer(isvtswitch, vt3); ! 975: break; ! 976: case 82: /* ctrl 0 (vt0) */ ! 977: defer(isvtswitch, vt0); ! 978: break; ! 979: case 83: /* ctrl del (toggle) */ ! 980: c = vtt; ! 981: defer(isvtswitch, vtt); ! 982: break; ! 983: } ! 984: } ! 985: ! 986: /* ! 987: * Handle special input sequences. ! 988: * The character passed is the key number. ! 989: * ! 990: * The keypad is translated by the following table, ! 991: * the first entry is the normal sequence, the second the shifted, ! 992: * and the third the alternate keypad sequence. ! 993: */ ! 994: static char *keypad[][3] = { ! 995: { ESCAPE_STRING "[H", "7", ESCAPE_STRING "?w" }, /* 71 */ ! 996: { ESCAPE_STRING "[A", "8", ESCAPE_STRING "?x" }, /* 72 */ ! 997: { ESCAPE_STRING "[I", "9", ESCAPE_STRING "?y" }, /* 73 */ ! 998: { ESCAPE_STRING "[D", "4", ESCAPE_STRING "?t" }, /* 75 */ ! 999: { ESCAPE_STRING "7", "5", ESCAPE_STRING "?u" }, /* 76 */ ! 1000: { ESCAPE_STRING "[C", "6", ESCAPE_STRING "?v" }, /* 77 */ ! 1001: { ESCAPE_STRING "[F", "1", ESCAPE_STRING "?q" }, /* 79 */ ! 1002: { ESCAPE_STRING "[B", "2", ESCAPE_STRING "?r" }, /* 80 */ ! 1003: { ESCAPE_STRING "[G", "3", ESCAPE_STRING "?s" }, /* 81 */ ! 1004: { ESCAPE_STRING "[L", "0", ESCAPE_STRING "?p" }, /* 82 */ ! 1005: { DELETE_STRING , ".", ESCAPE_STRING "?n" } /* 83 */ ! 1006: }; ! 1007: ! 1008: isspecial(c) ! 1009: int c; ! 1010: { ! 1011: register char *cp; ! 1012: register int s; ! 1013: int update_leds = 0; ! 1014: ! 1015: cp = 0; ! 1016: ! 1017: switch (c) { ! 1018: case 15: /* cursor back tab */ ! 1019: cp = "\033[Z"; ! 1020: break; ! 1021: case 53: ! 1022: if (extmode) ! 1023: cp = "/"; ! 1024: else if (shift & SES) ! 1025: cp = "_"; ! 1026: else ! 1027: cp = "-"; ! 1028: break; ! 1029: case 55: /* ignore PrtScr */ ! 1030: if (!extmode) ! 1031: cp = "*"; ! 1032: break; ! 1033: case 59: case 60: case 61: case 62: case 63: /* Function keys */ ! 1034: case 64: case 65: case 66: ! 1035: /* offset to function string */ ! 1036: /* Magic numbers 21 and 61 to mach vtnkb constants */ ! 1037: if ( shift & ALS ) { ! 1038: switch(c) { ! 1039: case 59: /* Alt-F1 */ ! 1040: defer(isvtswitch, vt0); ! 1041: break; ! 1042: case 60: /* Alt-F2 */ ! 1043: defer(isvtswitch, vt1); ! 1044: break; ! 1045: case 61: /* Alt-F3 */ ! 1046: defer(isvtswitch, vt2); ! 1047: break; ! 1048: case 62: /* Alt-F4 */ ! 1049: defer(isvtswitch, vt3); ! 1050: break; ! 1051: case 63: /* Alt-F5 */ ! 1052: defer(isvtswitch, vt4); ! 1053: break; ! 1054: case 64: /* Alt-F6 */ ! 1055: defer(isvtswitch, vt5); ! 1056: break; ! 1057: case 65: /* Alt-F7 */ ! 1058: defer(isvtswitch, vt6); ! 1059: break; ! 1060: case 66: /* Alt-F8 */ ! 1061: defer(isvtswitch, vt7); ! 1062: break; ! 1063: default: ! 1064: break; ! 1065: } ! 1066: } ! 1067: else { if((shift & (SES)) && (shift & CTS)) /* ctrl-shft-Fx */ ! 1068: cp = isfval[c-29]; ! 1069: else { if(shift & CTS) /* ctrl-Fx */ ! 1070: cp = isfval[c-39]; ! 1071: else { if(shift & (SES)) /* shift-Fx */ ! 1072: cp = isfval[c-49]; ! 1073: else cp = isfval[c-59]; /* Plain Fx */ ! 1074: }}} ! 1075: break; ! 1076: case 67: case 68: ! 1077: /* offset to function string */ ! 1078: if ( shift & ALS ) { ! 1079: switch(c) { ! 1080: case 67: /* Alt-F9 */ ! 1081: defer(isvtswitch, vt8); ! 1082: break; ! 1083: case 68: /* Alt-F10 */ ! 1084: defer(isvtswitch, vt9); ! 1085: break; ! 1086: default: ! 1087: break; ! 1088: } ! 1089: } ! 1090: else { if ((shift & (SES)) && (shift & CTS)) /* cs-Fx */ ! 1091: cp = isfval[c-29]; ! 1092: else { if (shift & CTS) /* c-Fx */ ! 1093: cp = isfval[c-39]; ! 1094: else { if (shift & (SES)) /* s-Fx */ ! 1095: cp = isfval[c-49]; ! 1096: else cp = isfval[c-59]; /* Fx */ ! 1097: }}} ! 1098: break; ! 1099: case 70: /* Scroll Lock -- stop/start output */ ! 1100: { ! 1101: static char cbuf[2]; ! 1102: ! 1103: cp = &cbuf[0]; /* working buffer */ ! 1104: if (! _IS_RAWIN_MODE (vttty [vtactive])) { ! 1105: ++update_leds; ! 1106: ! 1107: if (vttty[vtactive]->t_flags&T_STOP){/* output stopped? */ ! 1108: cbuf[0] = vttty[vtactive]->t_tchars.t_startc; ! 1109: scrollkb = 0; ! 1110: } else { ! 1111: cbuf[0] = vttty[vtactive]->t_tchars.t_stopc; ! 1112: scrollkb = 1; ! 1113: } ! 1114: } ! 1115: break; ! 1116: } ! 1117: ! 1118: case 79: /* 1/End */ ! 1119: case 80: /* 2/DOWN */ ! 1120: case 81: /* 3/PgDn */ ! 1121: case 82: /* 0/Ins */ ! 1122: case 83: /* ./Del */ ! 1123: --c; /* adjust code */ ! 1124: case 75: /* 4/LEFT */ ! 1125: case 76: /* 5 */ ! 1126: case 77: /* 6/RIGHT */ ! 1127: --c; /* adjust code */ ! 1128: case 71: /* 7/Home/Clear */ ! 1129: case 72: /* 8/UP */ ! 1130: case 73: /* 9/PgUp */ ! 1131: s = 0; /* start off with normal keypad */ ! 1132: if (shift & NMLS) /* num lock? */ ! 1133: s = 1; /* set shift pad */ ! 1134: if (shift & SES) /* shift? */ ! 1135: s ^= 1; /* toggle shift pad */ ! 1136: if (shift & AKPS) /* alternate pad? */ ! 1137: s = 2; /* set alternate pad */ ! 1138: if (extmode) /* not from keypad? */ ! 1139: s = 0; /* force normal sequence */ ! 1140: cp = keypad[c-71][s]; /* get keypad value */ ! 1141: break; ! 1142: } ! 1143: if (cp) /* send string */ ! 1144: while ((*cp != 0) && (*cp != -1)) ! 1145: isin( *cp++ & 0377 ); ! 1146: return update_leds; ! 1147: } ! 1148: ! 1149: /** ! 1150: * ! 1151: * void ! 1152: * ismmfunc( c ) -- process keyboard related output escape sequences ! 1153: * char c; ! 1154: */ ! 1155: void ! 1156: ismmfunc(c) ! 1157: register int c; ! 1158: { ! 1159: switch (c) { ! 1160: case 't': /* Enter numlock */ ! 1161: shift |= NMLS; ! 1162: updleds(); /* update LED status */ ! 1163: break; ! 1164: case 'u': /* Leave numlock */ ! 1165: shift &= ~NMLS; ! 1166: updleds(); /* update LED status */ ! 1167: break; ! 1168: case '=': /* Enter alternate keypad */ ! 1169: shift |= AKPS; ! 1170: break; ! 1171: case '>': /* Exit alternate keypad */ ! 1172: shift &= ~AKPS; ! 1173: break; ! 1174: case 'c': /* Reset terminal */ ! 1175: islock = 0; ! 1176: shift = 0; ! 1177: initkeys(); ! 1178: updleds(); /* update LED status */ ! 1179: break; ! 1180: } ! 1181: } ! 1182: ! 1183: /** ! 1184: * ! 1185: * void ! 1186: * isin( c ) -- append character to raw input silo ! 1187: * char c; ! 1188: */ ! 1189: static ! 1190: isin( c ) ! 1191: register int c; ! 1192: { ! 1193: int cache_it = 1; ! 1194: TTY * tp = vttty[vtactive]; ! 1195: ! 1196: /* ! 1197: * If using software incoming flow control, process and ! 1198: * discard t_stopc and t_startc. ! 1199: */ ! 1200: if (_IS_IXON_MODE (tp)) { ! 1201: #if _I386 ! 1202: if (_IS_START_CHAR (tp, c) || ! 1203: (_IS_IXANY_MODE (tp) && (tp->t_flags & T_STOP) != 0)) { ! 1204: tp->t_flags &= ~(T_STOP | T_XSTOP); ! 1205: ttstart(tp); ! 1206: cache_it = 0; ! 1207: } else if (_IS_STOP_CHAR (tp, c)) { ! 1208: if ((tp->t_flags & T_STOP) == 0) ! 1209: tp->t_flags |= (T_STOP | T_XSTOP); ! 1210: cache_it = 0; ! 1211: } ! 1212: #else ! 1213: if (_IS_STOP_CHAR (tp, c)) { ! 1214: if ((tp->t_flags & T_STOP) == 0) ! 1215: tp->t_flags |= T_STOP; ! 1216: cache_it = 0; ! 1217: } ! 1218: if (_IS_START_CHAR (tp, c)) { ! 1219: tp->t_flags &= ~ T_STOP; ! 1220: ttstart (tp); ! 1221: cache_it = 0; ! 1222: } ! 1223: #endif ! 1224: } ! 1225: /* ! 1226: * If the tty is not open the character is ! 1227: * just tossed away. ! 1228: */ ! 1229: if (vttty[vtactive]->t_open == 0) ! 1230: return; ! 1231: ! 1232: ! 1233: /* ! 1234: * Cache received character. ! 1235: */ ! 1236: if (cache_it) { ! 1237: in_silo.si_buf[ in_silo.si_ix ] = c; ! 1238: ! 1239: if ( ++in_silo.si_ix >= sizeof(in_silo.si_buf) ) ! 1240: in_silo.si_ix = 0; ! 1241: } ! 1242: } ! 1243: ! 1244: /** ! 1245: * ! 1246: * void ! 1247: * isbatch() -- raw input conversion routine ! 1248: * ! 1249: * Action: Enable the video display. ! 1250: * Canonize the raw input silo. ! 1251: * ! 1252: * Notes: isbatch() was scheduled as a deferred process by isrint(). ! 1253: */ ! 1254: static void ! 1255: isbatch( tp ) ! 1256: register TTY * tp; ! 1257: { ! 1258: register int c; ! 1259: static int lastc; ! 1260: VTDATA *vp = tp->t_ddp; ! 1261: ! 1262: /* ! 1263: * Ensure video display is enabled. ! 1264: */ ! 1265: if (vp->vmm_visible) ! 1266: mm_von(vp); ! 1267: ! 1268: isbusy = 0; ! 1269: ! 1270: /* ! 1271: * Process all cached characters. ! 1272: */ ! 1273: while ( in_silo.si_ix != in_silo.si_ox ) { ! 1274: ! 1275: /* ! 1276: * Get next cached char. ! 1277: */ ! 1278: c = in_silo.si_buf[ in_silo.si_ox ]; ! 1279: ! 1280: if ( in_silo.si_ox >= sizeof(in_silo.si_buf) - 1 ) ! 1281: in_silo.si_ox = 0; ! 1282: else ! 1283: in_silo.si_ox++; ! 1284: ! 1285: if (islock == 0 || _IS_INTERRUPT_CHAR (tp, c) || ! 1286: _IS_QUIT_CHAR (tp, c)) { ! 1287: ttin (tp, c); ! 1288: } else if (c == 'b' && lastc == ESCAPE_CHAR) { ! 1289: islock = 0; ! 1290: ttin (tp, lastc); ! 1291: ttin (tp, c); ! 1292: } else if (c == 'c' && lastc == ESCAPE_CHAR) { ! 1293: ttin (tp, lastc); ! 1294: ttin (tp, c); ! 1295: } else ! 1296: putchar ('\a'); ! 1297: ! 1298: lastc = c; ! 1299: } ! 1300: } ! 1301: ! 1302: /* ! 1303: * update the keyboard status LEDS ! 1304: */ ! 1305: ! 1306: updleds() ! 1307: { ! 1308: int s; ! 1309: ! 1310: s = sphi (); ! 1311: outb (KBDATA, LEDCMD); ! 1312: ledcmd = 1; ! 1313: spl (s); ! 1314: } ! 1315: ! 1316: /* ! 1317: * unlock the scroll in case an interrupt character is received ! 1318: */ ! 1319: kbunscroll() ! 1320: { ! 1321: scrollkb = 0; ! 1322: updleds(); ! 1323: } ! 1324: int ! 1325: VTttyinit(i) ! 1326: int i; ! 1327: { ! 1328: TTY *tp; ! 1329: ! 1330: /* ! 1331: * get pointer to TTY structure from kernal memory space ! 1332: */ ! 1333: if( (tp = vttty[i] = (TTY *)kalloc(sizeof (TTY))) == NULL ) ! 1334: return(0); ! 1335: PRINTV( " vttty[%d]: @%x, ", i, tp ); ! 1336: ! 1337: #if FAR_TTY ! 1338: /* ! 1339: * get pointers to the buffers pointed to by the TTY structure ! 1340: * from user memory space ! 1341: */ ! 1342: tp->t_buffer = salloc( (fsize_t)NCIB+2*SI_BUFSIZ, SFSYST|SFNSWP ); ! 1343: tp->t_ib = 0; ! 1344: tp->t_rawin.si_buf = NCIB; ! 1345: tp->t_rawout.si_buf = NCIB+SI_BUFSIZ; ! 1346: #endif ! 1347: tp->t_param = NULL; ! 1348: tp->t_start = &mmstart; ! 1349: ! 1350: #ifndef _I386 ! 1351: #if VT_MAJOR == KB_MAJOR ! 1352: tp->t_cs_sel = 0; ! 1353: #else ! 1354: tp->t_cs_sel = cs_sel(); ! 1355: #endif ! 1356: #endif ! 1357: tp->t_ddp = vtdata[i]; ! 1358: PRINTV( "data @%lx\n", tp->t_ddp ); ! 1359: return(1); ! 1360: } ! 1361: ! 1362: vtdatainit(vp) ! 1363: VTDATA *vp; ! 1364: { ! 1365: #ifndef _I386 ! 1366: VT_FARSEG vt_farseg; ! 1367: #endif ! 1368: /* ! 1369: * vtdata init - vmm part ! 1370: */ ! 1371: vp->vmm_invis = -1; /* cursor invisible */ ! 1372: ! 1373: #ifdef _I386 ! 1374: vp->vt_buffer = kalloc( TEXTBLOCK ); ! 1375: vp->vmm_seg = vp->vmm_mseg = ds_sel(); ! 1376: vp->vmm_off = vp->vmm_moff = vp->vt_buffer; ! 1377: #else ! 1378: vp->vt_buffer = salloc ( (fsize_t)TEXTBLOCK, SFSYST|SFNSWP|SFHIGH ); ! 1379: vp->vmm_seg = vp->vmm_mseg = FP_SEG( vp->vt_buffer->vt_faddr ); ! 1380: vp->vmm_off = vp->vmm_moff = FP_OFF( vp->vt_buffer->vt_faddr ); ! 1381: #endif ! 1382: PRINTV( "vt@%x init index %d,%d), seg %x, off %x\n", ! 1383: vp, vp->vt_ind, vp->vmm_mseg, vp->vmm_moff ); ! 1384: /* ! 1385: * vtdata init - vnkb part ! 1386: */ ! 1387: /* Make the first memory block active, if present */ ! 1388: vp->vnkb_lastc = 0; ! 1389: vp->vnkb_fnkeys = 0; ! 1390: vp->vnkb_funkeyp = 0; ! 1391: vp->vnkb_fk_loaded = 0; /* no Fn keys yet */ ! 1392: } ! 1393: ! 1394: /* ! 1395: * Given device number, return index for vtdata[], vttty[], etc. ! 1396: * ! 1397: * Major number must be VT_MAJOR for CPU to get here. ! 1398: * ! 1399: * Minor Number Index Value ! 1400: * ----- ------ ----- ----- ! 1401: * 0000 0000 vtactive ... device (2,0) is the active screen ! 1402: * 0000 0001 0 ! 1403: * 0000 0010 1 ! 1404: * 0000 0011 2 ! 1405: * .... ! 1406: * 0000 1111 14 ! 1407: * ! 1408: * 0100 xxxx xxxx ... color devices only ! 1409: * 0101 xxxx xxxx - (# of color devices found) ... monochrome only ! 1410: * ! 1411: * Return value is in range 0 to vtcount-1 for valid minor numbers, ! 1412: * -1 for invalid minor numbers. ! 1413: */ ! 1414: int ! 1415: vtindex( dev ) ! 1416: dev_t dev; ! 1417: { ! 1418: register int ret = -1; ! 1419: ! 1420: if ( dev & VT_PHYSICAL ) { ! 1421: int hw = ( dev >> 4 ) & 3; ! 1422: int hw_index = dev & 0x0F; ! 1423: ! 1424: if( hw_index < vtHWtable[hw]->found ) ! 1425: ret = vtHWtable[hw]->start + hw_index; ! 1426: } else { ! 1427: int lg_index = dev & 0x0F; ! 1428: ! 1429: if (lg_index == 0) ! 1430: ret = vtactive; ! 1431: if (lg_index > 0 && lg_index <= vtcount ) ! 1432: ret = lg_index-1; ! 1433: } ! 1434: if (ret >= 0) ! 1435: ret %= vtcount; ! 1436: else ! 1437: PRINTV( "vtindex: (%x) %d. invalid !\n", dev, ret ); ! 1438: return ret; ! 1439: } ! 1440: ! 1441: /* ! 1442: * ! 1443: * void ! 1444: * isvtswitch() -- deferred virtual terminal switch ! 1445: * ! 1446: * Action: - save current shift key status ! 1447: * - determine new active virtual terminal ! 1448: * - deactivate shift key status of the current virtual terminal ! 1449: * - deactivate current virtual terminal ! 1450: * - activate shift key status of the new virtual terminal with ! 1451: * the previously saved shift key status ! 1452: * - activate new virtual terminal ! 1453: * ! 1454: * Notes: isvtswitch() was scheduled as a deferred process by ! 1455: * process_key() which is a function called by isrint(). ! 1456: */ ! 1457: void ! 1458: isvtswitch(key_val) ! 1459: { ! 1460: register int new_index, i; ! 1461: unsigned lockshift, nolockshift; ! 1462: VTDATA *vp = vtdata[vtactive]; ! 1463: VTDATA *vp_old, *vp_new; ! 1464: static int vtprevious; ! 1465: ! 1466: lockshift = shift & (CPLS | NMLS); ! 1467: nolockshift = shift & ~(CPLS | NMLS); ! 1468: PRINTV( "F%d: %d", key_val, vtactive ); ! 1469: ! 1470: switch (key_val) { ! 1471: case VTKEY_HOME: ! 1472: new_index = 0; ! 1473: break; ! 1474: case VTKEY_NEXT: ! 1475: new_index = vtactive; ! 1476: for( i = 0; i < vtcount; ++i ) { ! 1477: new_index = ++new_index % vtcount; ! 1478: if( vttty[new_index]->t_open ) ! 1479: break; ! 1480: } ! 1481: break; ! 1482: case VTKEY_PREV: ! 1483: new_index = vtactive; ! 1484: for( i = 0; i < vtcount; ++i ) { ! 1485: new_index = (--new_index+vtcount) % vtcount; ! 1486: if( vttty[new_index]->t_open ) ! 1487: break; ! 1488: } ! 1489: break; ! 1490: case VTKEY_TOGL: ! 1491: new_index = vtprevious; ! 1492: break; ! 1493: default: ! 1494: new_index = vtindex(vtkey_to_dev(key_val)); ! 1495: if( new_index < 0) { ! 1496: putchar( '\007' ); ! 1497: return; ! 1498: } ! 1499: } ! 1500: ! 1501: T_CON(8, printf("%d->%d ", vtactive, new_index)); ! 1502: if( new_index == vtactive ) ! 1503: return; ! 1504: ! 1505: /* Save which locking shift states are in effect. */ ! 1506: ! 1507: vp_old = vtdata[vtactive]; ! 1508: vp_new = vtdata[new_index]; ! 1509: ! 1510: vp_old->vnkb_shift = lockshift; ! 1511: vtdeactivate(vp_new, vp_old); /* deactivate old virtual terminal */ ! 1512: ! 1513: /* Restore shift lock state, append current momentary shift state. */ ! 1514: shift = vp_new->vnkb_shift | nolockshift; ! 1515: ! 1516: vtactivate(vp_new); /* activate new virtual terminal */ ! 1517: updterminal(new_index); ! 1518: vtprevious = vtactive; ! 1519: vtactive = new_index; /* update vtactive */ ! 1520: } ! 1521: ! 1522: vtdeactivate(vp_new, vp_old) ! 1523: register VTDATA *vp_new, *vp_old; ! 1524: { ! 1525: register i; ! 1526: VTDATA *vpi; ! 1527: ! 1528: /* store old screen contents in memory segment */ ! 1529: ffcopy (vp_old->vmm_voff, vp_old->vmm_vseg, ! 1530: vp_old->vmm_moff, vp_old->vmm_mseg, TEXTBLOCK); ! 1531: ! 1532: /* ! 1533: * if changing to another screen on same video board ! 1534: * for all screens on same board as new screen ! 1535: * deactivate, but don't update ! 1536: * else - changing to a screen on different board ! 1537: * for all screens NOT on same board as new screen ! 1538: * deactivate, but don't update ! 1539: */ ! 1540: if ( vp_old->vmm_port == vp_new->vmm_port ) { ! 1541: T_CON(8, printf("deactivate on %x ", vp_new->vmm_port)); ! 1542: for (i = 0; i < vtcount; ++i) { ! 1543: vpi = vtdata[i]; ! 1544: if ( vpi->vmm_port == vp_new->vmm_port ) { ! 1545: /* deactivate, but don't update */ ! 1546: vpi->vmm_invis = ~0; ! 1547: vpi->vmm_visible = VNKB_FALSE; ! 1548: vpi->vmm_seg = vpi->vmm_mseg; ! 1549: vpi->vmm_off = vpi->vmm_moff; ! 1550: if( vpi->vmm_seg == 0 ) ! 1551: printf( "[1]vpi->vmm_seg = 0\n" ); ! 1552: PRINTV( "vt.back %d. seg %x off %x\n", i, ! 1553: vpi->vmm_seg, vpi->vmm_off ); ! 1554: } ! 1555: } ! 1556: } else { ! 1557: T_CON(8, printf("deactivate %x->%x ", ! 1558: vp_old->vmm_port, vp_new->vmm_port)); ! 1559: for (i = 0; i < vtcount; ++i) { ! 1560: vpi = vtdata[i]; ! 1561: if ( (vpi->vmm_port != vp_new->vmm_port) ! 1562: && (vpi->vmm_invis == 0) ) { ! 1563: /* update, but don't deactivate */ ! 1564: vpi->vmm_invis = ~0; ! 1565: updscreen(i); ! 1566: } ! 1567: } ! 1568: } ! 1569: } ! 1570: ! 1571: vtactivate(vp) ! 1572: VTDATA *vp; ! 1573: { ! 1574: register VTDATA *vpi; ! 1575: register i; ! 1576: ! 1577: /* ! 1578: * copy from screen contents from heap segment to video memory ! 1579: * only if necessary ! 1580: */ ! 1581: if (vp->vmm_visible == VNKB_FALSE) ! 1582: ffcopy (vp->vmm_moff, vp->vmm_mseg, ! 1583: vp->vmm_voff, vp->vmm_vseg, TEXTBLOCK); ! 1584: ! 1585: for (i = 0; i < vtcount; ++i) { ! 1586: vpi = vtdata[i]; ! 1587: if (vpi->vmm_port == vp->vmm_port) { ! 1588: vpi->vmm_invis = -1; ! 1589: vpi->vmm_visible = VNKB_FALSE; ! 1590: vpi->vmm_seg = vpi->vmm_mseg; ! 1591: vpi->vmm_off = vpi->vmm_moff; ! 1592: if (vpi->vmm_seg == 0) ! 1593: printf ("[2]vpi->vmm_seg = 0\n"); ! 1594: PRINTV ("vt.back seg %x off %x\n", ! 1595: vpi->vmm_seg, vpi->vmm_off); ! 1596: } ! 1597: } ! 1598: /* ! 1599: * Set new active terminal ! 1600: */ ! 1601: vp->vmm_invis = 0; ! 1602: vp->vmm_visible = VNKB_TRUE; ! 1603: vp->vmm_seg = vp->vmm_vseg; ! 1604: vp->vmm_off = vp->vmm_voff; ! 1605: if (vp->vmm_seg == 0) ! 1606: printf ("vp->vmm_seg = 0\n"); ! 1607: } ! 1608: ! 1609: /* ! 1610: * update the terminal to match vtactive ! 1611: */ ! 1612: updterminal(index) ! 1613: int index; ! 1614: { ! 1615: updscreen(index); ! 1616: updleds(); ! 1617: } ! 1618: ! 1619: /* ! 1620: * Given a function key number (e.g. vt0), ! 1621: * return the corresponding minor device number. ! 1622: * ! 1623: * Assume valid key number (VTKEY(fnum) is true) by the time we get here. ! 1624: */ ! 1625: int ! 1626: vtkey_to_dev(fnum) ! 1627: int fnum; ! 1628: { ! 1629: if (fnum >=vt0 && fnum <= vt15) ! 1630: return fnum-vt0+1; ! 1631: if (fnum >=color0 && fnum <= color15) ! 1632: return (fnum-color0)|(VT_PHYSICAL|VT_HW_COLOR); ! 1633: if (fnum >=mono0 && fnum <= mono15) ! 1634: return (fnum-mono0)|(VT_PHYSICAL|VT_HW_MONO); ! 1635: printf("vtkey_to_dev(%d)! ", fnum); ! 1636: return 0; ! 1637: } ! 1638: /* End of vtkb_d.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.