1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/*
* QEMU ADB support
*
* Copyright ( c ) 2004 Fabrice Bellard
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the "Software" ), to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
*/
# include "vl.h"
/* ADB commands */
# define ADB_BUSRESET 0x00
# define ADB_FLUSH 0x01
# define ADB_WRITEREG 0x08
# define ADB_READREG 0x0c
/* ADB device commands */
# define ADB_CMD_SELF_TEST 0xff
# define ADB_CMD_CHANGE_ID 0xfe
# define ADB_CMD_CHANGE_ID_AND_ACT 0xfd
# define ADB_CMD_CHANGE_ID_AND_ENABLE 0x00
/* ADB default device IDs (upper 4 bits of ADB command byte) */
# define ADB_DONGLE 1
# define ADB_KEYBOARD 2
# define ADB_MOUSE 3
# define ADB_TABLET 4
# define ADB_MODEM 5
# define ADB_MISC 7
46
47
48
/* error codes */
# define ADB_RET_NOTPRESENT ( - 2 )
49
int adb_request ( ADBBusState * s , uint8_t * obuf , const uint8_t * buf , int len )
50
51
52
53
{
ADBDevice * d ;
int devaddr , cmd , i ;
54
cmd = buf [ 0 ] & 0xf ;
55
56
57
58
59
60
61
62
if ( cmd == ADB_BUSRESET ) {
for ( i = 0 ; i < s -> nb_devices ; i ++ ) {
d = & s -> devices [ i ];
if ( d -> devreset ) {
d -> devreset ( d );
}
}
return 0 ;
63
}
64
devaddr = buf [ 0 ] >> 4 ;
65
66
67
for ( i = 0 ; i < s -> nb_devices ; i ++ ) {
d = & s -> devices [ i ];
if ( d -> devaddr == devaddr ) {
68
return d -> devreq ( d , obuf , buf , len );
69
70
}
}
71
return ADB_RET_NOTPRESENT ;
72
73
}
74
/* XXX: move that to cuda ? */
75
76
77
78
int adb_poll ( ADBBusState * s , uint8_t * obuf )
{
ADBDevice * d ;
int olen , i ;
79
uint8_t buf [ 1 ];
80
81
82
83
84
85
olen = 0 ;
for ( i = 0 ; i < s -> nb_devices ; i ++ ) {
if ( s -> poll_index >= s -> nb_devices )
s -> poll_index = 0 ;
d = & s -> devices [ s -> poll_index ];
86
87
88
89
90
91
buf [ 0 ] = ADB_READREG | ( d -> devaddr << 4 );
olen = adb_request ( s , obuf + 1 , buf , 1 );
/* if there is data, we poll again the same device */
if ( olen > 0 ) {
obuf [ 0 ] = buf [ 0 ];
olen ++ ;
92
break ;
93
94
}
s -> poll_index ++ ;
95
96
}
return olen ;
97
98
99
}
ADBDevice * adb_register_device ( ADBBusState * s , int devaddr ,
100
ADBDeviceRequest * devreq ,
101
ADBDeviceReset * devreset ,
102
103
104
105
106
107
108
109
void * opaque )
{
ADBDevice * d ;
if ( s -> nb_devices >= MAX_ADB_DEVICES )
return NULL ;
d = & s -> devices [ s -> nb_devices ++ ];
d -> bus = s ;
d -> devaddr = devaddr ;
110
d -> devreq = devreq ;
111
d -> devreset = devreset ;
112
113
114
115
116
117
118
d -> opaque = opaque ;
return d ;
}
/***************************************************************/
/* Keyboard ADB device */
119
120
121
122
123
typedef struct KBDState {
uint8_t data [ 128 ];
int rptr , wptr , count ;
} KBDState ;
124
125
126
127
128
129
static const uint8_t pc_to_adb_keycode [ 256 ] = {
0 , 53 , 18 , 19 , 20 , 21 , 23 , 22 , 26 , 28 , 25 , 29 , 27 , 24 , 51 , 48 ,
12 , 13 , 14 , 15 , 17 , 16 , 32 , 34 , 31 , 35 , 33 , 30 , 36 , 54 , 0 , 1 ,
2 , 3 , 5 , 4 , 38 , 40 , 37 , 41 , 39 , 50 , 56 , 42 , 6 , 7 , 8 , 9 ,
11 , 45 , 46 , 43 , 47 , 44 , 123 , 67 , 58 , 49 , 57 , 122 , 120 , 99 , 118 , 96 ,
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
132
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
133
134
135
136
137
138
0 , 0 , 0 , 94 , 0 , 93 , 0 , 0 , 0 , 0 , 0 , 0 , 104 , 102 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 76 , 125 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 105 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 75 , 0 , 0 , 124 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 115 , 62 , 116 , 0 , 59 , 0 , 60 , 0 , 119 ,
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 ,
141
142
143
144
145
};
static void adb_kbd_put_keycode ( void * opaque , int keycode )
{
ADBDevice * d = opaque ;
146
147
148
149
150
151
152
KBDState * s = d -> opaque ;
if ( s -> count < sizeof ( s -> data )) {
s -> data [ s -> wptr ] = keycode ;
if ( ++ s -> wptr == sizeof ( s -> data ))
s -> wptr = 0 ;
s -> count ++ ;
153
154
155
}
}
156
static int adb_kbd_poll ( ADBDevice * d , uint8_t * obuf )
157
{
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
static int ext_keycode ;
KBDState * s = d -> opaque ;
int adb_keycode , keycode ;
int olen ;
olen = 0 ;
for (;;) {
if ( s -> count == 0 )
break ;
keycode = s -> data [ s -> rptr ];
if ( ++ s -> rptr == sizeof ( s -> data ))
s -> rptr = 0 ;
s -> count -- ;
if ( keycode == 0xe0 ) {
ext_keycode = 1 ;
} else {
if ( ext_keycode )
adb_keycode = pc_to_adb_keycode [ keycode | 0x80 ];
else
adb_keycode = pc_to_adb_keycode [ keycode & 0x7f ];
179
180
181
182
obuf [ 0 ] = adb_keycode | ( keycode & 0x80 );
/* NOTE: could put a second keycode if needed */
obuf [ 1 ] = 0xff ;
olen = 2 ;
183
184
185
186
187
188
189
190
191
192
ext_keycode = 0 ;
break ;
}
}
return olen ;
}
static int adb_kbd_request ( ADBDevice * d , uint8_t * obuf ,
const uint8_t * buf , int len )
{
193
KBDState * s = d -> opaque ;
194
195
int cmd , reg , olen ;
196
197
198
199
if (( buf [ 0 ] & 0x0f ) == ADB_FLUSH ) {
/* flush keyboard fifo */
s -> wptr = s -> rptr = s -> count = 0 ;
return 0 ;
200
}
201
202
203
cmd = buf [ 0 ] & 0xc ;
reg = buf [ 0 ] & 0x3 ;
204
olen = 0 ;
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
switch ( cmd ) {
case ADB_WRITEREG :
switch ( reg ) {
case 2 :
/* LED status */
break ;
case 3 :
switch ( buf [ 2 ]) {
case ADB_CMD_SELF_TEST :
break ;
case ADB_CMD_CHANGE_ID :
case ADB_CMD_CHANGE_ID_AND_ACT :
case ADB_CMD_CHANGE_ID_AND_ENABLE :
d -> devaddr = buf [ 1 ] & 0xf ;
break ;
default :
/* XXX: check this */
d -> devaddr = buf [ 1 ] & 0xf ;
d -> handler = buf [ 2 ];
break ;
}
}
break ;
case ADB_READREG :
switch ( reg ) {
230
231
232
case 0 :
olen = adb_kbd_poll ( d , obuf );
break ;
233
234
235
case 1 :
break ;
case 2 :
236
237
238
obuf [ 0 ] = 0x00 ; /* XXX: check this */
obuf [ 1 ] = 0x07 ; /* led status */
olen = 2 ;
239
240
break ;
case 3 :
241
242
243
obuf [ 0 ] = d -> handler ;
obuf [ 1 ] = d -> devaddr ;
olen = 2 ;
244
245
246
247
break ;
}
break ;
}
248
return olen ;
249
250
}
251
252
253
254
255
256
257
258
259
260
261
static int adb_kbd_reset ( ADBDevice * d )
{
KBDState * s = d -> opaque ;
d -> handler = 1 ;
d -> devaddr = ADB_KEYBOARD ;
memset ( s , 0 , sizeof ( KBDState ));
return 0 ;
}
262
263
264
void adb_kbd_init ( ADBBusState * bus )
{
ADBDevice * d ;
265
266
KBDState * s ;
s = qemu_mallocz ( sizeof ( KBDState ));
267
268
269
d = adb_register_device ( bus , ADB_KEYBOARD , adb_kbd_request ,
adb_kbd_reset , s );
adb_kbd_reset ( d );
270
271
272
273
274
275
qemu_add_kbd_event_handler ( adb_kbd_put_keycode , d );
}
/***************************************************************/
/* Mouse ADB device */
276
277
278
279
280
typedef struct MouseState {
int buttons_state , last_buttons_state ;
int dx , dy , dz ;
} MouseState ;
281
282
283
284
static void adb_mouse_event ( void * opaque ,
int dx1 , int dy1 , int dz1 , int buttons_state )
{
ADBDevice * d = opaque ;
285
286
287
288
289
290
291
292
293
294
295
296
MouseState * s = d -> opaque ;
s -> dx += dx1 ;
s -> dy += dy1 ;
s -> dz += dz1 ;
s -> buttons_state = buttons_state ;
}
static int adb_mouse_poll ( ADBDevice * d , uint8_t * obuf )
{
MouseState * s = d -> opaque ;
297
298
int dx , dy ;
299
300
301
302
303
if ( s -> last_buttons_state == s -> buttons_state &&
s -> dx == 0 && s -> dy == 0 )
return 0 ;
dx = s -> dx ;
304
305
306
307
if ( dx < - 63 )
dx = - 63 ;
else if ( dx > 63 )
dx = 63 ;
308
309
dy = s -> dy ;
310
311
312
313
if ( dy < - 63 )
dy = - 63 ;
else if ( dy > 63 )
dy = 63 ;
314
315
316
317
318
s -> dx -= dx ;
s -> dy -= dy ;
s -> last_buttons_state = s -> buttons_state ;
319
320
dx &= 0x7f ;
dy &= 0x7f ;
321
322
if ( ! ( s -> buttons_state & MOUSE_EVENT_LBUTTON ))
323
dy |= 0x80 ;
324
if ( ! ( s -> buttons_state & MOUSE_EVENT_RBUTTON ))
325
dx |= 0x80 ;
326
327
328
329
obuf [ 0 ] = dy ;
obuf [ 1 ] = dx ;
return 2 ;
330
331
}
332
333
static int adb_mouse_request ( ADBDevice * d , uint8_t * obuf ,
const uint8_t * buf , int len )
334
{
335
MouseState * s = d -> opaque ;
336
337
int cmd , reg , olen ;
338
339
340
341
342
343
344
if (( buf [ 0 ] & 0x0f ) == ADB_FLUSH ) {
/* flush mouse fifo */
s -> buttons_state = s -> last_buttons_state ;
s -> dx = 0 ;
s -> dy = 0 ;
s -> dz = 0 ;
return 0 ;
345
}
346
347
348
cmd = buf [ 0 ] & 0xc ;
reg = buf [ 0 ] & 0x3 ;
349
olen = 0 ;
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
switch ( cmd ) {
case ADB_WRITEREG :
switch ( reg ) {
case 2 :
break ;
case 3 :
switch ( buf [ 2 ]) {
case ADB_CMD_SELF_TEST :
break ;
case ADB_CMD_CHANGE_ID :
case ADB_CMD_CHANGE_ID_AND_ACT :
case ADB_CMD_CHANGE_ID_AND_ENABLE :
d -> devaddr = buf [ 1 ] & 0xf ;
break ;
default :
/* XXX: check this */
d -> devaddr = buf [ 1 ] & 0xf ;
break ;
}
}
break ;
case ADB_READREG :
switch ( reg ) {
373
374
375
case 0 :
olen = adb_mouse_poll ( d , obuf );
break ;
376
377
378
case 1 :
break ;
case 3 :
379
380
381
obuf [ 0 ] = d -> handler ;
obuf [ 1 ] = d -> devaddr ;
olen = 2 ;
382
383
384
385
break ;
}
break ;
}
386
return olen ;
387
388
}
389
390
391
392
393
394
395
396
397
398
399
static int adb_mouse_reset ( ADBDevice * d )
{
MouseState * s = d -> opaque ;
d -> handler = 2 ;
d -> devaddr = ADB_MOUSE ;
memset ( s , 0 , sizeof ( MouseState ));
return 0 ;
}
400
401
402
void adb_mouse_init ( ADBBusState * bus )
{
ADBDevice * d ;
403
MouseState * s ;
404
405
s = qemu_mallocz ( sizeof ( MouseState ));
406
407
408
d = adb_register_device ( bus , ADB_MOUSE , adb_mouse_request ,
adb_mouse_reset , s );
adb_mouse_reset ( d );
ths
authored
18 years ago
409
qemu_add_mouse_event_handler ( adb_mouse_event , d , 0 , "QEMU ADB Mouse" );
410
}