Annotation of coherent/d/PS2_KERNEL/io.286/kb_vt.c, revision 1.1.1.1

1.1       root        1: /* (-lgl
                      2:  *     COHERENT Driver Kit Version 1.1.0
                      3:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
                      4:  *     All rights reserved. May not be copied without permission.
                      5:  -lgl) */
                      6: /*
                      7:  * Keyboard/display driver.
                      8:  * Coherent, IBM PC/XT/AT.
                      9:  */
                     10: 
                     11: /*
                     12:  *     virtual terminal additions Copyright 1991, 1992 Todd Fleming
                     13:  *     6/91, 1/92
                     14:  *
                     15:  *     Todd Fleming
                     16:  *     1991 Mountainside Drive
                     17:  *     Blacksburg, VA 24060
                     18:  */
                     19: 
                     20: /* Notes on virtual terminal additions:
                     21:  * 
                     22:  * Console minor dev # = 0, virtual terminal minor #'s = 1 - 10
                     23:  * User switches terminals w/CTRL + F1-10
                     24:  *
                     25:  *    Console is parasitic. Its output is always directed to the current
                     26:  * onscreen terminal and it steels its input from the current terminal.
                     27:  *
                     28:  *   NEVER allow the console to be enabled via /etc/ttys while virtual terminals
                     29:  * are enabled. It is only used in single-user mode and for system messages.
                     30:  * (When in single-user mode, the kernal automatically uses the console
                     31:  * even though it is disabled in /etc/ttys)
                     32:  *
                     33:  *    Each virtual terminal has its own resources for the screen buffer,
                     34:  * toggle key state (num, caps, and scroll lock), alternate keypad state,
                     35:  * keyboard lock state, and ESC-string parsing state. Except for input, 
                     36:  * all virtual terminals are fully functional at all times. The 
                     37:  * virtual-terminal switching is transparent to the kernal and user programs.
                     38:  *
                     39:  *    Loadable key tables are not supported. (This feature was unavailable in 
                     40:  * the origional source code for kb). Loadable function keys are supported.
                     41:  */
                     42: 
                     43: #include <sys/coherent.h>
                     44: #include <sys/i8086.h>
                     45: #include <sys/con.h>
                     46: #include <sys/devices.h>
                     47: #include <errno.h>
                     48: #include <sys/stat.h>
                     49: #include <sys/tty.h>
                     50: #include <signal.h>
                     51: #include <sys/sched.h>
                     52: #include <sys/silo.h>
                     53: 
                     54: #define NVIRTERMS 4                    /* Number of virtual terminals */
                     55:                                        /* (Does not include console) */
                     56: 
                     57: #define        SPC     0376                    /* Special encoding */
                     58: #define XXX    0377                    /* Non-character */
                     59: #define        KBDATA  0x60                    /* Keyboard data */
                     60: #define        KBCTRL  0x61                    /* Keyboard control */
                     61: #define        KBFLAG  0x80                    /* Keyboard reset flag */
                     62: #define        LEDCMD  0xED                    /* status indicator command */
                     63: #define        KBACK   0xFA                    /* status indicator acknowledge */
                     64: #define        EXTENDED1 0xE1                  /* extended key seq initiator */
                     65: 
                     66: #define        KEYUP   0x80                    /* Key up change */
                     67: #define        KEYSC   0x7F                    /* Key scan code mask */
                     68: #define        LSHIFT  0x2A-1                  /* Left shift key */
                     69: #define LSHIFTA 0x2B-1                 /* Alternate left-shift key */
                     70: #define        RSHIFT  0x36-1                  /* Right shift key */
                     71: #define        CTRL    0x1D-1                  /* Control key */
                     72: /*-- #define   CAPLOCK 0x1D-1  --*/            /* Control key */
                     73: #define        ALT     0x38-1                  /* Alt key */
                     74: #define        CAPLOCK 0x3A-1                  /* Caps lock key */
                     75: /*-- #define   CTRL    0x3A-1  --*/            /* Caps lock key */
                     76: #define        NUMLOCK 0x45-1                  /* Numeric lock key */
                     77: #define        DELETE  0x53-1                  /* Del, as in CTRL-ALT-DEL */
                     78: #define BACKSP 0x0E-1                  /* Back space */
                     79: #define SCRLOCK        0x46-1                  /* Scroll lock */
                     80: 
                     81: /* Shift flags */
                     82: #define        SRS     0x01                    /* Right shift key on */
                     83: #define        SLS     0x02                    /* Left shift key on */
                     84: #define CTS    0x04                    /* Ctrl key on */
                     85: #define ALS    0x08                    /* Alt key on */
                     86: #define CPLS   0x10                    /* Caps lock on */
                     87: #define NMLS   0x20                    /* Num lock on */
                     88: #define AKPS   0x40                    /* Alternate keypad shift */
                     89: #define SHFT   0x80                    /* Shift key flag */
                     90: 
                     91: /* Function key information */
                     92: #define        NFKEY   20                      /* Number of settable functions */
                     93: #define        NFCHAR  150                     /* Number of characters settable */
                     94: #define        NFBUF   (NFKEY*2+NFCHAR+1)      /* Size of buffer */
                     95: 
                     96: /*
                     97:  * Functions.
                     98:  */
                     99: int    isrint();
                    100: int    istime();
                    101: void   isbatch();
                    102: int    mmstart();
                    103: int    isopen();
                    104: int    isclose();
                    105: int    isread();
                    106: int    mmwrite();
                    107: int    isioctl();
                    108: void   mmwatch();
                    109: int    isload();
                    110: int    isuload();
                    111: int    ispoll();
                    112: int    nulldev();
                    113: int    nonedev();
                    114: 
                    115: /* 
                    116:  * virtual terminal stuff
                    117:  */
                    118: 
                    119: extern int mmcurvirterm;               /* current on-screen terminal */
                    120: extern int mmvirtermsinitialized;      /* initialization flag */
                    121: extern mminitvirterm();                        /* starter function */
                    122: extern mmchangevirterm();              /* mm's half of this function */
                    123: kbchangeterm();                                /* kb's part */
                    124: unsigned kbAKPShold[NVIRTERMS+1];      /* Alternate keypad states */
                    125: unsigned kbNUMLCKhold[NVIRTERMS+1];    /* NumLock states */
                    126: unsigned kbCAPLCKhold[NVIRTERMS+1];    /* CapLock states */
                    127: 
                    128: /*
                    129:  * Configuration table.
                    130:  */
                    131: CON iscon ={
                    132:        DFCHR|DFPOL,                    /* Flags */
                    133:        KB_MAJOR,                       /* Major index */
                    134:        isopen,                         /* Open */
                    135:        isclose,                        /* Close */
                    136:        nulldev,                        /* Block */
                    137:        isread,                         /* Read */
                    138:        mmwrite,                        /* Write */
                    139:        isioctl,                        /* Ioctl */
                    140:        nulldev,                        /* Powerfail */
                    141:        mmwatch,                        /* Timeout */
                    142:        isload,                         /* Load */
                    143:        isuload,                        /* Unload */
                    144:        ispoll                          /* Poll */
                    145: };
                    146: 
                    147: /*
                    148:  * Flag indicating turbo machine.
                    149:  */
                    150: int isturbo = 0;
                    151: 
                    152: /*
                    153:  * Terminal structures.
                    154:  * istty[0]= console
                    155:  * 1-10    = virtual terminals
                    156:  */
                    157: TTY    istty[NVIRTERMS+1] = {
                    158:        {{0}, {0}, 0,  mmstart, NULL, 0, 0},
                    159:        {{0}, {0}, 1,  mmstart, NULL, 0, 0},
                    160:        {{0}, {0}, 2,  mmstart, NULL, 0, 0},
                    161:        {{0}, {0}, 3,  mmstart, NULL, 0, 0},
                    162:        {{0}, {0}, 4,  mmstart, NULL, 0, 0},
                    163: #if 0
                    164:        {{0}, {0}, 5,  mmstart, NULL, 0, 0},
                    165:        {{0}, {0}, 6,  mmstart, NULL, 0, 0},
                    166:        {{0}, {0}, 7,  mmstart, NULL, 0, 0},
                    167:        {{0}, {0}, 8,  mmstart, NULL, 0, 0},
                    168:        {{0}, {0}, 9,  mmstart, NULL, 0, 0},
                    169:        {{0}, {0}, 10, mmstart, NULL, 0, 0}
                    170: #endif
                    171: };
                    172: silo_t in_silo[NVIRTERMS+1];
                    173: 
                    174: /*
                    175:  * State variables.
                    176:  */
                    177: int            islock[NVIRTERMS+1];    /* Keyboard locked flag */
                    178: int            isbusy;                 /* Raw input conversion busy */
                    179: static char    shift;                  /* Overall shift state */
                    180: static char    scroll[NVIRTERMS+1];    /* Scroll lock state */
                    181: static  char   lshift = LSHIFT;        /* Left shift alternate state */
                    182: static char    isfbuf[NFBUF];          /* Function key values */
                    183: static char    *isfval[NFKEY];         /* Function key string pointers */
                    184: static int     ledcmd;                 /* LED update command flag */
                    185: static int     extended;               /* extended key scan count */
                    186: 
                    187: /*
                    188:  * Tables for converting key code to ASCII.
                    189:  * lmaptab specifies unshifted conversion,
                    190:  * umaptab specifies shifted conversion,
                    191:  * smaptab specifies the shift states which are active.
                    192:  * An entry of XXX says the key is dead.
                    193:  * An entry of SPC requires further processing.
                    194:  *
                    195:  * Key codes:
                    196:  *     ESC .. <- == 1 .. 14
                    197:  *     -> .. \n == 15 .. 28
                    198:  *     CTRL .. ` == 29 .. 41
                    199:  *     ^Shift .. PrtSc == 42 .. 55
                    200:  *     ALT .. CapsLock == 56 .. 58
                    201:  *     F1 .. F10 == 59 .. 68
                    202:  *     NumLock .. Del == 69 .. 83
                    203:  */
                    204: static unsigned char lmaptab[] ={
                    205:             '\33',  '1',  '2',  '3',  '4',  '5',  '6',         /* 1 - 7 */
                    206:         '7',  '8',  '9',  '0',  '-',  '=', '\b', '\t',         /* 8 - 15 */
                    207:         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',         /* 16 - 23 */
                    208:         'o',  'p',  '[',  ']', '\r',  XXX,  'a',  's',         /* 24 - 31 */
                    209:         'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';',         /* 32 - 39 */
                    210:         '\'', '`',  XXX,  '\\',  'z',  'x',  'c',  'v',        /* 40 - 47 */
                    211:         'b',  'n',  'm',  ',',  '.',  '/',  XXX,  '*',         /* 48 - 55 */
                    212:         XXX,  ' ',  XXX,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 56 - 63 */
                    213:         SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 64 - 71 */
                    214:         SPC,  SPC,  '-',  SPC,  SPC,  SPC,  '+',  SPC,         /* 72 - 79 */
                    215:         SPC,  SPC,  SPC,  SPC                                  /* 80 - 83 */
                    216: };
                    217: 
                    218: static unsigned char umaptab[] ={
                    219:             '\33',  '!',  '@',  '#',  '$',  '%',  '^',         /* 1 - 7 */
                    220:         '&',  '*',  '(',  ')',  '_',  '+', '\b', SPC,          /* 8 - 15 */
                    221:         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',         /* 16 - 23 */
                    222:         'O',  'P',  '{',  '}', '\r',  XXX,  'A',  'S',         /* 24 - 31 */
                    223:         'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':',         /* 32 - 39 */
                    224:         '"',  '~',  XXX,  '|',  'Z',  'X',  'C',  'V',         /* 40 - 47 */
                    225:         'B',  'N',  'M',  '<',  '>',  '?',  XXX,  '*',         /* 48 - 55 */
                    226:         XXX,  ' ',  XXX,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 56 - 63 */
                    227:         SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,         /* 64 - 71 */
                    228:         SPC,  SPC,  '-',  SPC,  SPC,  SPC,  '+',  SPC,         /* 72 - 79 */
                    229:         SPC,  SPC,  SPC,  SPC                                  /* 80 - 83 */
                    230: };
                    231: 
                    232: #define SS0    0                       /* No shift */
                    233: #define SS1    (SLS|SRS|CTS)           /* Shift, Ctrl */
                    234: #define SES    (SLS|SRS)               /* Shift */
                    235: #define LET    (SLS|SRS|CPLS|CTS)      /* Shift, Caps, Ctrl */
                    236: #define KEY    (SLS|SRS|NMLS|AKPS)     /* Shift, Num, Alt keypad */
                    237: 
                    238: static unsigned char smaptab[] ={
                    239:               SS0,  SES,  SS1,  SES,  SES,  SES,  SS1,         /* 1 - 7 */
                    240:         SES,  SES,  SES,  SES,  SS1,  SES,  CTS,  SES,         /* 8 - 15 */
                    241:         LET,  LET,  LET,  LET,  LET,  LET,  LET,  LET,         /* 16 - 23 */
                    242:         LET,  LET,  SS1,  SS1,  CTS, SHFT,  LET,  LET,         /* 24 - 31 */
                    243:         LET,  LET,  LET,  LET,  LET,  LET,  LET,  SES,         /* 32 - 39 */
                    244:         SES,  SS1, SHFT,  SS1,  LET,  LET,  LET,  LET,         /* 40 - 47 */
                    245:         LET,  LET,  LET,  SES,  SES,  SES, SHFT,  SES,         /* 48 - 55 */
                    246:        SHFT,  SS1, SHFT,  SS0,  SS0,  SS0,  SS0,  SS0,         /* 56 - 63 */
                    247:         SS0,  SS0,  SS0,  SS0,  SS0, SHFT,  KEY,  KEY,         /* 64 - 71 */
                    248:         KEY,  KEY,  SS0,  KEY,  KEY,  KEY,  SS0,  KEY,         /* 72 - 79 */
                    249:         KEY,  KEY,  KEY,  KEY                                  /* 80 - 83 */
                    250: };
                    251: 
                    252: /*
                    253:  * Load entry point.
                    254:  *  Do reset the keyboard because it gets terribly munged
                    255:  *  if you type during the boot.
                    256:  */
                    257: isload()
                    258: {
                    259:        register int i;
                    260: 
                    261:        /*
                    262:         * Reset keyboard if NOT an XT turbo.
                    263:         */
                    264:        if ( ! isturbo ) {
                    265:                outb(KBCTRL, 0x0C);             /* Clock low */
                    266:                for (i = 10582; --i >= 0; );    /* For 20ms */
                    267:                outb(KBCTRL, 0xCC);             /* Clock high */
                    268:                for (i = 0; --i != 0; )
                    269:                        ;
                    270:                i = inb(KBDATA);
                    271:                outb(KBCTRL, 0xCC);                     /* Clear keyboard */
                    272:                outb(KBCTRL, 0x4D);                     /* Enable keyboard */
                    273:        }
                    274: 
                    275:        /*
                    276:         * Enable mmwatch() invocation every second.
                    277:         */
                    278:        drvl[KB_MAJOR].d_time = 1;
                    279: 
                    280:        /*
                    281:         * Seize keyboard interrupt.
                    282:         */
                    283:        setivec(1, isrint);
                    284: 
                    285:        /*
                    286:         * Initiailize video display.
                    287:         */
                    288:        for(i=0;i<=NVIRTERMS;i++)       /* initialize console, virterms */
                    289:         mmstart( &istty[i] );
                    290: }
                    291: 
                    292: /*
                    293:  * Unload entry point.
                    294:  */
                    295: isuload()
                    296: {
                    297:        clrivec(1);
                    298: }
                    299: 
                    300: /*
                    301:  * Default function key strings (terminated by -1 [\377])
                    302:  */
                    303: static char *deffuncs[] = {
                    304:        "\33[1x\377",   /* F1 */
                    305:        "\33[2x\377",   /* F2 */
                    306:        "\33[3x\377",   /* F3 */
                    307:        "\33[4x\377",   /* F4 */
                    308:        "\33[5x\377",   /* F5 */
                    309:        "\33[6x\377",   /* F6 */
                    310:        "\33[7x\377",   /* F7 */
                    311:        "\33[8x\377",   /* F8 */
                    312:        "\33[9x\377",   /* F9 */
                    313:        "\33[0x\377",   /* F10 - historical value */
                    314:        "\33[1y\377",   /* F11 */
                    315:        "\33[2y\377",   /* F12 */
                    316:        "\33[3y\377",   /* F13 */
                    317:        "\33[4y\377",   /* F14 */
                    318:        "\33[5y\377",   /* F15 */
                    319:        "\33[6y\377",   /* F16 */
                    320:        "\33[7y\377",   /* F17 */
                    321:        "\33[8y\377",   /* F18 */
                    322:        "\33[9y\377",   /* F19 */
                    323:        "\33[0y\377"    /* F20 */
                    324: };
                    325: 
                    326: /*
                    327:  * Open routine.
                    328:  */
                    329: isopen(dev)
                    330: dev_t dev;
                    331: {
                    332:        register int s;
                    333: 
                    334:        if (minor(dev) > NVIRTERMS) {
                    335:                u.u_error = ENXIO;
                    336:                return;
                    337:        }
                    338: 
                    339:        if ((istty[minor(dev)].t_flags&T_EXCL)!=0 && super()==0) {
                    340:                u.u_error = ENODEV;
                    341:                return;
                    342:        }
                    343:        ttsetgrp(&istty[minor(dev)], dev);
                    344: 
                    345:        s = sphi();
                    346:        if ((istty[minor(dev)].t_open)++ == 0)
                    347:        {  initkeys();   /* init function keys */
                    348:           istty[minor(dev)].t_flags = T_CARR;  /* indicate "carrier" */
                    349:           ttopen(&istty[minor(dev)]);
                    350:        }
                    351:        spl(s);
                    352:        updleds();                      /* update keyboard status LEDS */
                    353: }
                    354: 
                    355: /* Init function keys */
                    356: initkeys()
                    357: {      register int i;
                    358:        register char *cp1, *cp2;
                    359: 
                    360:        for (i=0; i<NFKEY; i++)
                    361:            isfval[i] = 0;          /* clear function key buffer */
                    362:        cp2 = isfbuf;               /* pointer to key buffer */   
                    363:        for (i=0; i<NFKEY; i++)
                    364:        {  isfval[i] = cp2;         /* save pointer to key string */
                    365:           cp1 = deffuncs[i];       /* get init string pointer */
                    366:           while ((*cp2++ = *cp1++) != -1)  /* copy key data */
                    367:             if (cp2 >= &isfbuf[NFBUF-3])   /* overflow? */
                    368:                return;
                    369:        }
                    370: }
                    371: 
                    372: /*
                    373:  * Close a tty.
                    374:  */
                    375: isclose(dev)
                    376: {
                    377:        register int s;
                    378: 
                    379:        s = sphi();
                    380:        if (--(istty[minor(dev)].t_open) == 0)
                    381:        {       s = sphi();
                    382:                ttclose(&istty[minor(dev)]);
                    383:        }
                    384:        spl(s);
                    385: }
                    386: 
                    387: /*
                    388:  * Read routine.
                    389:  */
                    390: isread(dev, iop)
                    391: dev_t dev;
                    392: IO *iop;
                    393: {
                    394:  dev_t usedev=dev;
                    395:        if(minor(usedev)==0 && istty[mmcurvirterm].t_open)
                    396:                                                /* Route input from current */
                    397:         usedev=makedev(2,mmcurvirterm);        /* virtual terminal to console (TBF) */
                    398:        ttread(&istty[minor(usedev)], iop, 0);
                    399:        if (istty[minor(usedev)].t_oq.cq_cc)
                    400:                mmtime(&istty[minor(usedev)]);
                    401: }
                    402: 
                    403: /*
                    404:  * Ioctl routine.
                    405:  */
                    406: isioctl(dev, com, vec)
                    407: dev_t dev;
                    408: struct sgttyb *vec;
                    409: {
                    410:        register int s;
                    411: 
                    412:        switch(com) {
                    413:        case TIOCSETF:
                    414:        case TIOCGETF:
                    415:                isfunction(com, (char *)vec);
                    416:                return;
                    417:        case TIOCSHIFT:   /* switch left-SHIFT and "\" */
                    418:                lshift = LSHIFTA;    /* alternate values */
                    419:                lmaptab[41] = '\\';
                    420:                lmaptab[42] = XXX;
                    421:                umaptab[41] = '|';
                    422:                umaptab[42] = XXX;
                    423:                smaptab[41] = SS1;
                    424:                smaptab[42] = SHFT;
                    425:                return;
                    426:        case TIOCCSHIFT:  /* normal (default) left-SHIFT and "\" */
                    427:                lshift = LSHIFT;     /* normal values */
                    428:                lmaptab[41] = XXX;
                    429:                lmaptab[42] = '\\';
                    430:                umaptab[41] = XXX;
                    431:                umaptab[42] = '|';
                    432:                smaptab[41] = SHFT;
                    433:                smaptab[42] = SS1;
                    434:                return;
                    435:        }
                    436:        s = sphi();
                    437:        ttioctl(&istty[minor(dev)], com, vec);
                    438:        spl(s);
                    439: }
                    440: 
                    441: /*
                    442:  * Set and receive the function keys.
                    443:  */
                    444: isfunction(c, v)
                    445: int c;
                    446: char *v;
                    447: {
                    448:        register char *cp;
                    449:        register int i;
                    450: 
                    451:        if (c == TIOCGETF) {
                    452:                for (cp = isfbuf; cp < &isfbuf[NFBUF]; cp++)
                    453:                    putubd(v++, *cp);
                    454:        } else {
                    455:                for (i=0; i<NFKEY; i++)         /* zap current settings */
                    456:                        isfval[i] = 0;
                    457:                cp = isfbuf;                    /* pointer to key buffer */
                    458:                for (i=0; i<NFKEY; i++) {
                    459:                        isfval[i] = cp;         /* save pointer to key string */
                    460:                        while ((*cp++ = getubd(v++)) != -1)  /* copy key data */
                    461:                                if (cp >= &isfbuf[NFBUF-3])  /* overflow? */
                    462:                                        return;
                    463:                }
                    464:        }
                    465: }
                    466: 
                    467: 
                    468: /*
                    469:  * Poll routine.
                    470:  */
                    471: ispoll( dev, ev, msec )
                    472: dev_t dev;
                    473: int ev;
                    474: int msec;
                    475: {
                    476:        if(minor(dev)==0 && istty[mmcurvirterm].t_open)
                    477:                                        /* Route input from current */
                    478:         dev=makedev(2,mmcurvirterm);   /* virtual terminal to console (TBF) */
                    479: 
                    480:        /*
                    481:         * Priority polls not supported.
                    482:         */
                    483:        ev &= ~POLLPRI;
                    484: 
                    485:        /*
                    486:         * Input poll failure.
                    487:         */
                    488:        if ( (ev & POLLIN) && (istty[minor(dev)].t_iq.cq_cc == 0) ) {
                    489: 
                    490:                if ( msec != 0 )
                    491:                        pollopen( &istty[minor(dev)].t_ipolls );
                    492: 
                    493:                /*
                    494:                 * Second look AFTER enabling monitor, avoiding interrupt race.
                    495:                 */
                    496:                if ( istty[minor(dev)].t_iq.cq_cc == 0 )
                    497:                        ev &= ~POLLIN;
                    498:        }
                    499: 
                    500:        return ev;
                    501: }
                    502: 
                    503: /*
                    504:  * Receive interrupt.
                    505:  */
                    506: isrint()
                    507: {
                    508:        register int    c;
                    509:        register int    s;
                    510:        register int    r;
                    511:        int     savests;
                    512:        int     update_leds = 0;
                    513: 
                    514:        /*
                    515:         * Schedule raw input handler if not already active.
                    516:         */
                    517:        if ( isbusy == 0 ) {
                    518:                if(istty[mmcurvirterm].t_open)  /* only for opened term (TBF) */
                    519:                 defer( isbatch, &istty[mmcurvirterm] );
                    520:                else                            /* use console */
                    521:                 defer( isbatch, &istty[0] );
                    522:                isbusy = 1;
                    523:        }
                    524: 
                    525:        /*
                    526:         * Pull character from the data
                    527:         * port. Pulse the KBFLAG in the control
                    528:         * port to reset the data buffer.
                    529:         */
                    530:        r = inb(KBDATA) & 0xFF;
                    531:        c = inb(KBCTRL);
                    532:        outb(KBCTRL, c|KBFLAG);
                    533:        outb(KBCTRL, c);
                    534: #if    KBDEBUG
                    535:        printf("kbd: %d\n", r);                 /* print scan code/direction */
                    536: #endif
                    537:        if (ledcmd) {
                    538:                /* ledcmd = 0; */
                    539:                if (r == KBACK) {               /* output to status LEDS */
                    540:                        ledcmd = 0;
                    541:                        c = scroll[mmcurvirterm] & 1;
                    542:                        if (shift & NMLS)
                    543:                                c |= 2;
                    544:                        if (shift & CPLS)
                    545:                                c |= 4;
                    546:                        outb(KBDATA, c);
                    547:                        return;
                    548:                }
                    549:                /*return;*/
                    550:        }
                    551:        if (extended > 0) {                     /* if multi-character seq, */
                    552:                --extended;                     /* ... ignore this char */
                    553:                return;
                    554:        }
                    555:        if (r == EXTENDED1) {                   /* ignore extended sequences */
                    556:                extended = 5;
                    557:                return;
                    558:        }
                    559:        if (r == 0xFF) {
                    560:                return; /* Overrun */
                    561:        }
                    562:        c = (r & KEYSC) - 1;
                    563:        /*
                    564:         * Check for reset.
                    565:         */
                    566:        if ((r&KEYUP) == 0 && c == DELETE && (shift&(CTS|ALS)) == (CTS|ALS))
                    567:                boot();
                    568: 
                    569:        /*
                    570:         * Track "shift" keys.
                    571:         */
                    572:        s = smaptab[c];
                    573:        if (s&SHFT) {
                    574:                if (r&KEYUP) {                  /* "shift" released */
                    575:                        if (c == RSHIFT)
                    576:                                shift &= ~SRS;
                    577:                        else if (c == lshift)
                    578:                                shift &= ~SLS;
                    579:                        else if (c == CTRL)
                    580:                                shift &= ~CTS;
                    581:                        else if (c == ALT)
                    582:                                shift &= ~ALS;
                    583:                } else {                        /* "shift" pressed */
                    584:                        if (c == lshift)
                    585:                                shift |= SLS;
                    586:                        else if (c == RSHIFT)
                    587:                                shift |= SRS;
                    588:                        else if (c == CTRL)
                    589:                                shift |= CTS;
                    590:                        else if (c == ALT)
                    591:                                shift |= ALS;
                    592:                        else if (c == CAPLOCK) {
                    593:                                shift ^= CPLS;  /* toggle cap lock */
                    594:                                kbCAPLCKhold[mmcurvirterm]=shift&CPLS; /* TBF */
                    595:                                updleds();
                    596:                        } else if (c == NUMLOCK) {
                    597:                                shift ^= NMLS;  /* toggle num lock */
                    598:                                kbNUMLCKhold[mmcurvirterm]=shift&NMLS; /* TBF */
                    599:                                updleds();
                    600:                        }
                    601:                }
                    602:                return;
                    603:        }
                    604: 
                    605:        /*
                    606:         * No other key up codes of interest.
                    607:         */
                    608:        if (r&KEYUP) {
                    609:                return;
                    610:        }
                    611: 
                    612:         /*
                    613:          * If CTRL-F? switch virtual terminals (TBF)
                    614:         *
                    615:          */
                    616: 
                    617:        if(c>=58 && c-58<NVIRTERMS && shift&CTS && !(shift&(SRS|SLS|ALS)))
                    618:         defer(kbchangeterm,(char *)(c-58+1));  
                    619:         
                    620:        /*
                    621:         * If the tty is not open the character is
                    622:         * just tossed away. XXXXXXXXXX
                    623:         * routed to console if opened (TBF)
                    624:         */
                    625: 
                    626:        if (istty[mmcurvirterm].t_open == 0 && istty[0].t_open==0) {
                    627:           return;
                    628:        }
                    629: 
                    630:        /*
                    631:         * Map character, based on the
                    632:         * current state of the shift, control,
                    633:         * meta and lock flags.
                    634:         */
                    635:        if (shift & CTS) {
                    636:                if (s == CTS)                   /* Map Ctrl (BS | NL) */
                    637:                        c = (c == BACKSP) ? 0x7F : 0x0A;  
                    638:                else if (s==SS1 || s==LET)      /* Normal Ctrl map */
                    639:                        c = umaptab[c]&0x1F;    /* Clear bits 5-6 */
                    640:                else {
                    641:                        return;                 /* Ignore this char */
                    642:                }
                    643:        } else if (s &= shift) {
                    644:                if (shift & SES) {               /* if shift on */
                    645:                        if (s & (CPLS|NMLS))     /* if caps/num lock */
                    646:                                c = lmaptab[c];  /* use unshifted */
                    647:                        else
                    648:                                c = umaptab[c];  /* use shifted */
                    649:                } else {                         /* if shift not on */
                    650:                        if (s & (CPLS|NMLS))     /* if caps/num lock */
                    651:                                c = umaptab[c];  /* use shifted */
                    652:                        else
                    653:                                c = lmaptab[c];  /* use unshifted */
                    654:                }
                    655:        } else                                   
                    656:                c = lmaptab[c];                  /* use unshifted */
                    657: 
                    658:        /*
                    659:         * Act on character.
                    660:         */
                    661:        if (c == XXX) {
                    662:                return;                          /* char to ignore */
                    663:        }
                    664: 
                    665:        if (c != SPC) {                  /* not special char? */
                    666:                if (shift & ALS)         /* ALT (meta bit)? */
                    667:                        c |= 0x80;       /* set meta */
                    668: #if    KBDEBUG
                    669:        printf("%x %c ", c, c&0xff);
                    670: #endif
                    671:                isin(c);                 /* send the char */
                    672:        } else {
                    673:                update_leds += isspecial(r);     /* special chars */
                    674:        }
                    675:        if (update_leds) {
                    676:                savests = sphi();
                    677:                outb(KBDATA, LEDCMD);
                    678:                ledcmd = 1;
                    679:                spl(savests);
                    680:        }
                    681: }
                    682: 
                    683: /*
                    684:  * Handle special input sequences.
                    685:  * The character passed is the key number.
                    686:  *
                    687:  * The keypad is translated by the following table,
                    688:  * the first entry is the normal sequence, the second the shifted,
                    689:  * and the third the alternate keypad sequence.
                    690:  */
                    691: static char *keypad[][3] = {
                    692:        { "\33[H",  "7", "\33?w" },     /* 71 */
                    693:        { "\33[A",  "8", "\33?x" },     /* 72 */
                    694:        { "\33[V",  "9", "\33?y" },     /* 73 */
                    695:        { "\33[D",  "4", "\33?t" },     /* 75 */
                    696:        { "\0337",  "5", "\33?u" },     /* 76 */
                    697:        { "\33[C",  "6", "\33?v" },     /* 77 */
                    698:        { "\33[24H","1", "\33?q" },     /* 79 */
                    699:        { "\33[B",  "2", "\33?r" },     /* 80 */
                    700:        { "\33[U",  "3", "\33?s" },     /* 81 */
                    701:        { "\33[@",  "0", "\33?p" },     /* 82 */
                    702:        { "\33[P", ".",  "\33?n" }      /* 83 */
                    703: };
                    704: 
                    705: isspecial(c)
                    706: int c;
                    707: {
                    708:        register char *cp;
                    709:        register int s;
                    710:        int     update_leds = 0;
                    711: 
                    712:        cp = 0;
                    713: 
                    714:        switch (c) {
                    715:        case 15:                                        /* cursor back tab */
                    716:                cp = "\033[Z";
                    717:                break;
                    718:        case 59: case 60: case 61: case 62: case 63:    /* Function keys */
                    719:        case 64: case 65: case 66: case 67: case 68:
                    720:                /* offset to function string */
                    721:                if(shift&CTS)
                    722:                        cp="";                  /* disable CTRL-F? (TBF) */
                    723:                else
                    724:                {
                    725:                        if ( shift & ALS )
                    726:                                cp = isfval[c-49];
                    727:                        else
                    728:                                cp = isfval[c-59];
                    729:                }
                    730:                break;
                    731: 
                    732:        case 70:                /* Scroll Lock -- stop/start output */
                    733:        {
                    734:                static char cbuf[2];
                    735: 
                    736:                cp = &cbuf[0];  /* working buffer */
                    737:                if (!(istty[mmcurvirterm].t_sgttyb.sg_flags&RAWIN)) {   /* not if in RAW mode */
                    738:                        ++update_leds;
                    739:                        if (istty[mmcurvirterm].t_flags & T_STOP) {     /* output stopped? */
                    740:                           cbuf[0] = istty[mmcurvirterm].t_tchars.t_startc;  /* start it */
                    741:                           scroll[mmcurvirterm] = 0;
                    742:                        } else {
                    743:                           cbuf[0] = istty[mmcurvirterm].t_tchars.t_stopc;   /* stop output */
                    744:                           scroll[mmcurvirterm] = 1;
                    745:                        }
                    746:                }
                    747:                break;
                    748:        }
                    749: 
                    750:        case 79:                /* 1/End */
                    751:        case 80:                /* 2/DOWN */
                    752:        case 81:                /* 3/PgDn */
                    753:        case 82:                /* 0/Ins */
                    754:        case 83:                /* ./Del */
                    755:                --c;            /* adjust code */
                    756:        case 75:                /* 4/LEFT */
                    757:        case 76:                /* 5 */
                    758:        case 77:                /* 6/RIGHT */
                    759:                --c;            /* adjust code */
                    760:        case 71:                /* 7/Home/Clear */
                    761:        case 72:                /* 8/UP */
                    762:        case 73:                /* 9/PgUp */
                    763:                s = 0;                  /* start off with normal keypad */
                    764:                if (shift&NMLS)         /* num lock? */
                    765:                        s = 1;          /* set shift pad */
                    766:                if (shift&SES)          /* shift? */
                    767:                        s ^= 1;         /* toggle shift pad */
                    768:                if (shift&AKPS)         /* alternate pad? */
                    769:                        s = 2;          /* set alternate pad */         
                    770:                cp = keypad[c-71][s];   /* get keypad value */
                    771:                break;
                    772:        }
                    773:        if (cp)                                 /* send string */
                    774:                while ((*cp != 0) && (*cp != -1))
                    775:                        isin( *cp++ & 0377 );
                    776:        return update_leds;
                    777: }
                    778: 
                    779: /**
                    780:  *
                    781:  * void
                    782:  * ismmfunc( c,VTN )   -- process keyboard related output escape sequences
                    783:  * char c;
                    784:  * unsigned VTN; -- virterm #  0=console, 1-NVIRTERMS=virterm 
                    785:  */
                    786: void
                    787: ismmfunc(c,VTN)
                    788: register int c;
                    789: unsigned VTN;
                    790: { 
                    791:        switch (c) {
                    792:        case 't':       /* Enter numlock */
                    793:                kbNUMLCKhold[VTN]=NMLS;
                    794:                if(VTN==mmcurvirterm)
                    795:                 shift |= NMLS;
                    796:                updleds();                      /* update LED status */
                    797:                break;
                    798:        case 'u':       /* Leave numlock */
                    799:                kbNUMLCKhold[VTN]=0;
                    800:                if(VTN==mmcurvirterm)
                    801:                 shift &= ~NMLS;
                    802:                updleds();                      /* update LED status */
                    803:                break;
                    804:        case '=':       /* Enter alternate keypad */
                    805:                kbAKPShold[VTN]=AKPS;
                    806:                if(VTN==mmcurvirterm)
                    807:                        shift |= AKPS;
                    808:                break;
                    809:        case '>':       /* Exit alternate keypad */
                    810:                kbAKPShold[VTN]=0;
                    811:                if(VTN==mmcurvirterm) 
                    812:                        shift &= ~AKPS;
                    813:                break;
                    814:        case 'c':       /* Reset terminal */
                    815:                islock[VTN] = 0;
                    816:                kbAKPShold[VTN]=0;
                    817:                kbNUMLCKhold[VTN]=0;
                    818:                kbCAPLCKhold[VTN]=0;
                    819:                scroll[VTN]=0;
                    820:                if(VTN==mmcurvirterm)
                    821:                 shift  = 0;
                    822:                if(istty[VTN].t_flags & T_STOP)         /* output stopped? */
                    823:                 ttin(&istty[VTN],                      /* re-start output */
                    824:                      istty[VTN].t_tchars.t_startc);
                    825:                initkeys();
                    826:                updleds();                      /* update LED status */
                    827:                break;
                    828:        }
                    829: }
                    830: 
                    831: /**
                    832:  *
                    833:  * void
                    834:  * isin( c )   -- append character to raw input silo
                    835:  * char c;
                    836:  */
                    837: static
                    838: isin( c )
                    839: register int c;
                    840: {
                    841:        int cache_it = 1;
                    842:        register TTY * tp = istty + mmcurvirterm;
                    843:        register silo_t *in_s = in_silo + mmcurvirterm;
                    844: 
                    845:        if(!tp->t_open)
                    846:                tp = istty;
                    847: 
                    848:        /*
                    849:         * If using software incoming flow control, process and
                    850:         * discard t_stopc and t_startc.
                    851:         */
                    852:        if (!ISRIN) {
                    853:                if (ISSTOP) {
                    854:                        if ((tp->t_flags&T_STOP) == 0)
                    855:                                tp->t_flags |= T_STOP;
                    856:                        cache_it = 0;
                    857:                }
                    858:                if (ISSTART) {
                    859:                        tp->t_flags &= ~T_STOP;
                    860:                        ttstart(tp);
                    861:                        cache_it = 0;
                    862:                }
                    863:        }
                    864:        /*
                    865:         * Cache received character.
                    866:         */
                    867:        if (cache_it) {
                    868: #if KBDEBUG
                    869: printf("put %c ix=%d ox=%d\n", c,in_s->si_ix,in_s->si_ox);
                    870: #endif
                    871:                in_s->si_buf[ in_s->si_ix ] = c;
                    872: 
                    873:                if ( ++(in_s->si_ix) >= sizeof(in_s->si_buf) )
                    874:                        in_s->si_ix = 0;
                    875:        } 
                    876: }
                    877: 
                    878: /**
                    879:  *
                    880:  * void
                    881:  * isbatch()   -- raw input conversion routine
                    882:  *
                    883:  *     Action: Enable the video display.
                    884:  *             Canonize the raw input silo.
                    885:  *
                    886:  *     Notes:  isbatch() was scheduled as a deferred process by isrint().
                    887:  */
                    888: static void
                    889: isbatch( tp )
                    890: register TTY * tp;
                    891: {
                    892:        register int c;
                    893:        register silo_t *in_s = in_silo + mmcurvirterm;
                    894:        static int lastc;
                    895: 
                    896:        /*
                    897:         * Ensure video display is enabled.
                    898:         */
                    899:        mm_von();
                    900: 
                    901:        isbusy = 0;
                    902: 
                    903:        /*
                    904:         * Process all cached characters.
                    905:         */
                    906:        while ( in_s->si_ix != in_s->si_ox ) {
                    907: 
                    908:                /*
                    909:                 * Get next cached char.
                    910:                 */
                    911:                c = in_s->si_buf[ in_s->si_ox ];
                    912: 
                    913:                if ( in_s->si_ox >= sizeof(in_s->si_buf) - 1 )
                    914:                        in_s->si_ox = 0;
                    915:                else
                    916:                        in_s->si_ox++;
                    917: 
                    918: #if KBDEBUG
                    919: printf("get %c ix=%d ox=%d\n", c,in_s->si_ix,in_s->si_ox);
                    920: #endif
                    921:                if ( (islock[mmcurvirterm] == 0) || ISINTR || ISQUIT ) {
                    922:                        ttin( tp, c );
                    923:                }
                    924: 
                    925:                else if ( (c == 'b') && (lastc == '\033') ) {
                    926:                        islock[mmcurvirterm] = 0;
                    927:                        ttin( tp, lastc );
                    928:                        ttin( tp, c );
                    929:                }
                    930: 
                    931:                else if ( (c == 'c') && (lastc == '\033') ) {
                    932:                        ttin( tp, lastc );
                    933:                        ttin( tp, c );
                    934:                }
                    935: 
                    936:                else
                    937:                        putchar('\007');
                    938: 
                    939:                lastc = c;
                    940:        }
                    941: }
                    942: 
                    943: /*
                    944:  * update the keyboard status LEDS
                    945:  */
                    946: updleds()
                    947: {
                    948:        int     s;
                    949: 
                    950:        s = sphi();
                    951:        outb(KBDATA, LEDCMD);
                    952:        ledcmd = 1;
                    953:        spl(s);
                    954: }
                    955: 
                    956: /*
                    957:  * unlock the scroll in case an interrupt character is received
                    958:  */
                    959: kbunscroll()
                    960: {
                    961:        scroll[mmcurvirterm] = 0;
                    962:        updleds();
                    963: }
                    964: 
                    965: /*
                    966:  * Change terminals (TBF)
                    967:  * scheduled as a deferred process by isrint
                    968:  */
                    969: kbchangeterm(termno)
                    970: char *termno;
                    971: {
                    972:  unsigned intrstate=sphi();                    /* Disable interrupts */
                    973: 
                    974:  mmchangeterm((unsigned int)termno);   
                    975: 
                    976:  if(kbAKPShold[mmcurvirterm])                  /* set alternate keypad */
                    977:   shift|=AKPS;
                    978:  else
                    979:   shift&=~AKPS;
                    980: 
                    981:  if(kbCAPLCKhold[mmcurvirterm])                /* set capslock */
                    982:   shift|=CPLS;
                    983:  else
                    984:   shift&=~CPLS;
                    985: 
                    986:  if(kbNUMLCKhold[mmcurvirterm])                /* set numlock */
                    987:   shift|=NMLS;
                    988:  else
                    989:   shift&=~NMLS;
                    990: 
                    991:  updleds(); 
                    992:  spl(intrstate);                               /* Restore interrupts */
                    993: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.