Win32 build fix.
[qemu] / hw / slavio_serial.c
index 4b02d29..b13e7c4 100644 (file)
@@ -45,6 +45,8 @@
 #ifdef DEBUG_SERIAL
 #define SER_DPRINTF(fmt, args...) \
 do { printf("SER: " fmt , ##args); } while (0)
+#define pic_set_irq(irq, level) \
+do { printf("SER: set_irq(%d): %d\n", (irq), (level)); pic_set_irq((irq),(level));} while (0)
 #else
 #define SER_DPRINTF(fmt, args...)
 #endif
@@ -174,6 +176,50 @@ static void slavio_serial_reset(void *opaque)
     slavio_serial_reset_chn(&s->chn[1]);
 }
 
+static inline void clr_rxint(ChannelState *s)
+{
+    s->rxint = 0;
+    if (s->chn == 0)
+        s->rregs[3] &= ~0x20;
+    else {
+        s->otherchn->rregs[3] &= ~4;
+    }
+    slavio_serial_update_irq(s);
+}
+
+static inline void set_rxint(ChannelState *s)
+{
+    s->rxint = 1;
+    if (s->chn == 0)
+        s->rregs[3] |= 0x20;
+    else {
+        s->otherchn->rregs[3] |= 4;
+    }
+    slavio_serial_update_irq(s);
+}
+
+static inline void clr_txint(ChannelState *s)
+{
+    s->txint = 0;
+    if (s->chn == 0)
+        s->rregs[3] &= ~0x10;
+    else {
+        s->otherchn->rregs[3] &= ~2;
+    }
+    slavio_serial_update_irq(s);
+}
+
+static inline void set_txint(ChannelState *s)
+{
+    s->txint = 1;
+    if (s->chn == 0)
+        s->rregs[3] |= 0x10;
+    else {
+        s->otherchn->rregs[3] |= 2;
+    }
+    slavio_serial_update_irq(s);
+}
+
 static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
     SerialState *ser = opaque;
@@ -195,13 +241,17 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint
            val &= 0x38;
            switch (val) {
            case 8:
-               s->reg |= 0x8;
+               newreg |= 0x8;
                break;
            case 0x20:
-               s->rxint = 0;
+                clr_rxint(s);
                break;
            case 0x28:
-               s->txint = 0;
+                clr_txint(s);
+               break;
+           case 0x38:
+                clr_rxint(s);
+                clr_txint(s);
                break;
            default:
                break;
@@ -245,13 +295,9 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint
                handle_kbd_command(s, val);
            }
            s->txint = 1;
-           s->rregs[0] |= 4;
-           // Interrupts reported only on channel A
-           if (s->chn == 0)
-               s->rregs[3] |= 0x10;
-           else {
-               s->otherchn->rregs[3] |= 2;
-           }
+           s->rregs[0] |= 4; // Tx buffer empty
+           s->rregs[1] |= 1; // All sent
+            set_txint(s);
            slavio_serial_update_irq(s);
        }
        break;
@@ -278,12 +324,13 @@ static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
        s->reg = 0;
        return ret;
     case 1:
-       SER_DPRINTF("Read channel %c, ch %d\n", channel? 'b' : 'a', s->rx);
        s->rregs[0] &= ~1;
+        clr_rxint(s);
        if (s->type == kbd)
            ret = get_queue(s);
        else
            ret = s->rx;
+       SER_DPRINTF("Read channel %c, ch %d\n", channel? 'b' : 'a', ret);
        return ret;
     default:
        break;
@@ -303,16 +350,10 @@ static int serial_can_receive(void *opaque)
 
 static void serial_receive_byte(ChannelState *s, int ch)
 {
+    SER_DPRINTF("put ch %d\n", ch);
     s->rregs[0] |= 1;
-    // Interrupts reported only on channel A
-    if (s->chn == 0)
-       s->rregs[3] |= 0x20;
-    else {
-       s->otherchn->rregs[3] |= 4;
-    }
     s->rx = ch;
-    s->rxint = 1;
-    slavio_serial_update_irq(s);
+    set_rxint(s);
 }
 
 static void serial_receive_break(ChannelState *s)
@@ -454,7 +495,6 @@ static void handle_kbd_command(ChannelState *s, int val)
     switch (val) {
     case 1: // Reset, return type code
        put_queue(s, 0xff);
-       put_queue(s, 0xff);
        put_queue(s, 5); // Type 5
        break;
     case 7: // Query layout
@@ -498,7 +538,7 @@ void slavio_serial_ms_kbd_init(int base, int irq)
     slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
     cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
 
-    qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0]);
+    qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0);
     qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
     qemu_register_reset(slavio_serial_reset, s);
     slavio_serial_reset(s);