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