1
2
/*
* QEMU ADB support
ths
authored
18 years ago
3
*
4
* Copyright ( c ) 2004 Fabrice Bellard
ths
authored
18 years ago
5
*
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
* 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 .
*/
24
25
26
# include "hw.h"
# include "ppc_mac.h"
# include "console.h"
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/* 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
48
49
50
/* error codes */
# define ADB_RET_NOTPRESENT ( - 2 )
51
int adb_request ( ADBBusState * s , uint8_t * obuf , const uint8_t * buf , int len )
52
53
54
55
{
ADBDevice * d ;
int devaddr , cmd , i ;
56
cmd = buf [ 0 ] & 0xf ;
57
58
59
60
61
62
63
64
if ( cmd == ADB_BUSRESET ) {
for ( i = 0 ; i < s -> nb_devices ; i ++ ) {
d = & s -> devices [ i ];
if ( d -> devreset ) {
d -> devreset ( d );
}
}
return 0 ;
65
}
66
devaddr = buf [ 0 ] >> 4 ;
67
68
69
for ( i = 0 ; i < s -> nb_devices ; i ++ ) {
d = & s -> devices [ i ];
if ( d -> devaddr == devaddr ) {
70
return d -> devreq ( d , obuf , buf , len );
71
72
}
}
73
return ADB_RET_NOTPRESENT ;
74
75
}
76
/* XXX: move that to cuda ? */
77
78
79
80
int adb_poll ( ADBBusState * s , uint8_t * obuf )
{
ADBDevice * d ;
int olen , i ;
81
uint8_t buf [ 1 ];
82
83
84
85
86
87
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 ];
88
89
90
91
92
93
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 ++ ;
94
break ;
95
96
}
s -> poll_index ++ ;
97
98
}
return olen ;
99
100
}
ths
authored
18 years ago
101
102
103
ADBDevice * adb_register_device ( ADBBusState * s , int devaddr ,
ADBDeviceRequest * devreq ,
ADBDeviceReset * devreset ,
104
105
106
107
108
109
110
111
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 ;
112
d -> devreq = devreq ;
113
d -> devreset = devreset ;
114
115
116
117
118
119
120
d -> opaque = opaque ;
return d ;
}
/***************************************************************/
/* Keyboard ADB device */
121
122
123
124
125
typedef struct KBDState {
uint8_t data [ 128 ];
int rptr , wptr , count ;
} KBDState ;
126
127
128
129
130
131
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 ,
132
84 , 85 , 82 , 65 , 0 , 0 , 10 , 103 , 111 , 0 , 0 , 110 , 81 , 0 , 0 , 0 ,
133
134
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 ,
135
136
137
138
139
140
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 ,
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 ,
143
144
145
146
147
};
static void adb_kbd_put_keycode ( void * opaque , int keycode )
{
ADBDevice * d = opaque ;
148
149
150
151
152
153
154
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 ++ ;
155
156
157
}
}
158
static int adb_kbd_poll ( ADBDevice * d , uint8_t * obuf )
159
{
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
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 ];
181
182
183
184
obuf [ 0 ] = adb_keycode | ( keycode & 0x80 );
/* NOTE: could put a second keycode if needed */
obuf [ 1 ] = 0xff ;
olen = 2 ;
185
186
187
188
189
190
191
192
193
194
ext_keycode = 0 ;
break ;
}
}
return olen ;
}
static int adb_kbd_request ( ADBDevice * d , uint8_t * obuf ,
const uint8_t * buf , int len )
{
195
KBDState * s = d -> opaque ;
196
197
int cmd , reg , olen ;
198
199
200
201
if (( buf [ 0 ] & 0x0f ) == ADB_FLUSH ) {
/* flush keyboard fifo */
s -> wptr = s -> rptr = s -> count = 0 ;
return 0 ;
202
}
203
204
205
cmd = buf [ 0 ] & 0xc ;
reg = buf [ 0 ] & 0x3 ;
206
olen = 0 ;
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
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 ) {
232
233
234
case 0 :
olen = adb_kbd_poll ( d , obuf );
break ;
235
236
237
case 1 :
break ;
case 2 :
238
239
240
obuf [ 0 ] = 0x00 ; /* XXX: check this */
obuf [ 1 ] = 0x07 ; /* led status */
olen = 2 ;
241
242
break ;
case 3 :
243
244
245
obuf [ 0 ] = d -> handler ;
obuf [ 1 ] = d -> devaddr ;
olen = 2 ;
246
247
248
249
break ;
}
break ;
}
250
return olen ;
251
252
}
253
254
255
256
257
258
259
260
261
262
263
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 ;
}
264
265
266
void adb_kbd_init ( ADBBusState * bus )
{
ADBDevice * d ;
267
268
KBDState * s ;
s = qemu_mallocz ( sizeof ( KBDState ));
269
270
271
d = adb_register_device ( bus , ADB_KEYBOARD , adb_kbd_request ,
adb_kbd_reset , s );
adb_kbd_reset ( d );
272
273
274
275
276
277
qemu_add_kbd_event_handler ( adb_kbd_put_keycode , d );
}
/***************************************************************/
/* Mouse ADB device */
278
279
280
281
282
typedef struct MouseState {
int buttons_state , last_buttons_state ;
int dx , dy , dz ;
} MouseState ;
283
284
285
286
static void adb_mouse_event ( void * opaque ,
int dx1 , int dy1 , int dz1 , int buttons_state )
{
ADBDevice * d = opaque ;
287
288
289
290
291
292
293
294
295
296
297
298
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 ;
299
300
int dx , dy ;
301
302
303
if ( s -> last_buttons_state == s -> buttons_state &&
s -> dx == 0 && s -> dy == 0 )
return 0 ;
ths
authored
18 years ago
304
305
dx = s -> dx ;
306
307
308
309
if ( dx < - 63 )
dx = - 63 ;
else if ( dx > 63 )
dx = 63 ;
ths
authored
18 years ago
310
311
dy = s -> dy ;
312
313
314
315
if ( dy < - 63 )
dy = - 63 ;
else if ( dy > 63 )
dy = 63 ;
ths
authored
18 years ago
316
317
318
319
s -> dx -= dx ;
s -> dy -= dy ;
s -> last_buttons_state = s -> buttons_state ;
ths
authored
18 years ago
320
321
322
dx &= 0x7f ;
dy &= 0x7f ;
ths
authored
18 years ago
323
324
if ( ! ( s -> buttons_state & MOUSE_EVENT_LBUTTON ))
325
dy |= 0x80 ;
326
if ( ! ( s -> buttons_state & MOUSE_EVENT_RBUTTON ))
327
dx |= 0x80 ;
ths
authored
18 years ago
328
329
330
331
obuf [ 0 ] = dy ;
obuf [ 1 ] = dx ;
return 2 ;
332
333
}
334
335
static int adb_mouse_request ( ADBDevice * d , uint8_t * obuf ,
const uint8_t * buf , int len )
336
{
337
MouseState * s = d -> opaque ;
338
int cmd , reg , olen ;
ths
authored
18 years ago
339
340
341
342
343
344
345
346
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 ;
347
}
348
349
350
cmd = buf [ 0 ] & 0xc ;
reg = buf [ 0 ] & 0x3 ;
351
olen = 0 ;
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
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 ) {
375
376
377
case 0 :
olen = adb_mouse_poll ( d , obuf );
break ;
378
379
380
case 1 :
break ;
case 3 :
381
382
383
obuf [ 0 ] = d -> handler ;
obuf [ 1 ] = d -> devaddr ;
olen = 2 ;
384
385
386
387
break ;
}
break ;
}
388
return olen ;
389
390
}
391
392
393
394
395
396
397
398
399
400
401
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 ;
}
402
403
404
void adb_mouse_init ( ADBBusState * bus )
{
ADBDevice * d ;
405
MouseState * s ;
406
407
s = qemu_mallocz ( sizeof ( MouseState ));
408
409
410
d = adb_register_device ( bus , ADB_MOUSE , adb_mouse_request ,
adb_mouse_reset , s );
adb_mouse_reset ( d );
ths
authored
18 years ago
411
qemu_add_mouse_event_handler ( adb_mouse_event , d , 0 , "QEMU ADB Mouse" );
412
}