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
29 #define ADB_BUSRESET 0x00
30 #define ADB_FLUSH 0x01
31 #define ADB_WRITEREG 0x08
32 #define ADB_READREG 0x0c
34 /* ADB device commands */
35 #define ADB_CMD_SELF_TEST 0xff
36 #define ADB_CMD_CHANGE_ID 0xfe
37 #define ADB_CMD_CHANGE_ID_AND_ACT 0xfd
38 #define ADB_CMD_CHANGE_ID_AND_ENABLE 0x00
40 /* ADB default device IDs (upper 4 bits of ADB command byte) */
42 #define ADB_KEYBOARD 2
49 #define ADB_RET_NOTPRESENT (-2)
51 int adb_request(ADBBusState
*s
, uint8_t *obuf
, const uint8_t *buf
, int len
)
57 if (cmd
== ADB_BUSRESET
) {
58 for(i
= 0; i
< s
->nb_devices
; i
++) {
66 devaddr
= buf
[0] >> 4;
67 for(i
= 0; i
< s
->nb_devices
; i
++) {
69 if (d
->devaddr
== devaddr
) {
70 return d
->devreq(d
, obuf
, buf
, len
);
73 return ADB_RET_NOTPRESENT
;
76 /* XXX: move that to cuda ? */
77 int adb_poll(ADBBusState
*s
, uint8_t *obuf
)
84 for(i
= 0; i
< s
->nb_devices
; i
++) {
85 if (s
->poll_index
>= s
->nb_devices
)
87 d
= &s
->devices
[s
->poll_index
];
88 buf
[0] = ADB_READREG
| (d
->devaddr
<< 4);
89 olen
= adb_request(s
, obuf
+ 1, buf
, 1);
90 /* if there is data, we poll again the same device */
101 ADBDevice
*adb_register_device(ADBBusState
*s
, int devaddr
,
102 ADBDeviceRequest
*devreq
,
103 ADBDeviceReset
*devreset
,
107 if (s
->nb_devices
>= MAX_ADB_DEVICES
)
109 d
= &s
->devices
[s
->nb_devices
++];
111 d
->devaddr
= devaddr
;
113 d
->devreset
= devreset
;
118 /***************************************************************/
119 /* Keyboard ADB device */
121 typedef struct KBDState
{
123 int rptr
, wptr
, count
;
126 static const uint8_t pc_to_adb_keycode
[256] = {
127 0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
128 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54, 0, 1,
129 2, 3, 5, 4, 38, 40, 37, 41, 39, 50, 56, 42, 6, 7, 8, 9,
130 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
131 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
132 84, 85, 82, 65, 0, 0, 10,103,111, 0, 0,110, 81, 0, 0, 0,
133 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
134 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
135 0, 0, 0, 94, 0, 93, 0, 0, 0, 0, 0, 0,104,102, 0, 0,
136 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76,125, 0, 0,
137 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0,
138 0, 0, 0, 0, 0, 75, 0, 0,124, 0, 0, 0, 0, 0, 0, 0,
139 0, 0, 0, 0, 0, 0, 0,115, 62,116, 0, 59, 0, 60, 0,119,
140 61,121,114,117, 0, 0, 0, 0, 0, 0, 0, 55,126, 0,127, 0,
141 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
142 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
145 static void adb_kbd_put_keycode(void *opaque
, int keycode
)
147 ADBDevice
*d
= opaque
;
148 KBDState
*s
= d
->opaque
;
150 if (s
->count
< sizeof(s
->data
)) {
151 s
->data
[s
->wptr
] = keycode
;
152 if (++s
->wptr
== sizeof(s
->data
))
158 static int adb_kbd_poll(ADBDevice
*d
, uint8_t *obuf
)
160 static int ext_keycode
;
161 KBDState
*s
= d
->opaque
;
162 int adb_keycode
, keycode
;
169 keycode
= s
->data
[s
->rptr
];
170 if (++s
->rptr
== sizeof(s
->data
))
174 if (keycode
== 0xe0) {
178 adb_keycode
= pc_to_adb_keycode
[keycode
| 0x80];
180 adb_keycode
= pc_to_adb_keycode
[keycode
& 0x7f];
181 obuf
[0] = adb_keycode
| (keycode
& 0x80);
182 /* NOTE: could put a second keycode if needed */
192 static int adb_kbd_request(ADBDevice
*d
, uint8_t *obuf
,
193 const uint8_t *buf
, int len
)
195 KBDState
*s
= d
->opaque
;
198 if ((buf
[0] & 0x0f) == ADB_FLUSH
) {
199 /* flush keyboard fifo */
200 s
->wptr
= s
->rptr
= s
->count
= 0;
215 case ADB_CMD_SELF_TEST
:
217 case ADB_CMD_CHANGE_ID
:
218 case ADB_CMD_CHANGE_ID_AND_ACT
:
219 case ADB_CMD_CHANGE_ID_AND_ENABLE
:
220 d
->devaddr
= buf
[1] & 0xf;
223 /* XXX: check this */
224 d
->devaddr
= buf
[1] & 0xf;
233 olen
= adb_kbd_poll(d
, obuf
);
238 obuf
[0] = 0x00; /* XXX: check this */
239 obuf
[1] = 0x07; /* led status */
243 obuf
[0] = d
->handler
;
244 obuf
[1] = d
->devaddr
;
253 static int adb_kbd_reset(ADBDevice
*d
)
255 KBDState
*s
= d
->opaque
;
258 d
->devaddr
= ADB_KEYBOARD
;
259 memset(s
, 0, sizeof(KBDState
));
264 void adb_kbd_init(ADBBusState
*bus
)
268 s
= qemu_mallocz(sizeof(KBDState
));
269 d
= adb_register_device(bus
, ADB_KEYBOARD
, adb_kbd_request
,
272 qemu_add_kbd_event_handler(adb_kbd_put_keycode
, d
);
275 /***************************************************************/
276 /* Mouse ADB device */
278 typedef struct MouseState
{
279 int buttons_state
, last_buttons_state
;
283 static void adb_mouse_event(void *opaque
,
284 int dx1
, int dy1
, int dz1
, int buttons_state
)
286 ADBDevice
*d
= opaque
;
287 MouseState
*s
= d
->opaque
;
292 s
->buttons_state
= buttons_state
;
296 static int adb_mouse_poll(ADBDevice
*d
, uint8_t *obuf
)
298 MouseState
*s
= d
->opaque
;
301 if (s
->last_buttons_state
== s
->buttons_state
&&
302 s
->dx
== 0 && s
->dy
== 0)
319 s
->last_buttons_state
= s
->buttons_state
;
324 if (!(s
->buttons_state
& MOUSE_EVENT_LBUTTON
))
326 if (!(s
->buttons_state
& MOUSE_EVENT_RBUTTON
))
334 static int adb_mouse_request(ADBDevice
*d
, uint8_t *obuf
,
335 const uint8_t *buf
, int len
)
337 MouseState
*s
= d
->opaque
;
340 if ((buf
[0] & 0x0f) == ADB_FLUSH
) {
341 /* flush mouse fifo */
342 s
->buttons_state
= s
->last_buttons_state
;
359 case ADB_CMD_SELF_TEST
:
361 case ADB_CMD_CHANGE_ID
:
362 case ADB_CMD_CHANGE_ID_AND_ACT
:
363 case ADB_CMD_CHANGE_ID_AND_ENABLE
:
364 d
->devaddr
= buf
[1] & 0xf;
367 /* XXX: check this */
368 d
->devaddr
= buf
[1] & 0xf;
376 olen
= adb_mouse_poll(d
, obuf
);
381 obuf
[0] = d
->handler
;
382 obuf
[1] = d
->devaddr
;
391 static int adb_mouse_reset(ADBDevice
*d
)
393 MouseState
*s
= d
->opaque
;
396 d
->devaddr
= ADB_MOUSE
;
397 memset(s
, 0, sizeof(MouseState
));
402 void adb_mouse_init(ADBBusState
*bus
)
407 s
= qemu_mallocz(sizeof(MouseState
));
408 d
= adb_register_device(bus
, ADB_MOUSE
, adb_mouse_request
,
411 qemu_add_mouse_event_handler(adb_mouse_event
, d
, 0, "QEMU ADB Mouse");