qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [4283] FDC fix 3/10 (Herv?\195?\169 Poussineau):


From: Blue Swirl
Subject: [Qemu-devel] [4283] FDC fix 3/10 (Herv?\195?\169 Poussineau):
Date: Tue, 29 Apr 2008 16:14:16 +0000

Revision: 4283
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4283
Author:   blueswir1
Date:     2008-04-29 16:14:15 +0000 (Tue, 29 Apr 2008)

Log Message:
-----------
FDC fix 3/10 (Herv?\195?\169 Poussineau):
- Fixes status A and status B registers. It removes one Sun4m mutation. Also 
removes the internal FD_CTRL_INTR flag.

Modified Paths:
--------------
    trunk/hw/fdc.c

Modified: trunk/hw/fdc.c
===================================================================
--- trunk/hw/fdc.c      2008-04-29 16:13:36 UTC (rev 4282)
+++ trunk/hw/fdc.c      2008-04-29 16:14:15 UTC (rev 4283)
@@ -323,6 +323,7 @@
                                     int dma_pos, int dma_len);
 static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status);
 
+static uint32_t fdctrl_read_statusA (fdctrl_t *fdctrl);
 static uint32_t fdctrl_read_statusB (fdctrl_t *fdctrl);
 static uint32_t fdctrl_read_dor (fdctrl_t *fdctrl);
 static void fdctrl_write_dor (fdctrl_t *fdctrl, uint32_t value);
@@ -339,7 +340,6 @@
     FD_CTRL_RESET  = 0x02,
     FD_CTRL_SLEEP  = 0x04, /* XXX: suppress that */
     FD_CTRL_BUSY   = 0x08, /* dma transfer in progress */
