|
|
1.1 ! root 1: /* ! 2: * Keyboard/display driver for French keyboard. ! 3: * Coherent, IBM PC/XT/AT (286 and 386). ! 4: */ ! 5: #include <sys/coherent.h> ! 6: #ifdef _I386 ! 7: #include <sys/reg.h> ! 8: #else ! 9: #include <sys/i8086.h> ! 10: #endif ! 11: #include <sys/con.h> ! 12: #include <sys/devices.h> ! 13: #include <errno.h> ! 14: #include <sys/stat.h> ! 15: #include <sys/tty.h> ! 16: #include <signal.h> ! 17: #include <sys/sched.h> ! 18: #include <sys/silo.h> ! 19: #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 20 /* 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: * Functions. ! 68: */ ! 69: int isrint(); ! 70: int istime(); ! 71: void isbatch(); ! 72: int mmstart(); ! 73: int isopen(); ! 74: int isclose(); ! 75: int isread(); ! 76: int mmwrite(); ! 77: int isioctl(); ! 78: void mmwatch(); ! 79: int isload(); ! 80: int isuload(); ! 81: int ispoll(); ! 82: int nulldev(); ! 83: int nonedev(); ! 84: ! 85: /* ! 86: * Configuration table. ! 87: */ ! 88: CON iscon ={ ! 89: DFCHR|DFPOL, /* Flags */ ! 90: KB_MAJOR, /* Major index */ ! 91: isopen, /* Open */ ! 92: isclose, /* Close */ ! 93: nulldev, /* Block */ ! 94: isread, /* Read */ ! 95: mmwrite, /* Write */ ! 96: isioctl, /* Ioctl */ ! 97: nulldev, /* Powerfail */ ! 98: mmwatch, /* Timeout */ ! 99: isload, /* Load */ ! 100: isuload, /* Unload */ ! 101: ispoll /* Poll */ ! 102: }; ! 103: ! 104: /* ! 105: * Flag indicating turbo machine. ! 106: */ ! 107: int isturbo = 0; ! 108: ! 109: /* ! 110: ============================================================================== ! 111: ============================================================================== ! 112: */ ! 113: /* constants for vtdata[] */ ! 114: #define VT_VGAPORT 0x3D4 ! 115: #define VT_MONOPORT 0x3B4 ! 116: ! 117: #ifdef _I386 ! 118: #define VT_MONOBASE SEG_VIDEOa ! 119: #define VT_VGABASE SEG_VIDEOb ! 120: #else ! 121: #define VT_MONOBASE 0xB000 ! 122: #define VT_VGABASE 0xB800 ! 123: #endif ! 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: ! 177: /* ! 178: * Tables for converting key code to ASCII. ! 179: * lmaptab specifies unshifted conversion, ! 180: * umaptab specifies shifted conversion, ! 181: * smaptab specifies the shift states which are active. ! 182: * An entry of XXX says the key is dead. ! 183: * An entry of SPC requires further processing. ! 184: * ! 185: * Key codes: ! 186: * ESC .. <- == 1 .. 14 ! 187: * -> .. \n == 15 .. 28 ! 188: * CTRL .. ` == 29 .. 41 ! 189: * ^Shift .. PrtSc == 42 .. 55 ! 190: * ALT .. CapsLock == 56 .. 58 ! 191: * F1 .. F10 == 59 .. 68 ! 192: * NumLock .. Del == 69 .. 83 ! 193: * ISO, F11, F12 == 86 .. 88 ! 194: */ ! 195: unsigned char agmaptab[] ={ /* Alt Gr */ ! 196: XXX, XXX, '~', '#', '{', '[', '|', /* 1 - 7 */ ! 197: '`', '\\', '^', '@', ']', '}', XXX, XXX, /* 8 - 15 */ ! 198: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 16 - 23 */ ! 199: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 24 - 31 */ ! 200: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 32 - 39 */ ! 201: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 40 - 47 */ ! 202: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 48 - 55 */ ! 203: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 56 - 63 */ ! 204: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 64 - 71 */ ! 205: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 72 - 79 */ ! 206: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 80 - 87 */ ! 207: XXX /* 88 */ ! 208: }; ! 209: ! 210: static unsigned char lmaptab[] ={ ! 211: '\33', '&','\202', '"', '\'', '(', '-', /* 1 - 7 */ ! 212: '\212','_','\207','\205',')', '=', '\b', '\t', /* 8 - 15 */ ! 213: 'a', 'z', 'e', 'r', 't', 'y', 'u', 'i', /* 16 - 23 */ ! 214: 'o', 'p','\260', '$', '\r', XXX, 'q', 's', /* 24 - 31 */ ! 215: 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', /* 32 - 39 */ ! 216: '\227','\375',XXX,'*', 'w', 'x', 'c', 'v', /* 40 - 47 */ ! 217: 'b', 'n', ',', ';', ':', SPC, XXX, SPC, /* 48 - 55 */ ! 218: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */ ! 219: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */ ! 220: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */ ! 221: SPC, SPC, SPC, SPC, XXX, XXX, '<', XXX, /* 80 - 87 */ ! 222: XXX /* 88 */ ! 223: }; ! 224: ! 225: static unsigned char umaptab[] ={ ! 226: '\33', '1', '2', '3', '4', '5', '6', /* 1 - 7 */ ! 227: '7', '8', '9', '0','\370', '+', '\b', SPC, /* 8 - 15 */ ! 228: 'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', /* 16 - 23 */ ! 229: 'O', 'P','\261','\234','\r', XXX, 'Q', 'S', /* 24 - 31 */ ! 230: 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', /* 32 - 39 */ ! 231: '%','\300',XXX,'\346', 'W', 'X', 'C', 'V', /* 40 - 47 */ ! 232: 'B', 'N', '?', '.', '/', SPC, XXX, SPC, /* 48 - 55 */ ! 233: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */ ! 234: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */ ! 235: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */ ! 236: SPC, SPC, SPC, SPC, XXX, XXX, '>', XXX, /* 80 - 87 */ ! 237: XXX /* 88 */ ! 238: }; ! 239: ! 240: #define SS0 0 /* No shift */ ! 241: #define SS1 (SLS|SRS|CTS) /* Shift, Ctrl */ ! 242: #define SES (SLS|SRS) /* Shift */ ! 243: #define LET (SLS|SRS|CPLS|CTS) /* Shift, Caps, Ctrl */ ! 244: #define KEY (SLS|SRS|NMLS|AKPS) /* Shift, Num, Alt keypad */ ! 245: ! 246: static unsigned char smaptab[] ={ ! 247: SS0, SES, SS1, SES, SES, SES, SS1, /* 1 - 7 */ ! 248: SES, SES, SES, SES, SS1, SES, CTS, SES, /* 8 - 15 */ ! 249: LET, LET, LET, LET, LET, LET, LET, LET, /* 16 - 23 */ ! 250: LET, LET, SS1, SS1, CTS, SHFT, LET, LET, /* 24 - 31 */ ! 251: LET, LET, LET, LET, LET, LET, LET, SES, /* 32 - 39 */ ! 252: SES, SS1, SHFT, SS1, LET, LET, LET, LET, /* 40 - 47 */ ! 253: LET, LET, LET, SES, SES, SES, SHFT, SES, /* 48 - 55 */ ! 254: SHFT, SS1, SHFT, SS0, SS0, SS0, SS0, SS0, /* 56 - 63 */ ! 255: SS0, SS0, SS0, SS0, SS0, SHFT, KEY, KEY, /* 64 - 71 */ ! 256: KEY, KEY, SS0, KEY, KEY, KEY, SS0, KEY, /* 72 - 79 */ ! 257: KEY, KEY, KEY, KEY, SS0, SS0, SES, SS0, /* 80 - 87 */ ! 258: SS0 ! 259: }; ! 260: ! 261: /* ! 262: * Load entry point. ! 263: * Do reset the keyboard because it gets terribly munged ! 264: * if you type during the boot. ! 265: */ ! 266: isload() ! 267: { ! 268: register short i; /* was: int i */ ! 269: register HWentry **hw; ! 270: register VTDATA *vp; ! 271: ! 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: static char *deffuncs[] = { ! 425: "\33[1x\377", /* F1 */ ! 426: "\33[2x\377", /* F2 */ ! 427: "\33[3x\377", /* F3 */ ! 428: "\33[4x\377", /* F4 */ ! 429: "\33[5x\377", /* F5 */ ! 430: "\33[6x\377", /* F6 */ ! 431: "\33[7x\377", /* F7 */ ! 432: "\33[8x\377", /* F8 */ ! 433: "\33[9x\377", /* F9 */ ! 434: "\33[0x\377", /* F10 - historical value */ ! 435: "\33[1y\377", /* F11 */ ! 436: "\33[2y\377", /* F12 */ ! 437: "\33[3y\377", /* F13 */ ! 438: "\33[4y\377", /* F14 */ ! 439: "\33[5y\377", /* F15 */ ! 440: "\33[6y\377", /* F16 */ ! 441: "\33[7y\377", /* F17 */ ! 442: "\33[8y\377", /* F18 */ ! 443: "\33[9y\377", /* F19 */ ! 444: "\33[0y\377" /* F20 */ ! 445: }; ! 446: ! 447: /* ! 448: * Open routine. ! 449: */ ! 450: isopen(dev, mode) ! 451: dev_t dev; ! 452: unsigned int mode; ! 453: { ! 454: register int s; ! 455: register TTY *tp; ! 456: int index = vtindex(dev); ! 457: ! 458: PRINTV("isopen: %x\n", dev); ! 459: if (index < 0 || index >= vtcount) { ! 460: u.u_error = ENXIO; ! 461: return; ! 462: } ! 463: ! 464: tp = vttty[index]; ! 465: if ((tp->t_flags&T_EXCL) != 0 && !super()) { ! 466: u.u_error = ENODEV; ! 467: return; ! 468: } ! 469: ttsetgrp(tp, dev, mode); ! 470: ! 471: s = sphi(); ! 472: if (tp->t_open++ == 0) { ! 473: initkeys(); /* init function keys */ ! 474: tp->t_flags = T_CARR; /* indicate "carrier" */ ! 475: ttopen(tp); ! 476: } ! 477: spl(s); ! 478: #if 0 ! 479: updleds(); /* update keyboard status LEDS */ ! 480: #endif ! 481: } ! 482: ! 483: /* Init function keys */ ! 484: initkeys() ! 485: { register int i; ! 486: register char *cp1, *cp2; ! 487: ! 488: for (i=0; i<NFKEY; i++) ! 489: isfval[i] = 0; /* clear function key buffer */ ! 490: cp2 = isfbuf; /* pointer to key buffer */ ! 491: for (i=0; i<NFKEY; i++) ! 492: { isfval[i] = cp2; /* save pointer to key string */ ! 493: cp1 = deffuncs[i]; /* get init string pointer */ ! 494: while ((*cp2++ = *cp1++) != -1) /* copy key data */ ! 495: if (cp2 >= &isfbuf[NFBUF-3]) /* overflow? */ ! 496: return; ! 497: } ! 498: } ! 499: ! 500: void isvtswitch(); /* deferred virtual terminal switch */ ! 501: ! 502: /* ! 503: * Close a tty. ! 504: */ ! 505: isclose(dev) ! 506: { ! 507: register int s; ! 508: int index = vtindex(dev); ! 509: register TTY *tp = vttty[index]; ! 510: ! 511: if (--tp->t_open == 0) ! 512: ttclose(tp); ! 513: ! 514: } ! 515: ! 516: /* ! 517: * Read routine. ! 518: */ ! 519: isread(dev, iop) ! 520: dev_t dev; ! 521: IO *iop; ! 522: { ! 523: int index = vtindex(dev); ! 524: register TTY *tp = vttty[index]; ! 525: ! 526: ttread(tp, iop, 0); ! 527: if (tp->t_oq.cq_cc) ! 528: mmtime(tp); ! 529: } ! 530: ! 531: /* ! 532: * Ioctl routine. ! 533: */ ! 534: isioctl(dev, com, vec) ! 535: dev_t dev; ! 536: struct sgttyb *vec; ! 537: { ! 538: register int s; ! 539: ! 540: switch(com) { ! 541: case TIOCSETF: ! 542: case TIOCGETF: ! 543: isfunction(com, (char *)vec); ! 544: goto ioc_done;; ! 545: case TIOCSHIFT: /* switch left-SHIFT and "\" */ ! 546: lshiftkb = LSHIFTA; /* alternate values */ ! 547: lmaptab[41] = '\\'; ! 548: lmaptab[42] = XXX; ! 549: umaptab[41] = '|'; ! 550: umaptab[42] = XXX; ! 551: smaptab[41] = SS1; ! 552: smaptab[42] = SHFT; ! 553: goto ioc_done;; ! 554: case TIOCCSHIFT: /* normal (default) left-SHIFT and "\" */ ! 555: lshiftkb = LSHIFT; /* normal values */ ! 556: lmaptab[41] = XXX; ! 557: lmaptab[42] = '\\'; ! 558: umaptab[41] = XXX; ! 559: umaptab[42] = '|'; ! 560: smaptab[41] = SHFT; ! 561: smaptab[42] = SS1; ! 562: goto ioc_done;; ! 563: } ! 564: s = sphi(); ! 565: ttioctl(vttty[vtindex(dev)], com, vec); ! 566: spl(s); ! 567: ! 568: ioc_done: ! 569: return; ! 570: } ! 571: ! 572: /* ! 573: * Set and receive the function keys. ! 574: */ ! 575: isfunction(c, v) ! 576: int c; ! 577: char *v; ! 578: { ! 579: register char *cp; ! 580: register int i; ! 581: ! 582: if (c == TIOCGETF) { ! 583: for (cp = isfbuf; cp < &isfbuf[NFBUF]; cp++) ! 584: putubd(v++, *cp); ! 585: } else { ! 586: for (i=0; i<NFKEY; i++) /* zap current settings */ ! 587: isfval[i] = 0; ! 588: cp = isfbuf; /* pointer to key buffer */ ! 589: for (i=0; i<NFKEY; i++) { ! 590: isfval[i] = cp; /* save pointer to key string */ ! 591: while ((*cp++ = getubd(v++)) != -1) /* copy key data */ ! 592: if (cp >= &isfbuf[NFBUF-3]) /* overflow? */ ! 593: return; ! 594: } ! 595: } ! 596: } ! 597: ! 598: ! 599: /* ! 600: * Poll routine. ! 601: */ ! 602: ispoll( dev, ev, msec ) ! 603: dev_t dev; ! 604: int ev; ! 605: int msec; ! 606: { ! 607: register TTY *tp = vttty[vtindex(dev)]; ! 608: ! 609: return ttpoll(tp, ev, msec); ! 610: } ! 611: ! 612: /* ! 613: * Receive interrupt. ! 614: */ ! 615: isrint() ! 616: { ! 617: register int c; ! 618: register int s; ! 619: register int r; ! 620: int savests; ! 621: int update_leds = 0; ! 622: ! 623: /* ! 624: * Schedule raw input handler if not already active. ! 625: */ ! 626: if ( isbusy == 0 ) { ! 627: isbusy = 1; ! 628: defer(isbatch, vttty[vtactive]); ! 629: } ! 630: ! 631: /* ! 632: * Pull character from the data ! 633: * port. Pulse the KBFLAG in the control ! 634: * port to reset the data buffer. ! 635: */ ! 636: r = inb(KBDATA) & 0xFF; ! 637: c = inb(KBCTRL); ! 638: outb(KBCTRL, c|KBFLAG); ! 639: outb(KBCTRL, c); ! 640: #if KBDEBUG ! 641: printf("kbd: %d\n", r); /* print scan code/direction */ ! 642: #endif ! 643: if (ledcmd) { ! 644: ledcmd = 0; ! 645: if (r == KBACK) { /* output to status LEDS */ ! 646: c = scrollkb & 1; ! 647: if (shift & NMLS) ! 648: c |= 2; ! 649: if (shift & CPLS) ! 650: c |= 4; ! 651: outb(KBDATA, c); ! 652: } ! 653: return; ! 654: } ! 655: if (extended > 0) { /* if multi-character seq, */ ! 656: --extended; /* ... ignore this char */ ! 657: return; ! 658: } ! 659: switch (r) { ! 660: case EXTENDED0: /* 0xE0 prefix found */ ! 661: ext0seen = 1; ! 662: return; ! 663: case EXTENDED1: /* ignore extended sequences */ ! 664: extended = 5; ! 665: return; ! 666: case 0xFF: /* Overrun */ ! 667: return; ! 668: } ! 669: ! 670: if (ext0seen) { ! 671: ext0seen = 0; ! 672: extmode = 1; ! 673: } else ! 674: extmode = 0; ! 675: ! 676: c = (r & KEYSC) - 1; ! 677: /* ! 678: * Check for reset. ! 679: */ ! 680: if ((r&KEYUP) == 0 && c == DELETE && (shift&(CTS|ALS)) == (CTS|ALS)) ! 681: boot(); ! 682: ! 683: /* ! 684: * Track "shift" keys. ! 685: */ ! 686: s = smaptab[c]; ! 687: if (s&SHFT) { ! 688: if (r&KEYUP) { /* "shift" released */ ! 689: if (c == RSHIFT) ! 690: shift &= ~SRS; ! 691: else if (c == lshiftkb) ! 692: shift &= ~SLS; ! 693: else if (c == CTRLkb) ! 694: shift &= ~CTS; ! 695: else if (c == ALTkb) ! 696: shift &= extmode ? ~AGS : ~ALS; ! 697: } else { /* "shift" pressed */ ! 698: if (c == lshiftkb) ! 699: shift |= SLS; ! 700: else if (c == RSHIFT) ! 701: shift |= SRS; ! 702: else if (c == CTRLkb) ! 703: shift |= CTS; ! 704: else if (c == ALTkb) ! 705: shift |= extmode ? AGS : ALS; ! 706: else if (c == CAPLOCK) { ! 707: shift ^= CPLS; /* toggle cap lock */ ! 708: updleds(); ! 709: } else if (c == NUMLOCK) { ! 710: shift ^= NMLS; /* toggle num lock */ ! 711: updleds(); ! 712: } ! 713: } ! 714: return; ! 715: } ! 716: ! 717: /* ! 718: * No other key up codes of interest. ! 719: */ ! 720: if (r&KEYUP) ! 721: return; ! 722: ! 723: /* ! 724: * Map character, based on the ! 725: * current state of the shift, control, alt graphics, ! 726: * meta (ALT) and lock flags. ! 727: */ ! 728: if (shift & AGS) /* Alt Graphics ? */ ! 729: c = agmaptab[c]; ! 730: else if (shift & CTS) { ! 731: if (s == CTS) /* Map Ctrl (BS | NL) */ ! 732: c = (c == BACKSP) ? 0x7F : 0x0A; ! 733: else if (s==SS1 || s==LET) /* Normal Ctrl map */ ! 734: c = umaptab[c]&0x1F; /* Clear bits 5-6 */ ! 735: else { if (s==KEY || s==SS0) ! 736: vtnumeric(r); ! 737: return; /* Ignore this char */ ! 738: } ! 739: } else if (s &= shift) { ! 740: if (shift & SES) { /* if shift on */ ! 741: if (s & (CPLS|NMLS)) /* if caps/num lock */ ! 742: c = lmaptab[c]; /* use unshifted */ ! 743: else ! 744: c = umaptab[c]; /* use shifted */ ! 745: } else { /* if shift not on */ ! 746: if (s & (CPLS|NMLS)) /* if caps/num lock */ ! 747: c = umaptab[c]; /* use shifted */ ! 748: else ! 749: c = lmaptab[c]; /* use unshifted */ ! 750: } ! 751: } else ! 752: c = lmaptab[c]; /* use unshifted */ ! 753: ! 754: /* ! 755: * Act on character. ! 756: */ ! 757: if (c == XXX) ! 758: return; /* char to ignore */ ! 759: ! 760: if (c != SPC) { /* not special char? */ ! 761: if (shift & ALS) /* ALT (meta bit)? */ ! 762: c |= 0x80; /* set meta */ ! 763: isin(c); /* send the char */ ! 764: } else ! 765: update_leds += isspecial(r); /* special chars */ ! 766: if (update_leds) { ! 767: savests = sphi(); ! 768: outb(KBDATA, LEDCMD); ! 769: ledcmd = 1; ! 770: spl(savests); ! 771: } ! 772: } ! 773: ! 774: /* ! 775: * Process numeric keypad for virtual terminals. ! 776: */ ! 777: vtnumeric(c) ! 778: int c; ! 779: { ! 780: switch (c) { ! 781: case 71: case 72: case 73: /* ctrl 7/8/9 (vt7, vt8, vt9) */ ! 782: defer(isvtswitch, c + 16); ! 783: break; ! 784: case 74: /* ctrl - */ ! 785: defer(isvtswitch, vtp); ! 786: break; ! 787: case 75: case 76: case 77: /* ctrl 4/5/6 (vt5, vt6, vt7) */ ! 788: defer(isvtswitch, c + 10); ! 789: break; ! 790: case 78: /* ctrl + */ ! 791: defer(isvtswitch, vtn); ! 792: break; ! 793: case 79: case 80: case 81: /* ctrl 1/2/3 */ ! 794: defer(isvtswitch, c + 2); ! 795: break; ! 796: case 82: /* ctrl 0 (vt0) */ ! 797: defer(isvtswitch, vt0); ! 798: break; ! 799: case 83: /* ctrl del (toggle) */ ! 800: c = vtt; ! 801: defer(isvtswitch, vtt); ! 802: break; ! 803: } ! 804: } ! 805: ! 806: /* ! 807: * Handle special input sequences. ! 808: * The character passed is the key number. ! 809: * ! 810: * The keypad is translated by the following table, ! 811: * the first entry is the normal sequence, the second the shifted, ! 812: * and the third the alternate keypad sequence. ! 813: */ ! 814: static char *keypad[][3] = { ! 815: { "\33[H", "7", "\33?w" }, /* 71 */ ! 816: { "\33[A", "8", "\33?x" }, /* 72 */ ! 817: { "\33[V", "9", "\33?y" }, /* 73 */ ! 818: { "\33[D", "4", "\33?t" }, /* 75 */ ! 819: { "\0337", "5", "\33?u" }, /* 76 */ ! 820: { "\33[C", "6", "\33?v" }, /* 77 */ ! 821: { "\33[24H","1", "\33?q" }, /* 79 */ ! 822: { "\33[B", "2", "\33?r" }, /* 80 */ ! 823: { "\33[U", "3", "\33?s" }, /* 81 */ ! 824: { "\33[@", "0", "\33?p" }, /* 82 */ ! 825: { "\33[P", ".", "\33?n" } /* 83 */ ! 826: }; ! 827: ! 828: isspecial(c) ! 829: int c; ! 830: { ! 831: register char *cp; ! 832: register int s; ! 833: int update_leds = 0; ! 834: ! 835: cp = 0; ! 836: ! 837: switch (c) { ! 838: case 15: /* cursor back tab */ ! 839: cp = "\033[Z"; ! 840: break; ! 841: case 53: ! 842: if (extmode) ! 843: cp = "/"; ! 844: else if (shift & SES) ! 845: cp = "_"; ! 846: else ! 847: cp = "-"; ! 848: break; ! 849: case 55: /* ignore PrtScr */ ! 850: if (!extmode) ! 851: cp = "*"; ! 852: break; ! 853: case 59: case 60: case 61: case 62: case 63: /* Function keys */ ! 854: case 64: case 65: case 66: ! 855: /* offset to function string */ ! 856: /* Magic numbers 21 and 61 to mach vtnkb constants */ ! 857: if ( shift & ALS ) ! 858: defer(isvtswitch, c + 21); ! 859: else ! 860: cp = isfval[c-59]; ! 861: break; ! 862: case 67: case 68: ! 863: /* offset to function string */ ! 864: if ( shift & ALS ) ! 865: defer(isvtswitch, c + 61); ! 866: else ! 867: cp = isfval[c-59]; ! 868: break; ! 869: case 70: /* Scroll Lock -- stop/start output */ ! 870: { ! 871: static char cbuf[2]; ! 872: ! 873: cp = &cbuf[0]; /* working buffer */ ! 874: if (!(vttty[vtactive]->t_sgttyb.sg_flags ! 875: & RAWIN)) { /* not if in RAW mode */ ! 876: ! 877: ++update_leds; ! 878: if (vttty[vtactive]->t_flags&T_STOP){/* output stopped? */ ! 879: cbuf[0] = vttty[vtactive]->t_tchars.t_startc; ! 880: scrollkb = 0; ! 881: } else { ! 882: cbuf[0] = vttty[vtactive]->t_tchars.t_stopc; ! 883: scrollkb = 1; ! 884: } ! 885: } ! 886: break; ! 887: } ! 888: ! 889: case 79: /* 1/End */ ! 890: case 80: /* 2/DOWN */ ! 891: case 81: /* 3/PgDn */ ! 892: case 82: /* 0/Ins */ ! 893: case 83: /* ./Del */ ! 894: --c; /* adjust code */ ! 895: case 75: /* 4/LEFT */ ! 896: case 76: /* 5 */ ! 897: case 77: /* 6/RIGHT */ ! 898: --c; /* adjust code */ ! 899: case 71: /* 7/Home/Clear */ ! 900: case 72: /* 8/UP */ ! 901: case 73: /* 9/PgUp */ ! 902: s = 0; /* start off with normal keypad */ ! 903: if (shift & NMLS) /* num lock? */ ! 904: s = 1; /* set shift pad */ ! 905: if (shift & SES) /* shift? */ ! 906: s ^= 1; /* toggle shift pad */ ! 907: if (shift & AKPS) /* alternate pad? */ ! 908: s = 2; /* set alternate pad */ ! 909: if (extmode) /* not from keypad? */ ! 910: s = 0; /* force normal sequence */ ! 911: cp = keypad[c-71][s]; /* get keypad value */ ! 912: break; ! 913: } ! 914: if (cp) /* send string */ ! 915: while ((*cp != 0) && (*cp != -1)) ! 916: isin( *cp++ & 0377 ); ! 917: return update_leds; ! 918: } ! 919: ! 920: /** ! 921: * ! 922: * void ! 923: * ismmfunc( c ) -- process keyboard related output escape sequences ! 924: * char c; ! 925: */ ! 926: void ! 927: ismmfunc(c) ! 928: register int c; ! 929: { ! 930: switch (c) { ! 931: case 't': /* Enter numlock */ ! 932: shift |= NMLS; ! 933: updleds(); /* update LED status */ ! 934: break; ! 935: case 'u': /* Leave numlock */ ! 936: shift &= ~NMLS; ! 937: updleds(); /* update LED status */ ! 938: break; ! 939: case '=': /* Enter alternate keypad */ ! 940: shift |= AKPS; ! 941: break; ! 942: case '>': /* Exit alternate keypad */ ! 943: shift &= ~AKPS; ! 944: break; ! 945: case 'c': /* Reset terminal */ ! 946: islock = 0; ! 947: shift = 0; ! 948: initkeys(); ! 949: updleds(); /* update LED status */ ! 950: break; ! 951: } ! 952: } ! 953: ! 954: /** ! 955: * ! 956: * void ! 957: * isin( c ) -- append character to raw input silo ! 958: * char c; ! 959: */ ! 960: static ! 961: isin( c ) ! 962: register int c; ! 963: { ! 964: int cache_it = 1; ! 965: TTY * tp = vttty[vtactive]; ! 966: ! 967: /* ! 968: * If using software incoming flow control, process and ! 969: * discard t_stopc and t_startc. ! 970: */ ! 971: if (ISIXON) { ! 972: #if _I386 ! 973: if (ISSTART || (ISIXANY && ISXSTOP)) { ! 974: tp->t_flags &= ~(T_STOP | T_XSTOP); ! 975: ttstart(tp); ! 976: cache_it = 0; ! 977: } else if (ISSTOP) { ! 978: if ((tp->t_flags&T_STOP) == 0) ! 979: tp->t_flags |= (T_STOP | T_XSTOP); ! 980: cache_it = 0; ! 981: } ! 982: #else ! 983: if (ISSTOP) { ! 984: if ((tp->t_flags&T_STOP) == 0) ! 985: tp->t_flags |= T_STOP; ! 986: cache_it = 0; ! 987: } ! 988: if (ISSTART) { ! 989: tp->t_flags &= ~T_STOP; ! 990: ttstart(tp); ! 991: cache_it = 0; ! 992: } ! 993: #endif ! 994: } ! 995: /* ! 996: * If the tty is not open the character is ! 997: * just tossed away. ! 998: */ ! 999: if (vttty[vtactive]->t_open == 0) ! 1000: return; ! 1001: ! 1002: ! 1003: /* ! 1004: * Cache received character. ! 1005: */ ! 1006: if (cache_it) { ! 1007: in_silo.si_buf[ in_silo.si_ix ] = c; ! 1008: ! 1009: if ( ++in_silo.si_ix >= sizeof(in_silo.si_buf) ) ! 1010: in_silo.si_ix = 0; ! 1011: } ! 1012: } ! 1013: ! 1014: /** ! 1015: * ! 1016: * void ! 1017: * isbatch() -- raw input conversion routine ! 1018: * ! 1019: * Action: Enable the video display. ! 1020: * Canonize the raw input silo. ! 1021: * ! 1022: * Notes: isbatch() was scheduled as a deferred process by isrint(). ! 1023: */ ! 1024: static void ! 1025: isbatch( tp ) ! 1026: register TTY * tp; ! 1027: { ! 1028: register int c; ! 1029: static int lastc; ! 1030: VTDATA *vp = tp->t_ddp; ! 1031: ! 1032: /* ! 1033: * Ensure video display is enabled. ! 1034: */ ! 1035: if (vp->vmm_visible) ! 1036: mm_von(vp); ! 1037: ! 1038: isbusy = 0; ! 1039: ! 1040: /* ! 1041: * Process all cached characters. ! 1042: */ ! 1043: while ( in_silo.si_ix != in_silo.si_ox ) { ! 1044: ! 1045: /* ! 1046: * Get next cached char. ! 1047: */ ! 1048: c = in_silo.si_buf[ in_silo.si_ox ]; ! 1049: ! 1050: if ( in_silo.si_ox >= sizeof(in_silo.si_buf) - 1 ) ! 1051: in_silo.si_ox = 0; ! 1052: else ! 1053: in_silo.si_ox++; ! 1054: ! 1055: if ( (islock == 0) || ISINTR || ISQUIT ) { ! 1056: ttin( tp, c ); ! 1057: } ! 1058: ! 1059: else if ( (c == 'b') && (lastc == '\033') ) { ! 1060: islock = 0; ! 1061: ttin( tp, lastc ); ! 1062: ttin( tp, c ); ! 1063: } ! 1064: ! 1065: else if ( (c == 'c') && (lastc == '\033') ) { ! 1066: ttin( tp, lastc ); ! 1067: ttin( tp, c ); ! 1068: } ! 1069: ! 1070: else ! 1071: putchar('\007'); ! 1072: ! 1073: lastc = c; ! 1074: } ! 1075: } ! 1076: ! 1077: /* ! 1078: * update the keyboard status LEDS ! 1079: */ ! 1080: updleds() ! 1081: { ! 1082: int s; ! 1083: ! 1084: s = sphi(); ! 1085: outb(KBDATA, LEDCMD); ! 1086: ledcmd = 1; ! 1087: spl(s); ! 1088: } ! 1089: ! 1090: /* ! 1091: * unlock the scroll in case an interrupt character is received ! 1092: */ ! 1093: kbunscroll() ! 1094: { ! 1095: scrollkb = 0; ! 1096: updleds(); ! 1097: } ! 1098: int ! 1099: VTttyinit(i) ! 1100: int i; ! 1101: { ! 1102: TTY *tp; ! 1103: ! 1104: /* ! 1105: * get pointer to TTY structure from kernal memory space ! 1106: */ ! 1107: if( (tp = vttty[i] = (TTY *)kalloc(sizeof (TTY))) == NULL ) ! 1108: return(0); ! 1109: PRINTV( " vttty[%d]: @%x, ", i, tp ); ! 1110: ! 1111: #if FAR_TTY ! 1112: /* ! 1113: * get pointers to the buffers pointed to by the TTY structure ! 1114: * from user memory space ! 1115: */ ! 1116: tp->t_buffer = salloc( (fsize_t)NCIB+2*SI_BUFSIZ, SFSYST|SFNSWP ); ! 1117: tp->t_ib = 0; ! 1118: tp->t_rawin.si_buf = NCIB; ! 1119: tp->t_rawout.si_buf = NCIB+SI_BUFSIZ; ! 1120: #endif ! 1121: tp->t_param = NULL; ! 1122: tp->t_start = &mmstart; ! 1123: ! 1124: #ifndef _I386 ! 1125: #if VT_MAJOR == KB_MAJOR ! 1126: tp->t_cs_sel = 0; ! 1127: #else ! 1128: tp->t_cs_sel = cs_sel(); ! 1129: #endif ! 1130: #endif ! 1131: tp->t_ddp = vtdata[i]; ! 1132: PRINTV( "data @%lx\n", tp->t_ddp ); ! 1133: return(1); ! 1134: } ! 1135: ! 1136: vtdatainit(vp) ! 1137: VTDATA *vp; ! 1138: { ! 1139: #ifndef _I386 ! 1140: VT_FARSEG vt_farseg; ! 1141: #endif ! 1142: /* ! 1143: * vtdata init - vmm part ! 1144: */ ! 1145: vp->vmm_invis = -1; /* cursor invisible */ ! 1146: ! 1147: #ifdef _I386 ! 1148: vp->vt_buffer = kalloc( TEXTBLOCK ); ! 1149: vp->vmm_seg = vp->vmm_mseg = ds_sel(); ! 1150: vp->vmm_off = vp->vmm_moff = vp->vt_buffer; ! 1151: #else ! 1152: vp->vt_buffer = salloc ( (fsize_t)TEXTBLOCK, SFSYST|SFNSWP|SFHIGH ); ! 1153: vp->vmm_seg = vp->vmm_mseg = FP_SEG( vp->vt_buffer->vt_faddr ); ! 1154: vp->vmm_off = vp->vmm_moff = FP_OFF( vp->vt_buffer->vt_faddr ); ! 1155: #endif ! 1156: PRINTV( "vt@%x init index %d,%d), seg %x, off %x\n", ! 1157: vp, vp->vt_ind, vp->vmm_mseg, vp->vmm_moff ); ! 1158: /* ! 1159: * vtdata init - vnkb part ! 1160: */ ! 1161: /* Make the first memory block active, if present */ ! 1162: vp->vnkb_lastc = 0; ! 1163: vp->vnkb_fnkeys = 0; ! 1164: vp->vnkb_funkeyp = 0; ! 1165: vp->vnkb_fk_loaded = 0; /* no Fn keys yet */ ! 1166: } ! 1167: ! 1168: /* ! 1169: * Given device number, return index for vtdata[], vttty[], etc. ! 1170: * ! 1171: * Major number must be VT_MAJOR for CPU to get here. ! 1172: * ! 1173: * Minor Number Index Value ! 1174: * ----- ------ ----- ----- ! 1175: * 0000 0000 vtactive ... device (2,0) is the active screen ! 1176: * 0000 0001 0 ! 1177: * 0000 0010 1 ! 1178: * 0000 0011 2 ! 1179: * .... ! 1180: * 0000 1111 14 ! 1181: * ! 1182: * 0100 xxxx xxxx ... color devices only ! 1183: * 0101 xxxx xxxx - (# of color devices found) ... monochrome only ! 1184: * ! 1185: * Return value is in range 0 to vtcount-1 for valid minor numbers, ! 1186: * -1 for invalid minor numbers. ! 1187: */ ! 1188: int ! 1189: vtindex( dev ) ! 1190: dev_t dev; ! 1191: { ! 1192: register int ret = -1; ! 1193: ! 1194: if ( dev & VT_PHYSICAL ) { ! 1195: int hw = ( dev >> 4 ) & 3; ! 1196: int hw_index = dev & 0x0F; ! 1197: ! 1198: if( hw_index < vtHWtable[hw]->found ) ! 1199: ret = vtHWtable[hw]->start + hw_index; ! 1200: } else { ! 1201: int lg_index = dev & 0x0F; ! 1202: ! 1203: if (lg_index == 0) ! 1204: ret = vtactive; ! 1205: if (lg_index > 0 && lg_index <= vtcount ) ! 1206: ret = lg_index-1; ! 1207: } ! 1208: if (ret >= 0) ! 1209: ret %= vtcount; ! 1210: else ! 1211: PRINTV( "vtindex: (%x) %d. invalid !\n", dev, ret ); ! 1212: return ret; ! 1213: } ! 1214: ! 1215: /* ! 1216: * ! 1217: * void ! 1218: * isvtswitch() -- deferred virtual terminal switch ! 1219: * ! 1220: * Action: - save current shift key status ! 1221: * - determine new active virtual terminal ! 1222: * - deactivate shift key status of the current virtual terminal ! 1223: * - deactivate current virtual terminal ! 1224: * - activate shift key status of the new virtual terminal with ! 1225: * the previously saved shift key status ! 1226: * - activate new virtual terminal ! 1227: * ! 1228: * Notes: isvtswitch() was scheduled as a deferred process by ! 1229: * process_key() which is a function called by isrint(). ! 1230: */ ! 1231: void ! 1232: isvtswitch(key_val) ! 1233: { ! 1234: register int new_index, i; ! 1235: unsigned lockshift, nolockshift; ! 1236: VTDATA *vp = vtdata[vtactive]; ! 1237: VTDATA *vp_old, *vp_new; ! 1238: static int vtprevious; ! 1239: ! 1240: lockshift = shift & (CPLS | NMLS); ! 1241: nolockshift = shift & ~(CPLS | NMLS); ! 1242: PRINTV( "F%d: %d", key_val, vtactive ); ! 1243: ! 1244: switch (key_val) { ! 1245: case VTKEY_HOME: ! 1246: new_index = 0; ! 1247: break; ! 1248: case VTKEY_NEXT: ! 1249: new_index = vtactive; ! 1250: for( i = 0; i < vtcount; ++i ) { ! 1251: new_index = ++new_index % vtcount; ! 1252: if( vttty[new_index]->t_open ) ! 1253: break; ! 1254: } ! 1255: break; ! 1256: case VTKEY_PREV: ! 1257: new_index = vtactive; ! 1258: for( i = 0; i < vtcount; ++i ) { ! 1259: new_index = (--new_index+vtcount) % vtcount; ! 1260: if( vttty[new_index]->t_open ) ! 1261: break; ! 1262: } ! 1263: break; ! 1264: case VTKEY_TOGL: ! 1265: new_index = vtprevious; ! 1266: break; ! 1267: default: ! 1268: new_index = vtindex(vtkey_to_dev(key_val)); ! 1269: if( new_index < 0) { ! 1270: putchar( '\007' ); ! 1271: return; ! 1272: } ! 1273: } ! 1274: ! 1275: T_CON(8, printf("%d->%d ", vtactive, new_index)); ! 1276: if( new_index == vtactive ) ! 1277: return; ! 1278: ! 1279: /* Save which locking shift states are in effect. */ ! 1280: ! 1281: vp_old = vtdata[vtactive]; ! 1282: vp_new = vtdata[new_index]; ! 1283: ! 1284: vp_old->vnkb_shift = lockshift; ! 1285: vtdeactivate(vp_new, vp_old); /* deactivate old virtual terminal */ ! 1286: ! 1287: /* Restore shift lock state, append current momentary shift state. */ ! 1288: shift = vp_new->vnkb_shift | nolockshift; ! 1289: ! 1290: vtactivate(vp_new); /* activate new virtual terminal */ ! 1291: updterminal(new_index); ! 1292: vtprevious = vtactive; ! 1293: vtactive = new_index; /* update vtactive */ ! 1294: } ! 1295: ! 1296: vtdeactivate(vp_new, vp_old) ! 1297: register VTDATA *vp_new, *vp_old; ! 1298: { ! 1299: register i; ! 1300: VTDATA *vpi; ! 1301: ! 1302: /* store old screen contents in memory segment */ ! 1303: FFCOPY( vp_old->vmm_voff, vp_old->vmm_vseg, ! 1304: vp_old->vmm_moff, vp_old->vmm_mseg, TEXTBLOCK ); ! 1305: ! 1306: /* ! 1307: * if changing to another screen on same video board ! 1308: * for all screens on same board as new screen ! 1309: * deactivate, but don't update ! 1310: * else - changing to a screen on different board ! 1311: * for all screens NOT on same board as new screen ! 1312: * deactivate, but don't update ! 1313: */ ! 1314: if ( vp_old->vmm_port == vp_new->vmm_port ) { ! 1315: T_CON(8, printf("deactivate on %x ", vp_new->vmm_port)); ! 1316: for (i = 0; i < vtcount; ++i) { ! 1317: vpi = vtdata[i]; ! 1318: if ( vpi->vmm_port == vp_new->vmm_port ) { ! 1319: /* deactivate, but don't update */ ! 1320: vpi->vmm_invis = ~0; ! 1321: vpi->vmm_visible = VNKB_FALSE; ! 1322: vpi->vmm_seg = vpi->vmm_mseg; ! 1323: vpi->vmm_off = vpi->vmm_moff; ! 1324: if( vpi->vmm_seg == 0 ) ! 1325: printf( "[1]vpi->vmm_seg = 0\n" ); ! 1326: PRINTV( "vt.back %d. seg %x off %x\n", i, ! 1327: vpi->vmm_seg, vpi->vmm_off ); ! 1328: } ! 1329: } ! 1330: } else { ! 1331: T_CON(8, printf("deactivate %x->%x ", ! 1332: vp_old->vmm_port, vp_new->vmm_port)); ! 1333: for (i = 0; i < vtcount; ++i) { ! 1334: vpi = vtdata[i]; ! 1335: if ( (vpi->vmm_port != vp_new->vmm_port) ! 1336: && (vpi->vmm_invis == 0) ) { ! 1337: /* update, but don't deactivate */ ! 1338: vpi->vmm_invis = ~0; ! 1339: updscreen(i); ! 1340: } ! 1341: } ! 1342: } ! 1343: } ! 1344: ! 1345: vtactivate(vp) ! 1346: VTDATA *vp; ! 1347: { ! 1348: register VTDATA *vpi; ! 1349: register i; ! 1350: ! 1351: /* ! 1352: * copy from screen contents from heap segment to video memory ! 1353: * only if necessary ! 1354: */ ! 1355: if ( vp->vmm_visible == VNKB_FALSE ) ! 1356: FFCOPY( vp->vmm_moff, vp->vmm_mseg, ! 1357: vp->vmm_voff, vp->vmm_vseg, TEXTBLOCK ); ! 1358: ! 1359: for (i = 0; i < vtcount; ++i) { ! 1360: vpi = vtdata[i]; ! 1361: if (vpi->vmm_port == vp->vmm_port) { ! 1362: vpi->vmm_invis = -1; ! 1363: vpi->vmm_visible = VNKB_FALSE; ! 1364: vpi->vmm_seg = vpi->vmm_mseg; ! 1365: vpi->vmm_off = vpi->vmm_moff; ! 1366: if( vpi->vmm_seg == 0 ) ! 1367: printf( "[2]vpi->vmm_seg = 0\n" ); ! 1368: PRINTV( "vt.back seg %x off %x\n", ! 1369: vpi->vmm_seg, vpi->vmm_off ); ! 1370: } ! 1371: } ! 1372: /* ! 1373: * Set new active terminal ! 1374: */ ! 1375: vp->vmm_invis = 0; ! 1376: vp->vmm_visible = VNKB_TRUE; ! 1377: vp->vmm_seg = vp->vmm_vseg; ! 1378: vp->vmm_off = vp->vmm_voff; ! 1379: if( vp->vmm_seg == 0 ) ! 1380: printf( "vp->vmm_seg = 0\n" ); ! 1381: } ! 1382: ! 1383: /* ! 1384: * update the terminal to match vtactive ! 1385: */ ! 1386: updterminal(index) ! 1387: int index; ! 1388: { ! 1389: updscreen(index); ! 1390: updleds(); ! 1391: } ! 1392: ! 1393: #undef si ! 1394: asmdump( cs, ds, es, di, si, bp, sp, bx, dx, cx, i, ip, ax ) ! 1395: int cs, ds, es, di, si, bp, sp, bx, dx, cx, i, ip, ax; ! 1396: { ! 1397: if( vt_verbose < 2 ) ! 1398: return; ! 1399: ! 1400: printf( "asmdump %d: es %x, ds %x, cs:ip %x:%x\n", i, es, ds, cs, ip ); ! 1401: printf( " ax %x, bx %x, cx %x, dx %x\n", ax, bx, cx, dx ); ! 1402: printf( " di %x, si %x, bp %x, sp %d\n", di, si, bp, sp ); ! 1403: #if USING_RS232 ! 1404: if( vt_verbose > 2 ) ! 1405: getchar(); ! 1406: #endif ! 1407: } ! 1408: ! 1409: vtdataprint( vp ) ! 1410: register VTDATA *vp; ! 1411: { ! 1412: if( vt_verbose < 2 ) ! 1413: return; ! 1414: ! 1415: printf( "VTDATA: @%x, esc %x, func %x()\n", ! 1416: vp, vp->vmm_esc, vp->vmm_func ); ! 1417: printf( " hw: port %x, seg %x, off %x\n", ! 1418: vp->vmm_port, vp->vmm_vseg, vp->vmm_voff ); ! 1419: printf( " memory: size %x, seg %x, off %x\n", ! 1420: 0/*vp->vmm_size*/, vp->vmm_mseg, vp->vmm_moff ); ! 1421: printf( " cursor: seg %x, off %x, visible %d\n", ! 1422: vp->vmm_seg, vp->vmm_off, !vp->vmm_invis ); ! 1423: printf( " row %d, col %d = offset %d.\n", ! 1424: vp->vmm_rowl, vp->vmm_col, vp->vmm_pos ); ! 1425: printf( " saved row %d, col %d\n", ! 1426: vp->vmm_srow, vp->vmm_scol ); ! 1427: printf( " screen: visible %d, attr %x, wrap %d, slow %d\n", ! 1428: vp->vmm_visible, vp->vmm_attr, vp->vmm_wrap, vp->vmm_slow ); ! 1429: printf( " row base %d, end %d, limit %d\n", ! 1430: vp->vmm_brow, vp->vmm_erow, vp->vmm_lrow ); ! 1431: printf( " row initial base %d, initial end %d\n", ! 1432: vp->vmm_ibrow, vp->vmm_ierow ); ! 1433: #if USING_RS232 ! 1434: if( vt_verbose > 2 ) ! 1435: getchar(); ! 1436: #endif ! 1437: } ! 1438: ! 1439: FFCOPY( src_off, src_seg, dst_off, dst_seg, count ) ! 1440: { ! 1441: register i; ! 1442: ! 1443: #if 0 ! 1444: i = ffcopy( src_off, src_seg, dst_off, dst_seg, count ); ! 1445: #else ! 1446: for( i = 0; i < count; i += 2 ) { ! 1447: register word = ffword( src_off, src_seg ); ! 1448: sfword( dst_off, dst_seg, word ); ! 1449: src_off += 2; ! 1450: dst_off += 2; ! 1451: } ! 1452: #endif ! 1453: return i; ! 1454: } ! 1455: ! 1456: /* ! 1457: * Given a function key number (e.g. vt0), ! 1458: * return the corresponding minor device number. ! 1459: * ! 1460: * Assume valid key number (VTKEY(fnum) is true) by the time we get here. ! 1461: */ ! 1462: int ! 1463: vtkey_to_dev(fnum) ! 1464: int fnum; ! 1465: { ! 1466: if (fnum >=vt0 && fnum <= vt15) ! 1467: return fnum-vt0+1; ! 1468: if (fnum >=color0 && fnum <= color15) ! 1469: return (fnum-color0)|(VT_PHYSICAL|VT_HW_COLOR); ! 1470: if (fnum >=mono0 && fnum <= mono15) ! 1471: return (fnum-mono0)|(VT_PHYSICAL|VT_HW_MONO); ! 1472: printf("vtkey_to_dev(%d)! ", fnum); ! 1473: return 0; ! 1474: } ! 1475: /* End of vtkb_f.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.