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,12 +111,13 @@
111 #define KBD_QUEUE_SIZE 256 111 #define KBD_QUEUE_SIZE 256
112 112
113 typedef struct { 113 typedef struct {
  114 + uint8_t aux[KBD_QUEUE_SIZE];
114 uint8_t data[KBD_QUEUE_SIZE]; 115 uint8_t data[KBD_QUEUE_SIZE];
115 int rptr, wptr, count; 116 int rptr, wptr, count;
116 } KBDQueue; 117 } KBDQueue;
117 118
118 typedef struct KBDState { 119 typedef struct KBDState {
119 - KBDQueue queues[2]; 120 + KBDQueue queue;
120 uint8_t write_cmd; /* if non zero, write data to port 60 is expected */ 121 uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
121 uint8_t status; 122 uint8_t status;
122 uint8_t mode; 123 uint8_t mode;
@@ -145,15 +146,15 @@ int reset_requested; @@ -145,15 +146,15 @@ int reset_requested;
145 incorrect, but it avoids having to simulate exact delays */ 146 incorrect, but it avoids having to simulate exact delays */
146 static void kbd_update_irq(KBDState *s) 147 static void kbd_update_irq(KBDState *s)
147 { 148 {
  149 + KBDQueue *q = &s->queue;
148 int irq12_level, irq1_level; 150 int irq12_level, irq1_level;
149 151
150 irq1_level = 0; 152 irq1_level = 0;
151 irq12_level = 0; 153 irq12_level = 0;
152 s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF); 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 s->status |= KBD_STAT_OBF; 156 s->status |= KBD_STAT_OBF;
156 - if (s->queues[1].count != 0) { 157 + if (q->aux[q->rptr]) {
157 s->status |= KBD_STAT_MOUSE_OBF; 158 s->status |= KBD_STAT_MOUSE_OBF;
158 if (s->mode & KBD_MODE_MOUSE_INT) 159 if (s->mode & KBD_MODE_MOUSE_INT)
159 irq12_level = 1; 160 irq12_level = 1;
@@ -169,7 +170,7 @@ static void kbd_update_irq(KBDState *s) @@ -169,7 +170,7 @@ static void kbd_update_irq(KBDState *s)
169 170
170 static void kbd_queue(KBDState *s, int b, int aux) 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 #if defined(DEBUG_MOUSE) || defined(DEBUG_KBD) 175 #if defined(DEBUG_MOUSE) || defined(DEBUG_KBD)
175 if (aux) 176 if (aux)
@@ -181,6 +182,7 @@ static void kbd_queue(KBDState *s, int b, int aux) @@ -181,6 +182,7 @@ static void kbd_queue(KBDState *s, int b, int aux)
181 #endif 182 #endif
182 if (q->count >= KBD_QUEUE_SIZE) 183 if (q->count >= KBD_QUEUE_SIZE)
183 return; 184 return;
  185 + q->aux[q->wptr] = aux;
184 q->data[q->wptr] = b; 186 q->data[q->wptr] = b;
185 if (++q->wptr == KBD_QUEUE_SIZE) 187 if (++q->wptr == KBD_QUEUE_SIZE)
186 q->wptr = 0; 188 q->wptr = 0;
@@ -288,30 +290,28 @@ static uint32_t kbd_read_data(void *opaque, uint32_t addr) @@ -288,30 +290,28 @@ static uint32_t kbd_read_data(void *opaque, uint32_t addr)
288 { 290 {
289 KBDState *s = opaque; 291 KBDState *s = opaque;
290 KBDQueue *q; 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 if (q->count == 0) { 296 if (q->count == 0) {
297 /* NOTE: if no data left, we return the last keyboard one 297 /* NOTE: if no data left, we return the last keyboard one
298 (needed for EMM386) */ 298 (needed for EMM386) */
299 /* XXX: need a timer to do things correctly */ 299 /* XXX: need a timer to do things correctly */
300 - q = &s->queues[0];  
301 index = q->rptr - 1; 300 index = q->rptr - 1;
302 if (index < 0) 301 if (index < 0)
303 index = KBD_QUEUE_SIZE - 1; 302 index = KBD_QUEUE_SIZE - 1;
304 val = q->data[index]; 303 val = q->data[index];
305 } else { 304 } else {
  305 + aux = q->aux[q->rptr];
306 val = q->data[q->rptr]; 306 val = q->data[q->rptr];
307 if (++q->rptr == KBD_QUEUE_SIZE) 307 if (++q->rptr == KBD_QUEUE_SIZE)
308 q->rptr = 0; 308 q->rptr = 0;
309 q->count--; 309 q->count--;
310 /* reading deasserts IRQ */ 310 /* reading deasserts IRQ */
311 - if (q == &s->queues[0])  
312 - pic_set_irq(1, 0);  
313 - else 311 + if (aux)
314 pic_set_irq(12, 0); 312 pic_set_irq(12, 0);
  313 + else
  314 + pic_set_irq(1, 0);
315 } 315 }
316 /* reassert IRQs if data left */ 316 /* reassert IRQs if data left */
317 kbd_update_irq(s); 317 kbd_update_irq(s);
@@ -452,7 +452,7 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) @@ -452,7 +452,7 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
452 s->mouse_buttons = buttons_state; 452 s->mouse_buttons = buttons_state;
453 453
454 if (!(s->mouse_status & MOUSE_STATUS_REMOTE) && 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 for(;;) { 456 for(;;) {
457 /* if not remote, send event. Multiple events are sent if 457 /* if not remote, send event. Multiple events are sent if
458 too big deltas */ 458 too big deltas */
@@ -632,18 +632,15 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) @@ -632,18 +632,15 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val)
632 void kbd_reset(KBDState *s) 632 void kbd_reset(KBDState *s)
633 { 633 {
634 KBDQueue *q; 634 KBDQueue *q;
635 - int i;  
636 635
637 s->kbd_write_cmd = -1; 636 s->kbd_write_cmd = -1;
638 s->mouse_write_cmd = -1; 637 s->mouse_write_cmd = -1;
639 s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT; 638 s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT;
640 s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED; 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 void kbd_init(void) 646 void kbd_init(void)