4 * Copyright (c) 2004 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
27 #define ADB_BUSRESET 0x00
28 #define ADB_FLUSH 0x01
29 #define ADB_WRITEREG 0x08
30 #define ADB_READREG 0x0c
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
38 /* ADB default device IDs (upper 4 bits of ADB command byte) */
40 #define ADB_KEYBOARD 2
47 #define ADB_RET_NOTPRESENT (-2)
49 int adb_request(ADBBusState
*s
, uint8_t *obuf
, const uint8_t *buf
, int len
)
55 if (cmd
== ADB_BUSRESET
) {
56 for(i
= 0; i
< s
->nb_devices
; i
++) {
64 devaddr
= buf
[0] >> 4;
65 for(i
= 0; i
< s
->nb_devices
; i
++) {
67 if (d
->devaddr
== devaddr
) {
68 return d
->devreq(d
, obuf
, buf
, len
);
71 return ADB_RET_NOTPRESENT
;
74 /* XXX: move that to cuda ? */
75 int adb_poll(ADBBusState
*s
, uint8_t *obuf
)
82 for(i
= 0; i
< s
->nb_devices
; i
++) {
83 if (s
->poll_index
>= s
->nb_devices
)
85 d
= &s
->devices
[s
->poll_index
];
86 buf
[0] = ADB_READREG
| (d
->devaddr
<< 4);
87 olen
= adb_request(s
, obuf
+ 1, buf
, 1);
88 /* if there is data, we poll again the same device */
99 ADBDevice
*adb_register_device(ADBBusState
*s
, int devaddr
,
100 ADBDeviceRequest
*devreq
,
101 ADBDeviceReset
*devreset
,
105 if (s
->nb_devices
>= MAX_ADB_DEVICES
)
107 d
= &s
->devices
[s
->nb_devices
++];
109 d
->devaddr
= devaddr
;
111 d
->devreset
= devreset
;
116 /***************************************************************/
117 /* Keyboard ADB device */
119 typedef struct KBDState
{
121 int rptr
, wptr
, count
;
124 static const uint8_t pc_to_adb_keycode
[256] = {
125 0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
126 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54, 0, 1,
127 2, 3, 5, 4, 38, 40, 37, 41, 39, 50, 56, 42, 6, 7, 8, 9,
128 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
129 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
130 84, 85, 82, 65, 0, 0, 10,103,111, 0, 0,110, 81, 0, 0, 0,
131 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
132 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
133 0, 0, 0, 94, 0, 93, 0, 0, 0, 0, 0, 0,104,102, 0, 0,
134 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76,125, 0, 0,
135 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0,
136 0, 0, 0, 0, 0, 75, 0, 0,124, 0, 0, 0, 0, 0, 0, 0,
137 0, 0, 0, 0, 0, 0, 0,115, 62,116, 0, 59, 0, 60, 0,119,
138 61,121,114,117, 0, 0, 0, 0, 0, 0, 0, 55,126, 0,127, 0,
139 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
140 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
143 static void adb_kbd_put_keycode(void *opaque
, int keycode
)
145 ADBDevice
*d
= opaque
;
146 KBDState
*s
= d
->opaque
;
148 if (s
->count
< sizeof(s
->data
)) {
149 s
->data
[s
->wptr
] = keycode
;
150 if (++s
->wptr
== sizeof(s
->data
))
156 static int adb_kbd_poll(ADBDevice
*d
, uint8_t *obuf
)
158 static int ext_keycode
;
159 KBDState
*s
= d
->opaque
;
160 int adb_keycode
, keycode
;
167 keycode
= s
->data
[s
->rptr
];
168 if (++s
->rptr
== sizeof(s
->data
))
172 if (keycode
== 0xe0) {
176 adb_keycode
= pc_to_adb_keycode
[keycode
| 0x80];
178 adb_keycode
= pc_to_adb_keycode
[keycode
& 0x7f];
179 obuf
[0] = adb_keycode
| (keycode
& 0x80);
180 /* NOTE: could put a second keycode if needed */
190 static int adb_kbd_request(ADBDevice
*d
, uint8_t *obuf
,
191 const uint8_t *buf
, int len
)
193 KBDState
*s
= d
->opaque
;
196 if ((buf
[0] & 0x0f) == ADB_FLUSH
) {
197 /* flush keyboard fifo */
198 s
->wptr
= s
->rptr
= s
->count
= 0;
213 case ADB_CMD_SELF_TEST
:
215 case ADB_CMD_CHANGE_ID
:
216 case ADB_CMD_CHANGE_ID_AND_ACT
:
217 case ADB_CMD_CHANGE_ID_AND_ENABLE
:
218 d
->devaddr
= buf
[1] & 0xf;
221 /* XXX: check this */
222 d
->devaddr
= buf
[1] & 0xf;
231 olen
= adb_kbd_poll(d
, obuf
);
236 obuf
[0] = 0x00; /* XXX: check this */
237 obuf
[1] = 0x07; /* led status */
241 obuf
[0] = d
->handler
;
242 obuf
[1] = d
->devaddr
;
251 static int adb_kbd_reset(ADBDevice
*d
)
253 KBDState
*s
= d
->opaque
;
256 d
->devaddr
= ADB_KEYBOARD
;
257 memset(s
, 0, sizeof(KBDState
));
262 void adb_kbd_init(ADBBusState
*bus
)
266 s
= qemu_mallocz(sizeof(KBDState
));
267 d
= adb_register_device(bus
, ADB_KEYBOARD
, adb_kbd_request
,
270 qemu_add_kbd_event_handler(adb_kbd_put_keycode
, d
);
273 /***************************************************************/
274 /* Mouse ADB device */
276 typedef struct MouseState
{
277 int buttons_state
, last_buttons_state
;
281 static void adb_mouse_event(void *opaque
,
282 int dx1
, int dy1
, int dz1
, int buttons_state
)
284 ADBDevice
*d
= opaque
;
285 MouseState
*s
= d
->opaque
;
290 s
->buttons_state
= buttons_state
;
294 static int adb_mouse_poll(ADBDevice
*d
, uint8_t *obuf
)
296 MouseState
*s
= d
->opaque
;
299 if (s
->last_buttons_state
== s
->buttons_state
&&
300 s
->dx
== 0 && s
->dy
== 0)
317 s
->last_buttons_state
= s
->buttons_state
;
322 if (!(s
->buttons_state
& MOUSE_EVENT_LBUTTON
))
324 if (!(s
->buttons_state
& MOUSE_EVENT_RBUTTON
))
332 static int adb_mouse_request(ADBDevice
*d
, uint8_t *obuf
,
333 const uint8_t *buf
, int len
)
335 MouseState
*s
= d
->opaque
;
338 if ((buf
[0] & 0x0f) == ADB_FLUSH
) {
339 /* flush mouse fifo */
340 s
->buttons_state
= s
->last_buttons_state
;
357 case ADB_CMD_SELF_TEST
:
359 case ADB_CMD_CHANGE_ID
:
360 case ADB_CMD_CHANGE_ID_AND_ACT
:
361 case ADB_CMD_CHANGE_ID_AND_ENABLE
:
362 d
->devaddr
= buf
[1] & 0xf;
365 /* XXX: check this */
366 d
->devaddr
= buf
[1] & 0xf;
374 olen
= adb_mouse_poll(d
, obuf
);
379 obuf
[0] = d
->handler
;
380 obuf
[1] = d
->devaddr
;
389 static int adb_mouse_reset(ADBDevice
*d
)
391 MouseState
*s
= d
->opaque
;
394 d
->devaddr
= ADB_MOUSE
;
395 memset(s
, 0, sizeof(MouseState
));
400 void adb_mouse_init(ADBBusState
*bus
)
405 s
= qemu_mallocz(sizeof(MouseState
));
406 d
= adb_register_device(bus
, ADB_MOUSE
, adb_mouse_request
,
409 qemu_add_mouse_event_handler(adb_mouse_event
, d
, 0, "QEMU ADB Mouse");