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