mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-24 12:09:58 +00:00
PS2 mouse and keyboard separation (Paul Brook)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1658 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
e80e1cc4b1
commit
daa579632d
@ -298,13 +298,13 @@ VL_OBJS+= usb.o usb-uhci.o usb-linux.o usb-hid.o
|
||||
|
||||
ifeq ($(TARGET_BASE_ARCH), i386)
|
||||
# Hardware support
|
||||
VL_OBJS+= ide.o ne2000.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
|
||||
VL_OBJS+= ide.o ne2000.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
|
||||
VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pc.o
|
||||
VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o
|
||||
DEFINES += -DHAS_AUDIO
|
||||
endif
|
||||
ifeq ($(TARGET_BASE_ARCH), ppc)
|
||||
VL_OBJS+= ppc.o ide.o ne2000.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
|
||||
VL_OBJS+= ppc.o ide.o ne2000.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
|
||||
VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
|
||||
VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o
|
||||
DEFINES += -DHAS_AUDIO
|
||||
@ -315,7 +315,7 @@ VL_OBJS+= mips_r4k.o dma.o vga.o serial.o ne2000.o i8254.o i8259.o
|
||||
endif
|
||||
ifeq ($(TARGET_BASE_ARCH), sparc)
|
||||
ifeq ($(TARGET_ARCH), sparc64)
|
||||
VL_OBJS+= sun4u.o ide.o ne2000.o pckbd.o vga.o
|
||||
VL_OBJS+= sun4u.o ide.o ne2000.o pckbd.o ps2.o vga.o
|
||||
VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o
|
||||
VL_OBJS+= cirrus_vga.o parallel.o
|
||||
VL_OBJS+= magic-load.o
|
||||
|
418
hw/pckbd.c
418
hw/pckbd.c
@ -110,32 +110,17 @@
|
||||
|
||||
#define KBD_QUEUE_SIZE 256
|
||||
|
||||
typedef struct {
|
||||
uint8_t aux[KBD_QUEUE_SIZE];
|
||||
uint8_t data[KBD_QUEUE_SIZE];
|
||||
int rptr, wptr, count;
|
||||
} KBDQueue;
|
||||
#define KBD_PENDING_KBD 1
|
||||
#define KBD_PENDING_AUX 2
|
||||
|
||||
typedef struct KBDState {
|
||||
KBDQueue queue;
|
||||
uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
|
||||
uint8_t status;
|
||||
uint8_t mode;
|
||||
/* keyboard state */
|
||||
int kbd_write_cmd;
|
||||
int scan_enabled;
|
||||
/* mouse state */
|
||||
int mouse_write_cmd;
|
||||
uint8_t mouse_status;
|
||||
uint8_t mouse_resolution;
|
||||
uint8_t mouse_sample_rate;
|
||||
uint8_t mouse_wrap;
|
||||
uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
|
||||
uint8_t mouse_detect_state;
|
||||
int mouse_dx; /* current values, needed for 'poll' mode */
|
||||
int mouse_dy;
|
||||
int mouse_dz;
|
||||
uint8_t mouse_buttons;
|
||||
/* Bitmask of devices with data available. */
|
||||
int pending;
|
||||
void *kbd;
|
||||
void *mouse;
|
||||
} KBDState;
|
||||
|
||||
KBDState kbd_state;
|
||||
@ -145,15 +130,15 @@ KBDState kbd_state;
|
||||
incorrect, but it avoids having to simulate exact delays */
|
||||
static void kbd_update_irq(KBDState *s)
|
||||
{
|
||||
KBDQueue *q = &s->queue;
|
||||
int irq12_level, irq1_level;
|
||||
|
||||
irq1_level = 0;
|
||||
irq12_level = 0;
|
||||
s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF);
|
||||
if (q->count != 0) {
|
||||
if (s->pending) {
|
||||
s->status |= KBD_STAT_OBF;
|
||||
if (q->aux[q->rptr]) {
|
||||
/* kdb data takes priority over aux data. */
|
||||
if (s->pending == KBD_PENDING_AUX) {
|
||||
s->status |= KBD_STAT_MOUSE_OBF;
|
||||
if (s->mode & KBD_MODE_MOUSE_INT)
|
||||
irq12_level = 1;
|
||||
@ -167,32 +152,26 @@ static void kbd_update_irq(KBDState *s)
|
||||
pic_set_irq(12, irq12_level);
|
||||
}
|
||||
|
||||
static void kbd_queue(KBDState *s, int b, int aux)
|
||||
static void kbd_update_kbd_irq(void *opaque, int level)
|
||||
{
|
||||
KBDQueue *q = &s->queue;
|
||||
KBDState *s = (KBDState *)opaque;
|
||||
|
||||
#if defined(DEBUG_MOUSE) || defined(DEBUG_KBD)
|
||||
if (aux)
|
||||
printf("mouse event: 0x%02x\n", b);
|
||||
#ifdef DEBUG_KBD
|
||||
if (level)
|
||||
s->pending |= KBD_PENDING_KBD;
|
||||
else
|
||||
printf("kbd event: 0x%02x\n", b);
|
||||
#endif
|
||||
#endif
|
||||
if (q->count >= KBD_QUEUE_SIZE)
|
||||
return;
|
||||
q->aux[q->wptr] = aux;
|
||||
q->data[q->wptr] = b;
|
||||
if (++q->wptr == KBD_QUEUE_SIZE)
|
||||
q->wptr = 0;
|
||||
q->count++;
|
||||
s->pending &= ~KBD_PENDING_KBD;
|
||||
kbd_update_irq(s);
|
||||
}
|
||||
|
||||
static void pc_kbd_put_keycode(void *opaque, int keycode)
|
||||
static void kbd_update_aux_irq(void *opaque, int level)
|
||||
{
|
||||
KBDState *s = opaque;
|
||||
kbd_queue(s, keycode, 0);
|
||||
KBDState *s = (KBDState *)opaque;
|
||||
|
||||
if (level)
|
||||
s->pending |= KBD_PENDING_AUX;
|
||||
else
|
||||
s->pending &= ~KBD_PENDING_AUX;
|
||||
kbd_update_irq(s);
|
||||
}
|
||||
|
||||
static uint32_t kbd_read_status(void *opaque, uint32_t addr)
|
||||
@ -206,6 +185,14 @@ static uint32_t kbd_read_status(void *opaque, uint32_t addr)
|
||||
return val;
|
||||
}
|
||||
|
||||
static void kbd_queue(KBDState *s, int b, int aux)
|
||||
{
|
||||
if (aux)
|
||||
ps2_queue(s->mouse, b);
|
||||
else
|
||||
ps2_queue(s->kbd, b);
|
||||
}
|
||||
|
||||
static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
|
||||
{
|
||||
KBDState *s = opaque;
|
||||
@ -287,304 +274,11 @@ static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
|
||||
static uint32_t kbd_read_data(void *opaque, uint32_t addr)
|
||||
{
|
||||
KBDState *s = opaque;
|
||||
KBDQueue *q;
|
||||
int val, index, aux;
|
||||
|
||||
q = &s->queue;
|
||||
if (q->count == 0) {
|
||||
/* NOTE: if no data left, we return the last keyboard one
|
||||
(needed for EMM386) */
|
||||
/* XXX: need a timer to do things correctly */
|
||||
index = q->rptr - 1;
|
||||
if (index < 0)
|
||||
index = KBD_QUEUE_SIZE - 1;
|
||||
val = q->data[index];
|
||||
} else {
|
||||
aux = q->aux[q->rptr];
|
||||
val = q->data[q->rptr];
|
||||
if (++q->rptr == KBD_QUEUE_SIZE)
|
||||
q->rptr = 0;
|
||||
q->count--;
|
||||
/* reading deasserts IRQ */
|
||||
if (aux)
|
||||
pic_set_irq(12, 0);
|
||||
else
|
||||
pic_set_irq(1, 0);
|
||||
}
|
||||
/* reassert IRQs if data left */
|
||||
kbd_update_irq(s);
|
||||
#ifdef DEBUG_KBD
|
||||
printf("kbd: read data=0x%02x\n", val);
|
||||
#endif
|
||||
return val;
|
||||
}
|
||||
|
||||
static void kbd_reset_keyboard(KBDState *s)
|
||||
{
|
||||
s->scan_enabled = 1;
|
||||
}
|
||||
if (s->pending == KBD_PENDING_AUX)
|
||||
return ps2_read_data(s->mouse);
|
||||
|
||||
static void kbd_write_keyboard(KBDState *s, int val)
|
||||
{
|
||||
switch(s->kbd_write_cmd) {
|
||||
default:
|
||||
case -1:
|
||||
switch(val) {
|
||||
case 0x00:
|
||||
kbd_queue(s, KBD_REPLY_ACK, 0);
|
||||
break;
|
||||
case 0x05:
|
||||
kbd_queue(s, KBD_REPLY_RESEND, 0);
|
||||
break;
|
||||
case KBD_CMD_GET_ID:
|
||||
kbd_queue(s, KBD_REPLY_ACK, 0);
|
||||
kbd_queue(s, 0xab, 0);
|
||||
kbd_queue(s, 0x83, 0);
|
||||
break;
|
||||
case KBD_CMD_ECHO:
|
||||
kbd_queue(s, KBD_CMD_ECHO, 0);
|
||||
break;
|
||||
case KBD_CMD_ENABLE:
|
||||
s->scan_enabled = 1;
|
||||
kbd_queue(s, KBD_REPLY_ACK, 0);
|
||||
break;
|
||||
case KBD_CMD_SET_LEDS:
|
||||
case KBD_CMD_SET_RATE:
|
||||
s->kbd_write_cmd = val;
|
||||
kbd_queue(s, KBD_REPLY_ACK, 0);
|
||||
break;
|
||||
case KBD_CMD_RESET_DISABLE:
|
||||
kbd_reset_keyboard(s);
|
||||
s->scan_enabled = 0;
|
||||
kbd_queue(s, KBD_REPLY_ACK, 0);
|
||||
break;
|
||||
case KBD_CMD_RESET_ENABLE:
|
||||
kbd_reset_keyboard(s);
|
||||
s->scan_enabled = 1;
|
||||
kbd_queue(s, KBD_REPLY_ACK, 0);
|
||||
break;
|
||||
case KBD_CMD_RESET:
|
||||
kbd_reset_keyboard(s);
|
||||
kbd_queue(s, KBD_REPLY_ACK, 0);
|
||||
kbd_queue(s, KBD_REPLY_POR, 0);
|
||||
break;
|
||||
default:
|
||||
kbd_queue(s, KBD_REPLY_ACK, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KBD_CMD_SET_LEDS:
|
||||
kbd_queue(s, KBD_REPLY_ACK, 0);
|
||||
s->kbd_write_cmd = -1;
|
||||
break;
|
||||
case KBD_CMD_SET_RATE:
|
||||
kbd_queue(s, KBD_REPLY_ACK, 0);
|
||||
s->kbd_write_cmd = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void kbd_mouse_send_packet(KBDState *s)
|
||||
{
|
||||
unsigned int b;
|
||||
int dx1, dy1, dz1;
|
||||
|
||||
dx1 = s->mouse_dx;
|
||||
dy1 = s->mouse_dy;
|
||||
dz1 = s->mouse_dz;
|
||||
/* XXX: increase range to 8 bits ? */
|
||||
if (dx1 > 127)
|
||||
dx1 = 127;
|
||||
else if (dx1 < -127)
|
||||
dx1 = -127;
|
||||
if (dy1 > 127)
|
||||
dy1 = 127;
|
||||
else if (dy1 < -127)
|
||||
dy1 = -127;
|
||||
b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
|
||||
kbd_queue(s, b, 1);
|
||||
kbd_queue(s, dx1 & 0xff, 1);
|
||||
kbd_queue(s, dy1 & 0xff, 1);
|
||||
/* extra byte for IMPS/2 or IMEX */
|
||||
switch(s->mouse_type) {
|
||||
default:
|
||||
break;
|
||||
case 3:
|
||||
if (dz1 > 127)
|
||||
dz1 = 127;
|
||||
else if (dz1 < -127)
|
||||
dz1 = -127;
|
||||
kbd_queue(s, dz1 & 0xff, 1);
|
||||
break;
|
||||
case 4:
|
||||
if (dz1 > 7)
|
||||
dz1 = 7;
|
||||
else if (dz1 < -7)
|
||||
dz1 = -7;
|
||||
b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
|
||||
kbd_queue(s, b, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* update deltas */
|
||||
s->mouse_dx -= dx1;
|
||||
s->mouse_dy -= dy1;
|
||||
s->mouse_dz -= dz1;
|
||||
}
|
||||
|
||||
static void pc_kbd_mouse_event(void *opaque,
|
||||
int dx, int dy, int dz, int buttons_state)
|
||||
{
|
||||
KBDState *s = opaque;
|
||||
|
||||
/* check if deltas are recorded when disabled */
|
||||
if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
|
||||
return;
|
||||
|
||||
s->mouse_dx += dx;
|
||||
s->mouse_dy -= dy;
|
||||
s->mouse_dz += dz;
|
||||
/* XXX: SDL sometimes generates nul events: we delete them */
|
||||
if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0 &&
|
||||
s->mouse_buttons == buttons_state)
|
||||
return;
|
||||
s->mouse_buttons = buttons_state;
|
||||
|
||||
if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
|
||||
(s->queue.count < (KBD_QUEUE_SIZE - 16))) {
|
||||
for(;;) {
|
||||
/* if not remote, send event. Multiple events are sent if
|
||||
too big deltas */
|
||||
kbd_mouse_send_packet(s);
|
||||
if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void kbd_write_mouse(KBDState *s, int val)
|
||||
{
|
||||
#ifdef DEBUG_MOUSE
|
||||
printf("kbd: write mouse 0x%02x\n", val);
|
||||
#endif
|
||||
switch(s->mouse_write_cmd) {
|
||||
default:
|
||||
case -1:
|
||||
/* mouse command */
|
||||
if (s->mouse_wrap) {
|
||||
if (val == AUX_RESET_WRAP) {
|
||||
s->mouse_wrap = 0;
|
||||
kbd_queue(s, AUX_ACK, 1);
|
||||
return;
|
||||
} else if (val != AUX_RESET) {
|
||||
kbd_queue(s, val, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
switch(val) {
|
||||
case AUX_SET_SCALE11:
|
||||
s->mouse_status &= ~MOUSE_STATUS_SCALE21;
|
||||
kbd_queue(s, AUX_ACK, 1);
|
||||
break;
|
||||
case AUX_SET_SCALE21:
|
||||
s->mouse_status |= MOUSE_STATUS_SCALE21;
|
||||
kbd_queue(s, AUX_ACK, 1);
|
||||
break;
|
||||
case AUX_SET_STREAM:
|
||||
s->mouse_status &= ~MOUSE_STATUS_REMOTE;
|
||||
kbd_queue(s, AUX_ACK, 1);
|
||||
break;
|
||||
case AUX_SET_WRAP:
|
||||
s->mouse_wrap = 1;
|
||||
kbd_queue(s, AUX_ACK, 1);
|
||||
break;
|
||||
case AUX_SET_REMOTE:
|
||||
s->mouse_status |= MOUSE_STATUS_REMOTE;
|
||||
kbd_queue(s, AUX_ACK, 1);
|
||||
break;
|
||||
case AUX_GET_TYPE:
|
||||
kbd_queue(s, AUX_ACK, 1);
|
||||
kbd_queue(s, s->mouse_type, 1);
|
||||
break;
|
||||
case AUX_SET_RES:
|
||||
case AUX_SET_SAMPLE:
|
||||
s->mouse_write_cmd = val;
|
||||
kbd_queue(s, AUX_ACK, 1);
|
||||
break;
|
||||
case AUX_GET_SCALE:
|
||||
kbd_queue(s, AUX_ACK, 1);
|
||||
kbd_queue(s, s->mouse_status, 1);
|
||||
kbd_queue(s, s->mouse_resolution, 1);
|
||||
kbd_queue(s, s->mouse_sample_rate, 1);
|
||||
break;
|
||||
case AUX_POLL:
|
||||
kbd_queue(s, AUX_ACK, 1);
|
||||
kbd_mouse_send_packet(s);
|
||||
break;
|
||||
case AUX_ENABLE_DEV:
|
||||
s->mouse_status |= MOUSE_STATUS_ENABLED;
|
||||
kbd_queue(s, AUX_ACK, 1);
|
||||
break;
|
||||
case AUX_DISABLE_DEV:
|
||||
s->mouse_status &= ~MOUSE_STATUS_ENABLED;
|
||||
kbd_queue(s, AUX_ACK, 1);
|
||||
break;
|
||||
case AUX_SET_DEFAULT:
|
||||
s->mouse_sample_rate = 100;
|
||||
s->mouse_resolution = 2;
|
||||
s->mouse_status = 0;
|
||||
kbd_queue(s, AUX_ACK, 1);
|
||||
break;
|
||||
case AUX_RESET:
|
||||
s->mouse_sample_rate = 100;
|
||||
s->mouse_resolution = 2;
|
||||
s->mouse_status = 0;
|
||||
s->mouse_type = 0;
|
||||
kbd_queue(s, AUX_ACK, 1);
|
||||
kbd_queue(s, 0xaa, 1);
|
||||
kbd_queue(s, s->mouse_type, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AUX_SET_SAMPLE:
|
||||
s->mouse_sample_rate = val;
|
||||
/* detect IMPS/2 or IMEX */
|
||||
switch(s->mouse_detect_state) {
|
||||
default:
|
||||
case 0:
|
||||
if (val == 200)
|
||||
s->mouse_detect_state = 1;
|
||||
break;
|
||||
case 1:
|
||||
if (val == 100)
|
||||
s->mouse_detect_state = 2;
|
||||
else if (val == 200)
|
||||
s->mouse_detect_state = 3;
|
||||
else
|
||||
s->mouse_detect_state = 0;
|
||||
break;
|
||||
case 2:
|
||||
if (val == 80)
|
||||
s->mouse_type = 3; /* IMPS/2 */
|
||||
s->mouse_detect_state = 0;
|
||||
break;
|
||||
case 3:
|
||||
if (val == 80)
|
||||
s->mouse_type = 4; /* IMEX */
|
||||
s->mouse_detect_state = 0;
|
||||
break;
|
||||
}
|
||||
kbd_queue(s, AUX_ACK, 1);
|
||||
s->mouse_write_cmd = -1;
|
||||
break;
|
||||
case AUX_SET_RES:
|
||||
s->mouse_resolution = val;
|
||||
kbd_queue(s, AUX_ACK, 1);
|
||||
s->mouse_write_cmd = -1;
|
||||
break;
|
||||
}
|
||||
return ps2_read_data(s->kbd);
|
||||
}
|
||||
|
||||
void kbd_write_data(void *opaque, uint32_t addr, uint32_t val)
|
||||
@ -597,10 +291,11 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val)
|
||||
|
||||
switch(s->write_cmd) {
|
||||
case 0:
|
||||
kbd_write_keyboard(s, val);
|
||||
ps2_write_keyboard(s->kbd, val);
|
||||
break;
|
||||
case KBD_CCMD_WRITE_MODE:
|
||||
s->mode = val;
|
||||
/* ??? */
|
||||
kbd_update_irq(s);
|
||||
break;
|
||||
case KBD_CCMD_WRITE_OBUF:
|
||||
@ -618,7 +313,7 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val)
|
||||
}
|
||||
break;
|
||||
case KBD_CCMD_WRITE_MOUSE:
|
||||
kbd_write_mouse(s, val);
|
||||
ps2_write_mouse(s->mouse, val);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -629,16 +324,9 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val)
|
||||
static void kbd_reset(void *opaque)
|
||||
{
|
||||
KBDState *s = opaque;
|
||||
KBDQueue *q;
|
||||
|
||||
s->kbd_write_cmd = -1;
|
||||
s->mouse_write_cmd = -1;
|
||||
s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT;
|
||||
s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED;
|
||||
q = &s->queue;
|
||||
q->rptr = 0;
|
||||
q->wptr = 0;
|
||||
q->count = 0;
|
||||
}
|
||||
|
||||
static void kbd_save(QEMUFile* f, void* opaque)
|
||||
@ -648,43 +336,17 @@ static void kbd_save(QEMUFile* f, void* opaque)
|
||||
qemu_put_8s(f, &s->write_cmd);
|
||||
qemu_put_8s(f, &s->status);
|
||||
qemu_put_8s(f, &s->mode);
|
||||
qemu_put_be32s(f, &s->kbd_write_cmd);
|
||||
qemu_put_be32s(f, &s->scan_enabled);
|
||||
qemu_put_be32s(f, &s->mouse_write_cmd);
|
||||
qemu_put_8s(f, &s->mouse_status);
|
||||
qemu_put_8s(f, &s->mouse_resolution);
|
||||
qemu_put_8s(f, &s->mouse_sample_rate);
|
||||
qemu_put_8s(f, &s->mouse_wrap);
|
||||
qemu_put_8s(f, &s->mouse_type);
|
||||
qemu_put_8s(f, &s->mouse_detect_state);
|
||||
qemu_put_be32s(f, &s->mouse_dx);
|
||||
qemu_put_be32s(f, &s->mouse_dy);
|
||||
qemu_put_be32s(f, &s->mouse_dz);
|
||||
qemu_put_8s(f, &s->mouse_buttons);
|
||||
}
|
||||
|
||||
static int kbd_load(QEMUFile* f, void* opaque, int version_id)
|
||||
{
|
||||
KBDState *s = (KBDState*)opaque;
|
||||
|
||||
if (version_id != 1)
|
||||
if (version_id != 2)
|
||||
return -EINVAL;
|
||||
qemu_get_8s(f, &s->write_cmd);
|
||||
qemu_get_8s(f, &s->status);
|
||||
qemu_get_8s(f, &s->mode);
|
||||
qemu_get_be32s(f, &s->kbd_write_cmd);
|
||||
qemu_get_be32s(f, &s->scan_enabled);
|
||||
qemu_get_be32s(f, &s->mouse_write_cmd);
|
||||
qemu_get_8s(f, &s->mouse_status);
|
||||
qemu_get_8s(f, &s->mouse_resolution);
|
||||
qemu_get_8s(f, &s->mouse_sample_rate);
|
||||
qemu_get_8s(f, &s->mouse_wrap);
|
||||
qemu_get_8s(f, &s->mouse_type);
|
||||
qemu_get_8s(f, &s->mouse_detect_state);
|
||||
qemu_get_be32s(f, &s->mouse_dx);
|
||||
qemu_get_be32s(f, &s->mouse_dy);
|
||||
qemu_get_be32s(f, &s->mouse_dz);
|
||||
qemu_get_8s(f, &s->mouse_buttons);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -693,13 +355,13 @@ void kbd_init(void)
|
||||
KBDState *s = &kbd_state;
|
||||
|
||||
kbd_reset(s);
|
||||
register_savevm("pckbd", 0, 1, kbd_save, kbd_load, s);
|
||||
register_savevm("pckbd", 0, 2, kbd_save, kbd_load, s);
|
||||
register_ioport_read(0x60, 1, 1, kbd_read_data, s);
|
||||
register_ioport_write(0x60, 1, 1, kbd_write_data, s);
|
||||
register_ioport_read(0x64, 1, 1, kbd_read_status, s);
|
||||
register_ioport_write(0x64, 1, 1, kbd_write_command, s);
|
||||
|
||||
qemu_add_kbd_event_handler(pc_kbd_put_keycode, s);
|
||||
qemu_add_mouse_event_handler(pc_kbd_mouse_event, s);
|
||||
s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
|
||||
s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
|
||||
qemu_register_reset(kbd_reset, s);
|
||||
}
|
||||
|
8
vl.h
8
vl.h
@ -928,6 +928,14 @@ void do_usb_add(const char *devname);
|
||||
void do_usb_del(const char *devname);
|
||||
void usb_info(void);
|
||||
|
||||
/* ps2.c */
|
||||
void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg);
|
||||
void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg);
|
||||
void ps2_write_mouse(void *, int val);
|
||||
void ps2_write_keyboard(void *, int val);
|
||||
uint32_t ps2_read_data(void *);
|
||||
void ps2_queue(void *, int b);
|
||||
|
||||
#endif /* defined(QEMU_TOOL) */
|
||||
|
||||
/* monitor.c */
|
||||
|
Loading…
Reference in New Issue
Block a user