Compile pckbd only once

Use a qemu_irq to indicate A20 line changes. Move I/O port 92
to pckbd.c.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
diff --git a/hw/pckbd.c b/hw/pckbd.c
index e83b8a6..5d268b4 100644
--- a/hw/pckbd.c
+++ b/hw/pckbd.c
@@ -87,6 +87,12 @@
 #define KBD_MODE_KCC 		0x40	/* Scan code conversion to PC format */
 #define KBD_MODE_RFU		0x80
 
+/* Output Port Bits */
+#define KBD_OUT_RESET           0x01    /* 1=normal mode, 0=reset */
+#define KBD_OUT_A20             0x02    /* x86 only */
+#define KBD_OUT_OBF             0x10    /* Keyboard output buffer full */
+#define KBD_OUT_MOUSE_OBF       0x20    /* Mouse output buffer full */
+
 /* Mouse Commands */
 #define AUX_SET_SCALE11		0xE6	/* Set 1:1 scaling */
 #define AUX_SET_SCALE21		0xE7	/* Set 2:1 scaling */
@@ -116,6 +122,7 @@
     uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
     uint8_t status;
     uint8_t mode;
+    uint8_t outport;
     /* Bitmask of devices with data available.  */
     uint8_t pending;
     void *kbd;
@@ -123,6 +130,7 @@
 
     qemu_irq irq_kbd;
     qemu_irq irq_mouse;
+    qemu_irq *a20_out;
     target_phys_addr_t mask;
 } KBDState;
 
@@ -136,11 +144,14 @@
     irq_kbd_level = 0;
     irq_mouse_level = 0;
     s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF);
+    s->outport &= ~(KBD_OUT_OBF | KBD_OUT_MOUSE_OBF);
     if (s->pending) {
         s->status |= KBD_STAT_OBF;
+        s->outport |= KBD_OUT_OBF;
         /* kbd data takes priority over aux data.  */
         if (s->pending == KBD_PENDING_AUX) {
             s->status |= KBD_STAT_MOUSE_OBF;
+            s->outport |= KBD_OUT_MOUSE_OBF;
             if (s->mode & KBD_MODE_MOUSE_INT)
                 irq_mouse_level = 1;
         } else {
@@ -194,6 +205,26 @@
         ps2_queue(s->kbd, b);
 }
 
+static void ioport92_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    KBDState *s = opaque;
+
+    s->outport = val;
+    if (s->a20_out) {
+        qemu_set_irq(*s->a20_out, (val >> 1) & 1);
+    }
+    if (!(val & 1)) {
+        qemu_system_reset_request();
+    }
+}
+
+static uint32_t ioport92_read(void *opaque, uint32_t addr)
+{
+    KBDState *s = opaque;
+
+    return s->outport;
+}
+
 static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
 {
     KBDState *s = opaque;
@@ -240,26 +271,20 @@
         kbd_queue(s, 0x00, 0);
         break;
     case KBD_CCMD_READ_OUTPORT:
-        /* XXX: check that */
-#ifdef TARGET_I386
-        val = 0x01 | (ioport_get_a20() << 1);
-#else
-        val = 0x01;
-#endif
-        if (s->status & KBD_STAT_OBF)
-            val |= 0x10;
-        if (s->status & KBD_STAT_MOUSE_OBF)
-            val |= 0x20;
-        kbd_queue(s, val, 0);
+        kbd_queue(s, s->outport, 0);
         break;
-#ifdef TARGET_I386
     case KBD_CCMD_ENABLE_A20:
-        ioport_set_a20(1);
+        if (s->a20_out) {
+            qemu_irq_raise(*s->a20_out);
+        }
+        s->outport |= KBD_OUT_A20;
         break;
     case KBD_CCMD_DISABLE_A20:
-        ioport_set_a20(0);
+        if (s->a20_out) {
+            qemu_irq_lower(*s->a20_out);
+        }
+        s->outport &= ~KBD_OUT_A20;
         break;
-#endif
     case KBD_CCMD_RESET:
         qemu_system_reset_request();
         break;
@@ -313,12 +338,7 @@
         kbd_queue(s, val, 1);
         break;
     case KBD_CCMD_WRITE_OUTPORT:
-#ifdef TARGET_I386
-        ioport_set_a20((val >> 1) & 1);
-#endif
-        if (!(val & 1)) {
-            qemu_system_reset_request();
-        }
+        ioport92_write(s, 0, val);
         break;
     case KBD_CCMD_WRITE_MOUSE:
         ps2_write_mouse(s->mouse, val);
@@ -335,6 +355,7 @@
 
     s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT;
     s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED;
+    s->outport = KBD_OUT_RESET | KBD_OUT_A20;
 }
 
 static const VMStateDescription vmstate_kbd = {
@@ -401,9 +422,6 @@
 
     s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
     s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
-#ifdef TARGET_I386
-    vmmouse_init(s->mouse);
-#endif
     qemu_register_reset(kbd_reset, s);
 }
 
@@ -412,6 +430,21 @@
     KBDState  kbd;
 } ISAKBDState;
 
+void i8042_isa_mouse_fake_event(void *opaque)
+{
+    ISADevice *dev = opaque;
+    KBDState *s = &(DO_UPCAST(ISAKBDState, dev, dev)->kbd);
+
+    ps2_mouse_fake_event(s->mouse);
+}
+
+void i8042_setup_a20_line(ISADevice *dev, qemu_irq *a20_out)
+{
+    KBDState *s = &(DO_UPCAST(ISAKBDState, dev, dev)->kbd);
+
+    s->a20_out = a20_out;
+}
+
 static const VMStateDescription vmstate_kbd_isa = {
     .name = "pckbd",
     .version_id = 3,
@@ -434,12 +467,11 @@
     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);
+    register_ioport_read(0x92, 1, 1, ioport92_read, s);
+    register_ioport_write(0x92, 1, 1, ioport92_write, s);
 
     s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
     s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
-#ifdef TARGET_I386
-    vmmouse_init(s->mouse);
-#endif
     qemu_register_reset(kbd_reset, s);
     return 0;
 }