-    FD_CTRL_INTR   = 0x10,
 };
 
 enum {
@@ -361,8 +361,8 @@
 };
 
 enum {
-    FD_REG_0 = 0x00,
-    FD_REG_STATUSB = 0x01,
+    FD_REG_SRA = 0x00,
+    FD_REG_SRB = 0x01,
     FD_REG_DOR = 0x02,
     FD_REG_TDR = 0x03,
     FD_REG_MSR = 0x04,
@@ -421,6 +421,26 @@
 };
 
 enum {
+    FD_SRA_DIR      = 0x01,
+    FD_SRA_nWP      = 0x02,
+    FD_SRA_nINDX    = 0x04,
+    FD_SRA_HDSEL    = 0x08,
+    FD_SRA_nTRK0    = 0x10,
+    FD_SRA_STEP     = 0x20,
+    FD_SRA_nDRV2    = 0x40,
+    FD_SRA_INTPEND  = 0x80,
+};
+
+enum {
+    FD_SRB_MTR0     = 0x01,
+    FD_SRB_MTR1     = 0x02,
+    FD_SRB_WGATE    = 0x04,
+    FD_SRB_RDATA    = 0x08,
+    FD_SRB_WDATA    = 0x10,
+    FD_SRB_DR0      = 0x20,
+};
+
+enum {
     FD_DOR_SELMASK  = 0x01,
     FD_DOR_nRESET   = 0x04,
     FD_DOR_DMAEN    = 0x08,
@@ -472,6 +492,8 @@
     target_phys_addr_t io_base;
     /* Controller state */
     QEMUTimer *result_timer;
+    uint8_t sra;
+    uint8_t srb;
     uint8_t state;
     uint8_t dma_en;
     uint8_t cur_drv;
@@ -506,15 +528,10 @@
     uint32_t retval;
 
     switch (reg & 0x07) {
-    case FD_REG_0:
-        if (fdctrl->sun4m) {
-            // Identify to Linux as S82078B
-            retval = fdctrl_read_statusB(fdctrl);
-        } else {
-            retval = (uint32_t)(-1);
-        }
+    case FD_REG_SRA:
+        retval = fdctrl_read_statusA(fdctrl);
         break;
-    case FD_REG_STATUSB:
+    case FD_REG_SRB:
         retval = fdctrl_read_statusB(fdctrl);
         break;
     case FD_REG_DOR:
@@ -617,6 +634,9 @@
 {
     fdctrl_t *s = opaque;
 
+    /* Controller state */
+    qemu_put_8s(f, &s->sra);
+    qemu_put_8s(f, &s->srb);
     qemu_put_8s(f, &s->state);
     qemu_put_8s(f, &s->dma_en);
     qemu_put_8s(f, &s->cur_drv);
@@ -661,6 +681,9 @@
     if (version_id != 1)
         return -EINVAL;
 
+    /* Controller state */
+    qemu_get_8s(f, &s->sra);
+    qemu_get_8s(f, &s->srb);
     qemu_get_8s(f, &s->state);
     qemu_get_8s(f, &s->dma_en);
     qemu_get_8s(f, &s->cur_drv);
@@ -712,9 +735,11 @@
 /* Change IRQ state */
 static void fdctrl_reset_irq (fdctrl_t *fdctrl)
 {
+    if (!(fdctrl->sra & FD_SRA_INTPEND))
+        return;
     FLOPPY_DPRINTF("Reset interrupt\n");
     qemu_set_irq(fdctrl->irq, 0);
-    fdctrl->state &= ~FD_CTRL_INTR;
+    fdctrl->sra &= ~FD_SRA_INTPEND;
 }
 
 static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status)
@@ -725,9 +750,9 @@
         fdctrl->int_status = status;
         return;
     }
-    if (~(fdctrl->state & FD_CTRL_INTR)) {
+    if (!(fdctrl->sra & FD_SRA_INTPEND)) {
         qemu_set_irq(fdctrl->irq, 1);
-        fdctrl->state |= FD_CTRL_INTR;
+        fdctrl->sra |= FD_SRA_INTPEND;
     }
     FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", status);
     fdctrl->int_status = status;
@@ -741,6 +766,10 @@
     FLOPPY_DPRINTF("reset controller\n");
     fdctrl_reset_irq(fdctrl);
     /* Initialise controller */
+    fdctrl->sra = 0;
+    fdctrl->srb = 0xc0;
+    if (!fdctrl->drives[1].bs)
+        fdctrl->sra |= FD_SRA_nDRV2;
     fdctrl->cur_drv = 0;
     /* FIFO state */
     fdctrl->data_pos = 0;
@@ -769,11 +798,24 @@
     return fdctrl->cur_drv == 0 ? drv0(fdctrl) : drv1(fdctrl);
 }
 
+/* Status A register : 0x00 (read-only) */
+static uint32_t fdctrl_read_statusA (fdctrl_t *fdctrl)
+{
+    uint32_t retval = fdctrl->sra;
+
+    FLOPPY_DPRINTF("status register A: 0x%02x\n", retval);
+
+    return retval;
+}
+
 /* Status B register : 0x01 (read-only) */
 static uint32_t fdctrl_read_statusB (fdctrl_t *fdctrl)
 {
-    FLOPPY_DPRINTF("status register: 0x00\n");
-    return 0;
+    uint32_t retval = fdctrl->srb;
+
+    FLOPPY_DPRINTF("status register B: 0x%02x\n", retval);
+
+    return retval;
 }
 
 /* Digital output register : 0x02 */
@@ -809,6 +851,23 @@
         }
     }
     FLOPPY_DPRINTF("digital output register set to 0x%02x\n", value);
+
+    /* Motors */
+    if (value & FD_DOR_MOTEN0)
+        fdctrl->srb |= FD_SRB_MTR0;
+    else
+        fdctrl->srb &= ~FD_SRB_MTR0;
+    if (value & FD_DOR_MOTEN1)
+        fdctrl->srb |= FD_SRB_MTR1;
+    else
+        fdctrl->srb &= ~FD_SRB_MTR1;
+
+    /* Drive */
+    if (value & 1)
+        fdctrl->srb |= FD_SRB_DR0;
+    else
+        fdctrl->srb &= ~FD_SRB_DR0;
+
     /* Drive motors state indicators */
     if (value & FD_DOR_MOTEN1)
         fd_start(drv1(fdctrl));






reply via email to

[Prev in Thread] Current Thread [Next in Thread]