|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1991,1990,1989 Carnegie Mellon University
4: * All Rights Reserved.
5: *
6: * Permission to use, copy, modify and distribute this software and its
7: * documentation is hereby granted, provided that both the copyright
8: * notice and this permission notice appear in all copies of the
9: * software, derivative works or modified versions, and any portions
10: * thereof, and that both notices appear in supporting documentation.
11: *
12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15: *
16: * Carnegie Mellon requests users of this software to return to
17: *
18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
22: *
23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26: /*
27: * File: lk201.c
28: * Author: Alessandro Forin, Carnegie Mellon University
29: * Date: 9/90
30: *
31: * Routines for the LK201 Keyboard Driver
32: */
33:
34: #include <lk.h>
35: #if NLK > 0
36: #include <bm.h>
37:
38: #include <mach_kdb.h>
39:
40: #include <mach/std_types.h>
41: #include <device/device_types.h>
42: #include <machine/machspl.h> /* spl definitions */
43: #include <sys/ioctl.h>
44: #include <machine/machspl.h>
45: #include <chips/lk201.h>
46: #include <chips/serial_defs.h>
47: #include <chips/screen_defs.h>
48:
49:
50: /*
51: * Structures describing the keyboard status
52: */
53: typedef struct {
54: unsigned short kbd_flags;
55: unsigned short kbd_previous;
56: char kbd_gen_shift;
57: char kbd_ctrl;
58: char kbd_lock;
59: char kbd_meta;
60: char kbd_shift;
61: } lk201_kbd_state_t;
62:
63: #define mapLOCKtoCNTRL 0x1 /* flags */
64:
65: typedef struct {
66: char led_active;
67: char led_pattern;
68: char led_increasing;
69: char led_lights;
70: int led_interval;
71: int led_light_count;
72: } lk201_led_state_t;
73:
74:
75: /*
76: * Keyboard state
77: */
78:
79: struct lk201_softc {
80: lk201_kbd_state_t kbd;
81: lk201_led_state_t led;
82: int sl_unit;
83: } lk201_softc_data[NLK];
84:
85: typedef struct lk201_softc *lk201_softc_t;
86:
87: lk201_softc_t lk201_softc[NLK];
88:
89: /*
90: * Forward decls
91: */
92: io_return_t
93: lk201_translation(
94: int key,
95: char c,
96: int tabcode );
97:
98: int
99: lk201_input(
100: int unit,
101: unsigned short data);
102:
103:
104: /*
105: * Autoconf (sort-of)
106: */
107: lk201_probe(
108: int unit)
109: {
110: lk201_softc[unit] = &lk201_softc_data[unit];
111: return 1;
112: }
113:
114: void lk201_attach(
115: int unit,
116: int sl_unit)
117: {
118: lk201_softc[unit]->sl_unit = sl_unit;
119: lk201_selftest(unit);
120: }
121:
122: /*
123: * Keyboard initialization
124: */
125:
126: static unsigned char lk201_reset_string[] = {
127: LK_CMD_LEDS_ON, LK_PARAM_LED_MASK(0xf), /* show we are resetting */
128: LK_CMD_SET_DEFAULTS,
129: LK_CMD_MODE(LK_MODE_RPT_DOWN,1),
130: LK_CMD_MODE(LK_MODE_RPT_DOWN,2),
131: LK_CMD_MODE(LK_MODE_RPT_DOWN,3),
132: LK_CMD_MODE(LK_MODE_RPT_DOWN,4),
133: LK_CMD_MODE(LK_MODE_DOWN_UP,5),
134: LK_CMD_MODE(LK_MODE_DOWN_UP,6),
135: LK_CMD_MODE(LK_MODE_RPT_DOWN,7),
136: LK_CMD_MODE(LK_MODE_RPT_DOWN,8),
137: LK_CMD_MODE(LK_MODE_RPT_DOWN,9),
138: LK_CMD_MODE(LK_MODE_RPT_DOWN,10),
139: LK_CMD_MODE(LK_MODE_RPT_DOWN,11),
140: LK_CMD_MODE(LK_MODE_RPT_DOWN,12),
141: LK_CMD_MODE(LK_MODE_DOWN,13),
142: LK_CMD_MODE(LK_MODE_RPT_DOWN,14),
143: LK_CMD_ENB_RPT,
144: /* LK_CMD_ENB_KEYCLK, LK_PARAM_VOLUME(4), */
145: LK_CMD_DIS_KEYCLK,
146: LK_CMD_RESUME,
147: LK_CMD_ENB_BELL, LK_PARAM_VOLUME(4),
148: LK_CMD_LEDS_OFF, LK_PARAM_LED_MASK(0xf)
149: };
150:
151: void
152: lk201_reset(
153: int unit)
154: {
155: register int i, sl;
156: register spl_t s;
157: lk201_softc_t lk;
158:
159: lk = lk201_softc[unit];
160: sl = lk->sl_unit;
161: s = spltty();
162: for (i = 0; i < sizeof(lk201_reset_string); i++) {
163: (*console_putc)(sl,
164: SCREEN_LINE_KEYBOARD,
165: lk201_reset_string[i]);
166: delay(100);
167: }
168: /* zero any state associated with previous keypresses */
169: bzero(lk, sizeof(*lk));
170: lk->sl_unit = sl;
171: splx(s);
172: }
173:
174: lk201_selftest(
175: int unit)
176: {
177: int messg[4], sl;
178: spl_t s;
179:
180: sl = lk201_softc[unit]->sl_unit;
181: s = spltty();
182: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_REQ_ID);
183: delay(10000);/* arbitrary */
184: messg[0] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
185: messg[1] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
186: splx(s);
187:
188: printf("( lk201 id %x.%x", messg[0], messg[1]);
189:
190: s = spltty();
191: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_POWER_UP);
192:
193: /* cannot do this, waiting too long might cause receiver overruns */
194: /* delay(80000);/* spec says 70 msecs or less */
195:
196: messg[0] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
197: messg[1] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
198: messg[2] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
199: messg[3] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
200: splx(s);
201:
202: printf(", self-test ");
203: if (messg[0] != 0x01 || messg[1] || messg[2] || messg[3])
204: printf("bad [%x %x %x %x]",
205: messg[0], messg[1], messg[2], messg[3]);
206: else
207: printf("ok )");
208:
209: lk201_reset(unit);
210: }
211:
212: /*
213: * Tinkerbell
214: */
215: void
216: lk201_ring_bell(
217: int unit)
218: {
219: spl_t s = spltty();
220: (*console_putc)(lk201_softc[unit]->sl_unit, SCREEN_LINE_KEYBOARD, LK_CMD_BELL);
221: splx(s);
222: }
223:
224: /*
225: * Here is your LED toy, Bob
226: */
227: void
228: lk201_lights(
229: int unit,
230: boolean_t on)
231: {
232: unsigned int sl;
233: spl_t s;
234:
235: sl = lk201_softc[unit]->sl_unit;
236: s = spltty();
237: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_OFF);
238: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(0xf));
239: if (on < 16 && on > 0) {
240: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_ON);
241: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(on));
242: }
243: splx(s);
244: }
245:
246:
247: lk201_led(
248: int unit)
249: {
250: lk201_led_state_t *leds = &lk201_softc[unit]->led;
251: unsigned int sl;
252: spl_t s;
253:
254: sl = lk201_softc[unit]->sl_unit;
255: if (leds->led_interval) { /* leds are on */
256: if (leds->led_light_count <= 0) { /* hit this lights */
257:
258: if (leds->led_lights <= 0) leds->led_lights= 1; /* sanity */
259: if (leds->led_lights > 16) leds->led_lights = 16;/* sanity */
260: leds->led_light_count = leds->led_interval; /* reset */
261: s = spltty();
262: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_OFF);
263: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(leds->led_lights));
264: switch (leds->led_pattern) {
265: case LED_OFF:
266: leds->led_interval = 0; /* since you can now set */
267: break; /* the interval even if off */
268: case LED_COUNT:
269: leds->led_lights++;
270: if (leds->led_lights > 16) leds->led_lights = 1;
271: break;
272: case LED_ROTATE:
273: leds->led_lights <<= 1;
274: if (leds->led_lights > 8) leds->led_lights = 1;
275: break;
276: case LED_CYLON:
277: if (leds->led_increasing) {
278: leds->led_lights <<= 1;
279: if (leds->led_lights > 8) {
280: leds->led_lights >>= 2;
281: leds->led_increasing = 0;
282: }
283: } else {
284: leds->led_lights >>= 1;
285: if (leds->led_lights <= 0) {
286: leds->led_lights = 2;
287: leds->led_increasing = 1;
288: }
289: }
290: break;
291: }
292: (*console_putc)( sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_ON);
293: (*console_putc)( sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(leds->led_lights));
294: splx(s);
295: }
296: leds->led_light_count--;
297: } else {
298: if (leds->led_lights) {
299: s = spltty();
300: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_OFF);
301: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(0xf));
302: leds->led_lights = 0;
303: splx(s);
304: }
305: leds->led_active = 0;
306: #if NBM > 0
307: screen_enable_vretrace(unit, 0); /* interrupts off */
308: #endif
309: }
310: }
311:
312:
313: /*
314: * Special user-visible ops
315: */
316: io_return_t
317: lk201_set_status(
318: int unit,
319: dev_flavor_t flavor,
320: dev_status_t status,
321: natural_t status_count)
322: {
323: lk201_led_state_t *leds = &lk201_softc[unit]->led;
324: lk201_kbd_state_t *kbd = &lk201_softc[unit]->kbd;
325:
326: switch( flavor ) {
327: case LK201_SEND_CMD:{
328: register lk201_cmd_t *cmd = (lk201_cmd_t*)status;
329: unsigned int cnt, s, sl;
330:
331: if ((status_count < (sizeof(*cmd)/sizeof(int))) ||
332: ((cnt = cmd->len) > 2))
333: return D_INVALID_SIZE;
334:
335: if (cnt == 0)
336: cmd->command |= LK_PARAM;
337: else
338: cmd->params[cnt-1] |= LK_PARAM;
339: sl = lk201_softc[unit]->sl_unit;
340: s = spltty();
341: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, cmd->command);
342: if (cnt > 0)
343: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, cmd->params[0]);
344: if (cnt > 1)
345: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, cmd->params[1]);
346: splx(s);
347: return D_SUCCESS;
348: }
349: case LK201_LED_PATTERN:{
350: register int ptn = * (int *) status;
351: if (ptn != LED_OFF && ptn != LED_COUNT &&
352: ptn != LED_ROTATE && ptn != LED_CYLON ) {
353: return -1;
354: } else {
355: leds->led_pattern = ptn;
356: }
357: break;
358: }
359: case LK201_LED_INTERVAL:{
360: register int lcnt = * (int *) status;
361: if (lcnt < 0)
362: lcnt = 1;
363: leds->led_interval = lcnt;
364: break;
365: }
366: case LK201_mapLOCKtoCNTRL:{
367: boolean_t enable = * (boolean_t*) status;
368: if (enable)
369: kbd->kbd_flags |= mapLOCKtoCNTRL;
370: else
371: kbd->kbd_flags &= ~mapLOCKtoCNTRL;
372: return D_SUCCESS;
373: }
374: case LK201_REMAP_KEY:{
375: register KeyMap *k = (KeyMap *) status;
376: int mode;
377:
378: if (status_count < (sizeof(KeyMap)/sizeof(int)))
379: return D_INVALID_SIZE;
380:
381: mode = k->shifted ? 1 : 0;
382: if (k->meta) mode += 2;
383: return lk201_translation( k->in_keyval,
384: k->out_keyval,
385: mode );
386: }
387: default:
388: return D_INVALID_OPERATION;
389: }
390: leds->led_lights = 1;
391: leds->led_active = 1;
392: #if NBM > 0
393: screen_enable_vretrace(unit, 1); /* interrupts on */
394: #endif
395: return D_SUCCESS;
396: }
397:
398: /*
399: * Keycode translation tables
400: *
401: * NOTE: these tables have been compressed a little bit
402: * because the lk201 cannot generate very small codes.
403: */
404:
405: unsigned char lk201_xlate_key[] = {
406: /* 86 */ 0 ,0
407: /* 88 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
408: /* 96 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
409: /* 104 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
410: /* 112 */ ,0 ,0x1b ,0x08 ,'\n' ,0 ,0 ,0 ,0
411: /* 120 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
412: /* 128 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
413: /* 136 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
414: /* 144 */ ,0 ,0 ,'0',0 ,'.','\r','1','2'
415: /* 152 */ ,'3','4','5','6',',','7','8','9'
416: /* 160 */ ,'-',0 ,0 ,0 ,0 ,0 ,0 ,0
417: /* 168 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
418: /* 176 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
419: /* 184 */ ,0 ,0 ,0 ,0 ,0x7f,'\r','\t','`'
420: /* 192 */ ,'1' ,'q' ,'a' ,'z' ,0 ,'2' ,'w' ,'s'
421: /* 200 */ ,'x' ,'<' ,0 ,'3' ,'e' ,'d' ,'c' ,0
422: /* 208 */ ,'4' ,'r' ,'f' ,'v' ,' ' ,0 ,'5' ,'t'
423: /* 216 */ ,'g' ,'b' ,0 ,'6' ,'y' ,'h' ,'n' ,0
424: /* 224 */ ,'7' ,'u' ,'j' ,'m' ,0 ,'8' ,'i' ,'k'
425: /* 232 */ ,',' ,0 ,'9' ,'o' ,'l' ,'.' ,0 ,'0'
426: /* 240 */ ,'p' ,0 ,';' ,'/' ,0 ,'=' ,']' ,'\\'
427: /* 248 */ ,0 ,'-' ,'[' ,'\'' ,0 ,0 ,0 ,0
428: };
429:
430: unsigned char lk201_xlate_shifted[] = {
431: /* 86 */ 0 ,0
432: /* 88 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
433: /* 96 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
434: /* 104 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
435: /* 112 */ ,0 ,0x1b ,0x08 ,'\n' ,0 ,0 ,0 ,0
436: /* 120 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
437: /* 128 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
438: /* 136 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
439: /* 144 */ ,0 ,0 ,'0',0 ,'.','\r','1','2'
440: /* 152 */ ,'3','4','5','6',',','7','8','9'
441: /* 160 */ ,'-',0 ,0 ,0 ,0 ,0 ,0 ,0
442: /* 168 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
443: /* 176 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
444: /* 184 */ ,0 ,0 ,0 ,0 ,0x7f ,'\r' ,'\t' ,'~'
445: /* 192 */ ,'!' ,'Q' ,'A' ,'Z' ,0 ,'@' ,'W' ,'S'
446: /* 200 */ ,'X' ,'>' ,0 ,'#' ,'E' ,'D' ,'C' ,0
447: /* 208 */ ,'$' ,'R' ,'F' ,'V' ,' ' ,0 ,'%' ,'T'
448: /* 216 */ ,'G' ,'B' ,0 ,'^' ,'Y' ,'H' ,'N' ,0
449: /* 224 */ ,'&' ,'U' ,'J' ,'M' ,0 ,'*' ,'I' ,'K'
450: /* 232 */ ,'<' ,0 ,'(' ,'O' ,'L' ,'>' ,0 ,')'
451: /* 240 */ ,'P' ,0 ,':' ,'?' ,0 ,'+' ,'}' ,'|'
452: /* 248 */ ,0 ,'_' ,'{' ,'"' ,0 ,0 ,0 ,0
453: };
454:
455: unsigned char lk201_xlate_meta[] = {
456: /* 86 */ 0 ,0
457: /* 88 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
458: /* 96 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
459: /* 104 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
460: /* 112 */ ,0 ,0x1b ,0x08 ,'\n' ,0 ,0 ,0 ,0
461: /* 120 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
462: /* 128 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
463: /* 136 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
464: /* 144 */ ,0 ,0 ,'0',0 ,'.','\r','1','2'
465: /* 152 */ ,'3','4','5','6',',','7','8','9'
466: /* 160 */ ,'-',0 ,0 ,0 ,0 ,0 ,0 ,0
467: /* 168 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
468: /* 176 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
469: /* 184 */ ,0 ,0 ,0 ,0 ,0x7f ,'\r' ,'\t' ,'~'
470: /* 192 */ ,'!' ,'Q' ,'A' ,'Z' ,0 ,'@' ,'W' ,'S'
471: /* 200 */ ,'X' ,'>' ,0 ,'#' ,'E' ,'D' ,'C' ,0
472: /* 208 */ ,'$' ,'R' ,'F' ,'V' ,' ' ,0 ,'%' ,'T'
473: /* 216 */ ,'G' ,'B' ,0 ,'^' ,'Y' ,'H' ,'N' ,0
474: /* 224 */ ,'&' ,'U' ,'J' ,'M' ,0 ,'*' ,'I' ,'K'
475: /* 232 */ ,'<' ,0 ,'(' ,'O' ,'L' ,'>' ,0 ,')'
476: /* 240 */ ,'P' ,0 ,':' ,'?' ,0 ,'+' ,'}' ,'|'
477: /* 248 */ ,0 ,'_' ,'{' ,'"' ,0 ,0 ,0 ,0
478: };
479:
480: unsigned char lk201_xlate_shifted_meta[] = {
481: /* 86 */ 0 ,0
482: /* 88 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
483: /* 96 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
484: /* 104 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
485: /* 112 */ ,0 ,0x1b ,0x08 ,'\n' ,0 ,0 ,0 ,0
486: /* 120 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
487: /* 128 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
488: /* 136 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
489: /* 144 */ ,0 ,0 ,'0',0 ,'.','\r','1','2'
490: /* 152 */ ,'3','4','5','6',',','7','8','9'
491: /* 160 */ ,'-',0 ,0 ,0 ,0 ,0 ,0 ,0
492: /* 168 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
493: /* 176 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
494: /* 184 */ ,0 ,0 ,0 ,0 ,0x7f ,'\r' ,'\t' ,'~'
495: /* 192 */ ,'!' ,'Q' ,'A' ,'Z' ,0 ,'@' ,'W' ,'S'
496: /* 200 */ ,'X' ,'>' ,0 ,'#' ,'E' ,'D' ,'C' ,0
497: /* 208 */ ,'$' ,'R' ,'F' ,'V' ,' ' ,0 ,'%' ,'T'
498: /* 216 */ ,'G' ,'B' ,0 ,'^' ,'Y' ,'H' ,'N' ,0
499: /* 224 */ ,'&' ,'U' ,'J' ,'M' ,0 ,'*' ,'I' ,'K'
500: /* 232 */ ,'<' ,0 ,'(' ,'O' ,'L' ,'>' ,0 ,')'
501: /* 240 */ ,'P' ,0 ,':' ,'?' ,0 ,'+' ,'}' ,'|'
502: /* 248 */ ,0 ,'_' ,'{' ,'"' ,0 ,0 ,0 ,0
503: };
504:
505:
506: io_return_t
507: lk201_translation(
508: int key,
509: char c,
510: int tabcode )
511: {
512: unsigned char *table;
513:
514: if ((key &= 0xff) < LK_MINCODE)
515: return D_INVALID_OPERATION;
516:
517: switch (tabcode) {
518: case 3:
519: table = lk201_xlate_shifted_meta;
520: break;
521: case 2:
522: table = lk201_xlate_meta;
523: break;
524: case 1:
525: table = lk201_xlate_shifted;
526: break;
527: case 0:
528: default:
529: table = lk201_xlate_key;
530: break;
531: }
532: table[key - LK_MINCODE] = c;
533: return D_SUCCESS;
534: }
535:
536: /*
537: * Input character processing
538: */
539:
540: lk201_rint(
541: int unit,
542: unsigned short data,
543: boolean_t handle_shift,
544: boolean_t from_kernel)
545: {
546: int c;
547: lk201_kbd_state_t *kbd = &lk201_softc[unit]->kbd;
548:
549: /*
550: * Keyboard touched, clean char to 8 bits.
551: */
552: #if NBM > 0
553: ssaver_bump(unit);
554: #endif
555:
556: data &= 0xff;
557:
558: /* Translate keycode into ASCII */
559: if ((c = lk201_input(unit, data)) == -1)
560: return -1;
561:
562: #if NBM > 0
563: /*
564: * Notify X, unless we are called from inside kernel
565: */
566: if (!from_kernel &&
567: screen_keypress_event(unit, DEV_KEYBD, data, EVT_BUTTON_RAW))
568: return -1;
569: #endif
570:
571: /* Handle shifting if need to */
572: if (kbd->kbd_gen_shift)
573: return (handle_shift) ? cngetc() : -1;
574:
575: return c;
576: }
577:
578: /*
579: * Routine to grock a character from LK201
580: */
581: #if MACH_KDB
582: int lk201_allow_kdb = 1;
583: #endif
584:
585: int lk201_debug = 0;
586:
587: lk201_input(
588: int unit,
589: unsigned short data)
590: {
591: int c, sl;
592: lk201_kbd_state_t *kbd = &lk201_softc[unit]->kbd;
593:
594: kbd->kbd_gen_shift = 0;
595:
596: #if MACH_KDB
597: if (lk201_allow_kdb && (data == LK_DO)) {
598: kdb_kintr();
599: return -2;
600: }
601: #endif
602:
603: /*
604: * Sanity checks
605: */
606:
607: if (data == LK_INPUT_ERR || data == LK_OUTPUT_ERR) {
608: printf(" Keyboard error, code = %x\n",data);
609: return -1;
610: }
611: if (data < LK_MINCODE)
612: return -1;
613:
614: /*
615: * Check special keys: shifts, ups, ..
616: */
617:
618: if (data == LK_LOCK && (kbd->kbd_flags&mapLOCKtoCNTRL))
619: data = LK_CNTRL;
620:
621: switch (data) {
622: case LK_LOCK:
623: kbd->kbd_lock ^= 1;
624: kbd->kbd_gen_shift = 1;
625: sl = lk201_softc[unit]->sl_unit;
626: /* called from interrupt, no need for spl */
627: if (kbd->kbd_lock)
628: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_ON);
629: else
630: (*console_putc)(sl,SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_OFF);
631: (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(0x4));
632: return 0;
633:
634: case LK_ALT:
635: case LK_L_ALT:
636: case LK_R_ALT:
637: case LK_R_COMPOSE:
638: kbd->kbd_meta ^= 1;
639: kbd->kbd_gen_shift = 1;
640: return 0;
641:
642: case LK_SHIFT:
643: case LK_R_SHIFT:
644: kbd->kbd_shift ^= 1;
645: kbd->kbd_gen_shift = 1;
646: return 0;
647:
648: case LK_CNTRL:
649: kbd->kbd_ctrl ^= 1;
650: kbd->kbd_gen_shift = 1;
651: return 0;
652:
653: case LK_ALLUP:
654: kbd->kbd_ctrl = 0;
655: kbd->kbd_shift = 0;
656: kbd->kbd_meta = 0;
657: kbd->kbd_gen_shift = 1;
658: return 0;
659:
660: case LK_REPEAT:
661: c = kbd->kbd_previous;
662: break;
663:
664: default:
665:
666: /*
667: * Do the key translation to ASCII
668: */
669: if (kbd->kbd_ctrl || kbd->kbd_lock || kbd->kbd_shift) {
670: c = ((kbd->kbd_meta) ?
671: lk201_xlate_shifted_meta : lk201_xlate_shifted)
672: [data - LK_MINCODE];
673: if (kbd->kbd_ctrl)
674: c &= 0x1f;
675: } else
676: c = ((kbd->kbd_meta) ?
677: lk201_xlate_meta : lk201_xlate_key)
678: [data-LK_MINCODE];
679: break;
680:
681: }
682:
683: kbd->kbd_previous = c;
684:
685: /*
686: * DEBUG code DEBUG
687: */
688: if (lk201_debug && (c == 0)) {
689: printf("lk201: [%x]\n", data);
690: }
691:
692: return c;
693: }
694:
695: #endif /* NLK > 0 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.