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