adb.c revision 1.9 1 /* $NetBSD: adb.c,v 1.9 1996/05/05 16:21:20 briggs Exp $ */
2
3 /*-
4 * Copyright (C) 1994 Bradley A. Grantham
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 e* notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Bradley A. Grantham.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/param.h>
34 #include <sys/device.h>
35 #include <sys/fcntl.h>
36 #include <sys/select.h>
37 #include <sys/proc.h>
38 #include <sys/signalvar.h>
39 #include <sys/systm.h>
40
41 #include <machine/adbsys.h>
42 #include <machine/autoconf.h>
43 #include <machine/keyboard.h>
44
45 #include "adbvar.h"
46 #include "itevar.h"
47 #include "../mac68k/macrom.h"
48
49 /*
50 * Function declarations.
51 */
52 static int adbmatch __P((struct device *, void *, void *));
53 static void adbattach __P((struct device *, struct device *, void *));
54
55 /*
56 * Global variables.
57 */
58 int adb_polling = 0; /* Are we polling? (Debugger mode) */
59
60 /*
61 * Local variables.
62 */
63
64 /* External keyboard translation matrix */
65 extern unsigned char keyboard[128][3];
66
67 /* Event queue definitions */
68 #if !defined(ADB_MAX_EVENTS)
69 #define ADB_MAX_EVENTS 200 /* Maximum events to be kept in queue */
70 /* maybe should be higher for slower macs? */
71 #endif /* !defined(ADB_MAX_EVENTS) */
72 static adb_event_t adb_evq[ADB_MAX_EVENTS]; /* ADB event queue */
73 static int adb_evq_tail = 0; /* event queue tail */
74 static int adb_evq_len = 0; /* event queue length */
75
76 /* ADB device state information */
77 static int adb_isopen = 0; /* Are we queuing events for adb_read? */
78 static struct selinfo adb_selinfo; /* select() info */
79 static struct proc *adb_ioproc = NULL; /* process to wakeup */
80
81 /* Key repeat parameters */
82 static int adb_rptdelay = 20; /* ticks before auto-repeat */
83 static int adb_rptinterval = 6; /* ticks between auto-repeat */
84 static int adb_repeating = -1; /* key that is auto-repeating */
85 static adb_event_t adb_rptevent;/* event to auto-repeat */
86
87 /* Driver definition. -- This should probably be a bus... */
88 struct cfattach adb_ca = {
89 sizeof(struct device), adbmatch, adbattach
90 };
91
92 struct cfdriver adb_cd = {
93 NULL, "adb", DV_DULL
94 };
95
96 static int
97 adbmatch(pdp, match, auxp)
98 struct device *pdp;
99 void *match, *auxp;
100 {
101 return 1;
102 }
103
104 static void
105 adbattach(parent, dev, aux)
106 struct device *parent, *dev;
107 void *aux;
108 {
109 printf(" (ADB event device)\n");
110 }
111
112 void
113 adb_enqevent(event)
114 adb_event_t *event;
115 {
116 int s;
117
118 if (adb_evq_tail < 0 || adb_evq_tail >= ADB_MAX_EVENTS)
119 panic("adb: event queue tail is out of bounds");
120
121 if (adb_evq_len < 0 || adb_evq_len > ADB_MAX_EVENTS)
122 panic("adb: event queue len is out of bounds");
123
124 s = splhigh();
125
126 if (adb_evq_len == ADB_MAX_EVENTS) {
127 splx(s);
128 return; /* Oh, well... */
129 }
130 adb_evq[(adb_evq_len + adb_evq_tail) % ADB_MAX_EVENTS] =
131 *event;
132 adb_evq_len++;
133
134 selwakeup(&adb_selinfo);
135 if (adb_ioproc)
136 psignal(adb_ioproc, SIGIO);
137
138 splx(s);
139 }
140
141 void
142 adb_handoff(event)
143 adb_event_t *event;
144 {
145 if (adb_isopen && !adb_polling) {
146 adb_enqevent(event);
147 } else {
148 if (event->def_addr == 2)
149 ite_intr(event);
150 }
151 }
152
153
154 void
155 adb_autorepeat(keyp)
156 void *keyp;
157 {
158 int key = (int) keyp;
159
160 adb_rptevent.bytes[0] |= 0x80;
161 microtime(&adb_rptevent.timestamp);
162 adb_handoff(&adb_rptevent); /* do key up */
163
164 adb_rptevent.bytes[0] &= 0x7f;
165 microtime(&adb_rptevent.timestamp);
166 adb_handoff(&adb_rptevent); /* do key down */
167
168 if (adb_repeating == key) {
169 timeout(adb_autorepeat, keyp, adb_rptinterval);
170 }
171 }
172
173
174 void
175 adb_dokeyupdown(event)
176 adb_event_t *event;
177 {
178 int adb_key;
179
180 if (event->def_addr == 2) {
181 adb_key = event->u.k.key & 0x7f;
182 if (!(event->u.k.key & 0x80) &&
183 keyboard[event->u.k.key & 0x7f][0] != 0) {
184 /* ignore shift & control */
185 if (adb_repeating != -1) {
186 untimeout(adb_autorepeat,
187 (void *) adb_rptevent.u.k.key);
188 }
189 adb_rptevent = *event;
190 adb_repeating = adb_key;
191 timeout(adb_autorepeat,
192 (void *) adb_key, adb_rptdelay);
193 } else {
194 if (adb_repeating != -1) {
195 adb_repeating = -1;
196 untimeout(adb_autorepeat,
197 (void *) adb_rptevent.u.k.key);
198 }
199 adb_rptevent = *event;
200 }
201 }
202 adb_handoff(event);
203 }
204
205 static adb_ms_buttons = 0;
206
207 void
208 adb_keymaybemouse(event)
209 adb_event_t *event;
210 {
211 static int optionkey_down = 0;
212 adb_event_t new_event;
213
214 if (event->u.k.key == ADBK_KEYDOWN(ADBK_OPTION)) {
215 optionkey_down = 1;
216 } else if (event->u.k.key == ADBK_KEYUP(ADBK_OPTION)) {
217 /* key up */
218 optionkey_down = 0;
219 if (adb_ms_buttons & 0xfe) {
220 adb_ms_buttons &= 1;
221 new_event.def_addr = ADBADDR_MS;
222 new_event.u.m.buttons = adb_ms_buttons;
223 new_event.u.m.dx = new_event.u.m.dy = 0;
224 microtime(&new_event.timestamp);
225 adb_dokeyupdown(&new_event);
226 }
227 } else if (optionkey_down) {
228 if (event->u.k.key == ADBK_KEYDOWN(ADBK_LEFT)) {
229 adb_ms_buttons |= 2; /* middle down */
230 new_event.def_addr = ADBADDR_MS;
231 new_event.u.m.buttons = adb_ms_buttons;
232 new_event.u.m.dx = new_event.u.m.dy = 0;
233 microtime(&new_event.timestamp);
234 adb_dokeyupdown(&new_event);
235 } else if (event->u.k.key == ADBK_KEYUP(ADBK_LEFT)) {
236 adb_ms_buttons &= ~2; /* middle up */
237 new_event.def_addr = ADBADDR_MS;
238 new_event.u.m.buttons = adb_ms_buttons;
239 new_event.u.m.dx = new_event.u.m.dy = 0;
240 microtime(&new_event.timestamp);
241 adb_dokeyupdown(&new_event);
242 } else if (event->u.k.key == ADBK_KEYDOWN(ADBK_RIGHT)) {
243 adb_ms_buttons |= 4; /* right down */
244 new_event.def_addr = ADBADDR_MS;
245 new_event.u.m.buttons = adb_ms_buttons;
246 new_event.u.m.dx = new_event.u.m.dy = 0;
247 microtime(&new_event.timestamp);
248 adb_dokeyupdown(&new_event);
249 } else if (event->u.k.key == ADBK_KEYUP(ADBK_RIGHT)) {
250 adb_ms_buttons &= ~4; /* right up */
251 new_event.def_addr = ADBADDR_MS;
252 new_event.u.m.buttons = adb_ms_buttons;
253 new_event.u.m.dx = new_event.u.m.dy = 0;
254 microtime(&new_event.timestamp);
255 adb_dokeyupdown(&new_event);
256 } else if (ADBK_MODIFIER(event->u.k.key)) {
257 /* ctrl, shift, cmd */
258 adb_dokeyupdown(event);
259 } else if (!(event->u.k.key & 0x80)) {
260 /* key down */
261 new_event = *event;
262
263 /* send option-down */
264 new_event.u.k.key = ADBK_KEYDOWN(ADBK_OPTION);
265 new_event.bytes[0] = new_event.u.k.key;
266 microtime(&new_event.timestamp);
267 adb_dokeyupdown(&new_event);
268
269 /* send key-down */
270 new_event.u.k.key = event->bytes[0];
271 new_event.bytes[0] = new_event.u.k.key;
272 microtime(&new_event.timestamp);
273 adb_dokeyupdown(&new_event);
274
275 /* send key-up */
276 new_event.u.k.key =
277 ADBK_KEYUP(ADBK_KEYVAL(event->bytes[0]));
278 microtime(&new_event.timestamp);
279 new_event.bytes[0] = new_event.u.k.key;
280 adb_dokeyupdown(&new_event);
281
282 /* send option-up */
283 new_event.u.k.key = ADBK_KEYUP(ADBK_OPTION);
284 new_event.bytes[0] = new_event.u.k.key;
285 microtime(&new_event.timestamp);
286 adb_dokeyupdown(&new_event);
287 } else {
288 /* option-keyup -- do nothing. */
289 }
290 } else {
291 adb_dokeyupdown(event);
292 }
293 }
294
295
296 void
297 adb_processevent(event)
298 adb_event_t *event;
299 {
300 adb_event_t new_event;
301 int i, button_bit, max_byte, mask, buttons;
302
303 new_event = *event;
304 buttons = 0;
305
306 switch (event->def_addr) {
307 case ADBADDR_KBD:
308 new_event.u.k.key = event->bytes[0];
309 new_event.bytes[1] = 0xff;
310 adb_keymaybemouse(&new_event);
311 if (event->bytes[1] != 0xff) {
312 new_event.u.k.key = event->bytes[1];
313 new_event.bytes[0] = event->bytes[1];
314 new_event.bytes[1] = 0xff;
315 adb_keymaybemouse(&new_event);
316 }
317 break;
318 case ADBADDR_MS:
319 /*
320 * This should handle both plain ol' Apple mice and mice
321 * that claim to support the Extended Apple Mouse Protocol.
322 */
323 max_byte = event->byte_count;
324 button_bit = 1;
325 switch (event->hand_id) {
326 case ADBMS_USPEED:
327 /* MicroSpeed mouse */
328 if (max_byte == 4)
329 buttons = (~event->bytes[2]) & 0xff;
330 else
331 buttons = (event->bytes[0] & 0x80) ? 0 : 1;
332 break;
333 default:
334 /* Classic Mouse Protocol (up to 2 buttons) */
335 for (i = 0; i < 2; i++, button_bit <<= 1)
336 /* 0 when button down */
337 if (!(event->bytes[i] & 0x80))
338 buttons |= button_bit;
339 else
340 buttons &= ~button_bit;
341 /* Extended Protocol (up to 6 more buttons) */
342 for (mask = 0x80; i < max_byte;
343 i += (mask == 0x80), button_bit <<= 1) {
344 /* 0 when button down */
345 if (!(event->bytes[i] & mask))
346 buttons |= button_bit;
347 else
348 buttons &= ~button_bit;
349 mask = ((mask >> 4) & 0xf)
350 | ((mask & 0xf) << 4);
351 }
352 break;
353 }
354 new_event.u.m.buttons = adb_ms_buttons | buttons;
355 new_event.u.m.dx = ((signed int) (event->bytes[1] & 0x3f)) -
356 ((event->bytes[1] & 0x40) ? 64 : 0);
357 new_event.u.m.dy = ((signed int) (event->bytes[0] & 0x3f)) -
358 ((event->bytes[0] & 0x40) ? 64 : 0);
359 adb_dokeyupdown(&new_event);
360 break;
361 default: /* God only knows. */
362 adb_dokeyupdown(event);
363 }
364 }
365
366
367 int
368 adbopen(dev, flag, mode, p)
369 dev_t dev;
370 int flag, mode;
371 struct proc *p;
372 {
373 register int unit;
374 int error = 0;
375 int s;
376
377 unit = minor(dev);
378 if (unit != 0)
379 return (ENXIO);
380
381 s = splhigh();
382 if (adb_isopen) {
383 splx(s);
384 return (EBUSY);
385 }
386 splx(s);
387 adb_evq_tail = 0;
388 adb_evq_len = 0;
389 adb_isopen = 1;
390 adb_ioproc = p;
391
392 return (error);
393 }
394
395
396 int
397 adbclose(dev, flag, mode, p)
398 dev_t dev;
399 int flag, mode;
400 struct proc *p;
401 {
402 adb_isopen = 0;
403 adb_ioproc = NULL;
404 return (0);
405 }
406
407
408 int
409 adbread(dev, uio, flag)
410 dev_t dev;
411 struct uio *uio;
412 int flag;
413 {
414 int s, error;
415 int willfit;
416 int total;
417 int firstmove;
418 int moremove;
419
420 if (uio->uio_resid < sizeof(adb_event_t))
421 return (EMSGSIZE); /* close enough. */
422
423 s = splhigh();
424 if (adb_evq_len == 0) {
425 splx(s);
426 return (0);
427 }
428 willfit = howmany(uio->uio_resid, sizeof(adb_event_t));
429 total = (adb_evq_len < willfit) ? adb_evq_len : willfit;
430
431 firstmove = (adb_evq_tail + total > ADB_MAX_EVENTS)
432 ? (ADB_MAX_EVENTS - adb_evq_tail) : total;
433
434 error = uiomove((caddr_t) & adb_evq[adb_evq_tail],
435 firstmove * sizeof(adb_event_t), uio);
436 if (error) {
437 splx(s);
438 return (error);
439 }
440 moremove = total - firstmove;
441
442 if (moremove > 0) {
443 error = uiomove((caddr_t) & adb_evq[0],
444 moremove * sizeof(adb_event_t), uio);
445 if (error) {
446 splx(s);
447 return (error);
448 }
449 }
450 adb_evq_tail = (adb_evq_tail + total) % ADB_MAX_EVENTS;
451 adb_evq_len -= total;
452 splx(s);
453 return (0);
454 }
455
456
457 int
458 adbwrite(dev, uio, flag)
459 dev_t dev;
460 struct uio *uio;
461 int flag;
462 {
463 return 0;
464 }
465
466
467 int
468 adbioctl(dev, cmd, data, flag, p)
469 dev_t dev;
470 int cmd;
471 caddr_t data;
472 int flag;
473 struct proc *p;
474 {
475 switch (cmd) {
476 case ADBIOC_DEVSINFO: {
477 adb_devinfo_t *di;
478 ADBDataBlock adbdata;
479 int totaldevs;
480 int adbaddr;
481 int i;
482
483 di = (void *) data;
484
485 /* Initialize to no devices */
486 for (i = 0; i < 16; i++)
487 di->dev[i].addr = -1;
488
489 totaldevs = CountADBs();
490 for (i = 1; i <= totaldevs; i++) {
491 adbaddr = GetIndADB(&adbdata, i);
492 di->dev[adbaddr].addr = adbaddr;
493 di->dev[adbaddr].default_addr = adbdata.origADBAddr;
494 di->dev[adbaddr].handler_id = adbdata.devType;
495 }
496
497 /* Must call ADB Manager to get devices now */
498 break;
499 }
500
501 case ADBIOC_GETREPEAT:{
502 adb_rptinfo_t *ri;
503
504 ri = (void *) data;
505 ri->delay_ticks = adb_rptdelay;
506 ri->interval_ticks = adb_rptinterval;
507 break;
508 }
509
510 case ADBIOC_SETREPEAT:{
511 adb_rptinfo_t *ri;
512
513 ri = (void *) data;
514 adb_rptdelay = ri->delay_ticks;
515 adb_rptinterval = ri->interval_ticks;
516 break;
517 }
518
519 case ADBIOC_RESET:
520 adb_init();
521 break;
522
523 case ADBIOC_LISTENCMD:{
524 adb_listencmd_t *lc;
525
526 lc = (void *) data;
527 }
528
529 default:
530 return (EINVAL);
531 }
532 return (0);
533 }
534
535
536 int
537 adbselect(dev, rw, p)
538 dev_t dev;
539 int rw;
540 struct proc *p;
541 {
542 switch (rw) {
543 case FREAD:
544 /* succeed if there is something to read */
545 if (adb_evq_len > 0)
546 return (1);
547 selrecord(p, &adb_selinfo);
548 break;
549
550 case FWRITE:
551 return (1); /* always fails => never blocks */
552 break;
553 }
554
555 return (0);
556 }
557