Commit 6f51f6b593e0a0065f83bcebb6f9e4aa05a4c8b3
1 parent
0294ffb9
keyboard irq generation fix
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@778 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
18 additions
and
21 deletions
hw/pckbd.c
... | ... | @@ -111,12 +111,13 @@ |
111 | 111 | #define KBD_QUEUE_SIZE 256 |
112 | 112 | |
113 | 113 | typedef struct { |
114 | + uint8_t aux[KBD_QUEUE_SIZE]; | |
114 | 115 | uint8_t data[KBD_QUEUE_SIZE]; |
115 | 116 | int rptr, wptr, count; |
116 | 117 | } KBDQueue; |
117 | 118 | |
118 | 119 | typedef struct KBDState { |
119 | - KBDQueue queues[2]; | |
120 | + KBDQueue queue; | |
120 | 121 | uint8_t write_cmd; /* if non zero, write data to port 60 is expected */ |
121 | 122 | uint8_t status; |
122 | 123 | uint8_t mode; |
... | ... | @@ -145,15 +146,15 @@ int reset_requested; |
145 | 146 | incorrect, but it avoids having to simulate exact delays */ |
146 | 147 | static void kbd_update_irq(KBDState *s) |
147 | 148 | { |
149 | + KBDQueue *q = &s->queue; | |
148 | 150 | int irq12_level, irq1_level; |
149 | 151 | |
150 | 152 | irq1_level = 0; |
151 | 153 | irq12_level = 0; |
152 | 154 | s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF); |
153 | - if (s->queues[0].count != 0 || | |
154 | - s->queues[1].count != 0) { | |
155 | + if (q->count != 0) { | |
155 | 156 | s->status |= KBD_STAT_OBF; |
156 | - if (s->queues[1].count != 0) { | |
157 | + if (q->aux[q->rptr]) { | |
157 | 158 | s->status |= KBD_STAT_MOUSE_OBF; |
158 | 159 | if (s->mode & KBD_MODE_MOUSE_INT) |
159 | 160 | irq12_level = 1; |
... | ... | @@ -169,7 +170,7 @@ static void kbd_update_irq(KBDState *s) |
169 | 170 | |
170 | 171 | static void kbd_queue(KBDState *s, int b, int aux) |
171 | 172 | { |
172 | - KBDQueue *q = &s->queues[aux]; | |
173 | + KBDQueue *q = &s->queue; | |
173 | 174 | |
174 | 175 | #if defined(DEBUG_MOUSE) || defined(DEBUG_KBD) |
175 | 176 | if (aux) |
... | ... | @@ -181,6 +182,7 @@ static void kbd_queue(KBDState *s, int b, int aux) |
181 | 182 | #endif |
182 | 183 | if (q->count >= KBD_QUEUE_SIZE) |
183 | 184 | return; |
185 | + q->aux[q->wptr] = aux; | |
184 | 186 | q->data[q->wptr] = b; |
185 | 187 | if (++q->wptr == KBD_QUEUE_SIZE) |
186 | 188 | q->wptr = 0; |
... | ... | @@ -288,30 +290,28 @@ static uint32_t kbd_read_data(void *opaque, uint32_t addr) |
288 | 290 | { |
289 | 291 | KBDState *s = opaque; |
290 | 292 | KBDQueue *q; |
291 | - int val, index; | |
293 | + int val, index, aux; | |
292 | 294 | |
293 | - q = &s->queues[1]; /* first check AUX data */ | |
294 | - if (q->count == 0) | |
295 | - q = &s->queues[0]; /* then check KBD data */ | |
295 | + q = &s->queue; | |
296 | 296 | if (q->count == 0) { |
297 | 297 | /* NOTE: if no data left, we return the last keyboard one |
298 | 298 | (needed for EMM386) */ |
299 | 299 | /* XXX: need a timer to do things correctly */ |
300 | - q = &s->queues[0]; | |
301 | 300 | index = q->rptr - 1; |
302 | 301 | if (index < 0) |
303 | 302 | index = KBD_QUEUE_SIZE - 1; |
304 | 303 | val = q->data[index]; |
305 | 304 | } else { |
305 | + aux = q->aux[q->rptr]; | |
306 | 306 | val = q->data[q->rptr]; |
307 | 307 | if (++q->rptr == KBD_QUEUE_SIZE) |
308 | 308 | q->rptr = 0; |
309 | 309 | q->count--; |
310 | 310 | /* reading deasserts IRQ */ |
311 | - if (q == &s->queues[0]) | |
312 | - pic_set_irq(1, 0); | |
313 | - else | |
311 | + if (aux) | |
314 | 312 | pic_set_irq(12, 0); |
313 | + else | |
314 | + pic_set_irq(1, 0); | |
315 | 315 | } |
316 | 316 | /* reassert IRQs if data left */ |
317 | 317 | kbd_update_irq(s); |
... | ... | @@ -452,7 +452,7 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) |
452 | 452 | s->mouse_buttons = buttons_state; |
453 | 453 | |
454 | 454 | if (!(s->mouse_status & MOUSE_STATUS_REMOTE) && |
455 | - (s->queues[1].count < (KBD_QUEUE_SIZE - 16))) { | |
455 | + (s->queue.count < (KBD_QUEUE_SIZE - 16))) { | |
456 | 456 | for(;;) { |
457 | 457 | /* if not remote, send event. Multiple events are sent if |
458 | 458 | too big deltas */ |
... | ... | @@ -632,18 +632,15 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) |
632 | 632 | void kbd_reset(KBDState *s) |
633 | 633 | { |
634 | 634 | KBDQueue *q; |
635 | - int i; | |
636 | 635 | |
637 | 636 | s->kbd_write_cmd = -1; |
638 | 637 | s->mouse_write_cmd = -1; |
639 | 638 | s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT; |
640 | 639 | s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED; |
641 | - for(i = 0; i < 2; i++) { | |
642 | - q = &s->queues[i]; | |
643 | - q->rptr = 0; | |
644 | - q->wptr = 0; | |
645 | - q->count = 0; | |
646 | - } | |
640 | + q = &s->queue; | |
641 | + q->rptr = 0; | |
642 | + q->wptr = 0; | |
643 | + q->count = 0; | |
647 | 644 | } |
648 | 645 | |
649 | 646 | void kbd_init(void) | ... | ... |