Don't use ds->dpy_copy directly from hw/ (Jan Niehusmann).
[qemu/mini2440.git] / hw / adb.c
blob5c0d6d5fd978c4b749b587afe2c258ca157a844c
1 /*
2 * QEMU ADB support
4 * Copyright (c) 2004 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
24 #include "hw.h"
25 #include "ppc_mac.h"
26 #include "console.h"
28 /* ADB commands */
29 #define ADB_BUSRESET 0x00
30 #define ADB_FLUSH 0x01
31 #define ADB_WRITEREG 0x08
32 #define ADB_READREG 0x0c
34 /* ADB device commands */
35 #define ADB_CMD_SELF_TEST 0xff
36 #define ADB_CMD_CHANGE_ID 0xfe
37 #define ADB_CMD_CHANGE_ID_AND_ACT 0xfd
38 #define ADB_CMD_CHANGE_ID_AND_ENABLE 0x00
40 /* ADB default device IDs (upper 4 bits of ADB command byte) */
41 #define ADB_DONGLE 1
42 #define ADB_KEYBOARD 2
43 #define ADB_MOUSE 3
44 #define ADB_TABLET 4
45 #define ADB_MODEM 5
46 #define ADB_MISC 7
48 /* error codes */
49 #define ADB_RET_NOTPRESENT (-2)
51 int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
53 ADBDevice *d;
54 int devaddr, cmd, i;
56 cmd = buf[0] & 0xf;
57 if (cmd == ADB_BUSRESET) {
58 for(i = 0; i < s->nb_devices; i++) {
59 d = &s->devices[i];
60 if (d->devreset) {
61 d->devreset(d);
64 return 0;
66 devaddr = buf[0] >> 4;
67 for(i = 0; i < s->nb_devices; i++) {
68 d = &s->devices[i];
69 if (d->devaddr == devaddr) {
70 return d->devreq(d, obuf, buf, len);
73 return ADB_RET_NOTPRESENT;
76 /* XXX: move that to cuda ? */
77 int adb_poll(ADBBusState *s, uint8_t *obuf)
79 ADBDevice *d;
80 int olen, i;
81 uint8_t buf[1];
83 olen = 0;
84 for(i = 0; i < s->nb_devices; i++) {
85 if (s->poll_index >= s->nb_devices)
86 s->poll_index = 0;
87 d = &s->devices[s->poll_index];
88 buf[0] = ADB_READREG | (d->devaddr << 4);
89 olen = adb_request(s, obuf + 1, buf, 1);
90 /* if there is data, we poll again the same device */
91 if (olen > 0) {
92 obuf[0] = buf[0];
93 olen++;
94 break;
96 s->poll_index++;
98 return olen;
101 ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
102 ADBDeviceRequest *devreq,
103 ADBDeviceReset *devreset,
104 void *opaque)
106 ADBDevice *d;
107 if (s->nb_devices >= MAX_ADB_DEVICES)
108 return NULL;
109 d = &s->devices[s->nb_devices++];
110 d->bus = s;
111 d->devaddr = devaddr;
112 d->devreq = devreq;
113 d->devreset = devreset;
114 d->opaque = opaque;
115 return d;
118 /***************************************************************/
119 /* Keyboard ADB device */
121 typedef struct KBDState {
122 uint8_t data[128];
123 int rptr, wptr, count;
124 } KBDState;
126 static const uint8_t pc_to_adb_keycode[256] = {
127 0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
128 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54, 0, 1,
129 2, 3, 5, 4, 38, 40, 37, 41, 39, 50, 56, 42, 6, 7, 8, 9,
130 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
131 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
132 84, 85, 82, 65, 0, 0, 10,103,111, 0, 0,110, 81, 0, 0, 0,
133 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
134 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
135 0, 0, 0, 94, 0, 93, 0, 0, 0, 0, 0, 0,104,102, 0, 0,
136 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76,125, 0, 0,
137 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0,
138 0, 0, 0, 0, 0, 75, 0, 0,124, 0, 0, 0, 0, 0, 0, 0,
139 0, 0, 0, 0, 0, 0, 0,115, 62,116, 0, 59, 0, 60, 0,119,
140 61,121,114,117, 0, 0, 0, 0, 0, 0, 0, 55,126, 0,127, 0,
141 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
142 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
145 static void adb_kbd_put_keycode(void *opaque, int keycode)
147 ADBDevice *d = opaque;
148 KBDState *s = d->opaque;
150 if (s->count < sizeof(s->data)) {
151 s->data[s->wptr] = keycode;
152 if (++s->wptr == sizeof(s->data))
153 s->wptr = 0;
154 s->count++;
158 static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
160 static int ext_keycode;
161 KBDState *s = d->opaque;
162 int adb_keycode, keycode;
163 int olen;
165 olen = 0;
166 for(;;) {
167 if (s->count == 0)
168 break;
169 keycode = s->data[s->rptr];
170 if (++s->rptr == sizeof(s->data))
171 s->rptr = 0;
172 s->count--;
174 if (keycode == 0xe0) {
175 ext_keycode = 1;
176 } else {
177 if (ext_keycode)
178 adb_keycode = pc_to_adb_keycode[keycode | 0x80];
179 else
180 adb_keycode = pc_to_adb_keycode[keycode & 0x7f];
181 obuf[0] = adb_keycode | (keycode & 0x80);
182 /* NOTE: could put a second keycode if needed */
183 obuf[1] = 0xff;
184 olen = 2;
185 ext_keycode = 0;
186 break;
189 return olen;
192 static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
193 const uint8_t *buf, int len)
195 KBDState *s = d->opaque;
196 int cmd, reg, olen;
198 if ((buf[0] & 0x0f) == ADB_FLUSH) {
199 /* flush keyboard fifo */
200 s->wptr = s->rptr = s->count = 0;
201 return 0;
204 cmd = buf[0] & 0xc;
205 reg = buf[0] & 0x3;
206 olen = 0;
207 switch(cmd) {
208 case ADB_WRITEREG:
209 switch(reg) {
210 case 2:
211 /* LED status */
212 break;
213 case 3:
214 switch(buf[2]) {
215 case ADB_CMD_SELF_TEST:
216 break;
217 case ADB_CMD_CHANGE_ID:
218 case ADB_CMD_CHANGE_ID_AND_ACT:
219 case ADB_CMD_CHANGE_ID_AND_ENABLE:
220 d->devaddr = buf[1] & 0xf;
221 break;
222 default:
223 /* XXX: check this */
224 d->devaddr = buf[1] & 0xf;
225 d->handler = buf[2];
226 break;
229 break;
230 case ADB_READREG:
231 switch(reg) {
232 case 0:
233 olen = adb_kbd_poll(d, obuf);
234 break;
235 case 1:
236 break;
237 case 2:
238 obuf[0] = 0x00; /* XXX: check this */
239 obuf[1] = 0x07; /* led status */
240 olen = 2;
241 break;
242 case 3:
243 obuf[0] = d->handler;
244 obuf[1] = d->devaddr;
245 olen = 2;
246 break;
248 break;
250 return olen;
253 static int adb_kbd_reset(ADBDevice *d)
255 KBDState *s = d->opaque;
257 d->handler = 1;
258 d->devaddr = ADB_KEYBOARD;
259 memset(s, 0, sizeof(KBDState));
261 return 0;
264 void adb_kbd_init(ADBBusState *bus)
266 ADBDevice *d;
267 KBDState *s;
268 s = qemu_mallocz(sizeof(KBDState));
269 d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
270 adb_kbd_reset, s);
271 adb_kbd_reset(d);
272 qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
275 /***************************************************************/
276 /* Mouse ADB device */
278 typedef struct MouseState {
279 int buttons_state, last_buttons_state;
280 int dx, dy, dz;
281 } MouseState;
283 static void adb_mouse_event(void *opaque,
284 int dx1, int dy1, int dz1, int buttons_state)
286 ADBDevice *d = opaque;
287 MouseState *s = d->opaque;
289 s->dx += dx1;
290 s->dy += dy1;
291 s->dz += dz1;
292 s->buttons_state = buttons_state;
296 static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
298 MouseState *s = d->opaque;
299 int dx, dy;
301 if (s->last_buttons_state == s->buttons_state &&
302 s->dx == 0 && s->dy == 0)
303 return 0;
305 dx = s->dx;
306 if (dx < -63)
307 dx = -63;
308 else if (dx > 63)
309 dx = 63;
311 dy = s->dy;
312 if (dy < -63)
313 dy = -63;
314 else if (dy > 63)
315 dy = 63;
317 s->dx -= dx;
318 s->dy -= dy;
319 s->last_buttons_state = s->buttons_state;
321 dx &= 0x7f;
322 dy &= 0x7f;
324 if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
325 dy |= 0x80;
326 if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
327 dx |= 0x80;
329 obuf[0] = dy;
330 obuf[1] = dx;
331 return 2;
334 static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
335 const uint8_t *buf, int len)
337 MouseState *s = d->opaque;
338 int cmd, reg, olen;
340 if ((buf[0] & 0x0f) == ADB_FLUSH) {
341 /* flush mouse fifo */
342 s->buttons_state = s->last_buttons_state;
343 s->dx = 0;
344 s->dy = 0;
345 s->dz = 0;
346 return 0;
349 cmd = buf[0] & 0xc;
350 reg = buf[0] & 0x3;
351 olen = 0;
352 switch(cmd) {
353 case ADB_WRITEREG:
354 switch(reg) {
355 case 2:
356 break;
357 case 3:
358 switch(buf[2]) {
359 case ADB_CMD_SELF_TEST:
360 break;
361 case ADB_CMD_CHANGE_ID:
362 case ADB_CMD_CHANGE_ID_AND_ACT:
363 case ADB_CMD_CHANGE_ID_AND_ENABLE:
364 d->devaddr = buf[1] & 0xf;
365 break;
366 default:
367 /* XXX: check this */
368 d->devaddr = buf[1] & 0xf;
369 break;
372 break;
373 case ADB_READREG:
374 switch(reg) {
375 case 0:
376 olen = adb_mouse_poll(d, obuf);
377 break;
378 case 1:
379 break;
380 case 3:
381 obuf[0] = d->handler;
382 obuf[1] = d->devaddr;
383 olen = 2;
384 break;
386 break;
388 return olen;
391 static int adb_mouse_reset(ADBDevice *d)
393 MouseState *s = d->opaque;
395 d->handler = 2;
396 d->devaddr = ADB_MOUSE;
397 memset(s, 0, sizeof(MouseState));
399 return 0;
402 void adb_mouse_init(ADBBusState *bus)
404 ADBDevice *d;
405 MouseState *s;
407 s = qemu_mallocz(sizeof(MouseState));
408 d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request,
409 adb_mouse_reset, s);
410 adb_mouse_reset(d);
411 qemu_add_mouse_event_handler(adb_mouse_event, d, 0, "QEMU ADB Mouse");