Commit e2733d20b2c8fade7e81aebb34e4e1db821d472f
1 parent
637f6cd7
ADB fixes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@965 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
210 additions
and
108 deletions
hw/adb.c
@@ -43,53 +43,53 @@ | @@ -43,53 +43,53 @@ | ||
43 | #define ADB_MODEM 5 | 43 | #define ADB_MODEM 5 |
44 | #define ADB_MISC 7 | 44 | #define ADB_MISC 7 |
45 | 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) | 46 | +int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len) |
61 | { | 47 | { |
62 | ADBDevice *d; | 48 | ADBDevice *d; |
63 | int devaddr, cmd, i; | 49 | int devaddr, cmd, i; |
64 | - uint8_t obuf[4]; | ||
65 | 50 | ||
66 | cmd = buf[0] & 0xf; | 51 | cmd = buf[0] & 0xf; |
67 | devaddr = buf[0] >> 4; | 52 | devaddr = buf[0] >> 4; |
68 | if (buf[1] == ADB_BUSRESET) { | 53 | if (buf[1] == ADB_BUSRESET) { |
69 | obuf[0] = 0x00; | 54 | obuf[0] = 0x00; |
70 | obuf[1] = 0x00; | 55 | obuf[1] = 0x00; |
71 | - adb_send_packet(s, obuf, 2); | ||
72 | - return; | 56 | + return 2; |
73 | } | 57 | } |
74 | if (cmd == ADB_FLUSH) { | 58 | if (cmd == ADB_FLUSH) { |
75 | obuf[0] = 0x00; | 59 | obuf[0] = 0x00; |
76 | obuf[1] = 0x00; | 60 | obuf[1] = 0x00; |
77 | - adb_send_packet(s, obuf, 2); | ||
78 | - return; | 61 | + return 2; |
79 | } | 62 | } |
80 | 63 | ||
81 | for(i = 0; i < s->nb_devices; i++) { | 64 | for(i = 0; i < s->nb_devices; i++) { |
82 | d = &s->devices[i]; | 65 | d = &s->devices[i]; |
83 | if (d->devaddr == devaddr) { | 66 | if (d->devaddr == devaddr) { |
84 | - d->receive_packet(d, buf, len); | ||
85 | - return; | 67 | + return d->devreq(d, obuf, buf, len); |
86 | } | 68 | } |
87 | } | 69 | } |
88 | - adb_send_packet1(s, ADB_RET_NOTPRESENT); | 70 | + return 0; |
71 | +} | ||
72 | + | ||
73 | +int adb_poll(ADBBusState *s, uint8_t *obuf) | ||
74 | +{ | ||
75 | + ADBDevice *d; | ||
76 | + int olen, i; | ||
77 | + | ||
78 | + olen = 0; | ||
79 | + for(i = 0; i < s->nb_devices; i++) { | ||
80 | + if (s->poll_index >= s->nb_devices) | ||
81 | + s->poll_index = 0; | ||
82 | + d = &s->devices[s->poll_index]; | ||
83 | + olen = d->devreq(d, obuf, NULL, 0); | ||
84 | + s->poll_index++; | ||
85 | + if (olen) | ||
86 | + break; | ||
87 | + } | ||
88 | + return olen; | ||
89 | } | 89 | } |
90 | 90 | ||
91 | ADBDevice *adb_register_device(ADBBusState *s, int devaddr, | 91 | ADBDevice *adb_register_device(ADBBusState *s, int devaddr, |
92 | - ADBDeviceReceivePacket *receive_packet, | 92 | + ADBDeviceRequest *devreq, |
93 | void *opaque) | 93 | void *opaque) |
94 | { | 94 | { |
95 | ADBDevice *d; | 95 | ADBDevice *d; |
@@ -98,7 +98,7 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr, | @@ -98,7 +98,7 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr, | ||
98 | d = &s->devices[s->nb_devices++]; | 98 | d = &s->devices[s->nb_devices++]; |
99 | d->bus = s; | 99 | d->bus = s; |
100 | d->devaddr = devaddr; | 100 | d->devaddr = devaddr; |
101 | - d->receive_packet = receive_packet; | 101 | + d->devreq = devreq; |
102 | d->opaque = opaque; | 102 | d->opaque = opaque; |
103 | return d; | 103 | return d; |
104 | } | 104 | } |
@@ -106,80 +106,108 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr, | @@ -106,80 +106,108 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr, | ||
106 | /***************************************************************/ | 106 | /***************************************************************/ |
107 | /* Keyboard ADB device */ | 107 | /* Keyboard ADB device */ |
108 | 108 | ||
109 | +typedef struct KBDState { | ||
110 | + uint8_t data[128]; | ||
111 | + int rptr, wptr, count; | ||
112 | +} KBDState; | ||
113 | + | ||
109 | static const uint8_t pc_to_adb_keycode[256] = { | 114 | 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, | 115 | 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, | 116 | 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, | 117 | 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, | 118 | 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, | 119 | 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, | 120 | + 84, 85, 82, 65, 0, 0, 10,103,111, 0, 0,110, 81, 0, 0, 0, |
123 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 121 | 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, | 122 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
123 | + 0, 0, 0, 94, 0, 93, 0, 0, 0, 0, 0, 0,104,102, 0, 0, | ||
124 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76,125, 0, 0, | ||
125 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0, | ||
126 | + 0, 0, 0, 0, 0, 75, 0, 0,124, 0, 0, 0, 0, 0, 0, 0, | ||
127 | + 0, 0, 0, 0, 0, 0, 0,115, 62,116, 0, 59, 0, 60, 0,119, | ||
128 | + 61,121,114,117, 0, 0, 0, 0, 0, 0, 0, 55,126, 0,127, 0, | ||
125 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 129 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
130 | + 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
126 | }; | 131 | }; |
127 | 132 | ||
128 | static void adb_kbd_put_keycode(void *opaque, int keycode) | 133 | static void adb_kbd_put_keycode(void *opaque, int keycode) |
129 | { | 134 | { |
130 | - static int ext_keycode; | ||
131 | ADBDevice *d = opaque; | 135 | 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; | 136 | + KBDState *s = d->opaque; |
137 | + | ||
138 | + if (s->count < sizeof(s->data)) { | ||
139 | + s->data[s->wptr] = keycode; | ||
140 | + if (++s->wptr == sizeof(s->data)) | ||
141 | + s->wptr = 0; | ||
142 | + s->count++; | ||
150 | } | 143 | } |
151 | } | 144 | } |
152 | 145 | ||
153 | -static void adb_kbd_receive_packet(ADBDevice *d, const uint8_t *buf, int len) | 146 | +static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf) |
154 | { | 147 | { |
155 | - int cmd, reg; | ||
156 | - uint8_t obuf[4]; | 148 | + static int ext_keycode; |
149 | + KBDState *s = d->opaque; | ||
150 | + int adb_keycode, keycode; | ||
151 | + int olen; | ||
152 | + | ||
153 | + olen = 0; | ||
154 | + for(;;) { | ||
155 | + if (s->count == 0) | ||
156 | + break; | ||
157 | + keycode = s->data[s->rptr]; | ||
158 | + if (++s->rptr == sizeof(s->data)) | ||
159 | + s->rptr = 0; | ||
160 | + s->count--; | ||
161 | + | ||
162 | + if (keycode == 0xe0) { | ||
163 | + ext_keycode = 1; | ||
164 | + } else { | ||
165 | + if (ext_keycode) | ||
166 | + adb_keycode = pc_to_adb_keycode[keycode | 0x80]; | ||
167 | + else | ||
168 | + adb_keycode = pc_to_adb_keycode[keycode & 0x7f]; | ||
169 | + obuf[0] = (d->devaddr << 4) | 0x0c; | ||
170 | + obuf[1] = adb_keycode | (keycode & 0x80); | ||
171 | + obuf[2] = 0xff; | ||
172 | + olen = 3; | ||
173 | + ext_keycode = 0; | ||
174 | + break; | ||
175 | + } | ||
176 | + } | ||
177 | + return olen; | ||
178 | +} | ||
179 | + | ||
180 | +static int adb_kbd_request(ADBDevice *d, uint8_t *obuf, | ||
181 | + const uint8_t *buf, int len) | ||
182 | +{ | ||
183 | + int cmd, reg, olen; | ||
184 | + | ||
185 | + if (!buf) { | ||
186 | + return adb_kbd_poll(d, obuf); | ||
187 | + } | ||
157 | 188 | ||
158 | cmd = buf[0] & 0xc; | 189 | cmd = buf[0] & 0xc; |
159 | reg = buf[0] & 0x3; | 190 | reg = buf[0] & 0x3; |
191 | + olen = 0; | ||
160 | switch(cmd) { | 192 | switch(cmd) { |
161 | case ADB_WRITEREG: | 193 | case ADB_WRITEREG: |
162 | switch(reg) { | 194 | switch(reg) { |
163 | case 2: | 195 | case 2: |
164 | /* LED status */ | 196 | /* LED status */ |
165 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
166 | break; | 197 | break; |
167 | case 3: | 198 | case 3: |
168 | switch(buf[2]) { | 199 | switch(buf[2]) { |
169 | case ADB_CMD_SELF_TEST: | 200 | case ADB_CMD_SELF_TEST: |
170 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
171 | break; | 201 | break; |
172 | case ADB_CMD_CHANGE_ID: | 202 | case ADB_CMD_CHANGE_ID: |
173 | case ADB_CMD_CHANGE_ID_AND_ACT: | 203 | case ADB_CMD_CHANGE_ID_AND_ACT: |
174 | case ADB_CMD_CHANGE_ID_AND_ENABLE: | 204 | case ADB_CMD_CHANGE_ID_AND_ENABLE: |
175 | d->devaddr = buf[1] & 0xf; | 205 | d->devaddr = buf[1] & 0xf; |
176 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
177 | break; | 206 | break; |
178 | default: | 207 | default: |
179 | /* XXX: check this */ | 208 | /* XXX: check this */ |
180 | d->devaddr = buf[1] & 0xf; | 209 | d->devaddr = buf[1] & 0xf; |
181 | d->handler = buf[2]; | 210 | d->handler = buf[2]; |
182 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
183 | break; | 211 | break; |
184 | } | 212 | } |
185 | } | 213 | } |
@@ -187,98 +215,122 @@ static void adb_kbd_receive_packet(ADBDevice *d, const uint8_t *buf, int len) | @@ -187,98 +215,122 @@ static void adb_kbd_receive_packet(ADBDevice *d, const uint8_t *buf, int len) | ||
187 | case ADB_READREG: | 215 | case ADB_READREG: |
188 | switch(reg) { | 216 | switch(reg) { |
189 | case 1: | 217 | case 1: |
190 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
191 | break; | 218 | break; |
192 | case 2: | 219 | 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); | 220 | + obuf[0] = 0x00; /* XXX: check this */ |
221 | + obuf[1] = 0x07; /* led status */ | ||
222 | + olen = 2; | ||
197 | break; | 223 | break; |
198 | case 3: | 224 | 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); | 225 | + obuf[0] = d->handler; |
226 | + obuf[1] = d->devaddr; | ||
227 | + olen = 2; | ||
203 | break; | 228 | break; |
204 | } | 229 | } |
205 | break; | 230 | break; |
206 | } | 231 | } |
232 | + return olen; | ||
207 | } | 233 | } |
208 | 234 | ||
209 | void adb_kbd_init(ADBBusState *bus) | 235 | void adb_kbd_init(ADBBusState *bus) |
210 | { | 236 | { |
211 | ADBDevice *d; | 237 | ADBDevice *d; |
212 | - | ||
213 | - d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_receive_packet, NULL); | 238 | + KBDState *s; |
239 | + s = qemu_mallocz(sizeof(KBDState)); | ||
240 | + d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request, s); | ||
241 | + d->handler = 1; | ||
214 | qemu_add_kbd_event_handler(adb_kbd_put_keycode, d); | 242 | qemu_add_kbd_event_handler(adb_kbd_put_keycode, d); |
215 | } | 243 | } |
216 | 244 | ||
217 | /***************************************************************/ | 245 | /***************************************************************/ |
218 | /* Mouse ADB device */ | 246 | /* Mouse ADB device */ |
219 | 247 | ||
248 | +typedef struct MouseState { | ||
249 | + int buttons_state, last_buttons_state; | ||
250 | + int dx, dy, dz; | ||
251 | +} MouseState; | ||
252 | + | ||
220 | static void adb_mouse_event(void *opaque, | 253 | static void adb_mouse_event(void *opaque, |
221 | int dx1, int dy1, int dz1, int buttons_state) | 254 | int dx1, int dy1, int dz1, int buttons_state) |
222 | { | 255 | { |
223 | ADBDevice *d = opaque; | 256 | ADBDevice *d = opaque; |
224 | - uint8_t buf[4]; | 257 | + MouseState *s = d->opaque; |
258 | + | ||
259 | + s->dx += dx1; | ||
260 | + s->dy += dy1; | ||
261 | + s->dz += dz1; | ||
262 | + s->buttons_state = buttons_state; | ||
263 | +} | ||
264 | + | ||
265 | + | ||
266 | +static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf) | ||
267 | +{ | ||
268 | + MouseState *s = d->opaque; | ||
225 | int dx, dy; | 269 | int dx, dy; |
226 | 270 | ||
227 | - dx = dx1; | 271 | + if (s->last_buttons_state == s->buttons_state && |
272 | + s->dx == 0 && s->dy == 0) | ||
273 | + return 0; | ||
274 | + | ||
275 | + dx = s->dx; | ||
228 | if (dx < -63) | 276 | if (dx < -63) |
229 | dx = -63; | 277 | dx = -63; |
230 | else if (dx > 63) | 278 | else if (dx > 63) |
231 | dx = 63; | 279 | dx = 63; |
232 | - | ||
233 | - dy = dy1; | 280 | + |
281 | + dy = s->dy; | ||
234 | if (dy < -63) | 282 | if (dy < -63) |
235 | dy = -63; | 283 | dy = -63; |
236 | else if (dy > 63) | 284 | else if (dy > 63) |
237 | dy = 63; | 285 | dy = 63; |
238 | - | 286 | + |
287 | + s->dx -= dx; | ||
288 | + s->dy -= dy; | ||
289 | + s->last_buttons_state = s->buttons_state; | ||
290 | + | ||
239 | dx &= 0x7f; | 291 | dx &= 0x7f; |
240 | dy &= 0x7f; | 292 | dy &= 0x7f; |
241 | - | ||
242 | - if (buttons_state & MOUSE_EVENT_LBUTTON) | 293 | + |
294 | + if (s->buttons_state & MOUSE_EVENT_LBUTTON) | ||
243 | dy |= 0x80; | 295 | dy |= 0x80; |
244 | - if (buttons_state & MOUSE_EVENT_RBUTTON) | 296 | + if (s->buttons_state & MOUSE_EVENT_RBUTTON) |
245 | dx |= 0x80; | 297 | 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); | 298 | + |
299 | + obuf[0] = (d->devaddr << 4) | 0x0c; | ||
300 | + obuf[1] = dy; | ||
301 | + obuf[2] = dx; | ||
302 | + return 3; | ||
252 | } | 303 | } |
253 | 304 | ||
254 | -static void adb_mouse_receive_packet(ADBDevice *d, const uint8_t *buf, int len) | 305 | +static int adb_mouse_request(ADBDevice *d, uint8_t *obuf, |
306 | + const uint8_t *buf, int len) | ||
255 | { | 307 | { |
256 | - int cmd, reg; | ||
257 | - uint8_t obuf[4]; | 308 | + int cmd, reg, olen; |
309 | + | ||
310 | + if (!buf) { | ||
311 | + return adb_mouse_poll(d, obuf); | ||
312 | + } | ||
258 | 313 | ||
259 | cmd = buf[0] & 0xc; | 314 | cmd = buf[0] & 0xc; |
260 | reg = buf[0] & 0x3; | 315 | reg = buf[0] & 0x3; |
316 | + olen = 0; | ||
261 | switch(cmd) { | 317 | switch(cmd) { |
262 | case ADB_WRITEREG: | 318 | case ADB_WRITEREG: |
263 | switch(reg) { | 319 | switch(reg) { |
264 | case 2: | 320 | case 2: |
265 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
266 | break; | 321 | break; |
267 | case 3: | 322 | case 3: |
268 | switch(buf[2]) { | 323 | switch(buf[2]) { |
269 | case ADB_CMD_SELF_TEST: | 324 | case ADB_CMD_SELF_TEST: |
270 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
271 | break; | 325 | break; |
272 | case ADB_CMD_CHANGE_ID: | 326 | case ADB_CMD_CHANGE_ID: |
273 | case ADB_CMD_CHANGE_ID_AND_ACT: | 327 | case ADB_CMD_CHANGE_ID_AND_ACT: |
274 | case ADB_CMD_CHANGE_ID_AND_ENABLE: | 328 | case ADB_CMD_CHANGE_ID_AND_ENABLE: |
275 | d->devaddr = buf[1] & 0xf; | 329 | d->devaddr = buf[1] & 0xf; |
276 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
277 | break; | 330 | break; |
278 | default: | 331 | default: |
279 | /* XXX: check this */ | 332 | /* XXX: check this */ |
280 | d->devaddr = buf[1] & 0xf; | 333 | d->devaddr = buf[1] & 0xf; |
281 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
282 | break; | 334 | break; |
283 | } | 335 | } |
284 | } | 336 | } |
@@ -286,23 +338,25 @@ static void adb_mouse_receive_packet(ADBDevice *d, const uint8_t *buf, int len) | @@ -286,23 +338,25 @@ static void adb_mouse_receive_packet(ADBDevice *d, const uint8_t *buf, int len) | ||
286 | case ADB_READREG: | 338 | case ADB_READREG: |
287 | switch(reg) { | 339 | switch(reg) { |
288 | case 1: | 340 | case 1: |
289 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
290 | break; | 341 | break; |
291 | case 3: | 342 | 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); | 343 | + obuf[0] = d->handler; |
344 | + obuf[1] = d->devaddr; | ||
345 | + olen = 2; | ||
296 | break; | 346 | break; |
297 | } | 347 | } |
298 | break; | 348 | break; |
299 | } | 349 | } |
350 | + return olen; | ||
300 | } | 351 | } |
301 | 352 | ||
302 | void adb_mouse_init(ADBBusState *bus) | 353 | void adb_mouse_init(ADBBusState *bus) |
303 | { | 354 | { |
304 | ADBDevice *d; | 355 | ADBDevice *d; |
356 | + MouseState *s; | ||
305 | 357 | ||
306 | - d = adb_register_device(bus, ADB_MOUSE, adb_mouse_receive_packet, NULL); | 358 | + s = qemu_mallocz(sizeof(MouseState)); |
359 | + d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request, s); | ||
360 | + d->handler = 2; | ||
307 | qemu_add_mouse_event_handler(adb_mouse_event, d); | 361 | qemu_add_mouse_event_handler(adb_mouse_event, d); |
308 | } | 362 | } |
hw/cuda.c
@@ -85,6 +85,7 @@ | @@ -85,6 +85,7 @@ | ||
85 | #define CUDA_COMBINED_FORMAT_IIC 0x25 | 85 | #define CUDA_COMBINED_FORMAT_IIC 0x25 |
86 | 86 | ||
87 | #define CUDA_TIMER_FREQ (4700000 / 6) | 87 | #define CUDA_TIMER_FREQ (4700000 / 6) |
88 | +#define CUDA_ADB_POLL_FREQ 50 | ||
88 | 89 | ||
89 | typedef struct CUDATimer { | 90 | typedef struct CUDATimer { |
90 | unsigned int latch; | 91 | unsigned int latch; |
@@ -121,6 +122,7 @@ typedef struct CUDAState { | @@ -121,6 +122,7 @@ typedef struct CUDAState { | ||
121 | uint8_t autopoll; | 122 | uint8_t autopoll; |
122 | uint8_t data_in[128]; | 123 | uint8_t data_in[128]; |
123 | uint8_t data_out[16]; | 124 | uint8_t data_out[16]; |
125 | + QEMUTimer *adb_poll_timer; | ||
124 | } CUDAState; | 126 | } CUDAState; |
125 | 127 | ||
126 | static CUDAState cuda_state; | 128 | static CUDAState cuda_state; |
@@ -469,15 +471,42 @@ void adb_send_packet(ADBBusState *bus, const uint8_t *buf, int len) | @@ -469,15 +471,42 @@ void adb_send_packet(ADBBusState *bus, const uint8_t *buf, int len) | ||
469 | cuda_send_packet_to_host(s, data, len + 1); | 471 | cuda_send_packet_to_host(s, data, len + 1); |
470 | } | 472 | } |
471 | 473 | ||
474 | +void cuda_adb_poll(void *opaque) | ||
475 | +{ | ||
476 | + CUDAState *s = opaque; | ||
477 | + uint8_t obuf[ADB_MAX_OUT_LEN + 2]; | ||
478 | + int olen; | ||
479 | + | ||
480 | + olen = adb_poll(&adb_bus, obuf + 2); | ||
481 | + if (olen > 0) { | ||
482 | + obuf[0] = ADB_PACKET; | ||
483 | + obuf[1] = 0x40; /* polled data */ | ||
484 | + cuda_send_packet_to_host(s, obuf, olen + 2); | ||
485 | + } | ||
486 | + qemu_mod_timer(s->adb_poll_timer, | ||
487 | + qemu_get_clock(vm_clock) + | ||
488 | + (ticks_per_sec / CUDA_ADB_POLL_FREQ)); | ||
489 | +} | ||
490 | + | ||
472 | static void cuda_receive_packet(CUDAState *s, | 491 | static void cuda_receive_packet(CUDAState *s, |
473 | const uint8_t *data, int len) | 492 | const uint8_t *data, int len) |
474 | { | 493 | { |
475 | uint8_t obuf[16]; | 494 | uint8_t obuf[16]; |
476 | - int ti; | 495 | + int ti, autopoll; |
477 | 496 | ||
478 | switch(data[0]) { | 497 | switch(data[0]) { |
479 | case CUDA_AUTOPOLL: | 498 | case CUDA_AUTOPOLL: |
480 | - s->autopoll = data[1]; | 499 | + autopoll = (data[1] != 0); |
500 | + if (autopoll != s->autopoll) { | ||
501 | + s->autopoll = autopoll; | ||
502 | + if (autopoll) { | ||
503 | + qemu_mod_timer(s->adb_poll_timer, | ||
504 | + qemu_get_clock(vm_clock) + | ||
505 | + (ticks_per_sec / CUDA_ADB_POLL_FREQ)); | ||
506 | + } else { | ||
507 | + qemu_del_timer(s->adb_poll_timer); | ||
508 | + } | ||
509 | + } | ||
481 | obuf[0] = CUDA_PACKET; | 510 | obuf[0] = CUDA_PACKET; |
482 | obuf[1] = data[1]; | 511 | obuf[1] = data[1]; |
483 | cuda_send_packet_to_host(s, obuf, 2); | 512 | cuda_send_packet_to_host(s, obuf, 2); |
@@ -522,7 +551,20 @@ static void cuda_receive_packet_from_host(CUDAState *s, | @@ -522,7 +551,20 @@ static void cuda_receive_packet_from_host(CUDAState *s, | ||
522 | #endif | 551 | #endif |
523 | switch(data[0]) { | 552 | switch(data[0]) { |
524 | case ADB_PACKET: | 553 | case ADB_PACKET: |
525 | - adb_receive_packet(&adb_bus, data + 1, len - 1); | 554 | + { |
555 | + uint8_t obuf[ADB_MAX_OUT_LEN + 2]; | ||
556 | + int olen; | ||
557 | + olen = adb_request(&adb_bus, obuf + 2, data + 1, len - 1); | ||
558 | + if (olen != 0) { | ||
559 | + obuf[0] = ADB_PACKET; | ||
560 | + obuf[1] = 0x00; | ||
561 | + } else { | ||
562 | + /* empty reply */ | ||
563 | + obuf[0] = ADB_PACKET; | ||
564 | + obuf[1] = 0x02; | ||
565 | + } | ||
566 | + cuda_send_packet_to_host(s, obuf, olen + 2); | ||
567 | + } | ||
526 | break; | 568 | break; |
527 | case CUDA_PACKET: | 569 | case CUDA_PACKET: |
528 | cuda_receive_packet(s, data + 1, len - 1); | 570 | cuda_receive_packet(s, data + 1, len - 1); |
@@ -574,6 +616,8 @@ int cuda_init(openpic_t *openpic, int irq) | @@ -574,6 +616,8 @@ int cuda_init(openpic_t *openpic, int irq) | ||
574 | s->timers[1].latch = 0x10000; | 616 | s->timers[1].latch = 0x10000; |
575 | s->ier = T1_INT | SR_INT; | 617 | s->ier = T1_INT | SR_INT; |
576 | set_counter(s, &s->timers[1], 0xffff); | 618 | set_counter(s, &s->timers[1], 0xffff); |
619 | + | ||
620 | + s->adb_poll_timer = qemu_new_timer(vm_clock, cuda_adb_poll, s); | ||
577 | cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s); | 621 | cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s); |
578 | return cuda_mem_index; | 622 | return cuda_mem_index; |
579 | } | 623 | } |
vl.h
@@ -528,8 +528,7 @@ PCIBus *pci_pmac_init(void); | @@ -528,8 +528,7 @@ PCIBus *pci_pmac_init(void); | ||
528 | /* openpic.c */ | 528 | /* openpic.c */ |
529 | typedef struct openpic_t openpic_t; | 529 | typedef struct openpic_t openpic_t; |
530 | void openpic_set_irq (openpic_t *opp, int n_IRQ, int level); | 530 | void openpic_set_irq (openpic_t *opp, int n_IRQ, int level); |
531 | -openpic_t *openpic_init (PCIBus *bus, | ||
532 | - uint32_t isu_base, uint32_t idu_base, int nb_cpus); | 531 | +openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus); |
533 | 532 | ||
534 | /* vga.c */ | 533 | /* vga.c */ |
535 | 534 | ||
@@ -727,28 +726,33 @@ int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, | @@ -727,28 +726,33 @@ int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, | ||
727 | 726 | ||
728 | #define MAX_ADB_DEVICES 16 | 727 | #define MAX_ADB_DEVICES 16 |
729 | 728 | ||
730 | -typedef struct ADBDevice ADBDevice; | 729 | +#define ADB_MAX_OUT_LEN 16 |
731 | 730 | ||
732 | -typedef void ADBDeviceReceivePacket(ADBDevice *d, const uint8_t *buf, int len); | 731 | +typedef struct ADBDevice ADBDevice; |
733 | 732 | ||
733 | +/* buf = NULL means polling */ | ||
734 | +typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out, | ||
735 | + const uint8_t *buf, int len); | ||
734 | struct ADBDevice { | 736 | struct ADBDevice { |
735 | struct ADBBusState *bus; | 737 | struct ADBBusState *bus; |
736 | int devaddr; | 738 | int devaddr; |
737 | int handler; | 739 | int handler; |
738 | - ADBDeviceReceivePacket *receive_packet; | 740 | + ADBDeviceRequest *devreq; |
739 | void *opaque; | 741 | void *opaque; |
740 | }; | 742 | }; |
741 | 743 | ||
742 | typedef struct ADBBusState { | 744 | typedef struct ADBBusState { |
743 | ADBDevice devices[MAX_ADB_DEVICES]; | 745 | ADBDevice devices[MAX_ADB_DEVICES]; |
744 | int nb_devices; | 746 | int nb_devices; |
747 | + int poll_index; | ||
745 | } ADBBusState; | 748 | } ADBBusState; |
746 | 749 | ||
747 | -void adb_receive_packet(ADBBusState *s, const uint8_t *buf, int len); | ||
748 | -void adb_send_packet(ADBBusState *s, const uint8_t *buf, int len); | 750 | +int adb_request(ADBBusState *s, uint8_t *buf_out, |
751 | + const uint8_t *buf, int len); | ||
752 | +int adb_poll(ADBBusState *s, uint8_t *buf_out); | ||
749 | 753 | ||
750 | ADBDevice *adb_register_device(ADBBusState *s, int devaddr, | 754 | ADBDevice *adb_register_device(ADBBusState *s, int devaddr, |
751 | - ADBDeviceReceivePacket *receive_packet, | 755 | + ADBDeviceRequest *devreq, |
752 | void *opaque); | 756 | void *opaque); |
753 | void adb_kbd_init(ADBBusState *bus); | 757 | void adb_kbd_init(ADBBusState *bus); |
754 | void adb_mouse_init(ADBBusState *bus); | 758 | void adb_mouse_init(ADBBusState *bus); |