Statistics
| Branch: | Revision:

root / hw / adb.c @ e4394131

History | View | Annotate | Download (12.3 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
    return d;
127
}
128

    
129
/***************************************************************/
130
/* Keyboard ADB device */
131

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
286
    return 0;
287
}
288

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

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

    
297
    return 0;
298
}
299

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

    
312
/***************************************************************/
313
/* Mouse ADB device */
314

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

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

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

    
332

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

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

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

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

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

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

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

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

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

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

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

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

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

    
439
    return 0;
440
}
441

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

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

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

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

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

    
466
    return 0;
467
}
468

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

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