2
2
* QEMU PS/2 keyboard/mouse emulation
4
4
* Copyright (c) 2003 Fabrice Bellard
6
6
* Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
* of this software and associated documentation files (the "Software"), to deal
8
8
* in the Software without restriction, including without limitation the rights
34
32
/* Keyboard Commands */
35
33
#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
36
34
#define KBD_CMD_ECHO 0xEE
37
#define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */
38
35
#define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
39
36
#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
40
37
#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
45
42
/* Keyboard Replies */
46
43
#define KBD_REPLY_POR 0xAA /* Power on reset */
47
#define KBD_REPLY_ID 0xAB /* Keyboard ID */
48
44
#define KBD_REPLY_ACK 0xFA /* Command ACK */
49
45
#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
134
129
s->update_irq(s->update_arg, 1);
138
keycode is expressed as follow:
139
bit 7 - 0 key pressed, 1 = key released
140
bits 6-0 - translated scancode set 2
142
132
static void ps2_put_keycode(void *opaque, int keycode)
144
134
PS2KbdState *s = opaque;
146
/* XXX: add support for scancode sets 1 and 3 */
147
if (!s->translate && keycode < 0xe0 && s->scancode_set == 2)
135
if (!s->translate && keycode < 0xe0)
149
137
if (keycode & 0x80)
150
138
ps2_queue(&s->common, 0xf0);
204
191
case KBD_CMD_GET_ID:
205
192
ps2_queue(&s->common, KBD_REPLY_ACK);
206
/* We emulate a MF2 AT keyboard here */
207
ps2_queue(&s->common, KBD_REPLY_ID);
209
ps2_queue(&s->common, 0x41);
211
ps2_queue(&s->common, 0x83);
193
ps2_queue(&s->common, 0xab);
194
ps2_queue(&s->common, 0x83);
213
196
case KBD_CMD_ECHO:
214
197
ps2_queue(&s->common, KBD_CMD_ECHO);
246
case KBD_CMD_SCANCODE:
248
if (s->scancode_set == 1)
249
ps2_put_keycode(s, 0x43);
250
else if (s->scancode_set == 2)
251
ps2_put_keycode(s, 0x41);
252
else if (s->scancode_set == 3)
253
ps2_put_keycode(s, 0x3f);
255
if (val >= 1 && val <= 3)
256
s->scancode_set = val;
257
ps2_queue(&s->common, KBD_REPLY_ACK);
259
s->common.write_cmd = -1;
261
228
case KBD_CMD_SET_LEDS:
262
229
ps2_queue(&s->common, KBD_REPLY_ACK);
263
230
s->common.write_cmd = -1;
327
294
s->mouse_dz -= dz1;
330
static void ps2_mouse_event(void *opaque,
297
static void ps2_mouse_event(void *opaque,
331
298
int dx, int dy, int dz, int buttons_state)
333
300
PS2MouseState *s = opaque;
467
434
s->mouse_detect_state = 0;
471
438
s->mouse_type = 3; /* IMPS/2 */
472
439
s->mouse_detect_state = 0;
476
443
s->mouse_type = 4; /* IMEX */
477
444
s->mouse_detect_state = 0;
502
469
static void ps2_common_save (QEMUFile *f, PS2State *s)
504
qemu_put_be32 (f, s->write_cmd);
505
qemu_put_be32 (f, s->queue.rptr);
506
qemu_put_be32 (f, s->queue.wptr);
507
qemu_put_be32 (f, s->queue.count);
471
qemu_put_be32s (f, &s->write_cmd);
472
qemu_put_be32s (f, &s->queue.rptr);
473
qemu_put_be32s (f, &s->queue.wptr);
474
qemu_put_be32s (f, &s->queue.count);
508
475
qemu_put_buffer (f, s->queue.data, sizeof (s->queue.data));
511
478
static void ps2_common_load (QEMUFile *f, PS2State *s)
513
s->write_cmd=qemu_get_be32 (f);
514
s->queue.rptr=qemu_get_be32 (f);
515
s->queue.wptr=qemu_get_be32 (f);
516
s->queue.count=qemu_get_be32 (f);
480
qemu_get_be32s (f, &s->write_cmd);
481
qemu_get_be32s (f, &s->queue.rptr);
482
qemu_get_be32s (f, &s->queue.wptr);
483
qemu_get_be32s (f, &s->queue.count);
517
484
qemu_get_buffer (f, s->queue.data, sizeof (s->queue.data));
522
489
PS2KbdState *s = (PS2KbdState*)opaque;
524
491
ps2_common_save (f, &s->common);
525
qemu_put_be32(f, s->scan_enabled);
526
qemu_put_be32(f, s->translate);
527
qemu_put_be32(f, s->scancode_set);
492
qemu_put_be32s(f, &s->scan_enabled);
493
qemu_put_be32s(f, &s->translate);
530
496
static void ps2_mouse_save(QEMUFile* f, void* opaque)
538
504
qemu_put_8s(f, &s->mouse_wrap);
539
505
qemu_put_8s(f, &s->mouse_type);
540
506
qemu_put_8s(f, &s->mouse_detect_state);
541
qemu_put_be32(f, s->mouse_dx);
542
qemu_put_be32(f, s->mouse_dy);
543
qemu_put_be32(f, s->mouse_dz);
507
qemu_put_be32s(f, &s->mouse_dx);
508
qemu_put_be32s(f, &s->mouse_dy);
509
qemu_put_be32s(f, &s->mouse_dz);
544
510
qemu_put_8s(f, &s->mouse_buttons);
549
515
PS2KbdState *s = (PS2KbdState*)opaque;
551
if (version_id != 2 && version_id != 3)
554
520
ps2_common_load (f, &s->common);
555
s->scan_enabled=qemu_get_be32(f);
556
s->translate=qemu_get_be32(f);
558
s->scancode_set=qemu_get_be32(f);
521
qemu_get_be32s(f, &s->scan_enabled);
522
qemu_get_be32s(f, &s->translate);
575
537
qemu_get_8s(f, &s->mouse_wrap);
576
538
qemu_get_8s(f, &s->mouse_type);
577
539
qemu_get_8s(f, &s->mouse_detect_state);
578
s->mouse_dx=qemu_get_be32(f);
579
s->mouse_dy=qemu_get_be32(f);
580
s->mouse_dz=qemu_get_be32(f);
540
qemu_get_be32s(f, &s->mouse_dx);
541
qemu_get_be32s(f, &s->mouse_dy);
542
qemu_get_be32s(f, &s->mouse_dz);
581
543
qemu_get_8s(f, &s->mouse_buttons);
589
551
s->common.update_irq = update_irq;
590
552
s->common.update_arg = update_arg;
592
553
ps2_reset(&s->common);
593
register_savevm("ps2kbd", 0, 3, ps2_kbd_save, ps2_kbd_load, s);
554
register_savevm("ps2kbd", 0, 2, ps2_kbd_save, ps2_kbd_load, s);
594
555
qemu_add_kbd_event_handler(ps2_put_keycode, s);
595
556
qemu_register_reset(ps2_reset, &s->common);