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