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