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