Annotation of coherent/d/286_KERNEL/USRSRC/io/nkb.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * User configurable AT keyboard/display driver.
                      3:  * 286/386 AT COHERENT
                      4:  */
                      5: #include <sys/coherent.h>
                      6: #include <sys/i8086.h>
                      7: #include <sys/con.h>
                      8: #include <errno.h>
                      9: #include <sys/stat.h>
                     10: #include <sys/tty.h>
                     11: #include <sys/uproc.h>
                     12: #include <signal.h>
                     13: #include <sys/seg.h>
                     14: #include <sys/sched.h>
                     15: #include <sys/kb.h>
                     16: #include <sys/devices.h>
                     17: 
                     18: #define        ISVEC           1               /* Keyboard interrupt vector */
                     19: 
                     20: #if    DEBUG
                     21: #define        KBDEBUG(x)      printf(x)       /* debugging output */
                     22: #define        KBDEBUG2(x,y)   printf(x,y)     /* debugging output */
                     23: #define        KBDEBUG3(x,y,z) printf(x,y,z)   /* debugging output */
                     24: #else
                     25: #define        KBDEBUG(x)                      /* no output */
                     26: #define        KBDEBUG2(x,y)                   /* no output */
                     27: #define        KBDEBUG3(x,y,z)                 /* no output */
                     28: #endif
                     29: 
                     30: /*
                     31:  * values for kbstate
                     32:  */
                     33: #define        KB_IDLE         0               /* nothing going on right now */
                     34: #define        KB_SINGLE       1               /* sent a single byte cmd to the kbd */
                     35: #define        KB_DOUBLE_1     2               /* sent 1st byte of 2-byte cmd to kbd */
                     36: #define        KB_DOUBLE_2     3               /* sent 2nd byte of 2-byte cmd to kbd */
                     37: 
                     38: /*
                     39:  * patchable params for non-standard keyboards
                     40:  */
                     41: int    KBDATA = 0x60;                  /* Keyboard data */
                     42: int    KBCTRL = 0x61;                  /* Keyboard control */
                     43: int    KBSTS_CMD = 0x64;               /* Keyboard status/command */
                     44: int    KBFLAG = 0x80;                  /* Keyboard reset flag */
                     45: int    KBBOOT = 1;                     /* 0: disallow reboot from keyboard */
                     46: int    KBTIMEOUT = 10000;              /* shouldn't need this much */
                     47: int    KBCMDBYTE = 0x05;               /* no translation */
                     48: 
                     49: /*
                     50:  * KBSTATUS bits
                     51:  */
                     52: #define        STS_OBUF_FULL   0x01            /* kbd output buffer full */
                     53: #define        STS_IBUF_FULL   0x02            /* kbd input buffer full */
                     54: #define        STS_SYSTEM      0x04
                     55: #define        STS_CMD_DATA    0x08            /* 1: command or status */
                     56: #define        STS_INHIBIT     0x10            /* 0: keyboard inhibited */
                     57: #define        STS_AUX_OBUF_FULL       0x20
                     58: #define        STS_TIMEOUT     0x40            /* general timeout */
                     59: #define        STS_PAR_ERR     0x80            /* parity error */
                     60: 
                     61: /*
                     62:  * The following are magic commands which read from or write to the
                     63:  * controller command byte. These get output to the KBSTS_CMD port.
                     64:  */
                     65: #define        C_READ_CMD      0x20            /* read controller command byte */
                     66: #define        C_WRITE_CMD     0x60            /* write controller command byte */
                     67: #define        C_TRANSLATE     0x40            /* translate enable bit in cmd byte */
                     68: 
                     69: /*
                     70:  * Globals:
                     71:  * The 286 keyboard mapping table is too large to fit into kernel data space,
                     72:  * so we need to allocate a segment to it.  386 is easy.
                     73:  * The function keys tend to be small and tend to change substantially
                     74:  * more often than the mapping table, so we keep them in the kernel data space.
                     75:  */
                     76: static unsigned shift;                 /* state of all shift/lock keys */
                     77: static unsigned char   **funkeyp = 0;  /* ptr to array of func. keys ptrs */
                     78: static FNKEY   *fnkeys = 0;            /* pointer to structure of values */
                     79: static unsigned fklength;              /* length of k_fnval field in fnkeys */
                     80: static unsigned prev_cmd;              /* previous command sent to KBD */
                     81: static unsigned cmd2;                  /* 2nd byte of command to KBD */
                     82: static unsigned sh_index;              /* shift/lock state index */
                     83: #if COH386
                     84: static KBTBL   kb[MAX_KEYS];           /* keyboard table */
                     85: #else
                     86: static SEG     *kbsegp;                /* keyboard table segment */
                     87: #endif
                     88: 
                     89: /*
                     90:  * State variables.
                     91:  */
                     92: int            islock;                 /* Keyboard locked flag */
                     93: int            isbusy;                 /* Raw input conversion busy */
                     94: static char    table_loaded;           /* true == keyboard table resident */
                     95: static char    fk_loaded;              /* true == function keys resident */
                     96: static int     kbstate = KB_IDLE;      /* current keyboard state */
                     97: 
                     98: /*
                     99:  * Functions.
                    100:  */
                    101: int            isrint();
                    102: int            istime();
                    103: void           isbatch();
                    104: int            mmstart();
                    105: int            isopen();
                    106: int            isclose();
                    107: int            isread();
                    108: int            mmwrite();
                    109: int            isioctl();
                    110: void           mmwatch();
                    111: int            isload();
                    112: int            isuload();
                    113: int            ispoll();
                    114: int            nulldev();
                    115: int            nonedev();
                    116: int            updleds();
                    117: 
                    118: /*
                    119:  * Configuration table.
                    120:  */
                    121: CON iscon ={
                    122:        DFCHR|DFPOL,                    /* Flags */
                    123:        KB_MAJOR,                       /* Major index */
                    124:        isopen,                         /* Open */
                    125:        isclose,                        /* Close */
                    126:        nulldev,                        /* Block */
                    127:        isread,                         /* Read */
                    128:        mmwrite,                        /* Write */
                    129:        isioctl,                        /* Ioctl */
                    130:        nulldev,                        /* Powerfail */
                    131:        mmwatch,                        /* Timeout */
                    132:        isload,                         /* Load */
                    133:        isuload,                        /* Unload */
                    134:        ispoll                          /* Poll */
                    135: };
                    136: 
                    137: /*
                    138:  * Terminal structure.
                    139:  */
                    140: TTY    istty = {
                    141:        {0}, {0}, 0, mmstart, NULL, 0, 0
                    142: };
                    143: 
                    144: /*
                    145:  * Load entry point.
                    146:  */
                    147: isload()
                    148: {
                    149:        kbstate = KB_IDLE;
                    150:        table_loaded = 0;               /* no keyboard table yet */
                    151:        fk_loaded = 0;                  /* no Fn keys yet */
                    152: 
                    153:        /*
                    154:         * Enable mmwatch() invocation every second.
                    155:         */
                    156:        drvl[KB_MAJOR].d_time = 1;
                    157: 
                    158:        /*
                    159:         * Seize keyboard interrupt.
                    160:         */
                    161:        setivec(ISVEC, isrint);
                    162: 
                    163:        /*
                    164:         * Initiailize video display.
                    165:         */
                    166:        mmstart( &istty );
                    167: 
                    168: #if !COH386
                    169:        /*
                    170:         * Allocate a 286 segment to store the in-core keyboard table.
                    171:         * This would be a lot more convenient in kernel data space,
                    172:         * but small model COHERENT doesn't have that luxury.
                    173:         */
                    174:        kbsegp = salloc((fsize_t)MAX_TABLE_SIZE, SFSYST|SFNSWP|SFHIGH);
                    175:        if (kbsegp == (SEG *)0)
                    176:                printf("kb: unable to allocate keyboard table segment\n");
                    177: #endif
                    178:        fklength = 0;
                    179:        KBDEBUG("Exiting kbload()\n");
                    180: }
                    181: 
                    182: /*
                    183:  * Unload entry point.
                    184:  */
                    185: isuload()
                    186: {
                    187:        if (kbstate != KB_IDLE)
                    188:                printf("kb: keyboard busy during unload\n");
                    189:        clrivec(ISVEC);
                    190: #if !COH386
                    191:        if (kbsegp != (SEG *)0) {
                    192:                table_loaded = 0;
                    193:                sfree(kbsegp);
                    194:        }
                    195: #endif
                    196: }
                    197: 
                    198: /*
                    199:  * Open routine.
                    200:  */
                    201: isopen(dev)
                    202: dev_t dev;
                    203: {
                    204:        register int s;
                    205: 
                    206:        KBDEBUG(" kbopen()");
                    207:        if (minor(dev) != 0) {
                    208:                u.u_error = ENXIO;
                    209:                return;
                    210:        }
                    211:        if ((istty.t_flags&T_EXCL) != 0 && !super()) {
                    212:                u.u_error = ENODEV;
                    213:                return;
                    214:        }
                    215:        ttsetgrp(&istty, dev);
                    216: 
                    217:        s = sphi();
                    218:        if (istty.t_open++ == 0) {
                    219:                istty.t_flags = T_CARR; /* indicate "carrier" */
                    220:                ttopen(&istty);
                    221:        }
                    222:        spl(s);
                    223: #if 0
                    224:        updleds();                      /* update keyboard status LEDS */
                    225: #endif
                    226: }
                    227: 
                    228: /*
                    229:  * Close a tty.
                    230:  */
                    231: isclose(dev)
                    232: {
                    233:        register int s;
                    234: 
                    235:        s = sphi();
                    236:        if (--istty.t_open == 0) {
                    237:                ttclose(&istty);
                    238:        }
                    239:        spl(s);
                    240: }
                    241: 
                    242: /*
                    243:  * Read routine.
                    244:  */
                    245: isread(dev, iop)
                    246: dev_t dev;
                    247: IO *iop;
                    248: {
                    249:        ttread(&istty, iop, 0);
                    250:        if (istty.t_oq.cq_cc)
                    251:                mmtime(&istty);
                    252: }
                    253: 
                    254: /*
                    255:  * Ioctl routine.
                    256:  * nb: archaic TIOCSHIFT and TIOCCSHIFT no longer needed/supported.
                    257:  */
                    258: isioctl(dev, com, vec)
                    259: dev_t dev;
                    260: struct sgttyb *vec;
                    261: {
                    262:        register int s;
                    263: 
                    264:        switch (com) {
                    265:        case TIOCSETF:
                    266:        case TIOCGETF:
                    267:                isfunction(com, (char *)vec);
                    268:                break;
                    269:        case TIOCSETKBT:
                    270:                issettable(vec);
                    271:                break;
                    272:        case TIOCGETKBT:
                    273:                isgettable(vec);
                    274:                break;
                    275:        default:                                /* pass to TTY driver */
                    276:                s = sphi();
                    277:                ttioctl(&istty, com, vec);
                    278:                spl(s);
                    279:                break;
                    280:        }
                    281: }
                    282: 
                    283: /*
                    284:  * Set the in-core keyboard mapping table.
                    285:  * The table is sorted by scan code prior to calling ioctl().
                    286:  * All unused table entries (holes in the scan code map) have
                    287:  * a zero for the k_key field.
                    288:  * This makes key lookup at interrupt time fast by using the scan code
                    289:  * as an index into the table.
                    290:  */
                    291: issettable(vec)
                    292: char   *vec;
                    293: {
                    294:        register unsigned i;
                    295:        register int s;
                    296:        int timeout;
                    297:        static  KBTBL   this_key;       /* current key from kbd table */
                    298:        unsigned int cmd_byte;
                    299: #if !COH386
                    300:        register faddr_t faddr;         /* address of keyboard table */
                    301: #endif
                    302: 
                    303:        KBDEBUG(" TIOCSETKBT");
                    304:        kb_cmd2(K_SCANCODE_CMD, 3);             /* select set 3 */
                    305:        kb_cmd(K_ALL_TMB_CMD);                  /* default: TMB for all keys */
                    306: #if !COH386
                    307:        faddr = kbsegp->s_faddr;
                    308: #endif
                    309:        for (i = 0; i < MAX_KEYS; ++i) {
                    310:                ukcopy(vec, &this_key, sizeof(this_key));
                    311: #if COH386
                    312:                kb[i] = this_key;               /* store away */
                    313: #else
                    314:                kfcopy(&this_key, faddr, sizeof(this_key));
                    315:                faddr += sizeof(this_key);
                    316: #endif
                    317:                vec += sizeof(this_key);
                    318:                if (this_key.k_key != i && this_key.k_key != 0) {
                    319:                        printf("kb: incorrect or unsorted table entry %d\n", i);
                    320:                        u.u_error = EBADFMT;
                    321:                        return;
                    322:                }
                    323:                if (this_key.k_key != i)
                    324:                        continue;               /* no key */
                    325:                switch (this_key.k_flags&TMODE) {
                    326:                case T:                         /* typematic */
                    327:                        kb_cmd2(K_KEY_T_CMD, i);
                    328:                        break;
                    329:                case M:                         /* make only */
                    330:                        kb_cmd2(K_KEY_M_CMD, i);
                    331:                        break;
                    332:                case MB:                        /* make/break */
                    333:                        kb_cmd2(K_KEY_MB_CMD, i);
                    334:                        break;
                    335:                case TMB:                       /* typematic make/break */
                    336:                        break;                  /* this is the default */
                    337:                default:
                    338:                        printf("kb: bad key mode\n");
                    339:                }
                    340:        }
                    341:        updleds();
                    342:        kb_cmd2(K_SCANCODE_CMD, 3);             /* select set 3 */
                    343:        kb_cmd(K_ENABLE_CMD);                   /* start scanning */
                    344:        /*
                    345:         * The following code disables translation from the on-board
                    346:         * keyboard/aux controller. Without disabling translation, the
                    347:         * received scan codes still look like code set 1 codes even
                    348:         * though we put the keyboard controller in scan code set 3.
                    349:         * Yes, this is progress....
                    350:         */
                    351: #if 0
                    352:        while (inb(KBSTS_CMD) & STS_IBUF_FULL)
                    353:                ;
                    354:        outb(KBSTS_CMD, C_READ_CMD);            /* read controller cmd byte */
                    355:        while (!(inb(KBSTS_CMD) & STS_OBUF_FULL))
                    356:                ;
                    357:        cmd_byte = inb(KBDATA);
                    358:        KBDEBUG2(" cmd_byte=%x", cmd_byte);
                    359: #endif
                    360:        timeout = KBTIMEOUT;
                    361:        s = sphi();
                    362:        while ((inb(KBSTS_CMD) & STS_IBUF_FULL) && --timeout > 0)
                    363:                ;
                    364:        outb(KBSTS_CMD, C_WRITE_CMD);           /* write controller cmd byte */
                    365:        for (timeout = 50; --timeout > 0; )
                    366:                ;
                    367:        timeout = KBTIMEOUT;
                    368:        while ((inb(KBSTS_CMD) & STS_IBUF_FULL) && --timeout > 0)
                    369:                ;
                    370:        outb(KBDATA, KBCMDBYTE);                 /* turn off translation */     
                    371:        timeout = KBTIMEOUT;
                    372:        while ((inb(KBSTS_CMD) & STS_IBUF_FULL) && --timeout > 0)
                    373:                ;
                    374:        spl(s);
                    375: #if DEBUG
                    376:        kb_cmd2(K_SCANCODE_CMD, 0);             /* query s.c. mode */
                    377: #endif
                    378:        ++table_loaded;
                    379: }
                    380: 
                    381: /*
                    382:  * Get the in-core keyboard mapping table and pass it to the user.
                    383:  */
                    384: isgettable(vec)
                    385: char   *vec;
                    386: {
                    387: #if COH386
                    388:        KBDEBUG(" TIOCGETKBT");
                    389:        kucopy(kb, vec, sizeof(kb));
                    390: #else
                    391:        register unsigned i;
                    392:        register faddr_t faddr;         /* address of keyboard table */
                    393:        static  KBTBL   this_key;       /* current key from kbd table */
                    394: 
                    395:        KBDEBUG(" TIOCGETKBT");
                    396:        faddr = kbsegp->s_faddr;
                    397:        for (i = 0; i < MAX_KEYS; ++i) {
                    398:                fkcopy( faddr, &this_key, sizeof(this_key));
                    399:                kucopy( &this_key, vec, sizeof(this_key));
                    400:                faddr += sizeof(this_key);
                    401:                vec += sizeof(this_key);
                    402:        }
                    403: #endif
                    404: }
                    405: 
                    406: 
                    407: /*
                    408:  * Set and receive the function keys.
                    409:  */
                    410: isfunction(c, v)
                    411: int c;
                    412: FNKEY *v;
                    413: {
                    414:        register unsigned char *cp;
                    415:        register unsigned i;
                    416:        unsigned char   numkeys = 0;
                    417: 
                    418:        if (c == TIOCGETF) {
                    419:                KBDEBUG(" TIOCGETF");
                    420:                if (!fk_loaded)
                    421:                        u.u_error = EINVAL;
                    422:                else
                    423:                        kucopy(fnkeys, v, fklength);    /* copy ours to user */
                    424:        } else { /* TIOCSETF */
                    425:                /*
                    426:                 * If we had a previous function key arena, free it up.
                    427:                 * Since we don't know how large the function key arena will
                    428:                 * be, we must size it in the user data space prior to
                    429:                 * (re)kalloc()'ing it. This is ugly, but a helluva lot better
                    430:                 * than the old driver which used a hard coded limit of 150!
                    431:                 */
                    432:                KBDEBUG(" TIOCSETF");
                    433:                fk_loaded = 0;
                    434:                if (fnkeys != (FNKEY *)0)
                    435:                        kfree(fnkeys);          /* free old arena */
                    436:                if (funkeyp != NULL)
                    437:                        kfree(funkeyp);         /* free old ptr array */
                    438:                ukcopy(&v->k_nfkeys, &numkeys, sizeof(numkeys));
                    439:                fklength = sizeof(FNKEY);
                    440:                cp = v->k_fnval;
                    441:                for (i = 0; i < numkeys; i++) {
                    442:                        do {
                    443:                                ++fklength;
                    444:                        } while (getubd(cp++) != DELIM);
                    445:                }
                    446:                fnkeys = (FNKEY *)kalloc(fklength);
                    447:                funkeyp = (unsigned char **)kalloc(numkeys * sizeof(char *));
                    448:                if (fnkeys == (FNKEY *)0 || funkeyp == NULL) {
                    449:                        if (fnkeys != (FNKEY *)0) {
                    450:                                kfree(fnkeys);
                    451:                                fnkeys = 0;
                    452:                        }
                    453:                        if (funkeyp != NULL) {
                    454:                                kfree(funkeyp);
                    455:                                funkeyp = 0;
                    456:                        }
                    457:                        u.u_error = ENOMEM;
                    458:                        return;
                    459:                }
                    460:                cp = fnkeys->k_fnval;                   /* point to Fn ... */
                    461:                v = v->k_fnval;                         /* ... key arena */
                    462:                for (i = 0; i < numkeys; i++) {
                    463:                        funkeyp[i] = cp;                   /* save pointer */
                    464:                        while ((*cp++ = getubd(v++)) != DELIM)  /* copy key */
                    465:                                ;
                    466:                }
                    467:                fnkeys->k_nfkeys = numkeys;
                    468:                fk_loaded = 1;
                    469:        }
                    470: }
                    471: 
                    472: 
                    473: /*
                    474:  * Poll routine.
                    475:  */
                    476: ispoll( dev, ev, msec )
                    477: dev_t dev;
                    478: int ev;
                    479: int msec;
                    480: {
                    481:        /*
                    482:         * Priority polls not supported.
                    483:         */
                    484:        ev &= ~POLLPRI;
                    485: 
                    486:        /*
                    487:         * Input poll failure.
                    488:         */
                    489:        if ( (ev & POLLIN) && (istty.t_iq.cq_cc == 0) ) {
                    490:                if ( msec != 0 )
                    491:                        pollopen( &istty.t_ipolls );
                    492:                /*
                    493:                 * Second look AFTER enabling monitor, avoiding interrupt race.
                    494:                 */
                    495:                if ( istty.t_iq.cq_cc == 0 )
                    496:                        ev &= ~POLLIN;
                    497:        }
                    498:        return ev;
                    499: }
                    500: 
                    501: /*
                    502:  * Receive interrupt.
                    503:  */
                    504: isrint()
                    505: {
                    506:        register unsigned c;
                    507:        register unsigned r;
                    508:        static  char keyup;
                    509: 
                    510:        /*
                    511:         * Schedule raw input handler if not already active.
                    512:         */
                    513:        if ( !isbusy ) {
                    514:                defer( isbatch, &istty );
                    515:                isbusy = 1;
                    516:        }
                    517: 
                    518:        /*
                    519:         * Pull character from the data
                    520:         * port. Pulse the KBFLAG in the control
                    521:         * port to reset the data buffer.
                    522:         */
                    523:        r = inb(KBDATA) & 0xFF;
                    524:        c = inb(KBCTRL);
                    525:        outb(KBCTRL, c|KBFLAG);
                    526:        outb(KBCTRL, c);
                    527: 
                    528:        /*
                    529:         * check returned value from keyboard to see if it's a command
                    530:         * or status back to us. If not, it we assume that it's a key code.
                    531:         */
                    532:        KBDEBUG2(" intr(%x)", r);
                    533:        switch (r) {
                    534:        case K_BREAK:
                    535:                keyup = 1;                      /* key going up */
                    536:                break;
                    537:        case K_ECHO_R:
                    538:        case K_BAT_OK:
                    539:                break;                          /* very nice, but ignored */
                    540:        case K_BAT_BAD:
                    541:                printf("kb: keyboard BAT failed\n");
                    542:                break;
                    543:        case K_RESEND:
                    544:                KBDEBUG("\nkb: request to resend command\n");
                    545:                outb(KBDATA, prev_cmd);
                    546:                break;
                    547:        case K_OVERRUN_23:
                    548:                printf("kb: keyboard buffer overrun\n");
                    549:                break;
                    550:        case K_ACK:
                    551:                /*
                    552:                 * we received an ACKnowledgement from the keyboard.
                    553:                 * advance the state machine and continue.
                    554:                 */
                    555:                KBDEBUG(" ACK");
                    556:                switch (kbstate) {
                    557:                case KB_IDLE:                   /* shouldn't happen */
                    558:                        printf("kb: ACK while keyboard idle\n");
                    559:                        break;
                    560:                case KB_SINGLE:                 /* done with 1-byte command */
                    561:                case KB_DOUBLE_2:               /* done w/ 2nd of 2-byte cmd */
                    562:                        kbstate = KB_IDLE;
                    563:                        wakeup(&kbstate);
                    564:                        break;
                    565:                case KB_DOUBLE_1:
                    566:                        kbstate = KB_DOUBLE_2;
                    567:                        outb(KBDATA, cmd2);
                    568:                        break;
                    569:                default:
                    570:                        printf("kb: bad kbstate %d\n", kbstate);
                    571:                        break;
                    572:                }
                    573:                break;
                    574:        default:
                    575:                process_key(r, keyup);
                    576:                keyup = 0;
                    577:        }
                    578: }
                    579: 
                    580: /*
                    581:  * Process a key given its scan code and direction.
                    582:  * 
                    583:  * In this table driven version of the keyboard driver, we trade off the
                    584:  * code complexity associated with all the black magic that used to be
                    585:  * performed on a per-key basis with the increased memory requirements
                    586:  * associated with the table driven approach.
                    587:  */
                    588: process_key( key, up)
                    589: unsigned key;
                    590: int     up;
                    591: {
                    592:        register unsigned char *cp;
                    593:        KBTBL   key_vals;                       /* table values for this key */
                    594:        unsigned val;
                    595:        unsigned char flags;
                    596: 
                    597:        KBDEBUG3(" proc(%x %s)", key, (up ? "up" : "down"));
                    598:        if (!table_loaded)
                    599:                return;                         /* throw away key */
                    600: #if COH386
                    601:        key_vals = kb[key];
                    602: #else
                    603:        fkcopy( kbsegp->s_faddr + (key * sizeof(KBTBL)),
                    604:                &key_vals, sizeof(key_vals));
                    605: #endif
                    606:        if (key_vals.k_key != key)              /* empty entry */
                    607:                return;
                    608:        flags = key_vals.k_flags;
                    609: 
                    610:        if (flags & S) {                        /* some shift/lock key ? */
                    611:                switch (key_vals.k_val[BASE]) {
                    612:                case caps:
                    613:                case num:
                    614:                        if (!up) {
                    615:                                shift ^= (1 << key_vals.k_val[BASE]);
                    616:                                updleds2();
                    617:                        }
                    618:                        break;
                    619:                case scroll:
                    620:                        if (!up) {
                    621:                                shift ^= (1 << key_vals.k_val[BASE]);
                    622:                                updleds2();
                    623:                                if (!(istty.t_sgttyb.sg_flags&RAWIN)) {
                    624:                                        if (istty.t_flags & T_STOP) {
                    625:                                                isin(istty.t_tchars.t_startc);
                    626:                                        } else {
                    627:                                                isin(istty.t_tchars.t_stopc);
                    628:                                        }
                    629:                                }
                    630:                        }
                    631:                        break;
                    632:                default:
                    633:                        if (up)
                    634:                                shift &= ~(1 << key_vals.k_val[BASE]);
                    635:                        else
                    636:                                shift |= (1 << key_vals.k_val[BASE]);
                    637:                        break;
                    638:                }
                    639:                /*
                    640:                 * Calculate the shift index based upon the state of
                    641:                 * the shift and lock keys.
                    642:                 */
                    643:                sh_index = BASE;                /* default condition */
                    644:                if (shift & (1 << altgr))
                    645:                        sh_index = ALT_GR;
                    646:                else {
                    647:                        if (shift & ((1 << lalt)|(1 << ralt)))
                    648:                                sh_index |= ALT;
                    649:                        if (shift & ((1 << lctrl)|(1 << rctrl)))
                    650:                                sh_index |= CTRL;
                    651:                        if (shift & ((1 << lshift)|(1 << rshift)))
                    652:                                sh_index |= SHIFT;
                    653:                }
                    654:                return;
                    655:        } /* if (flags & S) */
                    656: 
                    657:        /*
                    658:         * If the tty is not open or the key has no value in the current
                    659:         * shift state, the key is just tossed away.
                    660:         */
                    661:        if (up || !istty.t_open || key_vals.k_val[sh_index] == none)
                    662:                return;
                    663:        if (((flags & C) && (shift & (1 << caps)))
                    664:           || ((flags & N) && (shift & (1 << num))))
                    665:                val = key_vals.k_val[sh_index^SHIFT];
                    666:        else
                    667:                val = key_vals.k_val[sh_index];
                    668: 
                    669:        /*
                    670:         * Check for function key or special key implemented as
                    671:         * a function key (reboot == f0, tab and back-tab, etc).
                    672:         */
                    673:        if (flags & F) {
                    674:                if (val == 0 && !up && KBBOOT)
                    675:                        boot();
                    676:                if (!fk_loaded || val >= fnkeys->k_nfkeys)
                    677:                        return;
                    678:                if ((cp = funkeyp[val]) == NULL) /* has a value? */
                    679:                        return;
                    680:                while (*cp != DELIM)
                    681:                        isin(*cp++);            /* queue up Fn key value */
                    682:                return;
                    683:        }
                    684: 
                    685:        /*
                    686:         * Normal key processing.
                    687:         */
                    688:        isin(val);               /* send the char */
                    689:        return;
                    690: }
                    691: 
                    692: /**
                    693:  *
                    694:  * void
                    695:  * ismmfunc( c )       -- process keyboard related output escape sequences
                    696:  * char c;
                    697:  */
                    698: void
                    699: ismmfunc(c)
                    700: register int c;
                    701: {
                    702:        switch (c) {
                    703:        case 't':       /* Enter numlock */
                    704:                shift |= (1 << num);
                    705:                updleds();                      /* update LED status */
                    706:                break;
                    707:        case 'u':       /* Leave numlock */
                    708:                shift &= ~(1 << num);
                    709:                updleds();                      /* update LED status */
                    710:                break;
                    711:        case '=':                       /* Enter alternate keypad -- ignored */
                    712:        case '>':                       /* Exit alternate keypad -- ignored */
                    713:                break;
                    714:        case 'c':       /* Reset terminal */
                    715:                islock = 0;
                    716:                break;
                    717:        }
                    718: }
                    719: 
                    720: /**
                    721:  *
                    722:  * void
                    723:  * isin( c )   -- append character to raw input silo
                    724:  * char c;
                    725:  */
                    726: static
                    727: isin( c )
                    728: register int c;
                    729: {
                    730:        int cache_it = 1;
                    731:        TTY * tp = &istty;
                    732: 
                    733:        /*
                    734:         * If using software incoming flow control, process and
                    735:         * discard t_stopc and t_startc.
                    736:         */
                    737:        if (!ISRIN) {
                    738:                if (ISSTOP) {
                    739:                        if ((tp->t_flags&T_STOP) == 0)
                    740:                                tp->t_flags |= T_STOP;
                    741:                        cache_it = 0;
                    742:                }
                    743:                if (ISSTART) {
                    744:                        tp->t_flags &= ~T_STOP;
                    745:                        ttstart(tp);
                    746:                        cache_it = 0;
                    747:                }
                    748:        }
                    749: 
                    750:        /*
                    751:         * Cache received character.
                    752:         */
                    753:        if (cache_it) {
                    754:                istty.t_rawin.si_buf[ istty.t_rawin.si_ix ] = c;
                    755: 
                    756:                if ( ++istty.t_rawin.si_ix >= sizeof(istty.t_rawin.si_buf) )
                    757:                        istty.t_rawin.si_ix = 0;
                    758:        }
                    759: }
                    760: 
                    761: /**
                    762:  *
                    763:  * void
                    764:  * isbatch()   -- raw input conversion routine
                    765:  *
                    766:  *     Action: Enable the video display.
                    767:  *             Canonize the raw input silo.
                    768:  *
                    769:  *     Notes:  isbatch() was scheduled as a deferred process by isrint().
                    770:  */
                    771: static void
                    772: isbatch( tp )
                    773: register TTY * tp;
                    774: {
                    775:        register int c;
                    776:        static int lastc;
                    777: 
                    778:        /*
                    779:         * Ensure video display is enabled.
                    780:         */
                    781:        mm_von();
                    782:        isbusy = 0;
                    783: 
                    784:        /*
                    785:         * Process all cached characters.
                    786:         */
                    787:        while ( tp->t_rawin.si_ix != tp->t_rawin.si_ox ) {
                    788:                /*
                    789:                 * Get next cached char.
                    790:                 */
                    791:                c = tp->t_rawin.si_buf[ tp->t_rawin.si_ox ];
                    792: 
                    793:                if ( tp->t_rawin.si_ox >= sizeof(tp->t_rawin.si_buf) - 1 )
                    794:                        tp->t_rawin.si_ox = 0;
                    795:                else
                    796:                        tp->t_rawin.si_ox++;
                    797: 
                    798:                if ( (islock == 0) || ISINTR || ISQUIT ) {
                    799:                        ttin( tp, c );
                    800:                } else if ( (c == 'b') && (lastc == '\033') ) {
                    801:                        islock = 0;
                    802:                        ttin( tp, lastc );
                    803:                        ttin( tp, c );
                    804:                } else if ( (c == 'c') && (lastc == '\033') ) {
                    805:                        ttin( tp, lastc );
                    806:                        ttin( tp, c );
                    807:                } else
                    808:                        putchar('\007');
                    809:                lastc = c;
                    810:        }
                    811: }
                    812: 
                    813: /*
                    814:  * update the keyboard status LEDS.
                    815:  * we chose the shift/lock key positions so this would be easy.
                    816:  * this flavor of routine is called while processing a system call on
                    817:  * behalf of the user.
                    818:  */
                    819: updleds()
                    820: {
                    821:        kb_cmd2(K_LED_CMD, (shift >> 1) & 0x7);
                    822: }
                    823: 
                    824: /*
                    825:  * same as above, but callable from interrupt routines and other places
                    826:  * which cannot sleep() waiting for the state machine to go idle.
                    827:  */
                    828: updleds2()
                    829: {
                    830:        register timeout;
                    831:        register int s;
                    832: 
                    833:        timeout = KBTIMEOUT;
                    834:        s = sphi();
                    835:        while (--timeout > 0 && (inb(KBSTS_CMD) & STS_IBUF_FULL))
                    836:                ;
                    837:        kbstate = KB_DOUBLE_1;
                    838:        cmd2 = (shift >> 1) & 0x7;
                    839:        prev_cmd = K_LED_CMD;
                    840:        outb(KBDATA, K_LED_CMD);
                    841:        spl(s);
                    842: }
                    843: 
                    844: /*
                    845:  * unlock the scroll in case an interrupt character is received
                    846:  */
                    847: kbunscroll()
                    848: {
                    849:        shift &= ~(1 << scroll);
                    850:        updleds();
                    851: }
                    852: 
                    853: /*
                    854:  * ship a single byte command to the keyboard
                    855:  */
                    856: kb_cmd(cmd)
                    857: unsigned cmd;
                    858: {
                    859:        register int timeout;
                    860:        register int s;
                    861: 
                    862:        s = sphi();
                    863:        KBDEBUG2(" kb_cmd(%x)", cmd);
                    864:        while (kbstate != KB_IDLE)
                    865:                sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN);
                    866:        kbstate = KB_SINGLE;
                    867:        timeout = KBTIMEOUT;
                    868:        while (--timeout > 0 && (inb(KBSTS_CMD) & STS_IBUF_FULL))
                    869:                ;
                    870:        if (!timeout)
                    871:                printf("kb: command timeout\n");
                    872:        else {
                    873:                outb(KBDATA, cmd);
                    874:                while (kbstate != KB_IDLE)
                    875:                        sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN);
                    876:        }
                    877:        spl(s);
                    878: }
                    879: 
                    880: /*
                    881:  * ship a two byte command to the keyboard
                    882:  */
                    883: kb_cmd2(cmd, arg)
                    884: unsigned cmd, arg;
                    885: {
                    886:        register int timeout;
                    887:        register int s;
                    888: 
                    889:        s = sphi();
                    890:        KBDEBUG3(" kb_cmd2(%x, %x)", cmd, arg);
                    891:        while (kbstate != KB_IDLE)
                    892:                sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN);
                    893:        kbstate = KB_DOUBLE_1;
                    894:        cmd2 = arg;
                    895:        prev_cmd = cmd;
                    896:        timeout = KBTIMEOUT;
                    897:        while (--timeout > 0 && (inb(KBSTS_CMD) & STS_IBUF_FULL))
                    898:                ;
                    899:        if (!timeout)
                    900:                printf("kb: command timeout\n");
                    901:        else {
                    902:                outb(KBDATA, cmd);
                    903:                while (kbstate != KB_IDLE)
                    904:                        sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN);
                    905:        }
                    906:        spl(s);
                    907: }
                    908: 
                    909: /* End of nkb.c */

unix.superglobalmegacorp.com

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