Statistics
| Branch: | Revision:

root / hw / adb.c @ 1ad2134f

History | View | Annotate | Download (12.4 kB)

1 267002cd bellard
/*
2 267002cd bellard
 * QEMU ADB support
3 5fafdf24 ths
 *
4 267002cd bellard
 * Copyright (c) 2004 Fabrice Bellard
5 5fafdf24 ths
 *
6 267002cd bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 267002cd bellard
 * of this software and associated documentation files (the "Software"), to deal
8 267002cd bellard
 * in the Software without restriction, including without limitation the rights
9 267002cd bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 267002cd bellard
 * copies of the Software, and to permit persons to whom the Software is
11 267002cd bellard
 * furnished to do so, subject to the following conditions:
12 267002cd bellard
 *
13 267002cd bellard
 * The above copyright notice and this permission notice shall be included in
14 267002cd bellard
 * all copies or substantial portions of the Software.
15 267002cd bellard
 *
16 267002cd bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 267002cd bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 267002cd bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 267002cd bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 267002cd bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 267002cd bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 267002cd bellard
 * THE SOFTWARE.
23 267002cd bellard
 */
24 87ecb68b pbrook
#include "hw.h"
25 87ecb68b pbrook
#include "ppc_mac.h"
26 87ecb68b pbrook
#include "console.h"
27 267002cd bellard
28 ea026b2f blueswir1
/* debug ADB */
29 ea026b2f blueswir1
//#define DEBUG_ADB
30 ea026b2f blueswir1
31 ea026b2f blueswir1
#ifdef DEBUG_ADB
32 001faf32 Blue Swirl
#define ADB_DPRINTF(fmt, ...) \
33 001faf32 Blue Swirl
do { printf("ADB: " fmt , ## __VA_ARGS__); } while (0)
34 ea026b2f blueswir1
#else
35 001faf32 Blue Swirl
#define ADB_DPRINTF(fmt, ...)
36 ea026b2f blueswir1
#endif
37 ea026b2f blueswir1
38 267002cd bellard
/* ADB commands */
39 267002cd bellard
#define ADB_BUSRESET                0x00
40 267002cd bellard
#define ADB_FLUSH               0x01
41 267002cd bellard
#define ADB_WRITEREG                0x08
42 267002cd bellard
#define ADB_READREG                0x0c
43 267002cd bellard
44 267002cd bellard
/* ADB device commands */
45 267002cd bellard
#define ADB_CMD_SELF_TEST                0xff
46 267002cd bellard
#define ADB_CMD_CHANGE_ID                0xfe
47 267002cd bellard
#define ADB_CMD_CHANGE_ID_AND_ACT        0xfd
48 267002cd bellard
#define ADB_CMD_CHANGE_ID_AND_ENABLE        0x00
49 267002cd bellard
50 267002cd bellard
/* ADB default device IDs (upper 4 bits of ADB command byte) */
51 267002cd bellard
#define ADB_DONGLE        1
52 267002cd bellard
#define ADB_KEYBOARD        2
53 267002cd bellard
#define ADB_MOUSE        3
54 267002cd bellard
#define ADB_TABLET        4
55 267002cd bellard
#define ADB_MODEM        5
56 267002cd bellard
#define ADB_MISC        7
57 267002cd bellard
58 bec9d989 bellard
/* error codes */
59 bec9d989 bellard
#define ADB_RET_NOTPRESENT (-2)
60 bec9d989 bellard
61 e2733d20 bellard
int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
62 267002cd bellard
{
63 267002cd bellard
    ADBDevice *d;
64 267002cd bellard
    int devaddr, cmd, i;
65 267002cd bellard
66 819e712b bellard
    cmd = buf[0] & 0xf;
67 bec9d989 bellard
    if (cmd == ADB_BUSRESET) {
68 bec9d989 bellard
        for(i = 0; i < s->nb_devices; i++) {
69 bec9d989 bellard
            d = &s->devices[i];
70 bec9d989 bellard
            if (d->devreset) {
71 bec9d989 bellard
                d->devreset(d);
72 bec9d989 bellard
            }
73 bec9d989 bellard
        }
74 bec9d989 bellard
        return 0;
75 267002cd bellard
    }
76 bec9d989 bellard
    devaddr = buf[0] >> 4;
77 267002cd bellard
    for(i = 0; i < s->nb_devices; i++) {
78 267002cd bellard
        d = &s->devices[i];
79 267002cd bellard
        if (d->devaddr == devaddr) {
80 e2733d20 bellard
            return d->devreq(d, obuf, buf, len);
81 267002cd bellard
        }
82 267002cd bellard
    }
83 bec9d989 bellard
    return ADB_RET_NOTPRESENT;
84 e2733d20 bellard
}
85 e2733d20 bellard
86 bec9d989 bellard
/* XXX: move that to cuda ? */
87 e2733d20 bellard
int adb_poll(ADBBusState *s, uint8_t *obuf)
88 e2733d20 bellard
{
89 e2733d20 bellard
    ADBDevice *d;
90 e2733d20 bellard
    int olen, i;
91 bec9d989 bellard
    uint8_t buf[1];
92 e2733d20 bellard
93 e2733d20 bellard
    olen = 0;
94 e2733d20 bellard
    for(i = 0; i < s->nb_devices; i++) {
95 e2733d20 bellard
        if (s->poll_index >= s->nb_devices)
96 e2733d20 bellard
            s->poll_index = 0;
97 e2733d20 bellard
        d = &s->devices[s->poll_index];
98 bec9d989 bellard
        buf[0] = ADB_READREG | (d->devaddr << 4);
99 bec9d989 bellard
        olen = adb_request(s, obuf + 1, buf, 1);
100 bec9d989 bellard
        /* if there is data, we poll again the same device */
101 bec9d989 bellard
        if (olen > 0) {
102 bec9d989 bellard
            obuf[0] = buf[0];
103 bec9d989 bellard
            olen++;
104 e2733d20 bellard
            break;
105 bec9d989 bellard
        }
106 bec9d989 bellard
        s->poll_index++;
107 e2733d20 bellard
    }
108 e2733d20 bellard
    return olen;
109 267002cd bellard
}
110 267002cd bellard
111 5fafdf24 ths
ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
112 5fafdf24 ths
                               ADBDeviceRequest *devreq,
113 5fafdf24 ths
                               ADBDeviceReset *devreset,
114 267002cd bellard
                               void *opaque)
115 267002cd bellard
{
116 267002cd bellard
    ADBDevice *d;
117 267002cd bellard
    if (s->nb_devices >= MAX_ADB_DEVICES)
118 267002cd bellard
        return NULL;
119 267002cd bellard
    d = &s->devices[s->nb_devices++];
120 267002cd bellard
    d->bus = s;
121 267002cd bellard
    d->devaddr = devaddr;
122 e2733d20 bellard
    d->devreq = devreq;
123 bec9d989 bellard
    d->devreset = devreset;
124 267002cd bellard
    d->opaque = opaque;
125 83479693 blueswir1
    qemu_register_reset((QEMUResetHandler *)devreset, d);
126 6e6b7363 blueswir1
    d->devreset(d);
127 267002cd bellard
    return d;
128 267002cd bellard
}
129 267002cd bellard
130 267002cd bellard
/***************************************************************/
131 267002cd bellard
/* Keyboard ADB device */
132 267002cd bellard
133 e2733d20 bellard
typedef struct KBDState {
134 e2733d20 bellard
    uint8_t data[128];
135 e2733d20 bellard
    int rptr, wptr, count;
136 e2733d20 bellard
} KBDState;
137 e2733d20 bellard
138 267002cd bellard
static const uint8_t pc_to_adb_keycode[256] = {
139 267002cd bellard
  0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
140 267002cd bellard
 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54,  0,  1,
141 267002cd bellard
  2,  3,  5,  4, 38, 40, 37, 41, 39, 50, 56, 42,  6,  7,  8,  9,
142 267002cd bellard
 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
143 267002cd bellard
 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
144 e2733d20 bellard
 84, 85, 82, 65,  0,  0, 10,103,111,  0,  0,110, 81,  0,  0,  0,
145 267002cd bellard
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
146 267002cd bellard
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
147 e2733d20 bellard
  0,  0,  0, 94,  0, 93,  0,  0,  0,  0,  0,  0,104,102,  0,  0,
148 e2733d20 bellard
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 76,125,  0,  0,
149 e2733d20 bellard
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,105,  0,  0,  0,  0,  0,
150 e2733d20 bellard
  0,  0,  0,  0,  0, 75,  0,  0,124,  0,  0,  0,  0,  0,  0,  0,
151 e2733d20 bellard
  0,  0,  0,  0,  0,  0,  0,115, 62,116,  0, 59,  0, 60,  0,119,
152 e2733d20 bellard
 61,121,114,117,  0,  0,  0,  0,  0,  0,  0, 55,126,  0,127,  0,
153 267002cd bellard
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
154 e2733d20 bellard
  0,  0,  0,  0,  0, 95,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
155 267002cd bellard
};
156 267002cd bellard
157 267002cd bellard
static void adb_kbd_put_keycode(void *opaque, int keycode)
158 267002cd bellard
{
159 267002cd bellard
    ADBDevice *d = opaque;
160 e2733d20 bellard
    KBDState *s = d->opaque;
161 e2733d20 bellard
162 e2733d20 bellard
    if (s->count < sizeof(s->data)) {
163 e2733d20 bellard
        s->data[s->wptr] = keycode;
164 e2733d20 bellard
        if (++s->wptr == sizeof(s->data))
165 e2733d20 bellard
            s->wptr = 0;
166 e2733d20 bellard
        s->count++;
167 267002cd bellard
    }
168 267002cd bellard
}
169 267002cd bellard
170 e2733d20 bellard
static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
171 267002cd bellard
{
172 e2733d20 bellard
    static int ext_keycode;
173 e2733d20 bellard
    KBDState *s = d->opaque;
174 e2733d20 bellard
    int adb_keycode, keycode;
175 e2733d20 bellard
    int olen;
176 e2733d20 bellard
177 e2733d20 bellard
    olen = 0;
178 e2733d20 bellard
    for(;;) {
179 e2733d20 bellard
        if (s->count == 0)
180 e2733d20 bellard
            break;
181 e2733d20 bellard
        keycode = s->data[s->rptr];
182 e2733d20 bellard
        if (++s->rptr == sizeof(s->data))
183 e2733d20 bellard
            s->rptr = 0;
184 e2733d20 bellard
        s->count--;
185 e2733d20 bellard
186 e2733d20 bellard
        if (keycode == 0xe0) {
187 e2733d20 bellard
            ext_keycode = 1;
188 e2733d20 bellard
        } else {
189 e2733d20 bellard
            if (ext_keycode)
190 e2733d20 bellard
                adb_keycode =  pc_to_adb_keycode[keycode | 0x80];
191 e2733d20 bellard
            else
192 e2733d20 bellard
                adb_keycode =  pc_to_adb_keycode[keycode & 0x7f];
193 bec9d989 bellard
            obuf[0] = adb_keycode | (keycode & 0x80);
194 bec9d989 bellard
            /* NOTE: could put a second keycode if needed */
195 bec9d989 bellard
            obuf[1] = 0xff;
196 bec9d989 bellard
            olen = 2;
197 e2733d20 bellard
            ext_keycode = 0;
198 e2733d20 bellard
            break;
199 e2733d20 bellard
        }
200 e2733d20 bellard
    }
201 e2733d20 bellard
    return olen;
202 e2733d20 bellard
}
203 e2733d20 bellard
204 e2733d20 bellard
static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
205 e2733d20 bellard
                           const uint8_t *buf, int len)
