Annotation of coherent/b/kernel/io.386/vtnkb.c, revision 1.1.1.1

1.1       root        1: #define SWANFIX 1
                      2: #define GREEKFIX 1
                      3: 
                      4: /*
                      5:  * User configurable AT keyboard/display driver.
                      6:  * 286/386 AT COHERENT
                      7:  */
                      8: #include <sys/coherent.h>
                      9: #ifdef _I386
                     10: #include <sys/reg.h>
                     11: #else
                     12: #include <sys/i8086.h>
                     13: #endif
                     14: #include <sys/con.h>
                     15: #include <errno.h>
                     16: #include <sys/stat.h>
                     17: #include <sys/tty.h>
                     18: #include <signal.h>
                     19: #include <sys/seg.h>
                     20: #include <sys/sched.h>
                     21: #include <sys/kb.h>
                     22: #include <sys/devices.h>
                     23: #include <sys/silo.h>
                     24: 
                     25: #include <sys/vt.h>
                     26: 
                     27: #define        ISVEC           1               /* Keyboard interrupt vector */
                     28: #define        DEBUG           0
                     29: 
                     30: #define        KBDEBUG(x)      T_CON(1,printf(x));     /* debugging output */
                     31: #define        KBDEBUG2(x,y)   T_CON(1,printf(x,y));   /* debugging output */
                     32: #define        KBDEBUG3(x,y,z) T_CON(1,printf(x,y,z)); /* debugging output */
                     33: 
                     34: /*
                     35:  * values for kbstate
                     36:  */
                     37: #define        KB_IDLE         0               /* nothing going on right now */
                     38: #define        KB_SINGLE       1               /* sent a single byte cmd to the kbd */
                     39: #define        KB_DOUBLE_1     2               /* sent 1st byte of 2-byte cmd to kbd */
                     40: #define        KB_DOUBLE_2     3               /* sent 2nd byte of 2-byte cmd to kbd */
                     41: 
                     42: /*
                     43:  * patchable params for non-standard keyboards
                     44:  */
                     45: int    KBDATA = 0x60;                  /* Keyboard data */
                     46: int    KBCTRL = 0x61;                  /* Keyboard control */
                     47: int    KBSTS_CMD = 0x64;               /* Keyboard status/command */
                     48: int    KBFLAG = 0x80;                  /* Keyboard reset flag */
                     49: int    KBBOOT = 1;                     /* 0: disallow reboot from keyboard */
                     50: int    KBTIMEOUT = 10000;              /* shouldn't need this much */
                     51: int    KBCMDBYTE = 0x05;               /* no translation */
                     52: 
                     53: /*
                     54:  * KBSTATUS bits
                     55:  */
                     56: #define        STS_OBUF_FULL   0x01            /* kbd output buffer full */
                     57: #define        STS_IBUF_FULL   0x02            /* kbd input buffer full */
                     58: #define        STS_SYSTEM      0x04
                     59: #define        STS_CMD_DATA    0x08            /* 1: command or status */
                     60: #define        STS_INHIBIT     0x10            /* 0: keyboard inhibited */
                     61: #define        STS_AUX_OBUF_FULL       0x20
                     62: #define        STS_TIMEOUT     0x40            /* general timeout */
                     63: #define        STS_PAR_ERR     0x80            /* parity error */
                     64: 
                     65: /*
                     66:  * The following are magic commands which read from or write to the
                     67:  * controller command byte. These get output to the KBSTS_CMD port.
                     68:  */
                     69: #define        C_READ_CMD      0x20            /* read controller command byte */
                     70: #define        C_WRITE_CMD     0x60            /* write controller command byte */
                     71: #define        C_TRANSLATE     0x40            /* translate enable bit in cmd byte */
                     72: 
                     73: /*
                     74:  * Globals:
                     75:  * The 286 keyboard mapping table is too large to fit into kernel data space,
                     76:  * so we need to allocate a segment to it.  386 is easy.
                     77:  * The function keys tend to be small and tend to change substantially
                     78:  * more often than the mapping table, so we keep them in the kernel data space.
                     79:  */
                     80: static unsigned shift;                 /* state of all shift/lock keys */
                     81: static unsigned char   **funkeyp = 0;  /* ptr to array of func. keys ptrs */
                     82: static FNKEY   *fnkeys = 0;            /* pointer to structure of values */
                     83: static unsigned fklength;              /* length of k_fnval field in fnkeys */
                     84: static unsigned prev_cmd;              /* previous command sent to KBD */
                     85: static unsigned cmd2;                  /* 2nd byte of command to KBD */
                     86: static unsigned sh_index;              /* shift/lock state index */
                     87: #ifdef _I386
                     88: static KBTBL   kb[MAX_KEYS];           /* keyboard table */
                     89: #else
                     90: static SEG     *kbsegp;                /* keyboard table segment */
                     91: #endif
                     92: 
                     93: /*
                     94:  * State variables.
                     95:  */
                     96: int            islock;                 /* Keyboard locked flag */
                     97: int            isbusy;                 /* Raw input conversion busy */
                     98: static char    table_loaded;           /* true == keyboard table resident */
                     99: static char    fk_loaded;              /* true == function keys resident */
                    100: static int     kbstate = KB_IDLE;      /* current keyboard state */
                    101: 
                    102: /*
                    103:  * Functions.
                    104:  */
                    105: int            isrint();
                    106: int            istime();
                    107: void           isbatch();
                    108: int            mmstart();
                    109: int            isopen();
                    110: int            isclose();
                    111: int            isread();
                    112: int            mmwrite();
                    113: int            isioctl();
                    114: void           mmwatch();
                    115: int            isload();
                    116: int            isuload();
                    117: int            ispoll();
                    118: int            nulldev();
                    119: int            nonedev();
                    120: int            updleds();
                    121: 
                    122: /*
                    123:  * Configuration table.
                    124:  */
                    125: CON iscon ={
                    126:        DFCHR|DFPOL,                    /* Flags */
                    127:        KB_MAJOR,                       /* Major index */
                    128:        isopen,                         /* Open */
                    129:        isclose,                        /* Close */
                    130:        nulldev,                        /* Block */
                    131:        isread,                         /* Read */
                    132:        mmwrite,                        /* Write */
                    133:        isioctl,                        /* Ioctl */
                    134:        nulldev,                        /* Powerfail */
                    135:        mmwatch,                        /* Timeout */
                    136:        isload,                         /* Load */
                    137:        isuload,                        /* Unload */
                    138:        ispoll                          /* Poll */
                    139: };
                    140: 
                    141: /*
                    142: ==============================================================================
                    143: ==============================================================================
                    144: */
                    145: /* constants for vtdata[] */
                    146: #define VT_VGAPORT     0x3D4
                    147: #define VT_MONOPORT    0x3B4
                    148: 
                    149: #ifdef _I386
                    150: #define VT_MONOBASE    (SEG_VIDEOa|DPL_1)
                    151: #define VT_VGABASE     (SEG_VIDEOb|DPL_1)
                    152: #else
                    153: #define VT_MONOBASE    0xB000
                    154: #define VT_VGABASE     0xB800
                    155: #endif
                    156: 
                    157: /*
                    158:        Patchable table entrys,
                    159:        we go indirect in order to produce a label which can be addressed
                    160: */
                    161: #if SWANFIX
                    162: int VTSWAN = 0;                /* patch to 1 for epstein's fix for Swan keyboard */
                    163: #endif
                    164: 
                    165: #if GREEKFIX
                    166: static void ToggleGreek();
                    167: static int ToGreek();
                    168: int VTGREEK = 0;       /* patch to 1 for TECOP Greek mod */
                    169: #endif
                    170: 
                    171: HWentry        VTVGA =         { 4, 0, VT_VGAPORT, { 0, VT_VGABASE }, { 25, 80 } };
                    172: HWentry        VTMONO =        { 4, 0, VT_MONOPORT, { 0, VT_MONOBASE }, { 25, 80 } };
                    173: 
                    174: HWentry        *vtHWtable[] = {
                    175:        VTVGA,          /* VGA followed by MONO is compatible to DOS */
                    176:        VTMONO,
                    177:        0               /* MUST STAY AS LAST ELEMENT !!! */
                    178: };
                    179: 
                    180: extern int     mminit();
                    181: static VTDATA  const_vtdata    = {
                    182:        mminit, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 23, 24, 0, 0, 0, 23, 0, 0, 1
                    183: };
                    184: 
                    185: /* later this should be dynamic */
                    186: VTDATA *vtconsole, **vtdata;
                    187: 
                    188: int    vtcount, vtmax;
                    189: extern int     vtactive;
                    190: int    vt_verbose = { 0 };
                    191: int    vt_opened = { 0 };
                    192: 
                    193: /* Terminal structure. */
                    194: TTY    **vttty;
                    195: 
                    196: /*
                    197: ==============================================================================
                    198: ==============================================================================
                    199: */
                    200: 
                    201: static silo_t in_silo;
                    202: 
                    203: /*
                    204:  * Given hw pointer for one of four types of adapters, see if
                    205:  * device is present by write/readback of video memory.
                    206:  *
                    207:  * return 1 if present, else 0
                    208:  */
                    209: int
                    210: hwpresent( hw )
                    211: HWentry *hw;
                    212: {
                    213:        int     save, present = 1;
                    214: 
                    215:        PRINTV( "hwpresent: %x:%x",
                    216:                hw->vidmemory.seg, hw->vidmemory.off );
                    217:        save = ffword( hw->vidmemory.off, hw->vidmemory.seg );
                    218: 
                    219:        sfword(  hw->vidmemory.off, hw->vidmemory.seg, 0xAA55 );
                    220:        if( ffword( hw->vidmemory.off, hw->vidmemory.seg ) != 0xAA55 )
                    221:                present = 0;
                    222: 
                    223:        sfword(  hw->vidmemory.off, hw->vidmemory.seg, 0x55AA );
                    224:        if( ffword( hw->vidmemory.off, hw->vidmemory.seg ) != 0x55AA )
                    225:                present = 0;
                    226: 
                    227:        sfword(  hw->vidmemory.off, hw->vidmemory.seg, save );
                    228:        PRINTV( "%s present\n", present ? "" : " NOT" );
                    229:        return present;
                    230: }
                    231: 
                    232: /*
                    233:  * Load entry point.
                    234:  */
                    235: isload()
                    236: {
                    237:        register        int i;
                    238:        register        HWentry **hw;
                    239:        register        VTDATA *vp;
                    240: 
                    241:        PRINTV("vtload:\n");
                    242:        fk_loaded = 0;
                    243:        table_loaded = 0;
                    244:        kbstate = KB_IDLE;
                    245: 
                    246:        /* figure out what our current max is */
                    247:        for( vtmax = 0, hw = vtHWtable; *hw; ++hw ) {
                    248:                vtmax += (*hw)->count;
                    249:                (*hw)->found = 0;       /* assume non-exist */
                    250:        }
                    251:        PRINTV( "vtload: %d screens possible\n", vtmax );
                    252: 
                    253:        vtdata = (VTDATA **) kalloc( vtmax * sizeof( *vtdata ) );
                    254:        if( vtdata == NULL ) {
                    255:                printf( "vtload: unable to obtain vtdata[%d]\n", vtmax );
                    256:                u.u_error = -1;
                    257:                return;
                    258:        }
                    259:        PRINTV( "vtload: obtained vtdata[%d] @%x\n", vtmax, vtdata );
                    260: 
                    261:        vttty = (TTY **) kalloc( vtmax * sizeof( *vttty ) );
                    262:        if( vttty == NULL ) {
                    263:                printf( "vtload: unable to obtain vttty[%d]\n", vtmax );
                    264:                u.u_error = -1;
                    265:                return;
                    266:        }
                    267:        PRINTV( "vtload: obtained vttty[%d] @%x\n", vtmax, vttty );
                    268: 
                    269:        /* determine which video adaptors are present */
                    270:        for( vtcount = 0, hw = vtHWtable; *hw; ++hw ) {
                    271: /* suppress board sensing since it seems to confuse some equipment */
                    272: #if 0
                    273:                if( !hwpresent(*hw) )
                    274:                        continue;
                    275: #endif
                    276: 
                    277:                /* remember our logical start */
                    278:                (*hw)->start = vtcount;
                    279:                PRINTV( ", start %d\n", vtcount );
                    280: 
                    281:                /* allocate the necessary memory */
                    282:                for ( i = 0; i < (*hw)->count; ++i ) {
                    283:                        vp = vtdata[vtcount] = kalloc( sizeof(VTDATA) );
                    284:                        PRINTV( "     vtdata[%d] = @%x\n", vtcount, vp );
                    285:                        if( vp == NULL || !VTttyinit(vtcount) ) {
                    286:                                printf("not enough memory for VTDATA\n" );
                    287:                                break;
                    288:                        }
                    289: 
                    290:                        /* fill in appropriately */
                    291:                        *vp = const_vtdata;
                    292:                        vp->vmm_port = (*hw)->port;
                    293:                        vp->vmm_vseg = (*hw)->vidmemory.seg;
                    294:                        vp->vmm_voff = (*hw)->vidmemory.off;
                    295: 
                    296:                        vp->vt_ind = vtcount;
                    297:                        vtdatainit(vp);
                    298:                        if (i == 0 ) {
                    299:                                vp->vmm_visible = VNKB_TRUE;
                    300:                                vp->vmm_seg = vp->vmm_vseg;
                    301:                                vp->vmm_off = vp->vmm_voff;
                    302:                                updscreen(vtcount);
                    303:                        }
                    304:                        (*hw)->found++;
                    305:                        vtcount++;
                    306:                }
                    307:        }
                    308: 
                    309:        /*
                    310:         * initialize vtconsole
                    311:         */
                    312:        vtconsole = vtdata[vtactive = 0];
                    313:        vtconsole->vmm_invis = 0;               /* vtconsole cursor visible */
                    314: 
                    315:        /*
                    316:         * Seize keyboard interrupt.
                    317:         */
                    318: #ifdef _I386
                    319:        setivec(ISVEC, isrint);
                    320: #else
                    321: #if    VT_MAJOR == KB_MAJOR
                    322:        setivec(1, isrint);
                    323: #else
                    324:        /*
                    325:         * Map table and vector to us
                    326:         */
                    327:        i = sphi();
                    328:        PRINTV( "VTload: unload old vector\n" );
                    329:        kcall( Kclrivec, 1 );
                    330:        setivec(1, isrint);
                    331:        spl( i );
                    332: #endif
                    333: #endif /* _I386 */
                    334: 
                    335:        /*
                    336:         * Enable mmwatch() invocation every second.
                    337:         */
                    338:        drvl[VT_MAJOR].d_time = 1;
                    339: 
                    340:        /*
                    341:         * Initialize video display.
                    342:         */
                    343:        for ( i = 0; i < vtcount; ++i )
                    344:                mmstart( vttty[i] );
                    345: 
                    346: 
                    347: #ifndef        _I386
                    348:        /*
                    349:         * Allocate a segment to store the in-core keyboard table.
                    350:         * This would be a lot more convenient in kernel data space,
                    351:         * but small model COHERENT doesn't have that luxury.
                    352:         */
                    353:        kbsegp = salloc((fsize_t)MAX_TABLE_SIZE, SFSYST|SFNSWP|SFHIGH);
                    354:        if (kbsegp == (SEG *)0)
                    355:                printf("kb: unable to allocate keyboard table segment\n");
                    356:        KBDEBUG("Exiting kbload()\n");
                    357: #endif
                    358:        fklength = 0;
                    359: }
                    360: 
                    361: /*
                    362:  * Unload entry point.
                    363:  */
                    364: isuload()
                    365: {
                    366:        register int i;
                    367:        register level = sphi();
                    368: 
                    369:        clrivec(ISVEC);
                    370: #ifndef        _I386
                    371: #if    VT_MAJOR != KB_MAJOR
                    372:        kcall( Ksetivec, ISVEC, &Kisrint );
                    373: #endif
                    374: #endif
                    375:        spl( level );
                    376: 
                    377:        /* Restore pointers to original state. */
                    378:        vtconsole = vtdata[0];
                    379:        vtconsole->vmm_invis = 0;
                    380:        vtconsole->vmm_visible = VNKB_TRUE;
                    381: 
                    382:        if( vt_opened )
                    383:                printf( "VTclose with %d open screens\n", vt_opened );
                    384:        if( kbstate != KB_IDLE )
                    385:                printf("kb: keyboard busy during unload\n");
                    386: #ifndef        _I386
                    387:        if (kbsegp != (SEG *)0) {
                    388:                table_loaded = 0;
                    389:                sfree(kbsegp);
                    390:        }
                    391: #endif
                    392: 
                    393: #ifndef        _I386
                    394:        for( i = 0; i < vtcount; ++i ) {
                    395:                PRINTV( "VTuload: free far %x:%x, tty %x\n",
                    396:                        vttty[i]->t_buffer->s_faddr, vttty[i] );
                    397:                sfree( vttty[i]->t_buffer );
                    398:                kfree( vttty[i] );
                    399:                sfree( vtdata[i].vt_buffer );
                    400:        }
                    401: #endif
                    402: }
                    403: 
                    404: /*
                    405:  * Open routine.
                    406:  */
                    407: isopen(dev, mode)
                    408: dev_t dev;
                    409: unsigned int mode;
                    410: {
                    411:        register int s;
                    412:        register TTY *tp;
                    413:        int     index = vtindex(dev);
                    414: 
                    415:        PRINTV("isopen: %x\n", dev);
                    416:        if (index < 0 || index >= vtcount) {
                    417:                u.u_error = ENXIO;
                    418:                return;
                    419:        }
                    420: 
                    421:        tp = vttty[index];
                    422:        if ((tp->t_flags&T_EXCL) != 0 && !super()) {
                    423:                u.u_error = ENODEV;
                    424:                return;
                    425:        }
                    426:        ttsetgrp(tp, dev, mode);
                    427: 
                    428:        s = sphi();
                    429:        if (tp->t_open++ == 0) {
                    430:                tp->t_flags = T_CARR;   /* indicate "carrier" */
                    431:                ttopen(tp);
                    432:        }
                    433:        spl(s);
                    434: #if 0
                    435:        updleds();                      /* update keyboard status LEDS */
                    436: #endif
                    437: }
                    438: 
                    439: 
                    440: void isvtswitch();
                    441: 
                    442: /*
                    443:  * Close a tty.
                    444:  */
                    445: isclose(dev)
                    446: {
                    447:        register int s;
                    448:        int     index = vtindex(dev);
                    449:        register TTY *tp = vttty[index];
                    450: 
                    451: #if 0
                    452:        s = sphi();
                    453:        if (--tp->t_open == 0) {
                    454:                ttclose(tp);
                    455:                spl(s);
                    456:                if( index == vtactive )
                    457:                        isvtswitch( VTKEY_HOME );
                    458:        } else
                    459:                spl(s);
                    460: #else
                    461:        if (--tp->t_open == 0)
                    462:                ttclose(tp);
                    463: #endif
                    464: }
                    465: 
                    466: /*
                    467:  * Read routine.
                    468:  */
                    469: isread(dev, iop)
                    470: dev_t dev;
                    471: IO *iop;
                    472: {
                    473:        int     index = vtindex(dev);
                    474:        register TTY *tp = vttty[index];
                    475: 
                    476:        ttread(tp, iop, 0);
                    477:        if (tp->t_oq.cq_cc)
                    478:                mmtime(tp);
                    479: }
                    480: 
                    481: /*
                    482:  * Ioctl routine.
                    483:  * nb: archaic TIOCSHIFT and TIOCCSHIFT no longer needed/supported.
                    484:  */
                    485: isioctl(dev, com, vec)
                    486: dev_t dev;
                    487: struct sgttyb *vec;
                    488: {
                    489:        register int s;
                    490: 
                    491:        switch (com) {
                    492:        case TIOCSETF:
                    493:        case TIOCGETF:
                    494:                isfunction(com, (char *)vec);
                    495:                break;
                    496:        case TIOCSETKBT:
                    497:                issettable(vec);
                    498:                break;
                    499:        case TIOCGETKBT:
                    500:                isgettable(vec);
                    501:                break;
                    502:        default:                                /* pass to TTY driver */
                    503:                s = sphi();
                    504:                ttioctl(vttty[vtindex(dev)], com, vec);
                    505:                spl(s);
                    506:                break;
                    507:        }
                    508: }
                    509: 
                    510: /*
                    511:  * Set the in-core keyboard mapping table.
                    512:  * The table is sorted by scan code prior to calling ioctl().
                    513:  * All unused table entries (holes in the scan code map) have
                    514:  * a zero for the k_key field.
                    515:  * This makes key lookup at interrupt time fast by using the scan code
                    516:  * as an index into the table.
                    517:  */
                    518: issettable(vec)
                    519: char   *vec;
                    520: {
                    521:        register unsigned i;
                    522:        register int s;
                    523:        int timeout;
                    524:        static  KBTBL   this_key;       /* current key from kbd table */
                    525:        unsigned int cmd_byte;
                    526: #ifndef _I386
                    527:        register faddr_t faddr;         /* address of keyboard table */
                    528: #endif
                    529: 
                    530:        PRINTV(" TIOCSETKBT");
                    531:        kb_cmd2(K_SCANCODE_CMD, 3);             /* select set 3 */
                    532:        kb_cmd(K_ALL_TMB_CMD);                  /* default: TMB for all keys */
                    533: #ifndef _I386
                    534:        faddr = kbsegp->s_faddr;
                    535: #endif
                    536:        for (i = 0; i < MAX_KEYS; ++i) {
                    537:                ukcopy(vec, &this_key, sizeof(this_key));
                    538: #ifdef _I386
                    539:                kb[i] = this_key;               /* store away */
                    540: #else
                    541:                kfcopy(&this_key, faddr, sizeof(this_key));
                    542:                faddr += sizeof(this_key);
                    543: #endif
                    544:                vec += sizeof(this_key);
                    545:                if (this_key.k_key != i && this_key.k_key != 0) {
                    546:                        printf("kb: incorrect or unsorted table entry %d\n", i);
                    547: #ifdef _I386
                    548:                        u.u_error = EINVAL;
                    549: #else
                    550:                        u.u_error = EBADFMT;
                    551: #endif
                    552:                        return;
                    553:                }
                    554:                if (this_key.k_key != i)
                    555:                        continue;               /* no key */
                    556:                switch (this_key.k_flags&TMODE) {
                    557:                case T:                         /* typematic */
                    558:                        kb_cmd2(K_KEY_T_CMD, i);
                    559:                        break;
                    560:                case M:                         /* make only */
                    561:                        kb_cmd2(K_KEY_M_CMD, i);
                    562:                        break;
                    563:                case MB:                        /* make/break */
                    564:                        kb_cmd2(K_KEY_MB_CMD, i);
                    565:                        break;
                    566:                case TMB:                       /* typematic make/break */
                    567:                        break;                  /* this is the default */
                    568:                default:
                    569:                        printf("kb: bad key mode\n");
                    570:                }
                    571:        }
                    572:        updleds();
                    573:        kb_cmd2(K_SCANCODE_CMD, 3);             /* select set 3 */
                    574:        kb_cmd(K_ENABLE_CMD);                   /* start scanning */
                    575:        /*
                    576:         * The following code disables translation from the on-board
                    577:         * keyboard/aux controller. Without disabling translation, the
                    578:         * received scan codes still look like code set 1 codes even
                    579:         * though we put the keyboard controller in scan code set 3.
                    580:         * Yes, this is progress....
                    581:         */
                    582: #if 0
                    583:        while (inb(KBSTS_CMD) & STS_IBUF_FULL)
                    584:                ;
                    585:        outb(KBSTS_CMD, C_READ_CMD);            /* read controller cmd byte */
                    586:        while (!(inb(KBSTS_CMD) & STS_OBUF_FULL))
                    587:                ;
                    588:        cmd_byte = inb(KBDATA);
                    589:        KBDEBUG2(" cmd_byte=%x", cmd_byte);
                    590: #endif
                    591:        timeout = KBTIMEOUT;
                    592:        s = sphi();
                    593:        while ((inb(KBSTS_CMD) & STS_IBUF_FULL) && --timeout > 0)
                    594:                ;
                    595:        outb(KBSTS_CMD, C_WRITE_CMD);           /* write controller cmd byte */
                    596:        for (timeout = 50; --timeout > 0;)
                    597:                ;
                    598:        timeout = KBTIMEOUT;
                    599:        while ((inb(KBSTS_CMD) & STS_IBUF_FULL) && --timeout > 0)
                    600:                ;
                    601:        outb(KBDATA, KBCMDBYTE);                 /* turn off translation */     
                    602:        timeout = KBTIMEOUT;
                    603:        while ((inb(KBSTS_CMD) & STS_IBUF_FULL) && --timeout > 0)
                    604:                ;
                    605:        spl(s);
                    606: #if DEBUG || 1
                    607:        kb_cmd2(K_SCANCODE_CMD, 0);             /* query s.c. mode */
                    608: #endif
                    609:        ++table_loaded;
                    610:        PRINTV("... TIOCSETKBT\n");
                    611: }
                    612: 
                    613: /*
                    614:  * Get the in-core keyboard mapping table and pass it to the user.
                    615:  */
                    616: isgettable(vec)
                    617: char   *vec;
                    618: {
                    619: #ifdef _I386
                    620:        KBDEBUG(" TIOCGETKBT");
                    621:        kucopy(kb, vec, sizeof(kb));
                    622: #else
                    623:        register unsigned i;
                    624:        register faddr_t faddr;         /* address of keyboard table */
                    625:        static  KBTBL   this_key;       /* current key from kbd table */
                    626: 
                    627:        KBDEBUG(" TIOCGETKBT");
                    628:        faddr = kbsegp->s_faddr;
                    629:        for (i = 0; i < MAX_KEYS; ++i) {
                    630:                fkcopy(faddr, &this_key, sizeof(this_key));
                    631:                kucopy(&this_key, vec, sizeof(this_key));
                    632:                faddr += sizeof(this_key);
                    633:                vec += sizeof(this_key);
                    634:        }
                    635: #endif
                    636: }
                    637: 
                    638: 
                    639: /*
                    640:  * Set and receive the function keys.
                    641:  */
                    642: isfunction(c, v)
                    643: int c;
                    644: FNKEY *v;
                    645: {
                    646:        register unsigned char *cp;
                    647:        register unsigned i;
                    648:        unsigned char   numkeys = 0;
                    649: 
                    650:        if (c == TIOCGETF) {
                    651:                KBDEBUG(" TIOCGETF");
                    652:                if (!fk_loaded)
                    653:                        u.u_error = EINVAL;
                    654:                else
                    655:                        kucopy(fnkeys, v, fklength);    /* copy ours to user */
                    656:        } else { /* TIOCSETF */
                    657:                /*
                    658:                 * If we had a previous function key arena, free it up.
                    659:                 * Since we don't know how large the function key arena will
                    660:                 * be, we must size it in the user data space prior to
                    661:                 * (re)kalloc()'ing it. This is ugly, but a helluva lot better
                    662:                 * than the old driver which used a hard coded limit of 150!
                    663:                 */
                    664:                KBDEBUG(" TIOCSETF");
                    665:                fk_loaded = 0;
                    666:                if (fnkeys != (FNKEY *)0)
                    667:                        kfree(fnkeys);          /* free old arena */
                    668:                if (funkeyp != NULL)
                    669:                        kfree(funkeyp);         /* free old ptr array */
                    670:                ukcopy(&v->k_nfkeys, &numkeys, sizeof(numkeys));
                    671:                fklength = sizeof(FNKEY);
                    672:                cp = v->k_fnval;
                    673:                for (i = 0; i < numkeys; i++) {
                    674:                        do {
                    675:                                ++fklength;
                    676:                        } while (getubd(cp++) != DELIM);
                    677:                }
                    678:                fnkeys = (FNKEY *)kalloc(fklength);
                    679:                funkeyp = (unsigned char **)kalloc(numkeys * sizeof(char *));
                    680:                if (fnkeys == (FNKEY *)0 || funkeyp == NULL) {
                    681:                        if (fnkeys != (FNKEY *)0) {
                    682:                                kfree(fnkeys);
                    683:                                fnkeys = 0;
                    684:                        }
                    685:                        if (funkeyp != NULL) {
                    686:                                kfree(funkeyp);
                    687:                                funkeyp = 0;
                    688:                        }
                    689:                        u.u_error = ENOMEM;
                    690:                        return;
                    691:                }
                    692:                cp = fnkeys->k_fnval;                   /* point to Fn ... */
                    693:                v = v->k_fnval;                         /* ... key arena */
                    694:                for (i = 0; i < numkeys; i++) {
                    695:                        funkeyp[i] = cp;                   /* save pointer */
                    696:                        while ((*cp++ = getubd(v++)) != DELIM)  /* copy key */
                    697:                                ;
                    698:                }
                    699:                fnkeys->k_nfkeys = numkeys;
                    700:                fk_loaded = 1;
                    701:        }
                    702: }
                    703: 
                    704: 
                    705: /*
                    706:  * Poll routine.
                    707:  */
                    708: ispoll(dev, ev, msec)
                    709: dev_t dev;
                    710: int ev;
                    711: int msec;
                    712: {
                    713:        register TTY *tp = vttty[vtindex(dev)];
                    714: 
                    715:        return ttpoll(tp, ev, msec);
                    716: }
                    717: 
                    718: /*
                    719:  * Receive interrupt.
                    720:  */
                    721: #define        K_E0ESC 0xE0            /* Swan Keyboard, Strange Escape Byte   */
                    722: 
                    723: isrint()
                    724: {
                    725:        register unsigned c;
                    726:        register unsigned r;
                    727:        static  char keyup;
                    728: #if SWANFIX
                    729:        static  char e0esc;
                    730: #endif
                    731: 
                    732:        /*
                    733:         * Schedule raw input handler if not already active.
                    734:         */
                    735:        if (!isbusy) {
                    736:                defer(isbatch,  vttty[vtactive]);
                    737:                isbusy = 1;
                    738:        }
                    739: 
                    740:        /*
                    741:         * Pull character from the data
                    742:         * port. Pulse the KBFLAG in the control
                    743:         * port to reset the data buffer.
                    744:         */
                    745:        r = inb(KBDATA) & 0xFF;
                    746:        c = inb(KBCTRL);
                    747:        outb(KBCTRL, c|KBFLAG);
                    748:        outb(KBCTRL, c);
                    749: 
                    750:        /*
                    751:         * check returned value from keyboard to see if it's a command
                    752:         * or status back to us. If not, it we assume that it's a key code.
                    753:         */
                    754:        KBDEBUG2("\nintr(%x) ", r);
                    755:        switch (r) {
                    756:        case K_BREAK:
                    757:                keyup = 1;                      /* key going up */
                    758:                break;
                    759:        case K_ECHO_R:
                    760:        case K_BAT_OK:
                    761:                break;                          /* very nice, but ignored */
                    762:        case K_BAT_BAD:
                    763:                printf("kb: keyboard BAT failed\n");
                    764:                break;
                    765:        case K_RESEND:
                    766:                KBDEBUG("\nkb: request to resend command\n");
                    767:                outb(KBDATA, prev_cmd);
                    768:                break;
                    769:        case K_OVERRUN_23:
                    770:                printf("kb: keyboard buffer overrun\n");
                    771:                break;
                    772:        case K_ACK:
                    773:                /*
                    774:                 * we received an ACKnowledgement from the keyboard.
                    775:                 * advance the state machine and continue.
                    776:                 */
                    777:                KBDEBUG(" ACK ");
                    778:                switch (kbstate) {
                    779:                case KB_IDLE:                   /* shouldn't happen */
                    780:                        printf("vtnkb: ACK while idle ");
                    781:                        break;
                    782:                case KB_SINGLE:                 /* done with 1-byte command */
                    783:                case KB_DOUBLE_2:               /* done w/ 2nd of 2-byte cmd */
                    784:                        kbstate = KB_IDLE;
                    785:                        wakeup(&kbstate);
                    786:                        break;
                    787:                case KB_DOUBLE_1:
                    788:                        kbstate = KB_DOUBLE_2;
                    789:                        outb(KBDATA, cmd2);
                    790:                        break;
                    791:                default:
                    792:                        printf("kb: bad kbstate %d\n", kbstate);
                    793:                        break;
                    794:                }
                    795:                break;
                    796: #if SWANFIX
                    797:        case K_E0ESC:
                    798:                if (VTSWAN) {
                    799:                        e0esc = 1;
                    800:                        break;
                    801:                }
                    802: #endif
                    803:        default:
                    804: #if SWANFIX
                    805:                process_key(r, keyup, e0esc);
                    806:                e0esc = 0;
                    807: #else
                    808:                process_key(r, keyup);
                    809: #endif
                    810:                keyup = 0;
                    811:        }
                    812: }
                    813: 
                    814: /*
                    815:  * Process a key given its scan code and direction.
                    816:  * 
                    817:  * In this table driven version of the keyboard driver, we trade off the
                    818:  * code complexity associated with all the black magic that used to be
                    819:  * performed on a per-key basis with the increased memory requirements
                    820:  * associated with the table driven approach.
                    821:  */
                    822: #if SWANFIX 1
                    823: process_key(key, up, e0esc)
                    824: unsigned key;
                    825: char    up, e0esc;
                    826: #else
                    827: process_key(key, up)
                    828: unsigned key;
                    829: int     up;
                    830: #endif
                    831: {
                    832:        register unsigned char *cp;
                    833:        KBTBL   key_vals;                       /* table values for this key */
                    834:        unsigned val;
                    835:        unsigned char flags;
                    836:        register TTY *tp = vttty[vtactive];
                    837:        VTDATA *vp = vtdata[vtactive];
                    838: 
                    839:        KBDEBUG3(" proc(%x %s)", key, (up ? "up" : "down"));
                    840:        if (!table_loaded)
                    841:                return;                         /* throw away key */
                    842: #ifdef _I386
                    843:        /*
                    844:         *  It's ugly but, if e0esc, then we use the ALT_GR field to point
                    845:         *  at the actual table entry we want.  We weren't really using the
                    846:         *  ALT_GR field anyway.  Trouble remapping shift keys because
                    847:         *  loader requires all entries to be identical, thus ALT_GR is
                    848:         *  by default being used.
                    849:         */
                    850: 
                    851: #if SWANFIX
                    852:        if ( VTSWAN && e0esc && !(kb[key].k_flags&S) )
                    853:                key = kb[key].k_val[ALT_GR];   /* Ugly kludge */
                    854: #endif
                    855:        key_vals = kb[key];
                    856: #else
                    857:        fkcopy(kbsegp->s_faddr + (key * sizeof(KBTBL)),
                    858:                &key_vals, sizeof(key_vals));
                    859: #endif
                    860:        if (key_vals.k_key != key)              /* empty entry */
                    861:                return;
                    862:        flags = key_vals.k_flags;
                    863: 
                    864:        if (flags & S) {                        /* some shift/lock key ? */
                    865:                switch (key_vals.k_val[BASE]) {
                    866:                case caps:
                    867:                case num:
                    868:                        if (!up) {
                    869:                                shift ^= (1 << key_vals.k_val[BASE]);
                    870:                                updleds2();
                    871:                        }
                    872:                        break;
                    873:                case scroll:
                    874:                        if (!up) {
                    875:                                shift ^= (1 << key_vals.k_val[BASE]);
                    876:                                updleds2();
                    877:                                if (!(tp->t_sgttyb.sg_flags&RAWIN)) {
                    878:                                        if (tp->t_flags & T_STOP) {
                    879:                                                isin(tp->t_tchars.t_startc);
                    880:                                        } else {
                    881:                                                isin(tp->t_tchars.t_stopc);
                    882:                                        }
                    883:                                }
                    884:                        }
                    885:                        break;
                    886:                default:
                    887:                        if (up)
                    888:                                shift &= ~(1 << key_vals.k_val[BASE]);
                    889:                        else
                    890:                                shift |= (1 << key_vals.k_val[BASE]);
                    891:                        break;
                    892:                }
                    893:                /*
                    894:                 * Calculate the shift index based upon the state of
                    895:                 * the shift and lock keys.
                    896:                 */
                    897:                sh_index = BASE;                /* default condition */
                    898:                if (shift & (1 << altgr))
                    899:                        sh_index = ALT_GR;
                    900:                else {
                    901:                        if (shift & ((1 << lalt)|(1 << ralt)))
                    902:                                sh_index |= ALT;
                    903:                        if (shift & ((1 << lctrl)|(1 << rctrl)))
                    904:                                sh_index |= CTRL;
                    905:                        if (shift & ((1 << lshift)|(1 << rshift)))
                    906:                                sh_index |= SHIFT;
                    907:                }
                    908:                T_CON(2, printf("shift=%x sh_index=%d\n", shift, sh_index));
                    909:                return;
                    910:        } /* if (flags & S) */
                    911: 
                    912:        /*
                    913:         * If the key has no value in the current
                    914:         * shift state, the key is just tossed away.
                    915:         */
                    916:        if (up || key_vals.k_val[sh_index] == none)
                    917:                return;
                    918: 
                    919:        if (((flags & C) && (shift & (1 << caps)))
                    920:           || ((flags & N) && (shift & (1 << num))))
                    921:                val = key_vals.k_val[sh_index^SHIFT];
                    922:        else
                    923:                val = key_vals.k_val[sh_index];
                    924: 
                    925:        /*
                    926:         * Check for function key or special key implemented as
                    927:         * a function key (reboot == f0, tab and back-tab, etc).
                    928:         */
                    929:        if (flags & F) {
                    930:                PRINTV( "<{F%d}>", val );
                    931:                if (VTKEY(val)) {
                    932:                        T_CON(4,
                    933:                          printf( "<{F%d !!}>\b\b\b\b\b\b\b\b\b\b", val));
                    934:                        defer( isvtswitch, val );
                    935:                        return;
                    936:                }
                    937:                /* If the tty is not open, ignore it */
                    938:                if( !tp->t_open )
                    939:                        return;
                    940: #if GREEKFIX
                    941:                if (VTGREEK && val == fgk) {
                    942:                        ToggleGreek();
                    943:                        return;
                    944:                }
                    945: #endif /* GREEKFIX */
                    946:                if (val == 0 && !up && KBBOOT)
                    947:                        boot();
                    948:                if (!fk_loaded || val >= fnkeys->k_nfkeys)
                    949:                        return;
                    950:                if ((cp = funkeyp[val]) == NULL) /* has a value? */
                    951:                        return;
                    952:                while (*cp != DELIM)
                    953:                        isin(*cp++);            /* queue up Fn key value */
                    954:                return;
                    955:        }
                    956: 
                    957:        /*
                    958:         * Normal key processing.
                    959:         */
                    960:        /* If the tty is not open, ignore it */
                    961: #if GREEKFIX
                    962:        if( tp->t_open )
                    963:                if (VTGREEK) {
                    964:                        if (ToGreek(&val))
                    965:                                isin(val);
                    966:                } else
                    967:                        isin(val);
                    968: #else
                    969:        if( tp->t_open )
                    970:                isin(val);               /* send the char */
                    971: #endif /* GREEKFIX */
                    972: }
                    973: 
                    974: /**
                    975:  *
                    976:  * void
                    977:  * ismmfunc(c) -- process keyboard related output escape sequences
                    978:  * char c;
                    979:  */
                    980: void
                    981: ismmfunc(c)
                    982: register int c;
                    983: {
                    984: 
                    985:        switch (c) {
                    986:        case 't':       /* Enter numlock */
                    987:                shift |= (1 << num);
                    988:                updleds();                      /* update LED status */
                    989:                break;
                    990:        case 'u':       /* Leave numlock */
                    991:                shift &= ~(1 << num);
                    992:                updleds();                      /* update LED status */
                    993:                break;
                    994:        case '=':                       /* Enter alternate keypad -- ignored */
                    995:        case '>':                       /* Exit alternate keypad -- ignored */
                    996:                break;
                    997:        case 'c':       /* Reset terminal */
                    998:                islock = 0;
                    999:                break;
                   1000:        }
                   1001: }
                   1002: 
                   1003: /**
                   1004:  *
                   1005:  * void
                   1006:  * isin(c)     -- append character to raw input silo
                   1007:  * char c;
                   1008:  */
                   1009: static
                   1010: isin(c)
                   1011: register int c;
                   1012: {
                   1013:        int cache_it = 1;
                   1014:        TTY * tp = vttty[vtactive];
                   1015:        void ttstart();
                   1016: 
                   1017:        /*
                   1018:         * If using software incoming flow control, process and
                   1019:         * discard t_stopc and t_startc.
                   1020:         */
                   1021:        if (ISIXON) {
                   1022: #if _I386
                   1023:                if (ISSTART || (ISIXANY && ISXSTOP)) {
                   1024:                        tp->t_flags &= ~(T_STOP | T_XSTOP);
                   1025:                        ttstart(tp);
                   1026:                        cache_it = 0;
                   1027:                } else if (ISSTOP) {
                   1028:                        if ((tp->t_flags&T_STOP) == 0)
                   1029:                                tp->t_flags |= (T_STOP | T_XSTOP);
                   1030:                        cache_it = 0;
                   1031:                }
                   1032: #else
                   1033:                if (ISSTOP) {
                   1034:                        if ((tp->t_flags&T_STOP) == 0)
                   1035:                                tp->t_flags |= T_STOP;
                   1036:                        cache_it = 0;
                   1037:                }
                   1038:                if (ISSTART) {
                   1039:                        tp->t_flags &= ~T_STOP;
                   1040:                        ttstart(tp);
                   1041:                        cache_it = 0;
                   1042:                }
                   1043: #endif
                   1044:        }
                   1045: 
                   1046:        /*
                   1047:         * Cache received character.
                   1048:         */
                   1049:        if (cache_it) {
                   1050:                in_silo.si_buf[ in_silo.si_ix ] = c;
                   1051: 
                   1052:                if (++in_silo.si_ix >= sizeof(in_silo.si_buf))
                   1053:                        in_silo.si_ix = 0;
                   1054:        }
                   1055: }
                   1056: 
                   1057: /**
                   1058:  *
                   1059:  * void
                   1060:  * isbatch()   -- raw input conversion routine
                   1061:  *
                   1062:  *     Action: Enable the video display.
                   1063:  *             Canonize the raw input silo.
                   1064:  *
                   1065:  *     Notes:  isbatch() was scheduled as a deferred process by isrint().
                   1066:  */
                   1067: static void
                   1068: isbatch(tp)
                   1069: register TTY * tp;
                   1070: {
                   1071:        register int c;
                   1072:        static int lastc;
                   1073:        VTDATA *vp = tp->t_ddp;
                   1074: 
                   1075:        /*
                   1076:         * Ensure video display is enabled.
                   1077:         */
                   1078:        if( vp->vmm_visible ) {
                   1079:                mm_von(vp);
                   1080:        }
                   1081:        isbusy = 0;
                   1082: 
                   1083:        /*
                   1084:         * Process all cached characters.
                   1085:         */
                   1086:        while (in_silo.si_ix != in_silo.si_ox) {
                   1087:                /*
                   1088:                 * Get next cached char.
                   1089:                 */
                   1090:                c = in_silo.si_buf[ in_silo.si_ox ];
                   1091: 
                   1092:                if (in_silo.si_ox >= sizeof(in_silo.si_buf) - 1)
                   1093:                        in_silo.si_ox = 0;
                   1094:                else
                   1095:                        in_silo.si_ox++;
                   1096: 
                   1097:                if ((islock == 0) || ISINTR || ISQUIT) {
                   1098:                        ttin(tp, c);
                   1099:                } else if ((c == 'b') && (lastc == '\033')) {
                   1100:                        islock = 0;
                   1101:                        ttin(tp, lastc);
                   1102:                        ttin(tp, c);
                   1103:                } else if ((c == 'c') && (lastc == '\033')) {
                   1104:                        ttin(tp, lastc);
                   1105:                        ttin(tp, c);
                   1106:                } else
                   1107:                        putchar('\007');
                   1108:                lastc = c;
                   1109:        }
                   1110: }
                   1111: 
                   1112: /*
                   1113:  * update the keyboard status LEDS.
                   1114:  * we chose the shift/lock key positions so this would be easy.
                   1115:  * this flavor of routine is called while processing a system call on
                   1116:  * behalf of the user.
                   1117:  */
                   1118: updleds()
                   1119: {
                   1120:        kb_cmd2(K_LED_CMD, (shift >> 1) & 0x7);
                   1121: }
                   1122: 
                   1123: /*
                   1124:  * same as above, but callable from interrupt routines and other places
                   1125:  * which cannot sleep() waiting for the state machine to go idle.
                   1126:  */
                   1127: updleds2()
                   1128: {
                   1129:        register timeout;
                   1130:        register int s;
                   1131: 
                   1132:        timeout = KBTIMEOUT;
                   1133:        s = sphi();
                   1134:        while (--timeout > 0 && (inb(KBSTS_CMD) & STS_IBUF_FULL))
                   1135:                ;
                   1136:        kbstate = KB_DOUBLE_1;
                   1137:        cmd2 = (shift >> 1) & 0x7;
                   1138:        prev_cmd = K_LED_CMD;
                   1139:        outb(KBDATA, K_LED_CMD);
                   1140:        spl(s);
                   1141: }
                   1142: 
                   1143: /*
                   1144:  * unlock the scroll in case an interrupt character is received
                   1145:  */
                   1146: kbunscroll()
                   1147: {
                   1148:        shift &= ~(1 << scroll);
                   1149:        updleds();
                   1150: }
                   1151: 
                   1152: /*
                   1153:  * ship a single byte command to the keyboard
                   1154:  */
                   1155: kb_cmd(cmd)
                   1156: unsigned cmd;
                   1157: {
                   1158:        register int timeout;
                   1159:        register int s;
                   1160: 
                   1161:        s = sphi();
                   1162:        KBDEBUG2(" kb_cmd(%x)", cmd);
                   1163:        while (kbstate != KB_IDLE)
                   1164: #ifdef _I386
                   1165:                x_sleep(&kbstate, pritty, slpriSigCatch, "kb a");
                   1166: #else
                   1167:                v_sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN, "kb a");
                   1168: #endif
                   1169:        kbstate = KB_SINGLE;
                   1170:        timeout = KBTIMEOUT;
                   1171:        while (--timeout > 0 && (inb(KBSTS_CMD) & STS_IBUF_FULL))
                   1172:                ;
                   1173:        if (!timeout)
                   1174:                printf("kb: command timeout\n");
                   1175:        else {
                   1176:                outb(KBDATA, cmd);
                   1177:                while (kbstate != KB_IDLE)
                   1178: #ifdef _I386
                   1179:                        x_sleep(&kbstate, pritty, slpriSigCatch, "kb b");
                   1180: #else
                   1181:                        v_sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN, "kb b");
                   1182: #endif
                   1183:        }
                   1184:        spl(s);
                   1185: }
                   1186: 
                   1187: /*
                   1188:  * ship a two byte command to the keyboard
                   1189:  */
                   1190: kb_cmd2(cmd, arg)
                   1191: unsigned cmd, arg;
                   1192: {
                   1193:        register int timeout;
                   1194:        register int s;
                   1195: 
                   1196:        s = sphi();
                   1197:        KBDEBUG3(" kb_cmd2(%x, %x)", cmd, arg);
                   1198:        while (kbstate != KB_IDLE)
                   1199: #ifdef _I386
                   1200:                x_sleep(&kbstate, pritty, slpriSigCatch, "kb c");
                   1201: #else
                   1202:                v_sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN, "kb c");
                   1203: #endif
                   1204:        kbstate = KB_DOUBLE_1;
                   1205:        cmd2 = arg;
                   1206:        prev_cmd = cmd;
                   1207:        timeout = KBTIMEOUT;
                   1208:        while (--timeout > 0 && (inb(KBSTS_CMD) & STS_IBUF_FULL))
                   1209:                ;
                   1210:        if (!timeout)
                   1211:                printf("kb: command timeout\n");
                   1212:        else {
                   1213:                outb(KBDATA, cmd);
                   1214:                while (kbstate != KB_IDLE)
                   1215: #ifdef _I386
                   1216:                        x_sleep(&kbstate, pritty, slpriSigCatch, "kb d");
                   1217: #else
                   1218:                        v_sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN, "kb d");
                   1219: #endif
                   1220:        }
                   1221:        spl(s);
                   1222: }
                   1223: 
                   1224: /*
                   1225: ==============================================================================
                   1226: ==============================================================================
                   1227: */
                   1228: 
                   1229: int
                   1230: VTttyinit(i)
                   1231: int i;
                   1232: {
                   1233:        TTY *tp;
                   1234: 
                   1235:        /*
                   1236:         * get pointer to TTY structure from kernal memory space
                   1237:         */
                   1238:        if( (tp = vttty[i] = (TTY *)kalloc(sizeof (TTY))) == NULL )
                   1239:                return(0);
                   1240:        PRINTV( "     vttty[%d]: @%x, ", i, tp );
                   1241: 
                   1242: #if    FAR_TTY
                   1243:        /*
                   1244:         * get pointers to the buffers pointed to by the TTY structure 
                   1245:         * from user memory space
                   1246:         */
                   1247:        tp->t_buffer = salloc( (fsize_t)NCIB+2*SI_BUFSIZ, SFSYST|SFNSWP );
                   1248:        tp->t_ib = 0;
                   1249:        tp->t_rawin.si_buf = NCIB;
                   1250:        tp->t_rawout.si_buf = NCIB+SI_BUFSIZ;
                   1251: #endif
                   1252:        tp->t_param = NULL;
                   1253:        tp->t_start = &mmstart;
                   1254: 
                   1255: #ifndef        _I386
                   1256: #if    VT_MAJOR == KB_MAJOR
                   1257:        tp->t_cs_sel = 0;
                   1258: #else
                   1259:        tp->t_cs_sel = cs_sel();
                   1260: #endif
                   1261: #endif
                   1262:        tp->t_ddp = vtdata[i];
                   1263:        PRINTV( "data @%lx\n", tp->t_ddp );
                   1264:        return(1);
                   1265: }
                   1266: 
                   1267: vtdatainit(vp)
                   1268: VTDATA *vp;
                   1269: {
                   1270: #ifndef        _I386
                   1271:        VT_FARSEG       vt_farseg;
                   1272: #endif
                   1273:        /*
                   1274:         * vtdata init - vmm part
                   1275:         */
                   1276:        vp->vmm_invis = -1;                     /* cursor invisible */
                   1277: 
                   1278: #ifdef _I386
                   1279:        vp->vt_buffer = kalloc( TEXTBLOCK );
                   1280:        vp->vmm_seg = vp->vmm_mseg = ds_sel();
                   1281:        vp->vmm_off = vp->vmm_moff = vp->vt_buffer;
                   1282: #else
                   1283:        vp->vt_buffer = salloc ( (fsize_t)TEXTBLOCK, SFSYST|SFNSWP|SFHIGH );
                   1284:        vp->vmm_seg = vp->vmm_mseg = FP_SEG( vp->vt_buffer->vt_faddr );
                   1285:        vp->vmm_off = vp->vmm_moff = FP_OFF( vp->vt_buffer->vt_faddr );
                   1286: #endif
                   1287:        PRINTV( "vt@%x init index %d,%d), seg %x, off %x\n",
                   1288:                vp, vp->vt_ind, vp->vmm_mseg, vp->vmm_moff );
                   1289:        /*
                   1290:         * vtdata init - vnkb part
                   1291:         */
                   1292:        /* Make the first memory block active, if present */ 
                   1293:        vp->vnkb_lastc = 0;
                   1294:        vp->vnkb_fnkeys = 0;    
                   1295:        vp->vnkb_funkeyp = 0;   
                   1296:        vp->vnkb_fk_loaded = 0;                 /* no Fn keys yet */
                   1297: }
                   1298: 
                   1299: /*
                   1300:  * Given device number, return index for vtdata[], vttty[], etc.
                   1301:  *
                   1302:  * Major number must be VT_MAJOR for CPU to get here.
                   1303:  *
                   1304:  *      Minor Number   Index Value
                   1305:  *     ----- ------    ----- -----  
                   1306:  *     0000  0000      vtactive ... device (2,0) is the active screen
                   1307:  *     0000  0001      0
                   1308:  *     0000  0010      1
                   1309:  *     0000  0011      2
                   1310:  *        ....
                   1311:  *     0000  1111      14
                   1312:  *
                   1313:  *     0100  xxxx      xxxx ... color devices only
                   1314:  *     0101  xxxx      xxxx - (# of color devices found) ... monochrome only
                   1315:  *
                   1316:  * Return value is in range 0 to vtcount-1 for valid minor numbers,
                   1317:  * -1 for invalid minor numbers.
                   1318:  */
                   1319: int
                   1320: vtindex( dev )
                   1321: dev_t dev;
                   1322: {
                   1323:        register int    ret = -1;
                   1324: 
                   1325:        if ( dev & VT_PHYSICAL ) {
                   1326:                int     hw = ( dev >> 4 ) & 3;
                   1327:                int     hw_index = dev & 0x0F;
                   1328: 
                   1329:                if( hw_index < vtHWtable[hw]->found )
                   1330:                        ret = vtHWtable[hw]->start + hw_index;
                   1331:        } else {
                   1332:                int     lg_index = dev & 0x0F;
                   1333: 
                   1334:                if (lg_index == 0)
                   1335:                        ret = vtactive;
                   1336:                if (lg_index > 0 && lg_index <= vtcount ) 
                   1337:                        ret = lg_index-1;
                   1338:        }
                   1339:        if (ret >= 0)
                   1340:                ret %= vtcount;
                   1341:        else
                   1342:                PRINTV( "vtindex: (%x) %d. invalid !\n", dev, ret );
                   1343:        return ret;
                   1344: }
                   1345: 
                   1346: /*
                   1347:  *
                   1348:  * void
                   1349:  * isvtswitch()        -- deferred virtual terminal switch
                   1350:  *
                   1351:  *     Action: - save current shift key status
                   1352:  *             - determine new active virtual terminal
                   1353:  *             - deactivate shift key status of the current virtual terminal
                   1354:  *             - deactivate current virtual terminal
                   1355:  *             - activate shift key status of the new virtual terminal with 
                   1356:  *               the previously saved shift key status
                   1357:  *             - activate new virtual terminal 
                   1358:  *
                   1359:  *     Notes:  isvtswitch() was scheduled as a deferred process by 
                   1360:  *     process_key() which is a function called by isrint().
                   1361:  */
                   1362: void
                   1363: isvtswitch(key_val)
                   1364: {
                   1365:        register int    new_index, i;
                   1366:        unsigned        lockshift, nolockshift; 
                   1367:        VTDATA          *vp = vtdata[vtactive];
                   1368:        VTDATA          *vp_old, *vp_new;
                   1369:        static int      vtprevious;
                   1370: 
                   1371:        T_CON(2, printf("old shift=%x sh_index=%d\n", shift, sh_index));
                   1372:        lockshift = shift & ((1<<scroll)|(1<<num)|(1<<caps));
                   1373:        nolockshift = shift & ~((1<<scroll)|(1<<num)|(1<<caps));
                   1374: 
                   1375:        PRINTV( "F%d: %d", key_val, vtactive );
                   1376: #if 0
                   1377:        if( key_val == VTKEY_HOME )
                   1378:                new_index = 0;
                   1379:        else if( key_val == VTKEY_NEXT ) {
                   1380:                new_index = vtactive;
                   1381:                for( i = 0; i < vtcount; ++i ) {
                   1382:                        new_index = ++new_index % vtcount;
                   1383:                        if( vttty[new_index]->t_open )
                   1384:                                break;
                   1385:                }
                   1386:        } else {
                   1387:                new_index = vtindex(vtkey_to_dev(key_val));
                   1388:                if( new_index < 0) {
                   1389:                        putchar( '\007' );
                   1390:                        return;
                   1391:                }
                   1392:        }
                   1393: #else
                   1394:        switch (key_val) {
                   1395:        case VTKEY_HOME:
                   1396:                new_index = 0;
                   1397:                break;
                   1398:        case VTKEY_NEXT:
                   1399:                new_index = vtactive;
                   1400:                for( i = 0; i < vtcount; ++i ) {
                   1401:                        new_index = ++new_index % vtcount;
                   1402:                        if( vttty[new_index]->t_open )
                   1403:                                break;
                   1404:                }
                   1405:                break;
                   1406:        case VTKEY_PREV:
                   1407:                new_index = vtactive;
                   1408:                for( i = 0; i < vtcount; ++i ) {
                   1409:                        new_index = (--new_index+vtcount) % vtcount;
                   1410:                        if( vttty[new_index]->t_open )
                   1411:                                break;
                   1412:                }
                   1413:                break;
                   1414:        case VTKEY_TOGL:
                   1415:                new_index = vtprevious;
                   1416:                break;
                   1417:        default:
                   1418:                new_index = vtindex(vtkey_to_dev(key_val));
                   1419:                if( new_index < 0) {
                   1420:                        putchar( '\007' );
                   1421:                        return;
                   1422:                }
                   1423:        }
                   1424: #endif
                   1425:        T_CON(8, printf("%d->%d ", vtactive, new_index));
                   1426:        if( new_index == vtactive )
                   1427:                return;
                   1428: 
                   1429:        /* Save which locking shift states are in effect. */
                   1430: 
                   1431:        vp_old = vtdata[vtactive];
                   1432:        vp_new = vtdata[new_index];
                   1433: 
                   1434:        vp_old->vnkb_shift = lockshift;
                   1435:        vtdeactivate(vp_new, vp_old);   /* deactivate old virtual terminal */
                   1436: 
                   1437:        /* Restore shift lock state, append current momentary shift state. */
                   1438:        shift = vp_new->vnkb_shift | nolockshift;
                   1439:        T_CON(2, printf("new shift=%x sh_index=%d\n", shift, sh_index));
                   1440:        vtactivate(vp_new);             /* activate new virtual terminal */
                   1441:        updterminal(new_index);
                   1442:        vtprevious = vtactive;
                   1443:        vtactive = new_index;           /* update vtactive */
                   1444: }
                   1445: 
                   1446: vtdeactivate(vp_new, vp_old)
                   1447: register VTDATA        *vp_new, *vp_old;
                   1448: {
                   1449:        register i;
                   1450:        VTDATA  *vpi;
                   1451: 
                   1452:        /* store old screen contents in memory segment */
                   1453:        FFCOPY( vp_old->vmm_voff, vp_old->vmm_vseg,
                   1454:                vp_old->vmm_moff, vp_old->vmm_mseg, TEXTBLOCK );
                   1455: 
                   1456:        /*
                   1457:         * if changing to another screen on same video board
                   1458:         *      for all screens on same board as new screen
                   1459:         *              deactivate, but don't update
                   1460:         * else - changing to a screen on different board
                   1461:         *      for all screens NOT on same board as new screen
                   1462:         *              deactivate, but don't update
                   1463:         */
                   1464:        if ( vp_old->vmm_port == vp_new->vmm_port ) {
                   1465:                T_CON(8, printf("deactivate on %x ", vp_new->vmm_port));
                   1466:                for (i = 0; i < vtcount; ++i) {
                   1467:                        vpi = vtdata[i];
                   1468:                        if ( vpi->vmm_port == vp_new->vmm_port ) {
                   1469:                                /* deactivate, but don't update */
                   1470:                                vpi->vmm_invis = ~0; 
                   1471:                                vpi->vmm_visible = VNKB_FALSE;
                   1472:                                vpi->vmm_seg = vpi->vmm_mseg;
                   1473:                                vpi->vmm_off = vpi->vmm_moff;
                   1474:                                if( vpi->vmm_seg == 0 )
                   1475:                                        printf( "[1]vpi->vmm_seg = 0\n" );
                   1476:                                PRINTV( "vt.back %d. seg %x off %x\n", i,
                   1477:                                        vpi->vmm_seg, vpi->vmm_off );
                   1478:                        }
                   1479:                }
                   1480:        } else {
                   1481:                T_CON(8, printf("deactivate %x->%x ",
                   1482:                  vp_old->vmm_port, vp_new->vmm_port));
                   1483:                for (i = 0; i < vtcount; ++i) {
                   1484:                        vpi = vtdata[i];
                   1485:                        if ( (vpi->vmm_port != vp_new->vmm_port) 
                   1486:                          && (vpi->vmm_invis == 0) ) {
                   1487:                                /* update, but don't deactivate */
                   1488:                                vpi->vmm_invis = ~0; 
                   1489:                                updscreen(i);
                   1490:                        }
                   1491:                }
                   1492:        }
                   1493: }
                   1494: 
                   1495: vtactivate(vp)
                   1496: VTDATA *vp;
                   1497: {
                   1498:        register VTDATA *vpi;
                   1499:        register i;
                   1500: 
                   1501:        /* 
                   1502:         * copy from screen contents from heap segment to video memory 
                   1503:         * only if necessary
                   1504:         */
                   1505:        if ( vp->vmm_visible == VNKB_FALSE )
                   1506:                FFCOPY( vp->vmm_moff, vp->vmm_mseg,
                   1507:                        vp->vmm_voff, vp->vmm_vseg, TEXTBLOCK );
                   1508: 
                   1509:        for (i = 0; i < vtcount; ++i) {
                   1510:                vpi = vtdata[i];
                   1511:                if (vpi->vmm_port == vp->vmm_port) {
                   1512:                        vpi->vmm_invis = -1;
                   1513:                        vpi->vmm_visible = VNKB_FALSE;
                   1514:                        vpi->vmm_seg = vpi->vmm_mseg;
                   1515:                        vpi->vmm_off = vpi->vmm_moff;
                   1516:                        if( vpi->vmm_seg == 0 )
                   1517:                                printf( "[2]vpi->vmm_seg = 0\n" );
                   1518:                        PRINTV( "vt.back seg %x off %x\n",
                   1519:                                vpi->vmm_seg, vpi->vmm_off );
                   1520:                }               
                   1521:        }
                   1522:        /*
                   1523:         * Set new active terminal
                   1524:         */
                   1525:        vp->vmm_invis = 0;      
                   1526:        vp->vmm_visible = VNKB_TRUE;
                   1527:        vp->vmm_seg = vp->vmm_vseg;
                   1528:        vp->vmm_off = vp->vmm_voff;
                   1529:        if( vp->vmm_seg == 0 )
                   1530:                printf( "vp->vmm_seg = 0\n" );
                   1531: }
                   1532: 
                   1533: /*
                   1534:  * update the terminal to match vtactive
                   1535:  */
                   1536: updterminal(index)
                   1537: int index;
                   1538: {
                   1539:        updscreen(index);
                   1540:        updleds2();
                   1541: }
                   1542: 
                   1543: #undef si
                   1544: asmdump( cs, ds, es, di, si, bp, sp, bx, dx, cx, i, ip, ax )
                   1545: int    cs, ds, es, di, si, bp, sp, bx, dx, cx, i, ip, ax;
                   1546: {
                   1547:        if( vt_verbose < 2 )
                   1548:                return;
                   1549: 
                   1550:        printf( "asmdump %d: es %x, ds %x, cs:ip %x:%x\n", i, es, ds, cs, ip );
                   1551:        printf( "   ax %x, bx %x, cx %x, dx %x\n", ax, bx, cx, dx );
                   1552:        printf( "   di %x, si %x, bp %x, sp %d\n", di, si, bp, sp );
                   1553: #if    USING_RS232
                   1554:        if( vt_verbose > 2 )
                   1555:                getchar();
                   1556: #endif
                   1557: }
                   1558: 
                   1559: vtdataprint( vp )
                   1560: register VTDATA *vp;
                   1561: {
                   1562:        if( vt_verbose < 2 )
                   1563:                return;
                   1564: 
                   1565:        printf( "VTDATA:    @%x, esc %x, func %x()\n",
                   1566:                vp, vp->vmm_esc, vp->vmm_func );
                   1567:        printf( "       hw: port %x, seg %x, off %x\n",
                   1568:                vp->vmm_port, vp->vmm_vseg, vp->vmm_voff );
                   1569:        printf( "   memory: size %x, seg %x, off %x\n",
                   1570:                0/*vp->vmm_size*/, vp->vmm_mseg, vp->vmm_moff );
                   1571:        printf( "   cursor: seg %x, off %x, visible %d\n",
                   1572:                vp->vmm_seg, vp->vmm_off, !vp->vmm_invis );
                   1573:        printf( "           row %d, col %d = offset %d.\n",
                   1574:                vp->vmm_rowl, vp->vmm_col, vp->vmm_pos );
                   1575:        printf( "     saved row %d, col %d\n",
                   1576:                vp->vmm_srow, vp->vmm_scol );
                   1577:        printf( "   screen: visible %d, attr %x, wrap %d, slow %d\n",
                   1578:                vp->vmm_visible, vp->vmm_attr, vp->vmm_wrap, vp->vmm_slow );
                   1579:        printf( "           row base %d, end %d, limit %d\n",
                   1580:                vp->vmm_brow, vp->vmm_erow, vp->vmm_lrow ); 
                   1581:        printf( "           row initial base %d, initial end %d\n",
                   1582:                vp->vmm_ibrow, vp->vmm_ierow ); 
                   1583: #if    USING_RS232
                   1584:        if( vt_verbose > 2 )
                   1585:                getchar();
                   1586: #endif
                   1587: }
                   1588: 
                   1589: FFCOPY( src_off, src_seg, dst_off, dst_seg, count )
                   1590: {
                   1591:        register i;
                   1592: 
                   1593: #if    0
                   1594:        i = ffcopy( src_off, src_seg, dst_off, dst_seg, count );
                   1595: #else
                   1596:        for( i = 0; i < count; i += 2 ) {
                   1597:                register word = ffword( src_off, src_seg );
                   1598:                sfword( dst_off, dst_seg, word );
                   1599:                src_off += 2;
                   1600:                dst_off += 2;
                   1601:        }
                   1602: #endif
                   1603:        return i;       
                   1604: }
                   1605: 
                   1606: /*
                   1607:  * Given a function key number (e.g. vt0),
                   1608:  * return the corresponding minor device number.
                   1609:  *
                   1610:  * Assume valid key number (VTKEY(fnum) is true) by the time we get here.
                   1611:  */
                   1612: int
                   1613: vtkey_to_dev(fnum)
                   1614: int fnum;
                   1615: {
                   1616:        if (fnum >=vt0 && fnum <= vt15)
                   1617:                return fnum-vt0+1;
                   1618:        if (fnum >=color0 && fnum <= color15)
                   1619:                return (fnum-color0)|(VT_PHYSICAL|VT_HW_COLOR);
                   1620:        if (fnum >=mono0 && fnum <= mono15)
                   1621:                return (fnum-mono0)|(VT_PHYSICAL|VT_HW_MONO);
                   1622:        printf("vtkey_to_dev(%d)! ", fnum);
                   1623:        return 0;
                   1624: }
                   1625: 
                   1626: #if GREEKFIX
                   1627: /*
                   1628:  * ToggleGreek() must be called every time Alt+Enter is pressed.
                   1629:  * It toggles the "InGreek" flag and resets all others.
                   1630:  *
                   1631:  * ToGreek(unsigned *) returns FALSE if val is a dead key (Greek
                   1632:  * accent key) that must NOT be processed, TRUE otherwise.
                   1633: */     
                   1634: 
                   1635: static int     InGreek=0;
                   1636: static int     Tonos=0;
                   1637: static int     Dialytika=0;
                   1638: 
                   1639: static int     UpperG[26] = {
                   1640:   128,129,150,131,132,148,130,134,136,141,137,138,139,
                   1641:   140,142,143,58,144,145,146,135,151,145,149,147,133};
                   1642: 
                   1643: static int     LowerG[26] = {
                   1644:   152,153,175,155,156,173,154,158,160,165,161,162,163,
                   1645:   164,166,167,59,168,169,171,159,224,170,174,172,157};
                   1646: 
                   1647: static int     VoyelG[7] = {152,156,158,160,166,172,224};
                   1648: static int     TonedG[7] = {225,226,227,229,230,231,233};
                   1649: 
                   1650: void
                   1651: ToggleGreek()
                   1652: {
                   1653:        InGreek         ^= 1;
                   1654:        Tonos            = 0;
                   1655:        Dialytika        = 0;
                   1656:        return;
                   1657: }
                   1658: 
                   1659: int
                   1660: ToGreek(ip)
                   1661: unsigned       *ip;
                   1662: {
                   1663:        unsigned        i,j;
                   1664: 
                   1665:        i = *ip;
                   1666: 
                   1667:        /*      If Not Greek exit                       */
                   1668:        if(!InGreek)
                   1669:                return 1;
                   1670: 
                   1671:        /*      Capture dead keys                       */
                   1672:        if(i == ';') {
                   1673:                Tonos ^= 1;
                   1674:                return 0;
                   1675:        }       
                   1676: 
                   1677:        if(i == ':') {
                   1678:                Dialytika ^= 1;
                   1679:                return 0;
                   1680:        }       
                   1681: 
                   1682:        /*      Check if character translation needed   */
                   1683:        if ((i >= 'A') && (i <= 'Z'))
                   1684:                i = UpperG[i - 'A'];
                   1685:        else if ((i >= 'a') && (i <= 'z'))
                   1686:                i = LowerG[i - 'a'];
                   1687:        else
                   1688:                return 1;
                   1689: 
                   1690:        /*      Check if any accent has to be added     */
                   1691:        if (Tonos) {
                   1692:                Tonos = 0;
                   1693:                for(j = 0;j < 7;j++)
                   1694:                if (i == VoyelG[j]) {
                   1695:                        i = TonedG[j];
                   1696:                        break;
                   1697:                }
                   1698:        } else if (Dialytika) {
                   1699:                Dialytika=0;
                   1700:                if (i == 160)
                   1701:                        i = 228;
                   1702:                else if (i == 172)
                   1703:                        i = 232;
                   1704:        }
                   1705: 
                   1706:        /*      Exit point for translated characters    */
                   1707:        *(ip) = i;
                   1708:        return 1;
                   1709: }
                   1710: 
                   1711: #endif /* GREEKFIX */
                   1712: /* 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.