Annotation of researchv9/jerq/src/lib/sys/kbd.c, revision 1.1

1.1     ! root        1: #include <jerq.h>
        !             2: #include "queue.h"
        !             3: #include <kbd.h>
        !             4: #include <setup.h>
        !             5: 
        !             6: #define ESC    '\033'
        !             7: #define ESCB   0200
        !             8: #define DEL    '\177'
        !             9: #define K_KEY  0
        !            10: #define K_CHAR 1
        !            11: 
        !            12: /*
        !            13:  * Note that the keypad keys send what they say.
        !            14:  * the arrows send 'escape [' followed by A, B, C, D, H, except for HOME DOWN,
        !            15:  * which sends (ugh) esc [ 70;0H.  Clear sends esc[0J,
        !            16:  * Break, disconnect, and the pf keys send codes 0x80 through 0x89 respectively.
        !            17:  * If you want to tell the keypad numbers from the real ones, work in raw.
        !            18:  * The keytab table has been drastically extended for the TTYKBD and
        !            19:  * a binary search is now used. Why could'nt they generate sane codes!!
        !            20:  * WARNING, the keytab entries must be sorted into ascending order!
        !            21:  * For any ordinary "key", char c is sent.  The arrow keys or 0x80 with
        !            22:  * the ascii letter needed to send, except for HOME DOWN.  HOME DOWN
        !            23:  * and Clear are done by 0x8a and 0x8b, respectively, and break,
        !            24:  * disconnect and pfkeys are entered as shown above.
        !            25:  */
        !            26: 
        !            27: unsigned char keytab[][2] = {
        !            28:        0x8f, 0x81,             /* shifted key 42, discon  */
        !            29:        0x90, ESCB | 'B',       /* shifted key 109, down arrow */
        !            30:        0x91, ESCB | 'H',       /* shifted key 97, left-up arrow */
        !            31:        0x92, ESCB | 'A',       /* shifted key 98, up arrow */
        !            32:        0x93, ESCB | 0xa,       /* shifted key 99, home down arrow */
        !            33:        0x94, '4',              /* shifted key 79, 4 */
        !            34:        0x95, '5',      /* shifted key 80, 5 */
        !            35:        0x96, '6',      /* shifted key 81, 6 */
        !            36:        0x97, '7',      /* shifted key 60, 7 */
        !            37:        0x98, '8',      /* shifted key 61, 8 */
        !            38:        0x99, '9',      /* shifted key 62, 9 */
        !            39:        0x9a, ESCB | 'D',               /* shifted key 108, left arrow */
        !            40:        0x9b, ESCB | 'C',               /* shifted key 110, right arrow */
        !            41:        0xaf, 0x80,     /* unshifted key 42, break */
        !            42:        0xb0, '\0',     /* control key 35, ignored */
        !            43:        0xb1, '\0',     /* control key 26, ignored */
        !            44:        0xb3, '\0',     /* control key 28, ignored */
        !            45:        0xb4, '\0',     /* control key 29, ignored */
        !            46:        0xb5, '\0',     /* control key 30, ignored */
        !            47:        0xb6, '\012',   /* unshifted key 96, line-feed */
        !            48:        0xb7, '\0',     /* control key 32, ignored */
        !            49:        0xb8, '\0',     /* control key 33, ignored */
        !            50:        0xb9, '\0',     /* control key 34, ignored */
        !            51:        0xba, '\0',     /* control key 27, ignored */
        !            52:        0xbb, '\0',     /* control key 75, ignored */
        !            53:        0xbc, '\0',     /* control key 31, ignored */
        !            54:        0xbd, '\0',     /* control key 37, ignored */
        !            55:        0xbe, '\0',     /* control key 59, ignored */
        !            56:        0xbf, '\0',     /* control key 36, ignored */
        !            57:        0xc0, ESCB | 'H',       /* unshifted key 97, left-up arrow */
        !            58:        0xc1, ESCB | 'A',       /* unshifted key 98, up arrow */
        !            59:        0xc2, ESCB | 'B',       /* unshifted key 109, down arrow */
        !            60:        0xc3, ESCB | 'C',       /* unshifted key 110, right arrow */
        !            61:        0xc4, ESCB | 'D',       /* unshifted key 108, left arrow */
        !            62:        0xc6, ESCB | 0xa,       /* unshifted key 99, home down arrow */
        !            63:        0xc7, '\r',             /* shifted key 77, return */
        !            64:        0xc8, ESCB | 2,         /* shifted key 3, f1 */
        !            65:        0xc9, ESCB | 3,         /* shifted key 4, f2 */
        !            66:        0xca, ESCB | 4,         /* shifted key 5, f3 */
        !            67:        0xcb, ESCB | 5,         /* shifted key 8, f4 */
        !            68:        0xcc, ESCB | 6,         /* shifted key 9, f5 */
        !            69:        0xcd, ESCB | 7,         /* shifted key 12, f6 */
        !            70:        0xce, ESCB | 8,         /* shifted key 13, f7 */
        !            71:        0xcf, ESCB | 9,         /* shifted key 14, f8 */
        !            72:        0xd0, '\t',     /* unshifted key 45, tab */
        !            73:        0xd1, '\b',     /* shifted key 38, bs */
        !            74:        0xd2, '7',      /* unshifted key 60, 7 */
        !            75:        0xd3, '4',      /* unshifted key 79, 4 */
        !            76:        0xd4, '8',      /* unshifted key 61, 8 */
        !            77:        0xd5, '5',      /* unshifted key 80, 5 */
        !            78:        0xd6, '9',      /* unshifted key 62, 9 */
        !            79:        0xd7, '6',      /* unshifted key 81, 6 */
        !            80:        0xde, DEL,      /* shifted key 39, del */
        !            81:        0xe2, '\0',     /* control key 76, */
        !            82:        0xe3, ESC,      /* unshifted key 25, esc */
        !            83:        0xe5, ESCB | 0xb,       /* unshifted key 40, clr */
        !            84:        0xe7, '\r',     /* unshifted key 77, return */
        !            85:        0xe8, ESCB | 2,         /* unshifted key 3, f1 */
        !            86:        0xe9, ESCB | 3,         /* unshifted key 4, f2 */
        !            87:        0xea, ESCB | 4,         /* unshifted key 5, f3 */
        !            88:        0xeb, ESCB | 5,         /* unshifted key 8, f4 */
        !            89:        0xec, ESCB | 6,         /* unshifted key 9, f5 */
        !            90:        0xed, ESCB | 7,         /* unshifted key 12, f6 */
        !            91:        0xee, ESCB | 8,         /* unshifted key 13, f7 */
        !            92:        0xef, ESCB | 9,         /* unshifted key 14, f8 */
        !            93:        0xf0, '\t',     /* shifted key 45, tab */
        !            94:        0xf1, '\b',     /* unshifted key 38, bs */
        !            95:        0xf2, '\0',     /* shifted key 107, num-lock */
        !            96:        0xf3, ESC,      /* shifted key 25, esc */
        !            97:        0xf5, ESCB | 0xc,       /* shifted key 40, local clear functin */
        !            98:        0xf6, '\n',     /* shifted key 96, line-feed */
        !            99:        0xfe, DEL,      /* unshifted key 39, del */
        !           100: };
        !           101: 
        !           102: 
        !           103: int    kbdrepeat, rptcount, kbdstatus, dispstatus;
        !           104: 
        !           105:        /* lookup table for translating when keyboard uses numeric lock */
        !           106: unsigned char  numlocktab[7] = {'1','2','0','.','-',0xc5,'3'};
        !           107: 
        !           108: kbdchar()
        !           109: {
        !           110:        return qgetc(&KBDQUEUE);
        !           111: }
        !           112: 
        !           113: 
        !           114: kbdinit()
        !           115: {
        !           116:        /* init the keyboard */
        !           117:        DUART->b_cmnd = RESET_RECV | DIS_TX | DIS_RX;
        !           118:        DUART->b_cmnd = RESET_TRANS;
        !           119:        DUART->b_cmnd = RESET_ERR;
        !           120:        DUART->b_cmnd = RESET_MR;
        !           121:        DUART->mr1_2b = CHAR_ERR | PAR_ENB | EVN_PAR | CBITS8;
        !           122:        DUART->mr1_2b = NRML_MOD | ONEP000SB;
        !           123:        DUART->b_sr_csr  = BD4800BPS;
        !           124:        DUART->b_cmnd = RESET_MR | ENB_TX | ENB_RX;
        !           125:        DUART->scc_ropbc = 0x08; /* set output pins for kbd tx port*/
        !           126:        /* turn chirps on/off depending on BRAM */
        !           127: 
        !           128:        if (VALKEYTONE)
        !           129:                kbdstatus = 0;  /* no chirp */
        !           130:        else
        !           131:                kbdstatus = TTY_CHIRP;  /* chirp, chirp */
        !           132:        DUART->b_data = kbdstatus | 0x02; /* request status */
        !           133: }
        !           134: 
        !           135: auto2()
        !           136: {
        !           137:        register i;
        !           138:        register start, end;
        !           139:        Point   setupcur;
        !           140:        char    s;
        !           141:        char    c;
        !           142:        extern int blocked, ublocked;
        !           143: 
        !           144:        /* don't actually set the repeat bit until the character after the control code */
        !           145:        
        !           146:        s = DUART->b_sr_csr;
        !           147:        c = DUART->b_data;
        !           148: 
        !           149:        if (s & (FRM_ERR | OVR_RUN)) 
        !           150:                return; /* framing error or overrun error */
        !           151: 
        !           152:        if (s & PAR_ERR) {
        !           153:                /* parity error indicates this is a control word */
        !           154:                /* see what state caps lock is in       */
        !           155:                checkbram();
        !           156:                VALCAPS = (c & 0x4) ? 0 : 1; /* set the caps lock flag */
        !           157:                caps_msg();
        !           158:                setbram();      /* must adjust checksum */
        !           159:                if (c & 0x10) {
        !           160:                        /* turn repeat off */
        !           161:                        kbdrepeat = 0;
        !           162:                        rptcount = 0;
        !           163:                }
        !           164:                else { /* turn repeat on, the next character is to be repeated */
        !           165:                        kbdrepeat = RPTON;
        !           166:                }
        !           167:                return;
        !           168:        }
        !           169: 
        !           170:        rptcount = 0;   /* new charcter so restart repeat timer */
        !           171:        if (c & 0x80) {
        !           172:                switch (c & 0xff) {
        !           173:                case 0xb2:      /* numeric lock toggle */
        !           174:                case 0xf2:
        !           175:                        if(kbdrepeat & RPTON) {
        !           176:                                kbdrepeat = 0; /* don't want to repeat */
        !           177:                                return;
        !           178:                        }
        !           179:                        checkbram();
        !           180:                        VALNUM = 1 - VALNUM;
        !           181:                        setbram();
        !           182:                        num_msg();
        !           183:                        return;
        !           184:                case 0x8e:      /* un/shited key 41, selftest */
        !           185:                        test32(1);
        !           186:                        asm("  JMP reboot");
        !           187:                case 0xae:      /* setup */
        !           188:                        if(kbdrepeat & RPTON) {
        !           189:                                kbdrepeat = 0; /* don't want to repeat */
        !           190:                                return;
        !           191:                        }
        !           192:                        if(!ublocked && !blocked && !VALDWNLDFLAG)
        !           193:                                sendchar(0x13);         /* ^S */
        !           194:                        setupdisplay();
        !           195:                        if(!ublocked && !blocked && !VALDWNLDFLAG)
        !           196:                                sendchar(0x11);         /* ^Q */
        !           197:                        return;
        !           198:                }
        !           199:                if ((VALNUM) && (c >= 0xc0) && (c <= 0xc6)) {
        !           200:                                /* what fun: software lookup of numeric */
        !           201:                                /* locked values... why burden the hardware */
        !           202:                        c = numlocktab[c - 0xc0];
        !           203:                        qputc(&KBDQUEUE, (int)c);
        !           204:                        if((kbdrepeat & RPTMASK) == RPTON) {
        !           205:                                kbdrepeat = RPTHAVECHR | RPTON;
        !           206:                                kbdrepeat += (c & 0xff);
        !           207:                        }
        !           208:                        return;
        !           209:                }
        !           210: 
        !           211:                i = keytabsearch(c);
        !           212:                /*
        !           213:  *     here either keytab[i][K_KEY] == c, or c is not in the table
        !           214:  *     If c is not in the table, there is an error somewhere, so ring the bell
        !           215:  */
        !           216:                if (c == keytab[i][K_KEY]) {
        !           217:                        if(((c = (keytab[i][K_CHAR]) & 0xff) >= 0x80) && (c <= 0x89)) /* pfkey, break, disconnect, clear */
        !           218:                        {
        !           219:                                if(kbdrepeat & RPTON) {
        !           220:                                        kbdrepeat = 0; /* don't want to repeat */
        !           221:                                        return;
        !           222:                                }
        !           223:                                qputc( &KBDQUEUE, c );
        !           224:                                return;
        !           225:                        }
        !           226:                        kchkchar(c);
        !           227:                        if ((kbdrepeat & RPTMASK) == RPTON) {
        !           228:                                /* this is it! */
        !           229:                                kbdrepeat = RPTHAVECHR | RPTON | RPTLOOKUP;
        !           230:                                kbdrepeat += i;
        !           231:                        }
        !           232:                }
        !           233:                else {
        !           234:                        ringbell();
        !           235:                }
        !           236:        }
        !           237:        else {
        !           238:                qputc(&KBDQUEUE, (int)c);
        !           239:                if((kbdrepeat & RPTMASK) == RPTON) {
        !           240:                        kbdrepeat = RPTHAVECHR | RPTON;
        !           241:                        kbdrepeat += (c & 0xff);
        !           242:                }
        !           243:        }
        !           244: }
        !           245: 
        !           246: 
        !           247: 
        !           248: kchkchar(c)
        !           249: register char c;
        !           250: {
        !           251:        switch (c & 0xff) {
        !           252:        case 0x8a:      /* HOME DOWN    */
        !           253:                qputstr( &KBDQUEUE, "\033[70;1H");
        !           254:                break;
        !           255:        case 0x8b:      /* CLEAR */
        !           256:                if(kbdrepeat & RPTON) { /* turn off repeat */
        !           257:                        kbdrepeat = 0;
        !           258:                        return;
        !           259:                }
        !           260:                qputstr( &KBDQUEUE, "\033[2J");
        !           261:                break;
        !           262:        case 0x8c:      /* local clear function */
        !           263:                if(kbdrepeat & RPTON) {
        !           264:                        kbdrepeat = 0;
        !           265:                        return;
        !           266:                }
        !           267:                else
        !           268:                        qputc(&KBDQUEUE, c);
        !           269:                break;
        !           270:        case 0x80 | 'A':
        !           271:        case 0x80 | 'B':
        !           272:        case 0x80 | 'C':
        !           273:        case 0x80 | 'D':
        !           274:        case 0x80 | 'H':
        !           275:                qputstr( &KBDQUEUE, "\033[");
        !           276:                qputc( &KBDQUEUE, c & 0x7f);
        !           277:                break;
        !           278:        default:
        !           279:                if (c != '\0')
        !           280:                        qputc(&KBDQUEUE, (int)c);
        !           281:        }
        !           282: }
        !           283: 
        !           284: 
        !           285: kbdrpt()
        !           286: {
        !           287:        char    c;
        !           288: 
        !           289:        if (kbdrepeat & RPTLOOKUP) {
        !           290:                if ((c = keytab[kbdrepeat & 0xff][K_CHAR]) & 0x80) {
        !           291:                        kchkchar(c);
        !           292:                }
        !           293:                else if (c != '\0') {
        !           294:                        qputc(&KBDQUEUE, (int)c);
        !           295:                }
        !           296:        }
        !           297:        else {
        !           298:                qputc(&KBDQUEUE, kbdrepeat & 0xff);
        !           299:        }
        !           300: }
        !           301: 
        !           302: 
        !           303: 
        !           304: kgetc()
        !           305: {
        !           306:        register int    c;
        !           307:        register char   s;
        !           308:        register start, end, i;
        !           309: 
        !           310:        if(KBDQUEUE.c_cc > 0)
        !           311:                return(qgetc(&KBDQUEUE));
        !           312: 
        !           313:        while ((s = (DUART->b_sr_csr & (RCV_RDY | FRM_ERR | PAR_ERR | OVR_RUN | RCVD_BRK))) == 0)
        !           314:                aciapaws();             /* so we don't overload stupid part */
        !           315: 
        !           316:        if (!(s & RCV_RDY))
        !           317:                return(-1);
        !           318:        c = DUART->b_data;
        !           319:        if ((s & (FRM_ERR | PAR_ERR | OVR_RUN | RCVD_BRK)) == 0) /* just a char */
        !           320:        {
        !           321:                if(kbdrepeat & RPTON) {
        !           322:                        kbdrepeat = 0;  /* turn off repeat */
        !           323:                        return(-1);
        !           324:                }
        !           325:                if (c & 0x80) {
        !           326:                        switch (c & 0xff) {
        !           327:                        case 0x8e:      /* un/shited key 41, selftest */
        !           328:                                test32(1);
        !           329:                        case 0x8f:      /* shift break (disconnect) reboot the terminal */
        !           330:                                sendchar(0x11); /* cntl-Q       */
        !           331:                                asm("  JMP  reboot");
        !           332:                        case 0xae:      /* setup */
        !           333:                        case 0xc3:      /* right-arrow */
        !           334:                        case 0xc4:      /* left-arrow */
        !           335:                                return(c);
        !           336:                        case 0xb2:
        !           337:                        case 0xf2:      /* num lock key */
        !           338:                                VALNUM= 1 - VALNUM;
        !           339:                                setbram();
        !           340:                                num_setup();
        !           341:                                return(-1);
        !           342:                        }
        !           343:                        i = keytabsearch(c);
        !           344:                        /*
        !           345:         *      here either keytab[i][K_KEY] == c, or c is not in the table
        !           346:         *      If c is not in the table, there is an error somewhere, so ring the bell
        !           347:         */
        !           348:                        if (c == keytab[i][K_KEY]) {
        !           349:                                if (((c = keytab[i][K_CHAR]) & 0xff) <= 0x89 )  /* pfkey, break, disconnect */
        !           350:                                        return(c);
        !           351:                                kchkchar(c);
        !           352:                                return(-1);
        !           353:                        }
        !           354:                }
        !           355:                else
        !           356:                        return(c);
        !           357:        }
        !           358:        else if ((s & PAR_ERR) && (s & RCV_RDY))
        !           359:        {
        !           360:                VALCAPS = (c & 0x4) ? 0 : 1; /* set the caps lock flag */
        !           361:                cap_setup();
        !           362:                setbram();      /* fix checksum */
        !           363:                if(c & 0x10) {
        !           364:                        /* not repeating anything */
        !           365:                        kbdrepeat = 0;
        !           366:                        rptcount = 0;
        !           367:                }
        !           368:                else {
        !           369:                        /*
        !           370:                        * the keyboard will send us a character to repeat
        !           371:                        * since we dont repeat in setup, throw the next
        !           372:                        * character away.
        !           373:                        */
        !           374:                        kbdrepeat = RPTON;
        !           375:                }
        !           376:        }
        !           377:        return(-1);
        !           378: }
        !           379: 
        !           380: keytabsearch(c)                /* search keytab[] for char c */
        !           381: unsigned char c;
        !           382: {
        !           383:        register int start, end, i;
        !           384: /*
        !           385:  *     Assume start, end and i are indexes into keytab,
        !           386:  *     an array of two element structures. The elements are:
        !           387:  *             keytab[][2], the two elements are:
        !           388:  *                     char key;
        !           389:  *                     char c; /* the char to send, 0 - not sent
        !           390:  *             }
        !           391:  */
        !           392: 
        !           393:                start = 0;
        !           394:                end = sizeof(keytab) / sizeof(keytab[0]);
        !           395:                for (i = (start + end) / 2; 
        !           396:                    (keytab[i][K_KEY] != c) && (start <= end); 
        !           397:                    i = (start + end) / 2)
        !           398:                        if (c > keytab[i][K_KEY])
        !           399:                                start = i + 1;
        !           400:                        else
        !           401:                                end = i - 1;
        !           402: 
        !           403:        return (i);
        !           404:                        /*
        !           405:         *      here either keytab[i][K_KEY] == c, or c is not in the table
        !           406:         *      If c is not in the table, there is an error somewhere, so ring the bell
        !           407:         *      (bell gets rung by caller)
        !           408:         */
        !           409:  }

unix.superglobalmegacorp.com

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