206 e2733d20 bellard
{
207 bec9d989 bellard
    KBDState *s = d->opaque;
208 e2733d20 bellard
    int cmd, reg, olen;
209 e2733d20 bellard
210 bec9d989 bellard
    if ((buf[0] & 0x0f) == ADB_FLUSH) {
211 bec9d989 bellard
        /* flush keyboard fifo */
212 bec9d989 bellard
        s->wptr = s->rptr = s->count = 0;
213 bec9d989 bellard
        return 0;
214 e2733d20 bellard
    }
215 267002cd bellard
216 267002cd bellard
    cmd = buf[0] & 0xc;
217 267002cd bellard
    reg = buf[0] & 0x3;
218 e2733d20 bellard
    olen = 0;
219 267002cd bellard
    switch(cmd) {
220 267002cd bellard
    case ADB_WRITEREG:
221 267002cd bellard
        switch(reg) {
222 267002cd bellard
        case 2:
223 267002cd bellard
            /* LED status */
224 267002cd bellard
            break;
225 267002cd bellard
        case 3:
226 267002cd bellard
            switch(buf[2]) {
227 267002cd bellard
            case ADB_CMD_SELF_TEST:
228 267002cd bellard
                break;
229 267002cd bellard
            case ADB_CMD_CHANGE_ID:
230 267002cd bellard
            case ADB_CMD_CHANGE_ID_AND_ACT:
231 267002cd bellard
            case ADB_CMD_CHANGE_ID_AND_ENABLE:
232 267002cd bellard
                d->devaddr = buf[1] & 0xf;
233 267002cd bellard
                break;
234 267002cd bellard
            default:
235 267002cd bellard
                /* XXX: check this */
236 267002cd bellard
                d->devaddr = buf[1] & 0xf;
237 267002cd bellard
                d->handler = buf[2];
238 267002cd bellard
                break;
239 267002cd bellard
            }
240 267002cd bellard
        }
241 267002cd bellard
        break;
242 267002cd bellard
    case ADB_READREG:
243 267002cd bellard
        switch(reg) {
244 bec9d989 bellard
        case 0:
245 bec9d989 bellard
            olen = adb_kbd_poll(d, obuf);
246 bec9d989 bellard
            break;
247 267002cd bellard
        case 1:
248 267002cd bellard
            break;
249 267002cd bellard
        case 2:
250 e2733d20 bellard
            obuf[0] = 0x00; /* XXX: check this */
251 e2733d20 bellard
            obuf[1] = 0x07; /* led status */
252 e2733d20 bellard
            olen = 2;
253 267002cd bellard
            break;
254 267002cd bellard
        case 3:
255 e2733d20 bellard
            obuf[0] = d->handler;
256 e2733d20 bellard
            obuf[1] = d->devaddr;
257 e2733d20 bellard
            olen = 2;
258 267002cd bellard
            break;
259 267002cd bellard
        }
260 267002cd bellard
        break;
261 267002cd bellard
    }
262 e2733d20 bellard
    return olen;
263 267002cd bellard
}
264 267002cd bellard
265 9b64997f blueswir1
static void adb_kbd_save(QEMUFile *f, void *opaque)
266 9b64997f blueswir1
{
267 9b64997f blueswir1
    KBDState *s = (KBDState *)opaque;
268 9b64997f blueswir1
269 9b64997f blueswir1
    qemu_put_buffer(f, s->data, sizeof(s->data));
270 9b64997f blueswir1
    qemu_put_sbe32s(f, &s->rptr);
271 9b64997f blueswir1
    qemu_put_sbe32s(f, &s->wptr);
272 9b64997f blueswir1
    qemu_put_sbe32s(f, &s->count);
273 9b64997f blueswir1
}
274 9b64997f blueswir1
275 9b64997f blueswir1
static int adb_kbd_load(QEMUFile *f, void *opaque, int version_id)
276 9b64997f blueswir1
{
277 9b64997f blueswir1
    KBDState *s = (KBDState *)opaque;
278 9b64997f blueswir1
279 9b64997f blueswir1
    if (version_id != 1)
280 9b64997f blueswir1
        return -EINVAL;
281 9b64997f blueswir1
282 9b64997f blueswir1
    qemu_get_buffer(f, s->data, sizeof(s->data));
283 9b64997f blueswir1
    qemu_get_sbe32s(f, &s->rptr);
284 9b64997f blueswir1
    qemu_get_sbe32s(f, &s->wptr);
285 9b64997f blueswir1
    qemu_get_sbe32s(f, &s->count);
286 9b64997f blueswir1
287 9b64997f blueswir1
    return 0;
288 9b64997f blueswir1
}
289 9b64997f blueswir1
290 3988e897 bellard
static int adb_kbd_reset(ADBDevice *d)
291 3988e897 bellard
{
292 3988e897 bellard
    KBDState *s = d->opaque;
293 3988e897 bellard
294 3988e897 bellard
    d->handler = 1;
295 3988e897 bellard
    d->devaddr = ADB_KEYBOARD;
296 3988e897 bellard
    memset(s, 0, sizeof(KBDState));
297 3988e897 bellard
298 3988e897 bellard
    return 0;
299 3988e897 bellard
}
300 3988e897 bellard
301 267002cd bellard
void adb_kbd_init(ADBBusState *bus)
302 267002cd bellard
{
303 267002cd bellard
    ADBDevice *d;
304 e2733d20 bellard
    KBDState *s;
305 e2733d20 bellard
    s = qemu_mallocz(sizeof(KBDState));
306 3988e897 bellard
    d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
307 3988e897 bellard
                            adb_kbd_reset, s);
308 267002cd bellard
    qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
309 9b64997f blueswir1
    register_savevm("adb_kbd", -1, 1, adb_kbd_save,
310 9b64997f blueswir1
                    adb_kbd_load, s);
311 267002cd bellard
}
312 267002cd bellard
313 267002cd bellard
/***************************************************************/
314 267002cd bellard
/* Mouse ADB device */
315 267002cd bellard
316 e2733d20 bellard
typedef struct MouseState {
317 e2733d20 bellard
    int buttons_state, last_buttons_state;
318 e2733d20 bellard
    int dx, dy, dz;
319 e2733d20 bellard
} MouseState;
320 e2733d20 bellard
321 267002cd bellard
static void adb_mouse_event(void *opaque,
322 267002cd bellard
                            int dx1, int dy1, int dz1, int buttons_state)
323 267002cd bellard
{
324 267002cd bellard
    ADBDevice *d = opaque;
325 e2733d20 bellard
    MouseState *s = d->opaque;
326 e2733d20 bellard
327 e2733d20 bellard
    s->dx += dx1;
328 e2733d20 bellard
    s->dy += dy1;
329 e2733d20 bellard
    s->dz += dz1;
330 e2733d20 bellard
    s->buttons_state = buttons_state;
331 e2733d20 bellard
}
332 e2733d20 bellard
333 e2733d20 bellard
334 e2733d20 bellard
static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
335 e2733d20 bellard
{
336 e2733d20 bellard
    MouseState *s = d->opaque;
337 267002cd bellard
    int dx, dy;
338 267002cd bellard
339 e2733d20 bellard
    if (s->last_buttons_state == s->buttons_state &&
340 e2733d20 bellard
        s->dx == 0 && s->dy == 0)
341 e2733d20 bellard
        return 0;
342 3b46e624 ths
343 e2733d20 bellard
    dx = s->dx;
344 267002cd bellard
    if (dx < -63)
345 267002cd bellard
        dx = -63;
346 267002cd bellard
    else if (dx > 63)
347 267002cd bellard
        dx = 63;
348 3b46e624 ths
349 e2733d20 bellard
    dy = s->dy;
350 267002cd bellard
    if (dy < -63)
351 267002cd bellard
        dy = -63;
352 267002cd bellard
    else if (dy > 63)
353 267002cd bellard
        dy = 63;
354 3b46e624 ths
355 e2733d20 bellard
    s->dx -= dx;
356 e2733d20 bellard
    s->dy -= dy;
357 e2733d20 bellard
    s->last_buttons_state = s->buttons_state;
358 3b46e624 ths
359 267002cd bellard
    dx &= 0x7f;
360 267002cd bellard
    dy &= 0x7f;
361 3b46e624 ths
362 bec9d989 bellard
    if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
363 267002cd bellard
        dy |= 0x80;
364 bec9d989 bellard
    if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
365 267002cd bellard
        dx |= 0x80;
366 3b46e624 ths
367 bec9d989 bellard
    obuf[0] = dy;
368 bec9d989 bellard
    obuf[1] = dx;
369 bec9d989 bellard
    return 2;
370 267002cd bellard
}
371 267002cd bellard
372 e2733d20 bellard
static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
373 e2733d20 bellard
                             const uint8_t *buf, int len)
