Statistics
| Branch: | Revision:

root / hw / adb.c @ e2733d20

History | View | Annotate | Download (9.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 "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
int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
47
{
48
    ADBDevice *d;
49
    int devaddr, cmd, i;
50

    
51
    cmd = buf[0] & 0xf;
52
    devaddr = buf[0] >> 4;
53
    if (buf[1] == ADB_BUSRESET) {
54
        obuf[0] = 0x00;
55
        obuf[1] = 0x00;
56
        return 2;
57
    }
58
    if (cmd == ADB_FLUSH) {
59
        obuf[0] = 0x00;
60
        obuf[1] = 0x00;
61
        return 2;
62
    }
63

    
64
    for(i = 0; i < s->nb_devices; i++) {
65
        d = &s->devices[i];
66
        if (d->devaddr == devaddr) {
67
            return d->devreq(d, obuf, buf, len);
68
        }
69
    }
70
    return 0;
71
}
72

    
73
int adb_poll(ADBBusState *s, uint8_t *obuf)
74
{
75
    ADBDevice *d;
76
    int olen, i;
77

    
78
    olen = 0;
79
    for(i = 0; i < s->nb_devices; i++) {
80
        if (s->poll_index >= s->nb_devices)
81
            s->poll_index = 0;
82
        d = &s->devices[s->poll_index];
83
        olen = d->devreq(d, obuf, NULL, 0);
84
        s->poll_index++;
85
        if (olen)
86
            break;
87
    }
88
    return olen;
89
}
90

    
91
ADBDevice *adb_register_device(ADBBusState *s, int devaddr, 
92
                               ADBDeviceRequest *devreq, 
93
                               void *opaque)
94
{
95
    ADBDevice *d;
96
    if (s->nb_devices >= MAX_ADB_DEVICES)
97
        return NULL;
98
    d = &s->devices[s->nb_devices++];
99
    d->bus = s;
100
    d->devaddr = devaddr;
101
    d->devreq = devreq;
102
    d->opaque = opaque;
103
    return d;
104
}
105

    
106
/***************************************************************/
107
/* Keyboard ADB device */
108

    
109
typedef struct KBDState {
110
    uint8_t data[128];
111
    int rptr, wptr, count;
112
} KBDState;
113

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

    
133
static void adb_kbd_put_keycode(void *opaque, int keycode)
134
{
135
    ADBDevice *d = opaque;
136
    KBDState *s = d->opaque;
137

    
138
    if (s->count < sizeof(s->data)) {
139
        s->data[s->wptr] = keycode;
140
        if (++s->wptr == sizeof(s->data))
141
            s->wptr = 0;
142
        s->count++;
143
    }
144
}
145

    
146
static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
147
{
148
    static int ext_keycode;
149
    KBDState *s = d->opaque;
150
    int adb_keycode, keycode;
151
    int olen;
152

    
153
    olen = 0;
154
    for(;;) {
155
        if (s->count == 0)
156
            break;
157
        keycode = s->data[s->rptr];
158
        if (++s->rptr == sizeof(s->data))
159
            s->rptr = 0;
160
        s->count--;
161

    
162
        if (keycode == 0xe0) {
163
            ext_keycode = 1;
164
        } else {
165
            if (ext_keycode)
166
                adb_keycode =  pc_to_adb_keycode[keycode | 0x80];
167
            else
168
                adb_keycode =  pc_to_adb_keycode[keycode & 0x7f];
169
            obuf[0] = (d->devaddr << 4) | 0x0c;
170
            obuf[1] = adb_keycode | (keycode & 0x80);
171
            obuf[2] = 0xff;
172
            olen = 3;
173
            ext_keycode = 0;
174
            break;
175
        }
176
    }
177
    return olen;
178
}
179

    
180
static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
181
                           const uint8_t *buf, int len)
