Commit 6f51f6b593e0a0065f83bcebb6f9e4aa05a4c8b3

Authored by bellard
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)
... ...