Commit e7d93956508d86838d508345867ee8d2fe587459

Authored by aurel32
1 parent cf7a2fe2

Add KBD_CMD_SCANCODE command.

(Hervé Poussineau)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4082 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 34 additions and 5 deletions
hw/ps2.c
... ... @@ -34,6 +34,7 @@
34 34 /* Keyboard Commands */
35 35 #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
36 36 #define KBD_CMD_ECHO 0xEE
  37 +#define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */
37 38 #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
38 39 #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
39 40 #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
... ... @@ -89,6 +90,7 @@ typedef struct {
89 90 conversions we do the translation (if any) in the PS/2 emulation
90 91 not the keyboard controller. */
91 92 int translate;
  93 + int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
92 94 } PS2KbdState;
93 95  
94 96 typedef struct {
... ... @@ -131,10 +133,13 @@ void ps2_queue(void *opaque, int b)
131 133 s->update_irq(s->update_arg, 1);
132 134 }
133 135  
  136 +/* keycode is expressed in scancode set 2 */
134 137 static void ps2_put_keycode(void *opaque, int keycode)
135 138 {
136 139 PS2KbdState *s = opaque;
137   - if (!s->translate && keycode < 0xe0)
  140 +
  141 + /* XXX: add support for scancode sets 1 and 3 */
  142 + if (!s->translate && keycode < 0xe0 && s->scancode_set == 2)
138 143 {
139 144 if (keycode & 0x80)
140 145 ps2_queue(&s->common, 0xf0);
... ... @@ -174,6 +179,7 @@ uint32_t ps2_read_data(void *opaque)
174 179 static void ps2_reset_keyboard(PS2KbdState *s)
175 180 {
176 181 s->scan_enabled = 1;
  182 + s->scancode_set = 2;
177 183 }
178 184  
179 185 void ps2_write_keyboard(void *opaque, int val)
... ... @@ -192,8 +198,9 @@ void ps2_write_keyboard(void *opaque, int val)
192 198 break;
193 199 case KBD_CMD_GET_ID:
194 200 ps2_queue(&s->common, KBD_REPLY_ACK);
195   - ps2_queue(&s->common, 0xab);
196   - ps2_queue(&s->common, 0x83);
  201 + /* We emulate a MF2 AT keyboard here */
  202 + ps2_put_keycode(s, 0xab);
  203 + ps2_put_keycode(s, 0x83);
197 204 break;
198 205 case KBD_CMD_ECHO:
199 206 ps2_queue(&s->common, KBD_CMD_ECHO);
... ... @@ -202,6 +209,7 @@ void ps2_write_keyboard(void *opaque, int val)
202 209 s->scan_enabled = 1;
203 210 ps2_queue(&s->common, KBD_REPLY_ACK);
204 211 break;
  212 + case KBD_CMD_SCANCODE:
205 213 case KBD_CMD_SET_LEDS:
206 214 case KBD_CMD_SET_RATE:
207 215 s->common.write_cmd = val;
... ... @@ -227,6 +235,21 @@ void ps2_write_keyboard(void *opaque, int val)
227 235 break;
228 236 }
229 237 break;
  238 + case KBD_CMD_SCANCODE:
  239 + if (val == 0) {
  240 + if (s->scancode_set == 1)
  241 + ps2_put_keycode(s, 0x43);
  242 + else if (s->scancode_set == 2)
  243 + ps2_put_keycode(s, 0x41);
  244 + else if (s->scancode_set == 3)
  245 + ps2_put_keycode(s, 0x3f);
  246 + } else {
  247 + if (val >= 1 && val <= 3)
  248 + s->scancode_set = val;
  249 + ps2_queue(&s->common, KBD_REPLY_ACK);
  250 + }
  251 + s->common.write_cmd = -1;
  252 + break;
230 253 case KBD_CMD_SET_LEDS:
231 254 ps2_queue(&s->common, KBD_REPLY_ACK);
232 255 s->common.write_cmd = -1;
... ... @@ -493,6 +516,7 @@ static void ps2_kbd_save(QEMUFile* f, void* opaque)
493 516 ps2_common_save (f, &s->common);
494 517 qemu_put_be32(f, s->scan_enabled);
495 518 qemu_put_be32(f, s->translate);
  519 + qemu_put_be32(f, s->scancode_set);
496 520 }
497 521  
498 522 static void ps2_mouse_save(QEMUFile* f, void* opaque)
... ... @@ -516,12 +540,16 @@ static int ps2_kbd_load(QEMUFile* f, void* opaque, int version_id)
516 540 {
517 541 PS2KbdState *s = (PS2KbdState*)opaque;
518 542  
519   - if (version_id != 2)
  543 + if (version_id != 2 && version_id != 3)
520 544 return -EINVAL;
521 545  
522 546 ps2_common_load (f, &s->common);
523 547 s->scan_enabled=qemu_get_be32(f);
524 548 s->translate=qemu_get_be32(f);
  549 + if (version_id == 3)
  550 + s->scancode_set=qemu_get_be32(f);
  551 + else
  552 + s->scancode_set=2;
525 553 return 0;
526 554 }
527 555  
... ... @@ -552,8 +580,9 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
552 580  
553 581 s->common.update_irq = update_irq;
554 582 s->common.update_arg = update_arg;
  583 + s->scancode_set = 2;
555 584 ps2_reset(&s->common);
556   - register_savevm("ps2kbd", 0, 2, ps2_kbd_save, ps2_kbd_load, s);
  585 + register_savevm("ps2kbd", 0, 3, ps2_kbd_save, ps2_kbd_load, s);
557 586 qemu_add_kbd_event_handler(ps2_put_keycode, s);
558 587 qemu_register_reset(ps2_reset, &s->common);
559 588 return s;
... ...