Commit 67deb56246f006fa23b8a61681663f88e5b976fc
1 parent
877cf882
Fix keyboard detection bugs
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2703 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
36 additions
and
11 deletions
hw/slavio_serial.c
| @@ -108,6 +108,13 @@ static int serial_can_receive(void *opaque); | @@ -108,6 +108,13 @@ static int serial_can_receive(void *opaque); | ||
| 108 | static void serial_receive_byte(ChannelState *s, int ch); | 108 | static void serial_receive_byte(ChannelState *s, int ch); |
| 109 | static inline void set_txint(ChannelState *s); | 109 | static inline void set_txint(ChannelState *s); |
| 110 | 110 | ||
| 111 | +static void clear_queue(void *opaque) | ||
| 112 | +{ | ||
| 113 | + ChannelState *s = opaque; | ||
| 114 | + SERIOQueue *q = &s->queue; | ||
| 115 | + q->rptr = q->wptr = q->count = 0; | ||
| 116 | +} | ||
| 117 | + | ||
| 111 | static void put_queue(void *opaque, int b) | 118 | static void put_queue(void *opaque, int b) |
| 112 | { | 119 | { |
| 113 | ChannelState *s = opaque; | 120 | ChannelState *s = opaque; |
| @@ -137,7 +144,7 @@ static uint32_t get_queue(void *opaque) | @@ -137,7 +144,7 @@ static uint32_t get_queue(void *opaque) | ||
| 137 | q->rptr = 0; | 144 | q->rptr = 0; |
| 138 | q->count--; | 145 | q->count--; |
| 139 | } | 146 | } |
| 140 | - KBD_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val); | 147 | + SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val); |
| 141 | if (q->count > 0) | 148 | if (q->count > 0) |
| 142 | serial_receive_byte(s, 0); | 149 | serial_receive_byte(s, 0); |
| 143 | return val; | 150 | return val; |
| @@ -186,6 +193,7 @@ static void slavio_serial_reset_chn(ChannelState *s) | @@ -186,6 +193,7 @@ static void slavio_serial_reset_chn(ChannelState *s) | ||
| 186 | s->rx = s->tx = 0; | 193 | s->rx = s->tx = 0; |
| 187 | s->rxint = s->txint = 0; | 194 | s->rxint = s->txint = 0; |
| 188 | s->rxint_under_svc = s->txint_under_svc = 0; | 195 | s->rxint_under_svc = s->txint_under_svc = 0; |
| 196 | + clear_queue(s); | ||
| 189 | } | 197 | } |
| 190 | 198 | ||
| 191 | static void slavio_serial_reset(void *opaque) | 199 | static void slavio_serial_reset(void *opaque) |
| @@ -199,10 +207,19 @@ static inline void clr_rxint(ChannelState *s) | @@ -199,10 +207,19 @@ static inline void clr_rxint(ChannelState *s) | ||
| 199 | { | 207 | { |
| 200 | s->rxint = 0; | 208 | s->rxint = 0; |
| 201 | s->rxint_under_svc = 0; | 209 | s->rxint_under_svc = 0; |
| 202 | - if (s->chn == chn_a) | 210 | + if (s->chn == chn_a) { |
| 211 | + if (s->wregs[9] & 0x10) | ||
| 212 | + s->otherchn->rregs[2] = 0x60; | ||
| 213 | + else | ||
| 214 | + s->otherchn->rregs[2] = 0x06; | ||
| 203 | s->rregs[3] &= ~0x20; | 215 | s->rregs[3] &= ~0x20; |
| 204 | - else | 216 | + } else { |
| 217 | + if (s->wregs[9] & 0x10) | ||
| 218 | + s->rregs[2] = 0x60; | ||
| 219 | + else | ||
| 220 | + s->rregs[2] = 0x06; | ||
| 205 | s->otherchn->rregs[3] &= ~4; | 221 | s->otherchn->rregs[3] &= ~4; |
| 222 | + } | ||
| 206 | if (s->txint) | 223 | if (s->txint) |
| 207 | set_txint(s); | 224 | set_txint(s); |
| 208 | else | 225 | else |
| @@ -215,11 +232,19 @@ static inline void set_rxint(ChannelState *s) | @@ -215,11 +232,19 @@ static inline void set_rxint(ChannelState *s) | ||
| 215 | s->rxint = 1; | 232 | s->rxint = 1; |
| 216 | if (!s->txint_under_svc) { | 233 | if (!s->txint_under_svc) { |
| 217 | s->rxint_under_svc = 1; | 234 | s->rxint_under_svc = 1; |
| 218 | - if (s->chn == chn_a) | 235 | + if (s->chn == chn_a) { |
| 236 | + if (s->wregs[9] & 0x10) | ||
| 237 | + s->otherchn->rregs[2] = 0x30; | ||
| 238 | + else | ||
| 239 | + s->otherchn->rregs[2] = 0x0c; | ||
| 219 | s->rregs[3] |= 0x20; | 240 | s->rregs[3] |= 0x20; |
| 220 | - else | 241 | + } else { |
| 242 | + if (s->wregs[9] & 0x10) | ||
| 243 | + s->rregs[2] = 0x20; | ||
| 244 | + else | ||
| 245 | + s->rregs[2] = 0x04; | ||
| 221 | s->otherchn->rregs[3] |= 4; | 246 | s->otherchn->rregs[3] |= 4; |
| 222 | - s->rregs[2] = 4; | 247 | + } |
| 223 | slavio_serial_update_irq(s); | 248 | slavio_serial_update_irq(s); |
| 224 | } | 249 | } |
| 225 | } | 250 | } |
| @@ -607,12 +632,15 @@ static void handle_kbd_command(ChannelState *s, int val) | @@ -607,12 +632,15 @@ static void handle_kbd_command(ChannelState *s, int val) | ||
| 607 | KBD_DPRINTF("Command %d\n", val); | 632 | KBD_DPRINTF("Command %d\n", val); |
| 608 | switch (val) { | 633 | switch (val) { |
| 609 | case 1: // Reset, return type code | 634 | case 1: // Reset, return type code |
| 635 | + clear_queue(s); | ||
| 610 | put_queue(s, 0xff); | 636 | put_queue(s, 0xff); |
| 611 | - put_queue(s, 5); // Type 5 | 637 | + put_queue(s, 4); // Type 4 |
| 612 | break; | 638 | break; |
| 613 | case 7: // Query layout | 639 | case 7: // Query layout |
| 640 | + case 0xf: | ||
| 641 | + clear_queue(s); | ||
| 614 | put_queue(s, 0xfe); | 642 | put_queue(s, 0xfe); |
| 615 | - put_queue(s, 0x20); // XXX, layout? | 643 | + put_queue(s, 19); // XXX, layout? |
| 616 | break; | 644 | break; |
| 617 | default: | 645 | default: |
| 618 | break; | 646 | break; |
| @@ -625,9 +653,6 @@ static void sunmouse_event(void *opaque, | @@ -625,9 +653,6 @@ static void sunmouse_event(void *opaque, | ||
| 625 | ChannelState *s = opaque; | 653 | ChannelState *s = opaque; |
| 626 | int ch; | 654 | int ch; |
| 627 | 655 | ||
| 628 | - /* XXX: SDL sometimes generates nul events: we delete them */ | ||
| 629 | - if (dx == 0 && dy == 0 && dz == 0 && buttons_state == 0) | ||
| 630 | - return; | ||
| 631 | MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state); | 656 | MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state); |
| 632 | 657 | ||
| 633 | ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */ | 658 | ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */ |