Statistics
| Branch: | Revision:

root / hw / adb.c @ a08d4367

History | View | Annotate | Download (12.4 kB)

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 "hw.h"
25
#include "ppc_mac.h"
26
#include "console.h"
27

    
28
/* debug ADB */
29
//#define DEBUG_ADB
30

    
31
#ifdef DEBUG_ADB
32
#define ADB_DPRINTF(fmt, ...) \
33
do { printf("ADB: " fmt , ## __VA_ARGS__); } while (0)
34
#else
35
#define ADB_DPRINTF(fmt, ...)
36
#endif
37

    
38
/* ADB commands */
39
#define ADB_BUSRESET                0x00
40
#define ADB_FLUSH               0x01
41
#define ADB_WRITEREG                0x08
42
#define ADB_READREG                0x0c
43

    
44
/* ADB device commands */
45
#define ADB_CMD_SELF_TEST                0xff
46
#define ADB_CMD_CHANGE_ID                0xfe
47
#define ADB_CMD_CHANGE_ID_AND_ACT        0xfd
48
#define ADB_CMD_CHANGE_ID_AND_ENABLE        0x00
49

    
50
/* ADB default device IDs (upper 4 bits of ADB command byte) */
51
#define ADB_DONGLE        1
52
#define ADB_KEYBOARD        2
53
#define ADB_MOUSE        3
54
#define ADB_TABLET        4
55
#define ADB_MODEM        5
56
#define ADB_MISC        7
57

    
58
/* error codes */
59
#define ADB_RET_NOTPRESENT (-2)
60

    
61
int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
62
{
63
    ADBDevice *d;
64
    int devaddr, cmd, i;
65

    
66
    cmd = buf[0] & 0xf;
67
    if (cmd == ADB_BUSRESET) {
68
        for(i = 0; i < s->nb_devices; i++) {
69
            d = &s->devices[i];
70
            if (d->devreset) {
71
                d->devreset(d);
72
            }
73
        }
74
        return 0;
75
    }
76
    devaddr = buf[0] >> 4;
77
    for(i = 0; i < s->nb_devices; i++) {
78
        d = &s->devices[i];
79
        if (d->devaddr == devaddr) {
80
            return d->devreq(d, obuf, buf, len);
81
        }
82
    }
83
    return ADB_RET_NOTPRESENT;
84
}
85

    
86
/* XXX: move that to cuda ? */
87
int adb_poll(ADBBusState *s, uint8_t *obuf)
88
{
89
    ADBDevice *d;
90
    int olen, i;
91
    uint8_t buf[1];
92

    
93
    olen = 0;
94
    for(i = 0; i < s->nb_devices; i++) {
95
        if (s->poll_index >= s->nb_devices)
96
            s->poll_index = 0;
97
        d = &s->devices[s->poll_index];
98
        buf[0] = ADB_READREG | (d->devaddr << 4);
99
        olen = adb_request(s, obuf + 1, buf, 1);
100
        /* if there is data, we poll again the same device */
101
        if (olen > 0) {
102
            obuf[0] = buf[0];
103
            olen++;
104
            break;
105
        }
106
        s->poll_index++;
107
    }
108
    return olen;
109
}
110

    
111
ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
112
                               ADBDeviceRequest *devreq,
113
                               ADBDeviceReset *devreset,
114
                               void *opaque)
115
{
116
    ADBDevice *d;
117
    if (s->nb_devices >= MAX_ADB_DEVICES)
118
        return NULL;
119
    d = &s->devices[s->nb_devices++];
120
    d->bus = s;
121
    d->devaddr = devaddr;
122
    d->devreq = devreq;
123
    d->devreset = devreset;
124
    d->opaque = opaque;
125
    qemu_register_reset((QEMUResetHandler *)devreset, d);
126
    d->devreset(d);
127
    return d;
128
}
129

    
130
/***************************************************************/
131
/* Keyboard ADB device */
132

    
133
typedef struct KBDState {
134
    uint8_t data[128];
135
    int rptr, wptr, count;
136
} KBDState;
137

    
138
static const uint8_t pc_to_adb_keycode[256] = {
139
  0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
140
 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54,  0,  1,
141
  2,  3,  5,  4, 38, 40, 37, 41, 39, 50, 56, 42,  6,  7,  8,  9,
142
 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
143
 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
144
 84, 85, 82, 65,  0,  0, 10,103,111,  0,  0,110, 81,  0,  0,  0,
145
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
146
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
147
  0,  0,  0, 94,  0, 93,  0,  0,  0,  0,  0,  0,104,102,  0,  0,
148
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 76,125,  0,  0,
149
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,105,  0,  0,  0,  0,  0,
150
  0,  0,  0,  0,  0, 75,  0,  0,124,  0,  0,  0,  0,  0,  0,  0,
151
  0,  0,  0,  0,  0,  0,  0,115, 62,116,  0, 59,  0, 60,  0,119,
152
 61,121,114,117,  0,  0,  0,  0,  0,  0,  0, 55,126,  0,127,  0,
153
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
154
  0,  0,  0,  0,  0, 95,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
155
};
156

    
157
static void adb_kbd_put_keycode(void *opaque, int keycode)
158
{
159
    ADBDevice *d = opaque;
160
    KBDState *s = d->opaque;
161

    
162
    if (s->count < sizeof(s->data)) {
163
        s->data[s->wptr] = keycode;
164
        if (++s->wptr == sizeof(s->data))
165
            s->wptr = 0;
166
        s->count++;
167
    }
168
}
169

    
170
static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
171
{
172
    static int ext_keycode;
173
    KBDState *s = d->opaque;
174
    int adb_keycode, keycode;
175
    int olen;
176

    
177
    olen = 0;
178
    for(;;) {
179
        if (s->count == 0)
180
            break;
181
        keycode = s->data[s->rptr];
182
        if (++s->rptr == sizeof(s->data))
183
            s->rptr = 0;
184
        s->count--;
185

    
186
        if (keycode == 0xe0) {
187
            ext_keycode = 1;
188
        } else {
189
            if (ext_keycode)
190
                adb_keycode =  pc_to_adb_keycode[keycode | 0x80];
191
            else
192
                adb_keycode =  pc_to_adb_keycode[keycode & 0x7f];
193
            obuf[0] = adb_keycode | (keycode & 0x80);
194
            /* NOTE: could put a second keycode if needed */
195
            obuf[1] = 0xff;
196
            olen = 2;
197
            ext_keycode = 0;
198
            break;
199
        }
200
    }
201
    return olen;
202
}
203

    
204
static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
205
                           const uint8_t *buf, int len)
206
{
207
    KBDState *s = d->opaque;
208
    int cmd, reg, olen;
209

    
210
    if ((buf[0] & 0x0f) == ADB_FLUSH) {
211
        /* flush keyboard fifo */
212
        s->wptr = s->rptr = s->count = 0;
213
        return 0;
214
    }
215

    
216
    cmd = buf[0] & 0xc;
217
    reg = buf[0] & 0x3;
218
    olen = 0;
219
    switch(cmd) {
220
    case ADB_WRITEREG:
221
        switch(reg) {
222
        case 2:
223
            /* LED status */
224
            break;
225
        case 3:
226
            switch(buf[2]) {
227
            case ADB_CMD_SELF_TEST:
228
                break;
229
            case ADB_CMD_CHANGE_ID:
230
            case ADB_CMD_CHANGE_ID_AND_ACT:
231
            case ADB_CMD_CHANGE_ID_AND_ENABLE:
232
                d->devaddr = buf[1] & 0xf;
233
                break;
234
            default:
235
                /* XXX: check this */
236
                d->devaddr = buf[1] & 0xf;
237
                d->handler = buf[2];
238
                break;
239
            }
240
        }
241
        break;
242
    case ADB_READREG:
243
        switch(reg) {
244
        case 0:
245
            olen = adb_kbd_poll(d, obuf);
246
            break;
247
        case 1:
248
            break;
249
        case 2:
250
            obuf[0] = 0x00; /* XXX: check this */
251
            obuf[1] = 0x07; /* led status */
252
            olen = 2;
253
            break;
254
        case 3:
255
            obuf[0] = d->handler;
256
            obuf[1] = d->devaddr;
257
            olen = 2;
258
            break;
259
        }
260
        break;
261
    }
262
    return olen;
263
}
264

    
265
static void adb_kbd_save(QEMUFile *f, void *opaque)
266
{
267
    KBDState *s = (KBDState *)opaque;
268

    
269
    qemu_put_buffer(f, s->data, sizeof(s->data));
270
    qemu_put_sbe32s(f, &s->rptr);
271
    qemu_put_sbe32s(f, &s->wptr);
272
    qemu_put_sbe32s(f, &s->count);
273
}
274

    
275
static int adb_kbd_load(QEMUFile *f, void *opaque, int version_id)
276
{
277
    KBDState *s = (KBDState *)opaque;
278

    
279
    if (version_id != 1)
280
        return -EINVAL;
281

    
282
    qemu_get_buffer(f, s->data, sizeof(s->data));
283
    qemu_get_sbe32s(f, &s->rptr);
284
    qemu_get_sbe32s(f, &s->wptr);
285
    qemu_get_sbe32s(f, &s->count);
286

    
287
    return 0;
288
}
289

    
290
static int adb_kbd_reset(ADBDevice *d)
291
{
292
    KBDState *s = d->opaque;
293

    
294
    d->handler = 1;
295
    d->devaddr = ADB_KEYBOARD;
296
    memset(s, 0, sizeof(KBDState));
297

    
298
    return 0;
299
}
300

    
301
void adb_kbd_init(ADBBusState *bus)
302
{
303
    ADBDevice *d;
304
    KBDState *s;
305
    s = qemu_mallocz(sizeof(KBDState));
306
    d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
307
                            adb_kbd_reset, s);
308
    qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
309
    register_savevm("adb_kbd", -1, 1, adb_kbd_save,
310
                    adb_kbd_load, s);
311
}
312

    
313
/***************************************************************/
314
/* Mouse ADB device */
315

    
316
typedef struct MouseState {
317
    int buttons_state, last_buttons_state;
318
    int dx, dy, dz;
319
} MouseState;
320

    
321
static void adb_mouse_event(void *opaque,
322
                            int dx1, int dy1, int dz1, int buttons_state)
323
{
324
    ADBDevice *d = opaque;
325
    MouseState *s = d->opaque;
326

    
327
    s->dx += dx1;
328
    s->dy += dy1;
329
    s->dz += dz1;
330
    s->buttons_state = buttons_state;
331
}
332

    
333

    
334
static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
335
{
336
    MouseState *s = d->opaque;
337
    int dx, dy;
338

    
339
    if (s->last_buttons_state == s->buttons_state &&
340
        s->dx == 0 && s->dy == 0)
341
        return 0;
342

    
343
    dx = s->dx;
344
    if (dx < -63)
345
        dx = -63;
346
    else if (dx > 63)
347
        dx = 63;
348

    
349
    dy = s->dy;
350
    if (dy < -63)
351
        dy = -63;
352
    else if (dy > 63)
353
        dy = 63;
354

    
355
    s->dx -= dx;
356
    s->dy -= dy;
357
    s->last_buttons_state = s->buttons_state;
358

    
359
    dx &= 0x7f;
360
    dy &= 0x7f;
361

    
362
    if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
363
        dy |= 0x80;
364
    if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
365
        dx |= 0x80;
366

    
367
    obuf[0] = dy;
368
    obuf[1] = dx;
369
    return 2;
370
}
371

    
372
static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
373
                             const uint8_t *buf, int len)
