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