fixed register 0 usage - fixed mouse buttons
[qemu] / hw / adb.c
1 /*
2  * QEMU ADB support
3  * 
4  * Copyright (c) 2004 Fabrice Bellard
5  * 
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:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
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.
23  */
24 #include "vl.h"
25
26 /* ADB commands */
27 #define ADB_BUSRESET            0x00
28 #define ADB_FLUSH               0x01
29 #define ADB_WRITEREG            0x08
30 #define ADB_READREG             0x0c
31
32 /* ADB device commands */
33 #define ADB_CMD_SELF_TEST               0xff
34 #define ADB_CMD_CHANGE_ID               0xfe
35 #define ADB_CMD_CHANGE_ID_AND_ACT       0xfd
36 #define ADB_CMD_CHANGE_ID_AND_ENABLE    0x00
37
38 /* ADB default device IDs (upper 4 bits of ADB command byte) */
39 #define ADB_DONGLE      1
40 #define ADB_KEYBOARD    2
41 #define ADB_MOUSE       3
42 #define ADB_TABLET      4
43 #define ADB_MODEM       5
44 #define ADB_MISC        7
45
46 /* error codes */
47 #define ADB_RET_NOTPRESENT (-2)
48
49 int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
50 {
51     ADBDevice *d;
52     int devaddr, cmd, i;
53
54     cmd = buf[0] & 0xf;
55     if (cmd == ADB_BUSRESET) {
56         for(i = 0; i < s->nb_devices; i++) {
57             d = &s->devices[i];
58             if (d->devreset) {
59                 d->devreset(d);
60             }
61         }
62         return 0;
63     }
64     devaddr = buf[0] >> 4;
65     for(i = 0; i < s->nb_devices; i++) {
66         d = &s->devices[i];
67         if (d->devaddr == devaddr) {
68             return d->devreq(d, obuf, buf, len);
69         }
70     }
71     return ADB_RET_NOTPRESENT;
72 }
73
74 /* XXX: move that to cuda ? */
75 int adb_poll(ADBBusState *s, uint8_t *obuf)
76 {
77     ADBDevice *d;
78     int olen, i;
79     uint8_t buf[1];
80
81     olen = 0;
82     for(i = 0; i < s->nb_devices; i++) {
83         if (s->poll_index >= s->nb_devices)
84             s->poll_index = 0;
85         d = &s->devices[s->poll_index];
86         buf[0] = ADB_READREG | (d->devaddr << 4);
87         olen = adb_request(s, obuf + 1, buf, 1);
88         /* if there is data, we poll again the same device */
89         if (olen > 0) {
90             obuf[0] = buf[0];
91             olen++;
92             break;
93         }
94         s->poll_index++;
95     }
96     return olen;
97 }
98
99 ADBDevice *adb_register_device(ADBBusState *s, int devaddr, 
100                                ADBDeviceRequest *devreq, 
101                                ADBDeviceReset *devreset, 
102                                void *opaque)
103 {
104     ADBDevice *d;
105     if (s->nb_devices >= MAX_ADB_DEVICES)
106         return NULL;
107     d = &s->devices[s->nb_devices++];
108     d->bus = s;
109     d->devaddr = devaddr;
110     d->devreq = devreq;
111     d->devreset = devreset;
112     d->opaque = opaque;
113     return d;
114 }
115
116 /***************************************************************/
117 /* Keyboard ADB device */
118
119 typedef struct KBDState {
120     uint8_t data[128];
121     int rptr, wptr, count;
122 } KBDState;
123
124 static const uint8_t pc_to_adb_keycode[256] = {
125   0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
126  12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54,  0,  1,
127   2,  3,  5,  4, 38, 40, 37, 41, 39, 50, 56, 42,  6,  7,  8,  9,
128  11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
129  97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
130  84, 85, 82, 65,  0,  0, 10,103,111,  0,  0,110, 81,  0,  0,  0,
131   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
132   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
133   0,  0,  0, 94,  0, 93,  0,  0,  0,  0,  0,  0,104,102,  0,  0,
134   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 76,125,  0,  0,
135   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,105,  0,  0,  0,  0,  0,
136   0,  0,  0,  0,  0, 75,  0,  0,124,  0,  0,  0,  0,  0,  0,  0,
137   0,  0,  0,  0,  0,  0,  0,115, 62,116,  0, 59,  0, 60,  0,119,
138  61,121,114,117,  0,  0,  0,  0,  0,  0,  0, 55,126,  0,127,  0,
139   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
140   0,  0,  0,  0,  0, 95,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
141 };
142
143 static void adb_kbd_put_keycode(void *opaque, int keycode)
144 {
145     ADBDevice *d = opaque;
146     KBDState *s = d->opaque;
147
148     if (s->count < sizeof(s->data)) {
149         s->data[s->wptr] = keycode;
150         if (++s->wptr == sizeof(s->data))
151             s->wptr = 0;
152         s->count++;
153     }
154 }
155
156 static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
157 {
158     static int ext_keycode;
159     KBDState *s = d->opaque;
160     int adb_keycode, keycode;
161     int olen;
162
163     olen = 0;
164     for(;;) {
165         if (s->count == 0)
166             break;
167         keycode = s->data[s->rptr];
168         if (++s->rptr == sizeof(s->data))
169             s->rptr = 0;
170         s->count--;
171
172         if (keycode == 0xe0) {
173             ext_keycode = 1;
174         } else {
175             if (ext_keycode)
176                 adb_keycode =  pc_to_adb_keycode[keycode | 0x80];
177             else
178                 adb_keycode =  pc_to_adb_keycode[keycode & 0x7f];
179             obuf[0] = adb_keycode | (keycode & 0x80);
180             /* NOTE: could put a second keycode if needed */
181             obuf[1] = 0xff;
182             olen = 2;
183             ext_keycode = 0;
184             break;
185         }
186     }
187     return olen;
188 }
189
190 static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
191                            const uint8_t *buf, int len)
192 {
193     KBDState *s = d->opaque;
194     int cmd, reg, olen;
195
196     if ((buf[0] & 0x0f) == ADB_FLUSH) {
197         /* flush keyboard fifo */
198         s->wptr = s->rptr = s->count = 0;
199         return 0;
200     }
201
202     cmd = buf[0] & 0xc;
203     reg = buf[0] & 0x3;
204     olen = 0;
205     switch(cmd) {
206     case ADB_WRITEREG:
207         switch(reg) {
208         case 2:
209             /* LED status */
210             break;
211         case 3:
212             switch(buf[2]) {
213             case ADB_CMD_SELF_TEST:
214                 break;
215             case ADB_CMD_CHANGE_ID:
216             case ADB_CMD_CHANGE_ID_AND_ACT:
217             case ADB_CMD_CHANGE_ID_AND_ENABLE:
218                 d->devaddr = buf[1] & 0xf;
219                 break;
220             default:
221                 /* XXX: check this */
222                 d->devaddr = buf[1] & 0xf;
223                 d->handler = buf[2];
224                 break;
225             }
226         }
227         break;
228     case ADB_READREG:
229         switch(reg) {
230         case 0:
231             olen = adb_kbd_poll(d, obuf);
232             break;
233         case 1:
234             break;
235         case 2:
236             obuf[0] = 0x00; /* XXX: check this */
237             obuf[1] = 0x07; /* led status */
238             olen = 2;
239             break;
240         case 3:
241             obuf[0] = d->handler;
242             obuf[1] = d->devaddr;
243             olen = 2;
244             break;
245         }
246         break;
247     }
248     return olen;
249 }
250
251 void adb_kbd_init(ADBBusState *bus)
252 {
253     ADBDevice *d;
254     KBDState *s;
255     s = qemu_mallocz(sizeof(KBDState));
256     d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request, NULL, s);
257     d->handler = 1;
258     qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
259 }
260
261 /***************************************************************/
262 /* Mouse ADB device */
263
264 typedef struct MouseState {
265     int buttons_state, last_buttons_state;
266     int dx, dy, dz;
267 } MouseState;
268
269 static void adb_mouse_event(void *opaque,
270                             int dx1, int dy1, int dz1, int buttons_state)
271 {
272     ADBDevice *d = opaque;
273     MouseState *s = d->opaque;
274
275     s->dx += dx1;
276     s->dy += dy1;
277     s->dz += dz1;
278     s->buttons_state = buttons_state;
279 }
280
281
282 static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
283 {
284     MouseState *s = d->opaque;
285     int dx, dy;
286
287     if (s->last_buttons_state == s->buttons_state &&
288         s->dx == 0 && s->dy == 0)
289         return 0;
290         
291     dx = s->dx;
292     if (dx < -63)
293         dx = -63;
294     else if (dx > 63)
295         dx = 63;
296     
297     dy = s->dy;
298     if (dy < -63)
299         dy = -63;
300     else if (dy > 63)
301         dy = 63;
302     
303     s->dx -= dx;
304     s->dy -= dy;
305     s->last_buttons_state = s->buttons_state;
306     
307     dx &= 0x7f;
308     dy &= 0x7f;
309     
310     if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
311         dy |= 0x80;
312     if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
313         dx |= 0x80;
314     
315     obuf[0] = dy;
316     obuf[1] = dx;
317     return 2;
318 }
319
320 static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
321                              const uint8_t *buf, int len)
322 {
323     MouseState *s = d->opaque;
324     int cmd, reg, olen;
325     
326     if ((buf[0] & 0x0f) == ADB_FLUSH) {
327         /* flush mouse fifo */
328         s->buttons_state = s->last_buttons_state;
329         s->dx = 0;
330         s->dy = 0;
331         s->dz = 0;
332         return 0;
333     }
334
335     cmd = buf[0] & 0xc;
336     reg = buf[0] & 0x3;
337     olen = 0;
338     switch(cmd) {
339     case ADB_WRITEREG:
340         switch(reg) {
341         case 2:
342             break;
343         case 3:
344             switch(buf[2]) {
345             case ADB_CMD_SELF_TEST:
346                 break;
347             case ADB_CMD_CHANGE_ID:
348             case ADB_CMD_CHANGE_ID_AND_ACT:
349             case ADB_CMD_CHANGE_ID_AND_ENABLE:
350                 d->devaddr = buf[1] & 0xf;
351                 break;
352             default:
353                 /* XXX: check this */
354                 d->devaddr = buf[1] & 0xf;
355                 break;
356             }
357         }
358         break;
359     case ADB_READREG:
360         switch(reg) {
361         case 0:
362             olen = adb_mouse_poll(d, obuf);
363             break;
364         case 1:
365             break;
366         case 3:
367             obuf[0] = d->handler;
368             obuf[1] = d->devaddr;
369             olen = 2;
370             break;
371         }
372         break;
373     }
374     return olen;
375 }
376
377 void adb_mouse_init(ADBBusState *bus)
378 {
379     ADBDevice *d;
380     MouseState *s;
381
382     s = qemu_mallocz(sizeof(MouseState));
383     d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request, NULL, s);
384     d->handler = 2;
385     qemu_add_mouse_event_handler(adb_mouse_event, d);
386 }