FreeBSD/Linux Kernel Cross Reference
sys/chips/lk201.c
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 Software.Distribution@CS.CMU.EDU
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 * HISTORY
28 * $Log: lk201.c,v $
29 * Revision 2.13 93/05/15 19:37:02 mrt
30 * machparam.h -> machspl.h
31 *
32 * Revision 2.12 93/05/10 20:08:15 rvb
33 * Fixed types.
34 * [93/05/06 09:58:13 af]
35 *
36 * Revision 2.11 93/02/05 08:05:30 danner
37 * Flamingo, protos.
38 * [93/02/04 01:44:48 af]
39 *
40 * Always return -2 from debugger, regardless [jtp@hut.fi]
41 * Proper spl typing. 64bit clean. Made bitmap display optional.
42 * [92/11/30 af]
43 *
44 * Return -2 from lk201_input if the kdb hot key was received. Also
45 * do this if already inside kdb
46 * [92/10/24 jvh]
47 *
48 * Revision 2.10 92/02/19 16:45:50 elf
49 * Added keycodes for lk401.
50 * [92/01/31 af]
51 *
52 * Revision 2.9 91/08/24 11:52:22 af
53 * Spls for 3min. More uniformity. More flexible about where the serial
54 * line is.
55 * [91/08/02 02:18:02 af]
56 *
57 * Revision 2.8 91/06/25 20:54:11 rpd
58 * Tweaks to make gcc happy.
59 * [91/06/25 rpd]
60 *
61 * Revision 2.7 91/06/19 11:53:47 rvb
62 * mips->DECSTATION; vax->VAXSTATION
63 * [91/06/12 14:01:50 rvb]
64 *
65 * File moved here from mips/PMAX since it tries to be generic;
66 * it is used on the PMAX and the Vax3100.
67 * [91/06/04 rvb]
68 *
69 * Revision 2.6 91/05/14 17:23:39 mrt
70 * Correcting copyright
71 *
72 * Revision 2.5 91/05/13 06:04:00 af
73 * Added proper spl() protection around multibyte commands.
74 * [91/05/12 16:07:16 af]
75 *
76 * Revision 2.4 91/02/05 17:42:12 mrt
77 * Added author notices
78 * [91/02/04 11:14:34 mrt]
79 *
80 * Changed to use new Mach copyright
81 * [91/02/02 12:13:09 mrt]
82 *
83 * Revision 2.3 90/12/05 23:32:06 af
84 * Cleaned up.
85 * [90/12/03 23:26:28 af]
86 *
87 * Revision 2.1.1.1 90/11/01 03:42:36 af
88 * Created, from DEC specs:
89 * "VCB02 Video Subsystem Technical Manual"
90 * DEC Educational Services, AZ-GLGAB-MN, February 1986
91 * [90/09/03 af]
92 *
93 */
94 /*
95 * File: lk201.c
96 * Author: Alessandro Forin, Carnegie Mellon University
97 * Date: 9/90
98 *
99 * Routines for the LK201 Keyboard Driver
100 */
101
102 #include <lk.h>
103 #if NLK > 0
104 #include <bm.h>
105
106 #include <mach_kdb.h>
107
108 #include <mach/std_types.h>
109 #include <device/device_types.h>
110 #include <machine/machspl.h> /* spl definitions */
111 #include <sys/ioctl.h>
112 #include <machine/machspl.h>
113 #include <chips/lk201.h>
114 #include <chips/serial_defs.h>
115 #include <chips/screen_defs.h>
116
117
118 /*
119 * Structures describing the keyboard status
120 */
121 typedef struct {
122 unsigned short kbd_flags;
123 unsigned short kbd_previous;
124 char kbd_gen_shift;
125 char kbd_ctrl;
126 char kbd_lock;
127 char kbd_meta;
128 char kbd_shift;
129 } lk201_kbd_state_t;
130
131 #define mapLOCKtoCNTRL 0x1 /* flags */
132
133 typedef struct {
134 char led_active;
135 char led_pattern;
136 char led_increasing;
137 char led_lights;
138 int led_interval;
139 int led_light_count;
140 } lk201_led_state_t;
141
142
143 /*
144 * Keyboard state
145 */
146
147 struct lk201_softc {
148 lk201_kbd_state_t kbd;
149 lk201_led_state_t led;
150 int sl_unit;
151 } lk201_softc_data[NLK];
152
153 typedef struct lk201_softc *lk201_softc_t;
154
155 lk201_softc_t lk201_softc[NLK];
156
157 /*
158 * Forward decls
159 */
160 io_return_t
161 lk201_translation(
162 int key,
163 char c,
164 int tabcode );
165
166 int
167 lk201_input(
168 int unit,
169 unsigned short data);
170
171
172 /*
173 * Autoconf (sort-of)
174 */
175 lk201_probe(
176 int unit)
177 {
178 lk201_softc[unit] = &lk201_softc_data[unit];
179 return 1;
180 }
181
182 void lk201_attach(
183 int unit,
184 int sl_unit)
185 {
186 lk201_softc[unit]->sl_unit = sl_unit;
187 lk201_selftest(unit);
188 }
189
190 /*
191 * Keyboard initialization
192 */
193
194 static unsigned char lk201_reset_string[] = {
195 LK_CMD_LEDS_ON, LK_PARAM_LED_MASK(0xf), /* show we are resetting */
196 LK_CMD_SET_DEFAULTS,
197 LK_CMD_MODE(LK_MODE_RPT_DOWN,1),
198 LK_CMD_MODE(LK_MODE_RPT_DOWN,2),
199 LK_CMD_MODE(LK_MODE_RPT_DOWN,3),
200 LK_CMD_MODE(LK_MODE_RPT_DOWN,4),
201 LK_CMD_MODE(LK_MODE_DOWN_UP,5),
202 LK_CMD_MODE(LK_MODE_DOWN_UP,6),
203 LK_CMD_MODE(LK_MODE_RPT_DOWN,7),
204 LK_CMD_MODE(LK_MODE_RPT_DOWN,8),
205 LK_CMD_MODE(LK_MODE_RPT_DOWN,9),
206 LK_CMD_MODE(LK_MODE_RPT_DOWN,10),
207 LK_CMD_MODE(LK_MODE_RPT_DOWN,11),
208 LK_CMD_MODE(LK_MODE_RPT_DOWN,12),
209 LK_CMD_MODE(LK_MODE_DOWN,13),
210 LK_CMD_MODE(LK_MODE_RPT_DOWN,14),
211 LK_CMD_ENB_RPT,
212 /* LK_CMD_ENB_KEYCLK, LK_PARAM_VOLUME(4), */
213 LK_CMD_DIS_KEYCLK,
214 LK_CMD_RESUME,
215 LK_CMD_ENB_BELL, LK_PARAM_VOLUME(4),
216 LK_CMD_LEDS_OFF, LK_PARAM_LED_MASK(0xf)
217 };
218
219 void
220 lk201_reset(
221 int unit)
222 {
223 register int i, sl;
224 register spl_t s;
225 lk201_softc_t lk;
226
227 lk = lk201_softc[unit];
228 sl = lk->sl_unit;
229 s = spltty();
230 for (i = 0; i < sizeof(lk201_reset_string); i++) {
231 (*console_putc)(sl,
232 SCREEN_LINE_KEYBOARD,
233 lk201_reset_string[i]);
234 delay(100);
235 }
236 /* zero any state associated with previous keypresses */
237 bzero(lk, sizeof(*lk));
238 lk->sl_unit = sl;
239 splx(s);
240 }
241
242 lk201_selftest(
243 int unit)
244 {
245 int messg[4], sl;
246 spl_t s;
247
248 sl = lk201_softc[unit]->sl_unit;
249 s = spltty();
250 (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_REQ_ID);
251 delay(10000);/* arbitrary */
252 messg[0] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
253 messg[1] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
254 splx(s);
255
256 printf("( lk201 id %x.%x", messg[0], messg[1]);
257
258 s = spltty();
259 (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_POWER_UP);
260
261 /* cannot do this, waiting too long might cause receiver overruns */
262 /* delay(80000);/* spec says 70 msecs or less */
263
264 messg[0] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
265 messg[1] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
266 messg[2] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
267 messg[3] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
268 splx(s);
269
270 printf(", self-test ");
271 if (messg[0] != 0x01 || messg[1] || messg[2] || messg[3])
272 printf("bad [%x %x %x %x]",
273 messg[0], messg[1], messg[2], messg[3]);
274 else
275 printf("ok )");
276
277 lk201_reset(unit);
278 }
279
280 /*
281 * Tinkerbell
282 */
283 void
284 lk201_ring_bell(
285 int unit)
286 {
287 spl_t s = spltty();
288 (*console_putc)(lk201_softc[unit]->sl_unit, SCREEN_LINE_KEYBOARD, LK_CMD_BELL);
289 splx(s);
290 }
291
292 /*
293 * Here is your LED toy, Bob
294 */
295 void
296 lk201_lights(
297 int unit,
298 boolean_t on)
299 {
300 unsigned int sl;
301 spl_t s;
302
303 sl = lk201_softc[unit]->sl_unit;
304 s = spltty();
305 (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_OFF);
306 (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(0xf));
307 if (on < 16 && on > 0) {
308 (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_ON);
309 (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(on));
310 }
311 splx(s);
312 }
313
314
315 lk201_led(
316 int unit)
317 {
318 lk201_led_state_t *leds = &lk201_softc[unit]->led;
319 unsigned int sl;
320 spl_t s;
321
322 sl = lk201_softc[unit]->sl_unit;
323 if (leds->led_interval) { /* leds are on */
324 if (leds->led_light_count <= 0) { /* hit this lights */
325
326 if (leds->led_lights <= 0) leds->led_lights= 1; /* sanity */
327 if (leds->led_lights > 16) leds->led_lights = 16;/* sanity */
328 leds->led_light_count = leds->led_interval; /* reset */
329 s = spltty();
330 (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_OFF);
331 (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(leds->led_lights));
332 switch (leds->led_pattern) {
333 case LED_OFF:
334 leds->led_interval = 0; /* since you can now set */
335 break; /* the interval even if off */
336 case LED_COUNT:
337 leds->led_lights++;
338 if (leds->led_lights > 16) leds->led_lights = 1;
339 break;
340 case LED_ROTATE:
341 leds->led_lights <<= 1;
342 if (leds->led_lights > 8) leds->led_lights = 1;
343 break;
344 case LED_CYLON:
345 if (leds->led_increasing) {
346 leds->led_lights <<= 1;
347 if (leds->led_lights > 8) {
348 leds->led_lights >>= 2;
349 leds->led_increasing = 0;
350 }
351 } else {
352 leds->led_lights >>= 1;
353 if (leds->led_lights <= 0) {
354 leds->led_lights = 2;
355 leds->led_increasing = 1;
356 }
357 }
358 break;
359 }
360 (*console_putc)( sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_ON);
361 (*console_putc)( sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(leds->led_lights));
362 splx(s);
363 }
364 leds->led_light_count--;
365 } else {
366 if (leds->led_lights) {
367 s = spltty();
368 (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_OFF);
369 (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(0xf));
370 leds->led_lights = 0;
371 splx(s);
372 }
373 leds->led_active = 0;
374 #if NBM > 0
375 screen_enable_vretrace(unit, 0); /* interrupts off */
376 #endif
377 }
378 }
379
380
381 /*
382 * Special user-visible ops
383 */
384 io_return_t
385 lk201_set_status(
386 int unit,
387 dev_flavor_t flavor,
388 dev_status_t status,
389 natural_t status_count)
390 {
391 lk201_led_state_t *leds = &lk201_softc[unit]->led;
392 lk201_kbd_state_t *kbd = &lk201_softc[unit]->kbd;
393
394 switch( flavor ) {
395 case LK201_SEND_CMD:{
396 register lk201_cmd_t *cmd = (lk201_cmd_t*)status;
397 unsigned int cnt, s, sl;
398
399 if ((status_count < (sizeof(*cmd)/sizeof(int))) ||
400 ((cnt = cmd->len) > 2))
401 return D_INVALID_SIZE;
402
403 if (cnt == 0)
404 cmd->command |= LK_PARAM;
405 else
406 cmd->params[cnt-1] |= LK_PARAM;
407 sl = lk201_softc[unit]->sl_unit;
408 s = spltty();
409 (*console_putc)(sl, SCREEN_LINE_KEYBOARD, cmd->command);
410 if (cnt > 0)
411 (*console_putc)(sl, SCREEN_LINE_KEYBOARD, cmd->params[0]);
412 if (cnt > 1)
413 (*console_putc)(sl, SCREEN_LINE_KEYBOARD, cmd->params[1]);
414 splx(s);
415 return D_SUCCESS;
416 }
417 case LK201_LED_PATTERN:{
418 register int ptn = * (int *) status;
419 if (ptn != LED_OFF && ptn != LED_COUNT &&
420 ptn != LED_ROTATE && ptn != LED_CYLON ) {
421 return -1;
422 } else {
423 leds->led_pattern = ptn;
424 }
425 break;
426 }
427 case LK201_LED_INTERVAL:{
428 register int lcnt = * (int *) status;
429 if (lcnt < 0)
430 lcnt = 1;
431 leds->led_interval = lcnt;
432 break;
433 }
434 case LK201_mapLOCKtoCNTRL:{
435 boolean_t enable = * (boolean_t*) status;
436 if (enable)
437 kbd->kbd_flags |= mapLOCKtoCNTRL;
438 else
439 kbd->kbd_flags &= ~mapLOCKtoCNTRL;
440 return D_SUCCESS;
441 }
442 case LK201_REMAP_KEY:{
443 register KeyMap *k = (KeyMap *) status;
444 int mode;
445
446 if (status_count < (sizeof(KeyMap)/sizeof(int)))
447 return D_INVALID_SIZE;
448
449 mode = k->shifted ? 1 : 0;
450 if (k->meta) mode += 2;
451 return lk201_translation( k->in_keyval,
452 k->out_keyval,
453 mode );
454 }
455 default:
456 return D_INVALID_OPERATION;
457 }
458 leds->led_lights = 1;
459 leds->led_active = 1;
460 #if NBM > 0
461 screen_enable_vretrace(unit, 1); /* interrupts on */
462 #endif
463 return D_SUCCESS;
464 }
465
466 /*
467 * Keycode translation tables
468 *
469 * NOTE: these tables have been compressed a little bit
470 * because the lk201 cannot generate very small codes.
471 */
472
473 unsigned char lk201_xlate_key[] = {
474 /* 86 */ 0 ,0
475 /* 88 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
476 /* 96 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
477 /* 104 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
478 /* 112 */ ,0 ,0x1b ,0x08 ,'\n' ,0 ,0 ,0 ,0
479 /* 120 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
480 /* 128 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
481 /* 136 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
482 /* 144 */ ,0 ,0 ,'',0 ,'.','\r','1','2'
483 /* 152 */ ,'3','4','5','6',',','7','8','9'
484 /* 160 */ ,'-',0 ,0 ,0 ,0 ,0 ,0 ,0
485 /* 168 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
486 /* 176 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
487 /* 184 */ ,0 ,0 ,0 ,0 ,0x7f,'\r','\t','`'
488 /* 192 */ ,'1' ,'q' ,'a' ,'z' ,0 ,'2' ,'w' ,'s'
489 /* 200 */ ,'x' ,'<' ,0 ,'3' ,'e' ,'d' ,'c' ,0
490 /* 208 */ ,'4' ,'r' ,'f' ,'v' ,' ' ,0 ,'5' ,'t'
491 /* 216 */ ,'g' ,'b' ,0 ,'6' ,'y' ,'h' ,'n' ,0
492 /* 224 */ ,'7' ,'u' ,'j' ,'m' ,0 ,'8' ,'i' ,'k'
493 /* 232 */ ,',' ,0 ,'9' ,'o' ,'l' ,'.' ,0 ,''
494 /* 240 */ ,'p' ,0 ,';' ,'/' ,0 ,'=' ,']' ,'\\'
495 /* 248 */ ,0 ,'-' ,'[' ,'\'' ,0 ,0 ,0 ,0
496 };
497
498 unsigned char lk201_xlate_shifted[] = {
499 /* 86 */ 0 ,0
500 /* 88 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
501 /* 96 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
502 /* 104 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
503 /* 112 */ ,0 ,0x1b ,0x08 ,'\n' ,0 ,0 ,0 ,0
504 /* 120 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
505 /* 128 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
506 /* 136 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
507 /* 144 */ ,0 ,0 ,'',0 ,'.','\r','1','2'
508 /* 152 */ ,'3','4','5','6',',','7','8','9'
509 /* 160 */ ,'-',0 ,0 ,0 ,0 ,0 ,0 ,0
510 /* 168 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
511 /* 176 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
512 /* 184 */ ,0 ,0 ,0 ,0 ,0x7f ,'\r' ,'\t' ,'~'
513 /* 192 */ ,'!' ,'Q' ,'A' ,'Z' ,0 ,'@' ,'W' ,'S'
514 /* 200 */ ,'X' ,'>' ,0 ,'#' ,'E' ,'D' ,'C' ,0
515 /* 208 */ ,'$' ,'R' ,'F' ,'V' ,' ' ,0 ,'%' ,'T'
516 /* 216 */ ,'G' ,'B' ,0 ,'^' ,'Y' ,'H' ,'N' ,0
517 /* 224 */ ,'&' ,'U' ,'J' ,'M' ,0 ,'*' ,'I' ,'K'
518 /* 232 */ ,'<' ,0 ,'(' ,'O' ,'L' ,'>' ,0 ,')'
519 /* 240 */ ,'P' ,0 ,':' ,'?' ,0 ,'+' ,'}' ,'|'
520 /* 248 */ ,0 ,'_' ,'{' ,'"' ,0 ,0 ,0 ,0
521 };
522
523 unsigned char lk201_xlate_meta[] = {
524 /* 86 */ 0 ,0
525 /* 88 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
526 /* 96 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
527 /* 104 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
528 /* 112 */ ,0 ,0x1b ,0x08 ,'\n' ,0 ,0 ,0 ,0
529 /* 120 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
530 /* 128 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
531 /* 136 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
532 /* 144 */ ,0 ,0 ,'',0 ,'.','\r','1','2'
533 /* 152 */ ,'3','4','5','6',',','7','8','9'
534 /* 160 */ ,'-',0 ,0 ,0 ,0 ,0 ,0 ,0
535 /* 168 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
536 /* 176 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
537 /* 184 */ ,0 ,0 ,0 ,0 ,0x7f ,'\r' ,'\t' ,'~'
538 /* 192 */ ,'!' ,'Q' ,'A' ,'Z' ,0 ,'@' ,'W' ,'S'
539 /* 200 */ ,'X' ,'>' ,0 ,'#' ,'E' ,'D' ,'C' ,0
540 /* 208 */ ,'$' ,'R' ,'F' ,'V' ,' ' ,0 ,'%' ,'T'
541 /* 216 */ ,'G' ,'B' ,0 ,'^' ,'Y' ,'H' ,'N' ,0
542 /* 224 */ ,'&' ,'U' ,'J' ,'M' ,0 ,'*' ,'I' ,'K'
543 /* 232 */ ,'<' ,0 ,'(' ,'O' ,'L' ,'>' ,0 ,')'
544 /* 240 */ ,'P' ,0 ,':' ,'?' ,0 ,'+' ,'}' ,'|'
545 /* 248 */ ,0 ,'_' ,'{' ,'"' ,0 ,0 ,0 ,0
546 };
547
548 unsigned char lk201_xlate_shifted_meta[] = {
549 /* 86 */ 0 ,0
550 /* 88 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
551 /* 96 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
552 /* 104 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
553 /* 112 */ ,0 ,0x1b ,0x08 ,'\n' ,0 ,0 ,0 ,0
554 /* 120 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
555 /* 128 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
556 /* 136 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
557 /* 144 */ ,0 ,0 ,'',0 ,'.','\r','1','2'
558 /* 152 */ ,'3','4','5','6',',','7','8','9'
559 /* 160 */ ,'-',0 ,0 ,0 ,0 ,0 ,0 ,0
560 /* 168 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
561 /* 176 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
562 /* 184 */ ,0 ,0 ,0 ,0 ,0x7f ,'\r' ,'\t' ,'~'
563 /* 192 */ ,'!' ,'Q' ,'A' ,'Z' ,0 ,'@' ,'W' ,'S'
564 /* 200 */ ,'X' ,'>' ,0 ,'#' ,'E' ,'D' ,'C' ,0
565 /* 208 */ ,'$' ,'R' ,'F' ,'V' ,' ' ,0 ,'%' ,'T'
566 /* 216 */ ,'G' ,'B' ,0 ,'^' ,'Y' ,'H' ,'N' ,0
567 /* 224 */ ,'&' ,'U' ,'J' ,'M' ,0 ,'*' ,'I' ,'K'
568 /* 232 */ ,'<' ,0 ,'(' ,'O' ,'L' ,'>' ,0 ,')'
569 /* 240 */ ,'P' ,0 ,':' ,'?' ,0 ,'+' ,'}' ,'|'
570 /* 248 */ ,0 ,'_' ,'{' ,'"' ,0 ,0 ,0 ,0
571 };
572
573
574 io_return_t
575 lk201_translation(
576 int key,
577 char c,
578 int tabcode )
579 {
580 unsigned char *table;
581
582 if ((key &= 0xff) < LK_MINCODE)
583 return D_INVALID_OPERATION;
584
585 switch (tabcode) {
586 case 3:
587 table = lk201_xlate_shifted_meta;
588 break;
589 case 2:
590 table = lk201_xlate_meta;
591 break;
592 case 1:
593 table = lk201_xlate_shifted;
594 break;
595 case 0:
596 default:
597 table = lk201_xlate_key;
598 break;
599 }
600 table[key - LK_MINCODE] = c;
601 return D_SUCCESS;
602 }
603
604 /*
605 * Input character processing
606 */
607
608 lk201_rint(
609 int unit,
610 unsigned short data,
611 boolean_t handle_shift,
612 boolean_t from_kernel)
613 {
614 int c;
615 lk201_kbd_state_t *kbd = &lk201_softc[unit]->kbd;
616
617 /*
618 * Keyboard touched, clean char to 8 bits.
619 */
620 #if NBM > 0
621 ssaver_bump(unit);
622 #endif
623
624 data &= 0xff;
625
626 /* Translate keycode into ASCII */
627 if ((c = lk201_input(unit, data)) == -1)
628 return -1;
629
630 #if NBM > 0
631 /*
632 * Notify X, unless we are called from inside kernel
633 */
634 if (!from_kernel &&
635 screen_keypress_event(unit, DEV_KEYBD, data, EVT_BUTTON_RAW))
636 return -1;
637 #endif
638
639 /* Handle shifting if need to */
640 if (kbd->kbd_gen_shift)
641 return (handle_shift) ? cngetc() : -1;
642
643 return c;
644 }
645
646 /*
647 * Routine to grock a character from LK201
648 */
649 #if MACH_KDB
650 int lk201_allow_kdb = 1;
651 #endif
652
653 int lk201_debug = 0;
654
655 lk201_input(
656 int unit,
657 unsigned short data)
658 {
659 int c, sl;
660 lk201_kbd_state_t *kbd = &lk201_softc[unit]->kbd;
661
662 kbd->kbd_gen_shift = 0;
663
664 #if MACH_KDB
665 if (lk201_allow_kdb && (data == LK_DO)) {
666 kdb_kintr();
667 return -2;
668 }
669 #endif
670
671 /*
672 * Sanity checks
673 */
674
675 if (data == LK_INPUT_ERR || data == LK_OUTPUT_ERR) {
676 printf(" Keyboard error, code = %x\n",data);
677 return -1;
678 }
679 if (data < LK_MINCODE)
680 return -1;
681
682 /*
683 * Check special keys: shifts, ups, ..
684 */
685
686 if (data == LK_LOCK && (kbd->kbd_flags&mapLOCKtoCNTRL))
687 data = LK_CNTRL;
688
689 switch (data) {
690 case LK_LOCK:
691 kbd->kbd_lock ^= 1;
692 kbd->kbd_gen_shift = 1;
693 sl = lk201_softc[unit]->sl_unit;
694 /* called from interrupt, no need for spl */
695 if (kbd->kbd_lock)
696 (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_ON);
697 else
698 (*console_putc)(sl,SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_OFF);
699 (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(0x4));
700 return 0;
701
702 case LK_ALT:
703 case LK_L_ALT:
704 case LK_R_ALT:
705 case LK_R_COMPOSE:
706 kbd->kbd_meta ^= 1;
707 kbd->kbd_gen_shift = 1;
708 return 0;
709
710 case LK_SHIFT:
711 case LK_R_SHIFT:
712 kbd->kbd_shift ^= 1;
713 kbd->kbd_gen_shift = 1;
714 return 0;
715
716 case LK_CNTRL:
717 kbd->kbd_ctrl ^= 1;
718 kbd->kbd_gen_shift = 1;
719 return 0;
720
721 case LK_ALLUP:
722 kbd->kbd_ctrl = 0;
723 kbd->kbd_shift = 0;
724 kbd->kbd_meta = 0;
725 kbd->kbd_gen_shift = 1;
726 return 0;
727
728 case LK_REPEAT:
729 c = kbd->kbd_previous;
730 break;
731
732 default:
733
734 /*
735 * Do the key translation to ASCII
736 */
737 if (kbd->kbd_ctrl || kbd->kbd_lock || kbd->kbd_shift) {
738 c = ((kbd->kbd_meta) ?
739 lk201_xlate_shifted_meta : lk201_xlate_shifted)
740 [data - LK_MINCODE];
741 if (kbd->kbd_ctrl)
742 c &= 0x1f;
743 } else
744 c = ((kbd->kbd_meta) ?
745 lk201_xlate_meta : lk201_xlate_key)
746 [data-LK_MINCODE];
747 break;
748
749 }
750
751 kbd->kbd_previous = c;
752
753 /*
754 * DEBUG code DEBUG
755 */
756 if (lk201_debug && (c == 0)) {
757 printf("lk201: [%x]\n", data);
758 }
759
760 return c;
761 }
762
763 #endif /* NLK > 0 */
Cache object: 9b6970fedfd3dc4a81f90b3aa9a8b339
|