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