Statistics
| Branch: | Revision:

root / hw / adb.c @ 819e712b

History | View | Annotate | Download (8.7 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
#define ADB_RET_OK                        0
47
#define ADB_RET_INUSE                        1
48
#define ADB_RET_NOTPRESENT                2
49
#define ADB_RET_TIMEOUT                        3
50
#define ADB_RET_UNEXPECTED_RESULT        4
51
#define ADB_RET_REQUEST_ERROR                5
52
#define ADB_RET_BUS_ERROR                6
53

    
54

    
55
static void adb_send_packet1(ADBBusState *s, uint8_t reply)
56
{
57
    adb_send_packet(s, &reply, 1);
58
}
59

    
60
void adb_receive_packet(ADBBusState *s, const uint8_t *buf, int len)
61
{
62
    ADBDevice *d;
63
    int devaddr, cmd, i;
64
    uint8_t obuf[4];
65

    
66
    cmd = buf[0] & 0xf;
67
    devaddr = buf[0] >> 4;
68
    if (buf[1] == ADB_BUSRESET) {
69
        obuf[0] = 0x00;
70
        obuf[1] = 0x00;
71
        adb_send_packet(s, obuf, 2);
72
        return;
73
    }
74
    if (cmd == ADB_FLUSH) {
75
        obuf[0] = 0x00;
76
        obuf[1] = 0x00;
77
        adb_send_packet(s, obuf, 2);
78
        return;
79
    }
80

    
81
    for(i = 0; i < s->nb_devices; i++) {
82
        d = &s->devices[i];
83
        if (d->devaddr == devaddr) {
84
            d->receive_packet(d, buf, len);
85
            return;
86
        }
87
    }
88
    adb_send_packet1(s, ADB_RET_NOTPRESENT);
89
}
90

    
91
ADBDevice *adb_register_device(ADBBusState *s, int devaddr, 
92
                               ADBDeviceReceivePacket *receive_packet, 
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->receive_packet = receive_packet;
102
    d->opaque = opaque;
103
    return d;
104
}
105

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

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

    
128
static void adb_kbd_put_keycode(void *opaque, int keycode)
129
{
130
    static int ext_keycode;
131
    ADBDevice *d = opaque;
132
    uint8_t buf[4];
133
    int adb_keycode;
134
    
135
    if (keycode == 0xe0) {
136
        ext_keycode = 1;
137
    } else {
138
        
139
        if (ext_keycode)
140
            adb_keycode =  pc_to_adb_keycode[keycode | 0x80];
141
        else
142
            adb_keycode =  pc_to_adb_keycode[keycode & 0x7f];
143
            
144
        buf[0] = 0x40;
145
        buf[1] = (d->devaddr << 4) | 0x0c;
146
        buf[2] = adb_keycode | (keycode & 0x80);
147
        buf[3] = 0xff;
148
        adb_send_packet(d->bus, buf, 4);
149
        ext_keycode = 0;
150
    }
151
}
152

    
153
static void adb_kbd_receive_packet(ADBDevice *d, const uint8_t *buf, int len)
154
{
155
    int cmd, reg;
156
    uint8_t obuf[4];
157

    
158
    cmd = buf[0] & 0xc;
159
    reg = buf[0] & 0x3;
160
    switch(cmd) {
161
    case ADB_WRITEREG:
162
        switch(reg) {
163
        case 2:
164
            /* LED status */
165
            adb_send_packet1(d->bus, ADB_RET_OK);
166
            break;
167
        case 3:
168
            switch(buf[2]) {
169
            case ADB_CMD_SELF_TEST:
170
                adb_send_packet1(d->bus, ADB_RET_OK);
171
                break;
172
            case ADB_CMD_CHANGE_ID:
173
            case ADB_CMD_CHANGE_ID_AND_ACT:
174
            case ADB_CMD_CHANGE_ID_AND_ENABLE:
175
                d->devaddr = buf[1] & 0xf;
176
                adb_send_packet1(d->bus, ADB_RET_OK);
177
                break;
178
            default:
179
                /* XXX: check this */
180
                d->devaddr = buf[1] & 0xf;
181
                d->handler = buf[2];
182
                adb_send_packet1(d->bus, ADB_RET_OK);
183
                break;
184
            }
185
        }
186
        break;
187
    case ADB_READREG:
188
        switch(reg) {
189
        case 1:
190
            adb_send_packet1(d->bus, ADB_RET_OK);
191
            break;
192
        case 2:
193
            obuf[0] = ADB_RET_OK;
194
            obuf[1] = 0x00; /* XXX: check this */
195
            obuf[2] = 0x07; /* led status */
196
            adb_send_packet(d->bus, obuf, 3);
197
            break;
198
        case 3:
199
            obuf[0] = ADB_RET_OK;
200
            obuf[1] = d->handler;
201
            obuf[2] = d->devaddr;
202
            adb_send_packet(d->bus, obuf, 3);
203
            break;
204
        }
205
        break;
206
    }
207
}
208

    
209
void adb_kbd_init(ADBBusState *bus)
210
{
211
    ADBDevice *d;
212

    
213
    d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_receive_packet, NULL);
214
    qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
215
}
216

    
217
/***************************************************************/
218
/* Mouse ADB device */
219

    
220
static void adb_mouse_event(void *opaque,
221
                            int dx1, int dy1, int dz1, int buttons_state)