182
{
183
    int cmd, reg, olen;
184

    
185
    if (!buf) {
186
        return adb_kbd_poll(d, obuf);
187
    }
188

    
189
    cmd = buf[0] & 0xc;
190
    reg = buf[0] & 0x3;
191
    olen = 0;
192
    switch(cmd) {
193
    case ADB_WRITEREG:
194
        switch(reg) {
195
        case 2:
196
            /* LED status */
197
            break;
198
        case 3:
199
            switch(buf[2]) {
200
            case ADB_CMD_SELF_TEST:
201
                break;
202
            case ADB_CMD_CHANGE_ID:
203
            case ADB_CMD_CHANGE_ID_AND_ACT:
204
            case ADB_CMD_CHANGE_ID_AND_ENABLE:
205
                d->devaddr = buf[1] & 0xf;
206
                break;
207
            default:
208
                /* XXX: check this */
209
                d->devaddr = buf[1] & 0xf;
210
                d->handler = buf[2];
211
                break;
212
            }
213
        }
214
        break;
215
    case ADB_READREG:
216
        switch(reg) {
217
        case 1:
218
            break;
219
        case 2:
220
            obuf[0] = 0x00; /* XXX: check this */
221
            obuf[1] = 0x07; /* led status */
222
            olen = 2;
223
            break;
224
        case 3:
225
            obuf[0] = d->handler;
226
            obuf[1] = d->devaddr;
227
            olen = 2;
228
            break;
229
        }
230
        break;
231
    }
232
    return olen;
233
}
234

    
235
void adb_kbd_init(ADBBusState *bus)
236
{
237
    ADBDevice *d;
238
    KBDState *s;
239
    s = qemu_mallocz(sizeof(KBDState));
240
    d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request, s);
241
    d->handler = 1;
242
    qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
243
}
244

    
245
/***************************************************************/
246
/* Mouse ADB device */
247

    
248
typedef struct MouseState {
249
    int buttons_state, last_buttons_state;
250
    int dx, dy, dz;
251
} MouseState;
252

    
253
static void adb_mouse_event(void *opaque,
254
                            int dx1, int dy1, int dz1, int buttons_state)
255
{
256
    ADBDevice *d = opaque;
257
    MouseState *s = d->opaque;
258

    
259
    s->dx += dx1;
260
    s->dy += dy1;
261
    s->dz += dz1;
262
    s->buttons_state = buttons_state;
263
}
264

    
265

    
266
static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
267
{
268
    MouseState *s = d->opaque;
269
    int dx, dy;
270

    
271
    if (s->last_buttons_state == s->buttons_state &&
272
        s->dx == 0 && s->dy == 0)
273
        return 0;
274
        
275
    dx = s->dx;
276
    if (dx < -63)
277
        dx = -63;
278
    else if (dx > 63)
279
        dx = 63;
280
    
281
    dy = s->dy;
282
    if (dy < -63)
283
        dy = -63;
284
    else if (dy > 63)
285
        dy = 63;
286
    
287
    s->dx -= dx;
288
    s->dy -= dy;
289
    s->last_buttons_state = s->buttons_state;
290
    
291
    dx &= 0x7f;
292
    dy &= 0x7f;
293
    
294
    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
295
        dy |= 0x80;
296
    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
297
        dx |= 0x80;
298
    
299
    obuf[0] = (d->devaddr << 4) | 0x0c;
300
    obuf[1] = dy;
301
    obuf[2] = dx;
302
    return 3;
303
}
304

    
305
static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
306
                             const uint8_t *buf, int len)
307
{
308
    int cmd, reg, olen;
309
    
310
    if (!buf) {
311
        return adb_mouse_poll(d, obuf);
312
    }
313

    
314
    cmd = buf[0] & 0xc;
315
    reg = buf[0] & 0x3;
316
    olen = 0;
317
    switch(cmd) {
318
    case ADB_WRITEREG:
319
        switch(reg) {
320
        case 2:
321
            break;
322
        case 3:
323
            switch(buf[2]) {
324
            case ADB_CMD_SELF_TEST:
325
                break;
326
            case ADB_CMD_CHANGE_ID:
327
            case ADB_CMD_CHANGE_ID_AND_ACT:
328
            case ADB_CMD_CHANGE_ID_AND_ENABLE:
329
                d->devaddr = buf[1] & 0xf;
330
                break;
331
            default:
332
                /* XXX: check this */
333
                d->devaddr = buf[1] & 0xf;
334
                break;
335
            }
336
        }
337
        break;
338
    case ADB_READREG:
339
        switch(reg) {
340
        case 1:
341
            break;
342
        case 3:
343
            obuf[0] = d->handler;
344
            obuf[1] = d->devaddr;
345
            olen = 2;
346
            break;
347
        }
348
        break;
349
    }
350
    return olen;
351
}
352

    
353
void adb_mouse_init(ADBBusState *bus)
354
{
355
    ADBDevice *d;
356
    MouseState *s;
357

    
358
    s = qemu_mallocz(sizeof(MouseState));
359
    d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request, s);
360
    d->handler = 2;
361
    qemu_add_mouse_event_handler(adb_mouse_event, d);
362
}