@@ -212,13 +212,16 @@
static void ioport92_write(void *opaque, uint32_t addr, uint32_t val)
{
KBDState *s = opaque;
-
- DPRINTF("kbd: write outport=0x%02x\n", val);
- s->outport = val;
- if (s->a20_out) {
- qemu_set_irq(*s->a20_out, (val >> 1) & 1);
+ if (val & 0x02) { // bit 1: enable/disable A20
+ if (s->a20_out) qemu_irq_raise(*s->a20_out);
+ s->outport |= KBD_OUT_A20;
+ }
+ else
+ {
+ if (s->a20_out) qemu_irq_lower(*s->a20_out);
+ s->outport &= ~KBD_OUT_A20;
}
- if (!(val & 1)) {
+ if ((val & 1)) { // bit 0: raised -> fast reset
qemu_system_reset_request();
}
}
@@ -226,11 +229,8 @@
static uint32_t ioport92_read(void *opaque, uint32_t addr)
{
KBDState *s = opaque;
- uint32_t ret;
-
- ret = s->outport;
- DPRINTF("kbd: read outport=0x%02x\n", ret);
- return ret;
+ return (s->outport & 0x02); // only bit 1 (KBD_OUT_A20) of port 0x92 is identical to s->outport
+ /* XXX: bit 0 is fast reset, bits 6-7 hdd activity */
}
static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
@@ -340,7 +340,9 @@
kbd_queue(s, val, 1);
break;
case KBD_CCMD_WRITE_OUTPORT:
- ioport92_write(s, 0, val);
+ ioport92_write(s, 0, (ioport92_read(s,0) & 0xfc) // copy bits 2-7 of 0x92
+ | (val & 0x02) // bit 1 (enable a20)
+ | (~val & 0x01)); // bit 0 (fast reset) of port 0x92 has inverse logic
break;
case KBD_CCMD_WRITE_MOUSE:
ps2_write_mouse(s->mouse, val);