222
{
223
    ADBDevice *d = opaque;
224
    uint8_t buf[4];
225
    int dx, dy;
226

    
227
    dx = dx1;
228
    if (dx < -63)
229
        dx = -63;
230
    else if (dx > 63)
231
        dx = 63;
232

    
233
    dy = dy1;
234
    if (dy < -63)
235
        dy = -63;
236
    else if (dy > 63)
237
        dy = 63;
238

    
239
    dx &= 0x7f;
240
    dy &= 0x7f;
241

    
242
    if (buttons_state & MOUSE_EVENT_LBUTTON)
243
        dy |= 0x80;
244
    if (buttons_state & MOUSE_EVENT_RBUTTON)
245
        dx |= 0x80;
246

    
247
    buf[0] = 0x40;
248
    buf[1] = (d->devaddr << 4) | 0x0c;
249
    buf[2] = dy;
250
    buf[3] = dx;
251
    adb_send_packet(d->bus, buf, 4);
252
}
253

    
254
static void adb_mouse_receive_packet(ADBDevice *d, const uint8_t *buf, int len)
255
{
256
    int cmd, reg;
257
    uint8_t obuf[4];
258

    
259
    cmd = buf[0] & 0xc;
260
    reg = buf[0] & 0x3;
261
    switch(cmd) {
262
    case ADB_WRITEREG:
263
        switch(reg) {
264
        case 2:
265
            adb_send_packet1(d->bus, ADB_RET_OK);
266
            break;
267
        case 3:
268
            switch(buf[2]) {
269
            case ADB_CMD_SELF_TEST:
270
                adb_send_packet1(d->bus, ADB_RET_OK);
271
                break;
272
            case ADB_CMD_CHANGE_ID:
273
            case ADB_CMD_CHANGE_ID_AND_ACT:
274
            case ADB_CMD_CHANGE_ID_AND_ENABLE:
275
                d->devaddr = buf[1] & 0xf;
276
                adb_send_packet1(d->bus, ADB_RET_OK);
277
                break;
278
            default:
279
                /* XXX: check this */
280
                d->devaddr = buf[1] & 0xf;
281
                adb_send_packet1(d->bus, ADB_RET_OK);
282
                break;
283
            }
284
        }
285
        break;
286
    case ADB_READREG:
287
        switch(reg) {
288
        case 1:
289
            adb_send_packet1(d->bus, ADB_RET_OK);
290
            break;
291
        case 3:
292
            obuf[0] = ADB_RET_OK;
293
            obuf[1] = d->handler;
294
            obuf[2] = d->devaddr;
295
            adb_send_packet(d->bus, obuf, 3);
296
            break;
297
        }
298
        break;
299
    }
300
}
301

    
302
void adb_mouse_init(ADBBusState *bus)
303
{
304
    ADBDevice *d;
305

    
306
    d = adb_register_device(bus, ADB_MOUSE, adb_mouse_receive_packet, NULL);
307
    qemu_add_mouse_event_handler(adb_mouse_event, d);
308
}