374 267002cd bellard
{
375 bec9d989 bellard
    MouseState *s = d->opaque;
376 e2733d20 bellard
    int cmd, reg, olen;
377 3b46e624 ths
378 bec9d989 bellard
    if ((buf[0] & 0x0f) == ADB_FLUSH) {
379 bec9d989 bellard
        /* flush mouse fifo */
380 bec9d989 bellard
        s->buttons_state = s->last_buttons_state;
381 bec9d989 bellard
        s->dx = 0;
382 bec9d989 bellard
        s->dy = 0;
383 bec9d989 bellard
        s->dz = 0;
384 bec9d989 bellard
        return 0;
385 e2733d20 bellard
    }
386 267002cd bellard
387 267002cd bellard
    cmd = buf[0] & 0xc;
388 267002cd bellard
    reg = buf[0] & 0x3;
389 e2733d20 bellard
    olen = 0;
390 267002cd bellard
    switch(cmd) {
391 267002cd bellard
    case ADB_WRITEREG:
392 ea026b2f blueswir1
        ADB_DPRINTF("write reg %d val 0x%2.2x\n", reg, buf[1]);
393 267002cd bellard
        switch(reg) {
394 267002cd bellard
        case 2:
395 267002cd bellard
            break;
396 267002cd bellard
        case 3:
397 267002cd bellard
            switch(buf[2]) {
398 267002cd bellard
            case ADB_CMD_SELF_TEST:
399 267002cd bellard
                break;
400 267002cd bellard
            case ADB_CMD_CHANGE_ID:
401 267002cd bellard
            case ADB_CMD_CHANGE_ID_AND_ACT:
402 267002cd bellard
            case ADB_CMD_CHANGE_ID_AND_ENABLE:
403 267002cd bellard
                d->devaddr = buf[1] & 0xf;
404 267002cd bellard
                break;
405 267002cd bellard
            default:
406 267002cd bellard
                /* XXX: check this */
407 267002cd bellard
                d->devaddr = buf[1] & 0xf;
408 267002cd bellard
                break;
409 267002cd bellard
            }
410 267002cd bellard
        }
411 267002cd bellard
        break;
412 267002cd bellard
    case ADB_READREG:
413 267002cd bellard
        switch(reg) {
414 bec9d989 bellard
        case 0:
415 bec9d989 bellard
            olen = adb_mouse_poll(d, obuf);
416 bec9d989 bellard
            break;
417 267002cd bellard
        case 1:
418 267002cd bellard
            break;
419 267002cd bellard
        case 3:
420 e2733d20 bellard
            obuf[0] = d->handler;
421 e2733d20 bellard
            obuf[1] = d->devaddr;
422 e2733d20 bellard
            olen = 2;
423 267002cd bellard
            break;
424 267002cd bellard
        }
425 ea026b2f blueswir1
        ADB_DPRINTF("read reg %d obuf[0] 0x%2.2x obuf[1] 0x%2.2x\n", reg,
426 ea026b2f blueswir1
                    obuf[0], obuf[1]);
427 267002cd bellard
        break;
428 267002cd bellard
    }
429 e2733d20 bellard
    return olen;
430 267002cd bellard
}
431 267002cd bellard
432 3988e897 bellard
static int adb_mouse_reset(ADBDevice *d)
433 3988e897 bellard
{
434 3988e897 bellard
    MouseState *s = d->opaque;
435 3988e897 bellard
436 3988e897 bellard
    d->handler = 2;
437 3988e897 bellard
    d->devaddr = ADB_MOUSE;
438 3988e897 bellard
    memset(s, 0, sizeof(MouseState));
439 3988e897 bellard
440 3988e897 bellard
    return 0;
441 3988e897 bellard
}
442 3988e897 bellard
443 9b64997f blueswir1
static void adb_mouse_save(QEMUFile *f, void *opaque)
444 9b64997f blueswir1
{
445 9b64997f blueswir1
    MouseState *s = (MouseState *)opaque;
446 9b64997f blueswir1
447 9b64997f blueswir1
    qemu_put_sbe32s(f, &s->buttons_state);
448 9b64997f blueswir1
    qemu_put_sbe32s(f, &s->last_buttons_state);
449 9b64997f blueswir1
    qemu_put_sbe32s(f, &s->dx);
450 9b64997f blueswir1
    qemu_put_sbe32s(f, &s->dy);
451 9b64997f blueswir1
    qemu_put_sbe32s(f, &s->dz);
452 9b64997f blueswir1
}
453 9b64997f blueswir1
454 9b64997f blueswir1
static int adb_mouse_load(QEMUFile *f, void *opaque, int version_id)
455 9b64997f blueswir1
{
456 9b64997f blueswir1
    MouseState *s = (MouseState *)opaque;
457 9b64997f blueswir1
458 9b64997f blueswir1
    if (version_id != 1)
459 9b64997f blueswir1
        return -EINVAL;
460 9b64997f blueswir1
461 9b64997f blueswir1
    qemu_get_sbe32s(f, &s->buttons_state);
462 9b64997f blueswir1
    qemu_get_sbe32s(f, &s->last_buttons_state);
463 9b64997f blueswir1
    qemu_get_sbe32s(f, &s->dx);
464 9b64997f blueswir1
    qemu_get_sbe32s(f, &s->dy);
465 9b64997f blueswir1
    qemu_get_sbe32s(f, &s->dz);
466 9b64997f blueswir1
467 9b64997f blueswir1
    return 0;
468 9b64997f blueswir1
}
469 9b64997f blueswir1
470 267002cd bellard
void adb_mouse_init(ADBBusState *bus)
471 267002cd bellard
{
472 267002cd bellard
    ADBDevice *d;
473 e2733d20 bellard
    MouseState *s;
474 267002cd bellard
475 e2733d20 bellard
    s = qemu_mallocz(sizeof(MouseState));
476 3988e897 bellard
    d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request,
477 3988e897 bellard
                            adb_mouse_reset, s);
478 455204eb ths
    qemu_add_mouse_event_handler(adb_mouse_event, d, 0, "QEMU ADB Mouse");
479 9b64997f blueswir1
    register_savevm("adb_mouse", -1, 1, adb_mouse_save,
480 9b64997f blueswir1
                    adb_mouse_load, s);
481 267002cd bellard
}