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