374
{
375
    MouseState *s = d->opaque;
376
    int cmd, reg, olen;
377

    
378
    if ((buf[0] & 0x0f) == ADB_FLUSH) {
379
        /* flush mouse fifo */
380
        s->buttons_state = s->last_buttons_state;
381
        s->dx = 0;
382
        s->dy = 0;
383
        s->dz = 0;
384
        return 0;
385
    }
386

    
387
    cmd = buf[0] & 0xc;
388
    reg = buf[0] & 0x3;
389
    olen = 0;
390
    switch(cmd) {
391
    case ADB_WRITEREG:
392
        ADB_DPRINTF("write reg %d val 0x%2.2x\n", reg, buf[1]);
393
        switch(reg) {
394
        case 2:
395
            break;
396
        case 3:
397
            switch(buf[2]) {
398
            case ADB_CMD_SELF_TEST:
399
                break;
400
            case ADB_CMD_CHANGE_ID:
401
            case ADB_CMD_CHANGE_ID_AND_ACT:
402
            case ADB_CMD_CHANGE_ID_AND_ENABLE:
403
                d->devaddr = buf[1] & 0xf;
404
                break;
405
            default:
406
                /* XXX: check this */
407
                d->devaddr = buf[1] & 0xf;
408
                break;
409
            }
410
        }
411
        break;
412
    case ADB_READREG:
413
        switch(reg) {
414
        case 0:
415
            olen = adb_mouse_poll(d, obuf);
416
            break;
417
        case 1:
418
            break;
419
        case 3:
420
            obuf[0] = d->handler;
421
            obuf[1] = d->devaddr;
422
            olen = 2;
423
            break;
424
        }
425
        ADB_DPRINTF("read reg %d obuf[0] 0x%2.2x obuf[1] 0x%2.2x\n", reg,
426
                    obuf[0], obuf[1]);
427
        break;
428
    }
429
    return olen;
430
}
431

    
432
static int adb_mouse_reset(ADBDevice *d)
433
{
434
    MouseState *s = d->opaque;
435

    
436
    d->handler = 2;
437
    d->devaddr = ADB_MOUSE;
438
    memset(s, 0, sizeof(MouseState));
439

    
440
    return 0;
441
}
442

    
443
static void adb_mouse_save(QEMUFile *f, void *opaque)
444
{
445
    MouseState *s = (MouseState *)opaque;
446

    
447
    qemu_put_sbe32s(f, &s->buttons_state);
448
    qemu_put_sbe32s(f, &s->last_buttons_state);
449
    qemu_put_sbe32s(f, &s->dx);
450
    qemu_put_sbe32s(f, &s->dy);
451
    qemu_put_sbe32s(f, &s->dz);
452
}
453

    
454
static int adb_mouse_load(QEMUFile *f, void *opaque, int version_id)
455
{
456
    MouseState *s = (MouseState *)opaque;
457

    
458
    if (version_id != 1)
459
        return -EINVAL;
460

    
461
    qemu_get_sbe32s(f, &s->buttons_state);
462
    qemu_get_sbe32s(f, &s->last_buttons_state);
463
    qemu_get_sbe32s(f, &s->dx);
464
    qemu_get_sbe32s(f, &s->dy);
465
    qemu_get_sbe32s(f, &s->dz);
466

    
467
    return 0;
468
}
469

    
470
void adb_mouse_init(ADBBusState *bus)
471
{
472
    ADBDevice *d;
473
    MouseState *s;
474

    
475
    s = qemu_mallocz(sizeof(MouseState));
476
    d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request,
477
                            adb_mouse_reset, s);
478
    qemu_add_mouse_event_handler(adb_mouse_event, d, 0, "QEMU ADB Mouse");
479
    register_savevm("adb_mouse", -1, 1, adb_mouse_save,
480
                    adb_mouse_load, s);
481
}