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,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) |