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