|
|
1.1 root 1: /*
2: * io.386/kb.c
3: *
4: * non virtual terminal, nonloadable keyboard driver
5: *
6: * Revised: Fri Jul 30 08:08:03 1993 CDT
7: */
8:
9: /*
10: * Functions in this module:
11: * isload() isuload() isopen() initkeys()
12: * isclose() isread() kbstate() isioctl()
13: * isfunction() ispoll() isrint() isspecial()
14: * ismmfunc() isin() isbatch() updleds()
15: * kbunscroll()
16: */
17:
18: /**************************Included Files*****************************/
19:
20: #include <sys/coherent.h>
21: #include <sys/con.h>
22: #include <sys/devices.h>
23: #include <sys/errno.h>
24: #include <sys/kb.h>
25: #include <sys/stat.h>
26: #include <sys/tty.h>
27: #include <signal.h>
28: #include <sys/sched.h>
29: #include <sys/silo.h>
30:
31: /****************************Hardware Defines*************************/
32:
33: #define SPC 0376 /* Special encoding */
34: #define XXX 0377 /* Non-character */
35: #define KBDATA 0x60 /* Keyboard data */
36: #define KBCTRL 0x61 /* Keyboard control */
37: #define KBFLAG 0x80 /* Keyboard reset flag */
38: #define LEDCMD 0xED /* status indicator command */
39: #define KBACK 0xFA /* status indicator acknowledge */
40: #define EXTENDED0 0xE0 /* extended key seq initiator */
41: #define EXTENDED1 0xE1 /* extended key seq initiator */
42:
43: #define KEYUP 0x80 /* Key up change */
44: #define KEYSC 0x7F /* Key scan code mask */
45: #define LSHIFT 0x2A-1 /* Left shift key */
46: #define LSHIFTA 0x2B-1 /* Alternate left-shift key */
47: #define RSHIFT 0x36-1 /* Right shift key */
48: #define KB_CTRL_KEY 0x1D-1 /* Control key */
49:
50: #define KB_ALT_KEY 0x38-1 /* Alt key or ALT GR */
51: #define CAPLOCK 0x3A-1 /* Caps lock key */
52: #define NUMLOCK 0x45-1 /* Numeric lock key */
53: #define DELETE 0x53-1 /* Del, as in CTRL-ALT-DEL */
54: #define BACKSP 0x0E-1 /* Back space */
55: #define SCRLOCK 0x46-1 /* Scroll lock */
56:
57: /* Shift flags */
58: #define SRS 0x01 /* Right shift key on */
59: #define SLS 0x02 /* Left shift key on */
60: #define CTS 0x04 /* Ctrl key on */
61: #define ALS 0x08 /* Alt key on */
62: #define CPLS 0x10 /* Caps lock on */
63: #define NMLS 0x20 /* Num lock on */
64: #define AKPS 0x40 /* Alternate keypad shift */
65: #define SHFT 0x80 /* Shift key flag */
66: #define AGS 0x100 /* Alt Graphics on */
67:
68: /* Function key information */
69: #define NFKEY 50 /* Number of settable functions */
70: #define NFCHAR 150 /* Number of characters settable */
71: #define NFBUF (NFKEY*2+NFCHAR+1) /* Size of buffer */
72:
73: /****************************** Data Defines ****************************/
74:
75: #define ESCAPE_CHAR '\x1B'
76: #define ESCAPE_STRING "\x1B'
77: #define HEXFF_STRING "\xFF"
78: #define DELETE_STRING "\x7F"
79:
80: #define SS0 0 /* No shift */
81: #define SS1 (SLS|SRS|CTS) /* Shift, Ctrl */
82: #define SES (SLS|SRS) /* Shift */
83: #define LET (SLS|SRS|CPLS|CTS) /* Shift, Caps, Ctrl */
84: #define KEY (SLS|SRS|NMLS|AKPS) /* Shift, Num, Alt keypad */
85:
86: /*************************** X Stuff *************************************/
87:
88: /*
89: * special struct for the KDMAPDISP call
90: */
91:
92: #define KDMAPDISP (('K' << 8) | 2) /* map display into user space */
93: #define KDSKBMODE (('K' << 8) | 6) /* turn scan code xlate on/off */
94: #define KDMEMDISP (('K' << 8) | 7) /* dump byte of virt/phys mem */
95: #define KDENABIO (('K' << 8) | 60) /* enable IO */
96: #define KIOCSOUND (('K' << 8) | 63) /* start sound generation */
97: #define KDSETLED (('K' << 8) | 66) /* set leds */
98:
99: #define TIMER_CTL 0x43 /* Timer control */
100: #define TIMER_CNT 0x42 /* Timer counter */
101: #define SPEAKER_CTL 0x61 /* Speaker control */
102:
103: struct kd_memloc {
104: char *vaddr; /* virtual address to map to */
105: char *physaddr; /* physical address to map to */
106: long length; /* size in bytes to map */
107: long ioflg; /* enable I/O addresses if non-zero */
108: };
109:
110: /************************** Tables *****************************/
111:
112: /*
113: * Default function key strings (terminated by -1 [\377])
114: */
115: static char *deffuncs[] = {
116: /* Normal function keys */
117: ESCAPE_STRING "[M" HEXFF_STRING, /* F1 */
118: ESCAPE_STRING "[N" HEXFF_STRING, /* F2 */
119: ESCAPE_STRING "[O" HEXFF_STRING, /* F3 */
120: ESCAPE_STRING "[P" HEXFF_STRING, /* F4 */
121: ESCAPE_STRING "[Q" HEXFF_STRING, /* F5 */
122: ESCAPE_STRING "[R" HEXFF_STRING, /* F6 */
123: ESCAPE_STRING "[S" HEXFF_STRING, /* F7 */
124: ESCAPE_STRING "[T" HEXFF_STRING, /* F8 */
125: ESCAPE_STRING "[U" HEXFF_STRING, /* F9 */
126: ESCAPE_STRING "[V" HEXFF_STRING, /* F10 - historical value */
127:
128: /* Shifted function keys - no f11, f12 on 83-key keyboard */
129: ESCAPE_STRING "[Y" HEXFF_STRING, /* sF1 */
130: ESCAPE_STRING "[Z" HEXFF_STRING, /* sF2 */
131: ESCAPE_STRING "[a" HEXFF_STRING, /* sF3 */
132: ESCAPE_STRING "[b" HEXFF_STRING, /* sF4 */
133: ESCAPE_STRING "[c" HEXFF_STRING, /* sF5 */
134: ESCAPE_STRING "[d" HEXFF_STRING, /* sF6 */
135: ESCAPE_STRING "[e" HEXFF_STRING, /* sF7 */
136: ESCAPE_STRING "[f" HEXFF_STRING, /* sF8 */
137: ESCAPE_STRING "[g" HEXFF_STRING, /* sF9 */
138: ESCAPE_STRING "[h" HEXFF_STRING, /* sF10 */
139:
140: /* Ctrl-ed function keys */
141: ESCAPE_STRING "[k" HEXFF_STRING, /* cF1 */
142: ESCAPE_STRING "[l" HEXFF_STRING, /* cF2 */
143: ESCAPE_STRING "[m" HEXFF_STRING, /* cF3 */
144: ESCAPE_STRING "[n" HEXFF_STRING, /* cF4 */
145: ESCAPE_STRING "[o" HEXFF_STRING, /* cF5 */
146: ESCAPE_STRING "[p" HEXFF_STRING, /* cF6 */
147: ESCAPE_STRING "[q" HEXFF_STRING, /* cF7 */
148: ESCAPE_STRING "[r" HEXFF_STRING, /* cF8 */
149: ESCAPE_STRING "[s" HEXFF_STRING, /* cF9 */
150: ESCAPE_STRING "[t" HEXFF_STRING, /* cF10 */
151:
152: /* Ctrl-shifted function keys */
153: ESCAPE_STRING "[w" HEXFF_STRING, /* csF1 */
154: ESCAPE_STRING "[x" HEXFF_STRING, /* csF2 */
155: ESCAPE_STRING "[y" HEXFF_STRING, /* csF3 */
156: ESCAPE_STRING "[z" HEXFF_STRING, /* csF4 */
157: ESCAPE_STRING "[@" HEXFF_STRING, /* csF5 */
158: ESCAPE_STRING "[[" HEXFF_STRING, /* csF6 */
159: ESCAPE_STRING "[\\" HEXFF_STRING, /* csF7 */
160: ESCAPE_STRING "[]" HEXFF_STRING, /* csF8 */
161: ESCAPE_STRING "[^" HEXFF_STRING, /* csF9 */
162: ESCAPE_STRING "[_" HEXFF_STRING, /* csF10 */
163:
164: /* Alt keys -- use original 83-key settings since these
165: are not defined with a default for virtual terminals */
166: ESCAPE_STRING "[1y" HEXFF_STRING, /* aF1 */
167: ESCAPE_STRING "[2y" HEXFF_STRING, /* aF2 */
168: ESCAPE_STRING "[3y" HEXFF_STRING, /* aF3 */
169: ESCAPE_STRING "[4y" HEXFF_STRING, /* aF4 */
170: ESCAPE_STRING "[5y" HEXFF_STRING, /* aF5 */
171: ESCAPE_STRING "[6y" HEXFF_STRING, /* aF6 */
172: ESCAPE_STRING "[7y" HEXFF_STRING, /* aF7 */
173: ESCAPE_STRING "[8y" HEXFF_STRING, /* aF8 */
174: ESCAPE_STRING "[9y" HEXFF_STRING, /* aF9 */
175: ESCAPE_STRING "[0y" HEXFF_STRING /* aF10 */
176: };
177:
178: /*
179: * Handle special input sequences.
180: * The character passed is the key number.
181: *
182: * The keypad is translated by the following table,
183: * the first entry is the normal sequence, the second the shifted,
184: * and the third the alternate keypad sequence.
185: */
186: static char *keypad[][3] = {
187: { ESCAPE_STRING "[H", "7", ESCAPE_STRING "?w" }, /* 71 */
188: { ESCAPE_STRING "[A", "8", ESCAPE_STRING "?x" }, /* 72 */
189: { ESCAPE_STRING "[I", "9", ESCAPE_STRING "?y" }, /* 73 */
190: { ESCAPE_STRING "[D", "4", ESCAPE_STRING "?t" }, /* 75 */
191: { ESCAPE_STRING "7", "5", ESCAPE_STRING "?u" }, /* 76 */
192: { ESCAPE_STRING "[C", "6", ESCAPE_STRING "?v" }, /* 77 */
193: { ESCAPE_STRING "[F", "1", ESCAPE_STRING "?q" }, /* 79 */
194: { ESCAPE_STRING "[B", "2", ESCAPE_STRING "?r" }, /* 80 */
195: { ESCAPE_STRING "[G", "3", ESCAPE_STRING "?s" }, /* 81 */
196: { ESCAPE_STRING "[L", "0", ESCAPE_STRING "?p" }, /* 82 */
197: { DELETE_STRING , ".", ESCAPE_STRING "?n" } /* 83 */
198: };
199:
200: /*
201: * French Tables for converting key code to ASCII.
202: * lmaptab specifies unshifted conversion,
203: * umaptab specifies shifted conversion,
204: * smaptab specifies the shift states which are active.
205: * An entry of XXX says the key is dead.
206: * An entry of SPC requires further processing.
207: *
208: * Key codes:
209: * ESC .. <- == 1 .. 14
210: * -> .. \n == 15 .. 28
211: * CTRL .. ` == 29 .. 41
212: * ^Shift .. PrtSc == 42 .. 55
213: * ALT .. CapsLock == 56 .. 58
214: * F1 .. F10 == 59 .. 68
215: * NumLock .. Del == 69 .. 83
216: * ISO, F11, F12 == 86 .. 88
217: */
218: unsigned char fr_agmaptab[] ={ /* Alt Gr */
219: XXX, XXX, '~', '#', '{', '[', '|', /* 1 - 7 */
220: '`', '\\', '^', '@', ']', '}', XXX, XXX, /* 8 - 15 */
221: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 16 - 23 */
222: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 24 - 31 */
223: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 32 - 39 */
224: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 40 - 47 */
225: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 48 - 55 */
226: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 56 - 63 */
227: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 64 - 71 */
228: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 72 - 79 */
229: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 80 - 87 */
230: XXX /* 88 */
231: };
232:
233: static unsigned char fr_lmaptab[] ={
234: ESCAPE_CHAR, '&','\202', '"', '\'', '(', '-', /* 1 - 7 */
235: '\212','_','\207','\205',')', '=', '\b', '\t', /* 8 - 15 */
236: 'a', 'z', 'e', 'r', 't', 'y', 'u', 'i', /* 16 - 23 */
237: 'o', 'p','\260', '$', '\r', XXX, 'q', 's', /* 24 - 31 */
238: 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', /* 32 - 39 */
239: '\227','\375',XXX,'*', 'w', 'x', 'c', 'v', /* 40 - 47 */
240: 'b', 'n', ',', ';', ':', SPC, XXX, SPC, /* 48 - 55 */
241: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */
242: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */
243: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */
244: SPC, SPC, SPC, SPC, XXX, XXX, '<', XXX, /* 80 - 87 */
245: XXX /* 88 */
246: };
247:
248: static unsigned char fr_umaptab[] ={
249: ESCAPE_CHAR, '1', '2', '3', '4', '5', '6', /* 1 - 7 */
250: '7', '8', '9', '0','\370', '+', '\b', SPC, /* 8 - 15 */
251: 'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', /* 16 - 23 */
252: 'O', 'P','\261','\234','\r', XXX, 'Q', 'S', /* 24 - 31 */
253: 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', /* 32 - 39 */
254: '%','\300',XXX,'\346', 'W', 'X', 'C', 'V', /* 40 - 47 */
255: 'B', 'N', '?', '.', '/', SPC, XXX, SPC, /* 48 - 55 */
256: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */
257: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */
258: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */
259: SPC, SPC, SPC, SPC, XXX, XXX, '>', XXX, /* 80 - 87 */
260: XXX /* 88 */
261: };
262:
263: static unsigned char fr_smaptab[] ={
264: SS0, SES, SS1, SES, SES, SES, SS1, /* 1 - 7 */
265: SES, SES, SES, SES, SS1, SES, CTS, SES, /* 8 - 15 */
266: LET, LET, LET, LET, LET, LET, LET, LET, /* 16 - 23 */
267: LET, LET, SS1, SS1, CTS, SHFT, LET, LET, /* 24 - 31 */
268: LET, LET, LET, LET, LET, LET, LET, SES, /* 32 - 39 */
269: SES, SS1, SHFT, SS1, LET, LET, LET, LET, /* 40 - 47 */
270: LET, LET, LET, SES, SES, SES, SHFT, SES, /* 48 - 55 */
271: SHFT, SS1, SHFT, SS1, SS1, SS1, SS1, SS1, /* 56 - 63 */
272: SS1, SS1, SS1, SS1, SS1, SHFT, KEY, KEY, /* 64 - 71 */
273: KEY, KEY, SS0, KEY, KEY, KEY, SS0, KEY, /* 72 - 79 */
274: KEY, KEY, KEY, KEY, SS0, SS0, SES, SS0, /* 80 - 87 */
275: SS0
276: };
277: /*
278: * Tables for converting key code to ASCII.
279: * lmaptab specifies unshifted conversion,
280: * umaptab specifies shifted conversion,
281: * smaptab specifies the shift states which are active.
282: * An entry of XXX says the key is dead.
283: * An entry of SPC requires further processing.
284: *
285: * Key codes:
286: * ESC .. <- == 1 .. 14
287: * -> .. \n == 15 .. 28
288: * CTRL .. ` == 29 .. 41
289: * ^Shift .. PrtSc == 42 .. 55
290: * ALT .. CapsLock == 56 .. 58
291: * F1 .. F10 == 59 .. 68
292: * NumLock .. Del == 69 .. 83
293: */
294: static unsigned char us_lmaptab[] ={
295: ESCAPE_CHAR, '1', '2', '3', '4', '5', '6', /* 1 - 7 */
296: '7', '8', '9', '0', '-', '=', '\b', '\t', /* 8 - 15 */
297: 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* 16 - 23 */
298: 'o', 'p', '[', ']', '\r', XXX, 'a', 's', /* 24 - 31 */
299: 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 32 - 39 */
300: '\'', '`', XXX, '\\', 'z', 'x', 'c', 'v', /* 40 - 47 */
301: 'b', 'n', 'm', ',', '.', '/', XXX, '*', /* 48 - 55 */
302: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */
303: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */
304: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */
305: SPC, SPC, SPC, SPC /* 80 - 83 */
306: };
307:
308: static unsigned char us_umaptab[] ={
309: ESCAPE_CHAR, '!', '@', '#', '$', '%', '^', /* 1 - 7 */
310: '&', '*', '(', ')', '_', '+', '\b', SPC, /* 8 - 15 */
311: 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* 16 - 23 */
312: 'O', 'P', '{', '}', '\r', XXX, 'A', 'S', /* 24 - 31 */
313: 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 32 - 39 */
314: '"', '~', XXX, '|', 'Z', 'X', 'C', 'V', /* 40 - 47 */
315: 'B', 'N', 'M', '<', '>', '?', XXX, '*', /* 48 - 55 */
316: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */
317: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */
318: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */
319: SPC, SPC, SPC, SPC /* 80 - 83 */
320: };
321:
322: static unsigned char us_smaptab[] ={
323: SS0, SES, SS1, SES, SES, SES, SS1, /* 1 - 7 */
324: SES, SES, SES, SES, SS1, SES, CTS, SES, /* 8 - 15 */
325: LET, LET, LET, LET, LET, LET, LET, LET, /* 16 - 23 */
326: LET, LET, SS1, SS1, CTS, SHFT, LET, LET, /* 24 - 31 */
327: LET, LET, LET, LET, LET, LET, LET, SES, /* 32 - 39 */
328: SES, SS1, SHFT, SS1, LET, LET, LET, LET, /* 40 - 47 */
329: LET, LET, LET, SES, SES, SES, SHFT, SES, /* 48 - 55 */
330: SHFT, SS1, SHFT, SS1, SS1, SS1, SS1, SS1, /* 56 - 63 */
331: SS1, SS1, SS1, SS1, SS1, SHFT, KEY, KEY, /* 64 - 71 */
332: KEY, KEY, SS0, KEY, KEY, KEY, SS0, KEY, /* 72 - 79 */
333: KEY, KEY, KEY, KEY /* 80 - 83 */
334: };
335:
336: /*
337: * German Tables for converting key code to ASCII.
338: * lmaptab specifies unshifted conversion,
339: * umaptab specifies shifted conversion,
340: * smaptab specifies the shift states which are active.
341: * An entry of XXX says the key is dead.
342: * An entry of SPC requires further processing.
343: *
344: * Key codes:
345: * ESC .. <- == 1 .. 14
346: * -> .. \n == 15 .. 28
347: * CTRL .. ` == 29 .. 41
348: * ^Shift .. PrtSc == 42 .. 55
349: * ALT .. CapsLock == 56 .. 58
350: * F1 .. F10 == 59 .. 68
351: * NumLock .. Del == 69 .. 83
352: * ISO, F11, F12 == 86 .. 88
353: */
354: unsigned char de_agmaptab[] ={ /* Alt Gr */
355: XXX, XXX,'\375','\374',XXX, XXX, XXX, /* 1 - 7 */
356: '{', '[', ']', '}', '\\', XXX, XXX, XXX, /* 8 - 15 */
357: '@', XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 16 - 23 */
358: XXX, XXX, XXX, '~', XXX, XXX, XXX, XXX, /* 24 - 31 */
359: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 32 - 39 */
360: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 40 - 47 */
361: XXX, XXX,'\346', XXX, XXX, XXX, XXX, XXX, /* 48 - 55 */
362: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 56 - 63 */
363: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 64 - 71 */
364: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 72 - 79 */
365: XXX, XXX, XXX, XXX, XXX, XXX, '|', XXX, /* 80 - 87 */
366: XXX /* 88 */
367: };
368:
369: static unsigned char de_lmaptab[] ={
370: ESCAPE_CHAR, '1', '2', '3', '4', '5', '6', /* 1 - 7 */
371: '7', '8', '9', '0','\341','\'', '\b', '\t', /* 8 - 15 */
372: 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* 16 - 23 */
373: 'o', 'p','\201', '+', '\r', XXX, 'a', 's', /* 24 - 31 */
374: 'd', 'f', 'g', 'h', 'j', 'k', 'l','\224', /* 32 - 39 */
375: '\204','^', XXX, '#', 'y', 'x', 'c', 'v', /* 40 - 47 */
376: 'b', 'n', 'm', ',', '.', SPC, XXX, SPC, /* 48 - 55 */
377: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */
378: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */
379: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */
380: SPC, SPC, SPC, SPC, XXX, XXX, '<', XXX, /* 80 - 87 */
381: XXX /* 88 */
382: };
383:
384: static unsigned char de_umaptab[] ={
385: ESCAPE_CHAR, '!', '"','\025', '$', '%', '&', /* 1 - 7 */
386: '/', '(', ')', '=', '?', '`', '\b', SPC, /* 8 - 15 */
387: 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', /* 16 - 23 */
388: 'O', 'P','\232', '*', '\r', XXX, 'A', 'S', /* 24 - 31 */
389: 'D', 'F', 'G', 'H', 'J', 'K', 'L','\231', /* 32 - 39 */
390: '\216','\370',XXX,'\'', 'Y', 'X', 'C', 'V', /* 40 - 47 */
391: 'B', 'N', 'M', ';', ':', SPC, XXX, SPC, /* 48 - 55 */
392: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */
393: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */
394: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */
395: SPC, SPC, SPC, SPC, XXX, XXX, '>', XXX, /* 80 - 87 */
396: XXX /* 88 */
397: };
398:
399: static unsigned char de_smaptab[] ={
400: SS0, SES, SS1, SES, SES, SES, SS1, /* 1 - 7 */
401: SES, SES, SES, SES, SS1, SES, CTS, SES, /* 8 - 15 */
402: LET, LET, LET, LET, LET, LET, LET, LET, /* 16 - 23 */
403: LET, LET, SS1, SS1, CTS, SHFT, LET, LET, /* 24 - 31 */
404: LET, LET, LET, LET, LET, LET, LET, SES, /* 32 - 39 */
405: SES, SS1, SHFT, SS1, LET, LET, LET, LET, /* 40 - 47 */
406: LET, LET, LET, SES, SES, SES, SHFT, SES, /* 48 - 55 */
407: SHFT, SS1, SHFT, SS1, SS1, SS1, SS1, SS1, /* 56 - 63 */
408: SS1, SS1, SS1, SS1, SS1, SHFT, KEY, KEY, /* 64 - 71 */
409: KEY, KEY, SS0, KEY, KEY, KEY, SS0, KEY, /* 72 - 79 */
410: KEY, KEY, KEY, KEY, SS0, SS0, SES, SS0, /* 80 - 87 */
411: SS0
412: };
413:
414:
415:
416: /****************************** Functions *******************************/
417:
418: int isrint();
419: int istime();
420: void isbatch();
421: int mmstart();
422: int isopen();
423: int isclose();
424: int isread();
425: int mmwrite();
426: int isioctl();
427: void mmwatch();
428: int isload();
429: int isuload();
430: int ispoll();
431: int nulldev();
432: int nonedev();
433:
434: /************************** Configuration table *********************/
435:
436: CON kbcon ={
437: DFCHR|DFPOL, /* Flags */
438: KB_MAJOR, /* Major index */
439: isopen, /* Open */
440: isclose, /* Close */
441: nulldev, /* Block */
442: isread, /* Read */
443: mmwrite, /* Write */
444: isioctl, /* Ioctl */
445: nulldev, /* Powerfail */
446: mmwatch, /* Timeout */
447: isload, /* Load */
448: isuload, /* Unload */
449: ispoll /* Poll */
450: };
451:
452: /*********************** State variables / Patchables ***************/
453: int islock; /* Keyboard locked flag */
454: int isbusy; /* Raw input conversion busy */
455:
456: static short shift; /* Overall shift state */
457: static char scroll_lock; /* Scroll lock state */
458: static char lshift_state = LSHIFT; /* Left shift alternate state */
459: static char isfbuf[NFBUF]; /* Function key values */
460: static char *isfval[NFKEY]; /* Function key string pointers */
461: static int ledcmd; /* LED update command flag */
462: static int extended; /* extended key scan count */
463: static char extmode; /* use extended mode for this key */
464: static char ext0seen; /* 0xE0 prefix seen */
465: static int xlate = 1; /* scan code translation flag */
466:
467: /* Configurable variables - see ker/conf/console/Space.c */
468: extern int kb_lang;
469:
470: int isturbo = 0;
471: static int X11led;
472: static TIM tp;
473:
474: TTY istty = {
475: {0},
476: {0},
477: 0,
478: mmstart,
479: NULL,
480: 0,
481: 0
482: };
483: static silo_t in_silo;
484: static unsigned char *lmaptab, *umaptab, *smaptab, *agmaptab;
485:
486: /***************************** Code *****************************/
487:
488: /*
489: * Load entry point.
490: * Do reset the keyboard because it gets terribly munged
491: * if you type during the boot.
492: */
493: isload()
494: {
495: register short i;/* was: int i .. the loop below is hardly portable */
496:
497: /*
498: * Set up keyboard tables
499: */
500:
501: switch(kb_lang) {
502: case kb_lang_fr:
503: agmaptab = fr_agmaptab;
504: lmaptab = fr_lmaptab;
505: umaptab = fr_umaptab;
506: smaptab = fr_smaptab;
507: break;
508: case kb_lang_de:
509: agmaptab = de_agmaptab;
510: lmaptab = de_lmaptab;
511: umaptab = de_umaptab;
512: smaptab = de_smaptab;
513: break;
514: default:
515: agmaptab = 0;
516: lmaptab = us_lmaptab;
517: umaptab = us_umaptab;
518: smaptab = us_smaptab;
519: break;
520: } /* switch */
521:
522: /*
523: * Reset keyboard if NOT an XT turbo.
524: */
525: if ( ! isturbo ) {
526: outb(KBCTRL, 0x0C); /* Clock low */
527: for (i = 10582; --i >= 0; ); /* For 20ms */
528: outb(KBCTRL, 0xCC); /* Clock high */
529: for (i = 0; --i != 0; )
530: ;
531: i = inb(KBDATA);
532: outb(KBCTRL, 0xCC); /* Clear keyboard */
533: outb(KBCTRL, 0x4D); /* Enable keyboard */
534: }
535:
536: /*
537: * Enable mmwatch() invocation every second.
538: */
539: drvl[KB_MAJOR].d_time = 1;
540:
541: /*
542: * Seize keyboard interrupt.
543: */
544: setivec(1, isrint);
545:
546: /*
547: * Initialize video display.
548: */
549: mmstart( &istty );
550: }
551:
552: /*
553: * Unload entry point.
554: */
555: isuload()
556: {
557: clrivec(1);
558: }
559:
560:
561: /*
562: * Open routine.
563: */
564: isopen(dev, mode)
565: dev_t dev;
566: unsigned int mode;
567: {
568: register int s;
569:
570: if (minor(dev) != 0) {
571: u.u_error = ENXIO;
572: return;
573: }
574: if ((istty.t_flags&T_EXCL)!=0 && super()==0) {
575: u.u_error = ENODEV;
576: return;
577: }
578: ttsetgrp(&istty, dev, mode);
579:
580: s = sphi();
581: if (istty.t_open++ == 0)
582: { initkeys(); /* init function keys */
583: istty.t_flags = T_CARR; /* indicate "carrier" */
584: ttopen(&istty);
585: }
586: spl(s);
587: updleds(); /* update keyboard status LEDS */
588: }
589:
590: /* Init function keys */
591: initkeys()
592: { register int i;
593: register char *cp1, *cp2;
594:
595: for (i=0; i<NFKEY; i++)
596: isfval[i] = 0; /* clear function key buffer */
597: cp2 = isfbuf; /* pointer to key buffer */
598: for (i=0; i<NFKEY; i++)
599: { isfval[i] = cp2; /* save pointer to key string */
600: cp1 = deffuncs[i]; /* get init string pointer */
601: while ((*cp2++ = *cp1++) != -1) /* copy key data */
602: if (cp2 >= &isfbuf[NFBUF-3]) /* overflow? */
603: return;
604: }
605: }
606:
607: /*
608: * Close a tty.
609: */
610: isclose(dev)
611: {
612: register int s;
613:
614: s = sphi();
615: if (--istty.t_open == 0)
616: { s = sphi();
617: ttclose(&istty);
618: spl(s);
619: }
620: }
621:
622: /*
623: * Read routine.
624: */
625: isread(dev, iop)
626: dev_t dev;
627: IO *iop;
628: {
629: ttread(&istty, iop, 0);
630: if (istty.t_oq.cq_cc)
631: mmtime(&istty);
632: }
633:
634: /*
635: * Ioctl routine.
636: */
637: int
638: kbstate(action)
639: int action;
640: {
641: int i;
642: if (action == 1) {
643: timeout(&tp,20,kbstate,2);
644: outb(KBCTRL, 0xCC); /* Clock high */
645: }
646: if (action == 2) {
647: i = inb(KBDATA);
648: outb(KBCTRL, 0xCC); /* Clear keyboard */
649: outb(KBCTRL, 0x4D); /* Enable keyboard */
650: }
651: }
652:
653: isioctl(dev, com, vec)
654: dev_t dev;
655: struct sgttyb *vec;
656: {
657: register int s;
658:
659: switch(com) {
660: #define KDDEBUG 0
661: #if KDDEBUG
662: case KDMEMDISP:
663: {
664: struct kd_memloc* mem;
665: unsigned char ub, pb;
666: mem = vec;
667: pxcopy( mem->physaddr, &pb, 1, SEG_386_KD );
668: ub = getubd( mem->vaddr );
669: printf( "User's byte %x(%x), Physical byte %x, Addresses %x %x\n",
670: mem->ioflg, ub, pb, mem->vaddr, mem->physaddr );
671: goto ioc_done;;
672: }
673: #endif
674: case KDMAPDISP:
675: {
676: struct kd_memloc* mem;
677: mem = vec;
678: #if KDDEBUG
679: printf( "mapPhysUser(%x, %x, %x) = %d\n",
680: mem->vaddr, mem->physaddr, mem->length,
681: #endif
682: mapPhysUser(mem->vaddr, mem->physaddr, mem->length)
683: #if KDDEBUG
684: )
685: #endif
686: ;
687: }
688: case KDENABIO:
689: {
690: int i;
691: for (i = 0 ; i < 64 ; i++ )
692: iomapAnd(0,i);
693: goto ioc_done;;
694: }
695: case KIOCSOUND:
696: {
697: if (vec) {
698: outb(TIMER_CTL, 0xB6);
699: outb(TIMER_CNT, (int)vec&0xFF);
700: outb(TIMER_CNT, (int)vec>>8);
701: outb(SPEAKER_CTL, inb(SPEAKER_CTL) | 03); /* Turn speaker on */
702: }
703: else
704: outb(SPEAKER_CTL, inb(SPEAKER_CTL) & ~03 ); /* speaker off */
705: goto ioc_done;;
706: }
707: case KDSKBMODE:
708: {
709: outb(KBCTRL, 0x0C); /* Clock low */
710: timeout(&tp,3,kbstate,1); /* wait about 20-30ms */
711: xlate = (int)vec;
712: goto ioc_done;;
713: }
714: case KDSETLED:
715: {
716: X11led = (int)vec;
717: updleds();
718: goto ioc_done;;
719: }
720:
721: case TIOCSETF:
722: case TIOCGETF:
723: isfunction(com, (char *)vec);
724: goto ioc_done;;
725: case TIOCSHIFT: /* switch left-SHIFT and "\" */
726: lshift_state = LSHIFTA; /* alternate values */
727: lmaptab[41] = '\\';
728: lmaptab[42] = XXX;
729: umaptab[41] = '|';
730: umaptab[42] = XXX;
731: smaptab[41] = SS1;
732: smaptab[42] = SHFT;
733: goto ioc_done;;
734: case TIOCCSHIFT: /* normal (default) left-SHIFT and "\" */
735: lshift_state = LSHIFT; /* normal values */
736: lmaptab[41] = XXX;
737: lmaptab[42] = '\\';
738: umaptab[41] = XXX;
739: umaptab[42] = '|';
740: smaptab[41] = SHFT;
741: smaptab[42] = SS1;
742: goto ioc_done;;
743: }
744: s = sphi();
745: ttioctl(&istty, com, vec);
746: spl(s);
747:
748: ioc_done:
749: return;
750: }
751:
752: /*
753: * Set and receive the function keys.
754: */
755: isfunction(c, v)
756: int c;
757: char *v;
758: {
759: register char *cp;
760: register int i;
761:
762: if (c == TIOCGETF) {
763: for (cp = isfbuf; cp < &isfbuf[NFBUF]; cp++)
764: putubd(v++, *cp);
765: } else {
766: for (i=0; i<NFKEY; i++) /* zap current settings */
767: isfval[i] = 0;
768: cp = isfbuf; /* pointer to key buffer */
769: for (i=0; i<NFKEY; i++) {
770: isfval[i] = cp; /* save pointer to key string */
771: while ((*cp++ = getubd(v++)) != -1) /* copy key data */
772: if (cp >= &isfbuf[NFBUF-3]) /* overflow? */
773: return;
774: }
775: }
776: }
777:
778:
779: /*
780: * Poll routine.
781: */
782: ispoll( dev, ev, msec )
783: dev_t dev;
784: int ev;
785: int msec;
786: {
787: return ttpoll(&istty, ev, msec);
788: }
789:
790: /*
791: * Receive interrupt.
792: */
793: isrint()
794: {
795: register int c;
796: register int s;
797: register int r;
798: int savests;
799: int update_leds = 0;
800:
801: /*
802: * Schedule raw input handler if not already active.
803: */
804: if ( isbusy == 0 ) {
805: isbusy = 1;
806: defer( isbatch, &istty );
807: }
808:
809: /*
810: * Pull character from the data
811: * port. Pulse the KBFLAG in the control
812: * port to reset the data buffer.
813: */
814: r = inb(KBDATA) & 0xFF;
815: c = inb(KBCTRL);
816: outb(KBCTRL, c|KBFLAG);
817: outb(KBCTRL, c);
818: if (!xlate) {
819: if (ledcmd) {
820: ledcmd = 0;
821: if (r == KBACK) { /* output to status LEDS */
822: outb(KBDATA, X11led);
823: return;
824: }
825: }
826: isin(r);
827: return;
828: }
829:
830: #if KBDEBUG
831: printf("kbd: %d\n", r); /* print scan code/direction */
832: #endif
833: if (ledcmd) {
834: ledcmd = 0;
835: if (r == KBACK) { /* output to status LEDS */
836: c = scroll_lock & 1;
837: if (shift & NMLS)
838: c |= 2;
839: if (shift & CPLS)
840: c |= 4;
841: outb(KBDATA, c);
842: }
843: return;
844: }
845: if (extended > 0) { /* if multi-character seq, */
846: --extended; /* ... ignore this char */
847: return;
848: }
849: switch (r) {
850: case EXTENDED0: /* 0xE0 prefix found */
851: if(kb_lang == kb_lang_fr || kb_lang == kb_lang_de) {
852: ext0seen = 1;
853: return;
854: }
855: break;
856: case EXTENDED1: /* ignore extended sequences */
857: extended = 5;
858: return;
859: case 0xFF: /* Overrun */
860: return;
861: }
862:
863: if(kb_lang == kb_lang_fr || kb_lang == kb_lang_de) {
864: if (ext0seen) {
865: ext0seen = 0;
866: extmode = 1;
867: } else
868: extmode = 0;
869: }
870:
871: c = (r & KEYSC) - 1;
872: /*
873: * Check for reset.
874: */
875: if ((r&KEYUP) == 0 && c == DELETE && (shift&(CTS|ALS)) == (CTS|ALS))
876: boot();
877:
878: /*
879: * Track "shift" keys.
880: */
881: s = smaptab[c];
882: if (s&SHFT) {
883: if (r&KEYUP) { /* "shift" released */
884: if (c == RSHIFT)
885: shift &= ~SRS;
886: else if (c == lshift_state)
887: shift &= ~SLS;
888: else if (c == KB_CTRL_KEY)
889: shift &= ~CTS;
890: else if (c == KB_ALT_KEY) {
891: if(kb_lang == kb_lang_fr || kb_lang == kb_lang_de)
892: shift &= extmode ? ~AGS : ~ALS;
893: else
894: shift &= ~ALS;
895: }
896: } else { /* "shift" pressed */
897: if (c == lshift_state)
898: shift |= SLS;
899: else if (c == RSHIFT)
900: shift |= SRS;
901: else if (c == KB_CTRL_KEY)
902: shift |= CTS;
903: else if (c == KB_ALT_KEY) {
904: if(kb_lang == kb_lang_fr || kb_lang == kb_lang_de)
905: shift |= extmode ? AGS : ALS;
906: else
907: shift |= ALS;
908: }
909: else if (c == CAPLOCK) {
910: shift ^= CPLS; /* toggle cap lock */
911: updleds();
912: } else if (c == NUMLOCK) {
913: shift ^= NMLS; /* toggle num lock */
914: updleds();
915: }
916: }
917: return;
918: }
919:
920: /*
921: * No other key up codes of interest.
922: */
923: if (r&KEYUP)
924: return;
925:
926: /*
927: * If the tty is not open the character is
928: * just tossed away.
929: */
930: if (istty.t_open == 0)
931: return;
932:
933: /*
934: * Map character, based on the
935: * current state of the shift, control, alt graphics,
936: * meta (ALT) and lock flags.
937: */
938: if ((shift & AGS) && (kb_lang == kb_lang_fr || kb_lang == kb_lang_de)) /* Alt Graphics ? */
939: c = agmaptab[c];
940: else if (shift & CTS) {
941: if (s == CTS) /* Map Ctrl (BS | NL) */
942: c = (c == BACKSP) ? 0x7F : 0x0A;
943: else if (s==SS1 || s==LET) {
944: if((c = umaptab[c]) != SPC) /* Normal Ctrl map */
945: c &= 0x1F; /* Clear bits 5-6 */
946: } else
947: return; /* Ignore this char */
948: } else if (s &= shift) {
949: if (shift & SES) { /* if shift on */
950: if (s & (CPLS|NMLS)) /* if caps/num lock */
951: c = lmaptab[c]; /* use unshifted */
952: else
953: c = umaptab[c]; /* use shifted */
954: } else { /* if shift not on */
955: if (s & (CPLS|NMLS)) /* if caps/num lock */
956: c = umaptab[c]; /* use shifted */
957: else
958: c = lmaptab[c]; /* use unshifted */
959: }
960: } else
961: c = lmaptab[c]; /* use unshifted */
962:
963: /*
964: * Act on character.
965: */
966: if (c == XXX)
967: return; /* char to ignore */
968:
969: if (c != SPC) { /* not special char? */
970: if (shift & ALS) /* ALT (meta bit)? */
971: c |= 0x80; /* set meta */
972: isin(c); /* send the char */
973: } else
974: update_leds += isspecial(r); /* special chars */
975: if (update_leds) {
976: savests = sphi();
977: outb(KBDATA, LEDCMD);
978: ledcmd = 1;
979: spl(savests);
980: }
981: }
982:
983: isspecial(c)
984: int c;
985: {
986: register char *cp;
987: register int s;
988: int update_leds = 0;
989:
990: cp = 0;
991:
992: switch (c) {
993: case 15: /* cursor back tab */
994: cp = ESCAPE_STRING "[Z";
995: break;
996: case 53:
997: if(kb_lang == kb_lang_fr || kb_lang == kb_lang_de) {
998: if (extmode)
999: cp = "/";
1000: else
1001: if (shift & SES)
1002: cp = "\025";
1003: else
1004: cp = "!";
1005: }
1006: break;
1007: case 55: /* ignore PrtScr */
1008: if(kb_lang == kb_lang_fr || kb_lang == kb_lang_de) {
1009: if (!extmode)
1010: cp = "*";
1011: }
1012: break;
1013: case 59: case 60: case 61: case 62: case 63: /* Function keys */
1014: case 64: case 65: case 66: case 67: case 68:
1015: /* offset to function string */
1016: if ( shift & ALS )
1017: cp = isfval[c-19]; /* alt-Fx */
1018: else { if( (shift & (SES)) && (shift & CTS)) /*ctl-shift-Fx*/
1019: cp = isfval[c-29];
1020: else { if(shift & CTS) /* ctl-Fx */
1021: cp = isfval[c-39];
1022: else { if(shift & (SES)) /* shift-Fx */
1023: cp = isfval[c-49];
1024: else cp = isfval[c-59]; /* Fx */
1025: }}}
1026: break;
1027:
1028: case 70: /* Scroll Lock -- stop/start output */
1029: {
1030: static char cbuf[2];
1031:
1032: cp = &cbuf[0]; /* working buffer */
1033: if (!(istty.t_sgttyb.sg_flags&RAWIN)) { /* not if in RAW mode */
1034: ++update_leds;
1035: if (istty.t_flags & T_STOP) { /* output stopped? */
1036: cbuf[0] = istty.t_tchars.t_startc; /* start it */
1037: scroll_lock = 0;
1038: } else {
1039: cbuf[0] = istty.t_tchars.t_stopc; /* stop output */
1040: scroll_lock = 1;
1041: }
1042: }
1043: break;
1044: }
1045:
1046: case 79: /* 1/End */
1047: case 80: /* 2/DOWN */
1048: case 81: /* 3/PgDn */
1049: case 82: /* 0/Ins */
1050: case 83: /* ./Del */
1051: --c; /* adjust code */
1052: case 75: /* 4/LEFT */
1053: case 76: /* 5 */
1054: case 77: /* 6/RIGHT */
1055: --c; /* adjust code */
1056: case 71: /* 7/Home/Clear */
1057: case 72: /* 8/UP */
1058: case 73: /* 9/PgUp */
1059: s = 0; /* start off with normal keypad */
1060: if (shift & NMLS) /* num lock? */
1061: s = 1; /* set shift pad */
1062: if (shift & SES) /* shift? */
1063: s ^= 1; /* toggle shift pad */
1064: if (shift & AKPS) /* alternate pad? */
1065: s = 2; /* set alternate pad */
1066: if (extmode) /* not from keypad? */
1067: s = 0; /* force normal sequence */
1068: cp = keypad[c-71][s]; /* get keypad value */
1069: break;
1070: }
1071: if (cp) /* send string */
1072: while ((* cp != 0) && (* cp != -1))
1073: isin (* cp ++ & 0xFF);
1074: return update_leds;
1075: }
1076:
1077: /**
1078: *
1079: * void
1080: * ismmfunc( c ) -- process keyboard related output escape sequences
1081: * char c;
1082: */
1083: void
1084: ismmfunc(c)
1085: register int c;
1086: {
1087: switch (c) {
1088: case 't': /* Enter numlock */
1089: shift |= NMLS;
1090: updleds(); /* update LED status */
1091: break;
1092: case 'u': /* Leave numlock */
1093: shift &= ~NMLS;
1094: updleds(); /* update LED status */
1095: break;
1096: case '=': /* Enter alternate keypad */
1097: shift |= AKPS;
1098: break;
1099: case '>': /* Exit alternate keypad */
1100: shift &= ~AKPS;
1101: break;
1102: case 'c': /* Reset terminal */
1103: islock = 0;
1104: shift = 0;
1105: initkeys();
1106: updleds(); /* update LED status */
1107: break;
1108: }
1109: }
1110:
1111: /**
1112: *
1113: * void
1114: * isin( c ) -- append character to raw input silo
1115: * char c;
1116: */
1117: static
1118: isin( c )
1119: register int c;
1120: {
1121: int cache_it = 1;
1122: TTY * tp = &istty;
1123:
1124: /*
1125: * If using software incoming flow control, process and
1126: * discard t_stopc and t_startc.
1127: */
1128: if (_IS_IXON_MODE (tp)) {
1129: if (_IS_START_CHAR (tp, c) ||
1130: (_IS_IXANY_MODE (tp) && (tp->t_flags & T_STOP) != 0)) {
1131: tp->t_flags &= ~(T_STOP | T_XSTOP);
1132: ttstart(tp);
1133: cache_it = 0;
1134: } else if (_IS_STOP_CHAR (tp, c)) {
1135: if ((tp->t_flags&T_STOP) == 0)
1136: tp->t_flags |= (T_STOP | T_XSTOP);
1137: cache_it = 0;
1138: }
1139: }
1140:
1141: /*
1142: * Cache received character.
1143: */
1144: if (cache_it) {
1145: in_silo.si_buf[ in_silo.si_ix ] = c;
1146:
1147: if ( ++in_silo.si_ix >= sizeof(in_silo.si_buf) )
1148: in_silo.si_ix = 0;
1149: }
1150: }
1151:
1152: /**
1153: *
1154: * void
1155: * isbatch() -- raw input conversion routine
1156: *
1157: * Action: Enable the video display.
1158: * Canonize the raw input silo.
1159: *
1160: * Notes: isbatch() was scheduled as a deferred process by isrint().
1161: */
1162: static void
1163: isbatch( tp )
1164: register TTY * tp;
1165: {
1166: register int c;
1167: static int lastc;
1168:
1169: /*
1170: * Ensure video display is enabled.
1171: */
1172: mm_von();
1173:
1174: isbusy = 0;
1175:
1176: /*
1177: * Process all cached characters.
1178: */
1179: while ( in_silo.si_ix != in_silo.si_ox ) {
1180:
1181: /*
1182: * Get next cached char.
1183: */
1184: c = in_silo.si_buf[ in_silo.si_ox ];
1185:
1186: if ( in_silo.si_ox >= sizeof(in_silo.si_buf) - 1 )
1187: in_silo.si_ox = 0;
1188: else
1189: in_silo.si_ox++;
1190:
1191: if (islock == 0 || _IS_INTERRUPT_CHAR (tp, c) ||
1192: _IS_QUIT_CHAR (tp, c)) {
1193: ttin (tp, c);
1194: } else if (c == 'b' && lastc == ESCAPE_CHAR) {
1195: islock = 0;
1196: ttin (tp, lastc);
1197: ttin (tp, c);
1198: } else if (c == 'c' && lastc == ESCAPE_CHAR) {
1199: ttin (tp, lastc);
1200: ttin (tp, c);
1201: } else
1202: putchar ('\a');
1203:
1204: lastc = c;
1205: }
1206: }
1207:
1208: /*
1209: * update the keyboard status LEDS
1210: */
1211: updleds()
1212: {
1213: int s;
1214:
1215: s = sphi();
1216: outb(KBDATA, LEDCMD);
1217: ledcmd = 1;
1218: spl(s);
1219: }
1220:
1221: /*
1222: * unlock the scroll in case an interrupt character is received
1223: */
1224: kbunscroll()
1225: {
1226: scroll_lock = 0;
1227: updleds();
1228: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.