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