dragondos: get read side of driver working
authorAlan Cox <alan@linux.intel.com>
Wed, 3 Jun 2015 00:03:14 +0000 (01:03 +0100)
committerAlan Cox <alan@linux.intel.com>
Wed, 3 Jun 2015 00:03:14 +0000 (01:03 +0100)
With these changes we can now read dragondos floppies fairly reliably. We
need to optimise the wait for the initial DRQ as now and then we don't quite
make it in the clocks allowed and end up retrying

Writes blow up at the end of the second write in a FIRQ storm, not sure why
yet. Possibly its up to us to disable FIRQ in the NMI handler ?

Kernel/platform-dragon-nx32/devfd.c
Kernel/platform-dragon-nx32/floppy.s

index 56e4823..dd0a78a 100644 (file)
@@ -55,9 +55,6 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
     uint8_t *driveptr = fd_tab + minor;
     uint8_t cmd[7];
 
-    if(rawflag)
-        goto bad2;
-
     fd_motor_busy();           /* Touch the motor timer first so we don't
                                    go and turn it off as we are doing this */
     if (fd_selected != minor) {
@@ -76,7 +73,8 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
         dptr = (uint16_t)udata.u_base;
         block = udata.u_offset >> 9;
         nblock = udata.u_count >> 8;
-    }
+    } else
+        goto bad2;
 
 //    kprintf("Issue command: drive %d\n", minor);
     cmd[0] = rawflag;
@@ -89,15 +87,11 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
         
     while (nblock) {
         for (tries = 0; tries < 4 ; tries++) {
-            kprintf("fd sector %d track %d\n", cmd[3], cmd[2]);
             err = fd_operation(cmd, driveptr);
             if (err == 0)
                 break;
-            kprintf("fd error %d\n", err);
-            if (tries > 1) {
-                kputs("fd reset\n");
+            if (tries > 1)
                 fd_reset(driveptr);
-            }
         }
         /* FIXME: should we try the other half and then bale out ? */
         if (tries == 4)
@@ -111,7 +105,7 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
         nblock--;
     }
     fd_motor_idle();
-    return 1;
+    return 0;
 bad:
     kprintf("fd%d: error %x\n", minor, err);
 bad2:
index 245ccfe..ef37dfa 100644 (file)
@@ -107,6 +107,7 @@ fdsetup:
 ;
        beq     fdiosetup
 
+       lda     TRACK,x
        sta     <FDCDATA        ; target
        ;
        ;       So we can verify
@@ -155,15 +156,15 @@ noprecomp:
        sty     nmivector       ; so our NMI handler will clean up
        ldy     #0              ; timeout handling
        orcc    #0x50           ; irqs off or we'll miss bytes
+       ldb     DIRECT,x
+       cmpb    #0x01           ; read ?
+       beq     fdio_in_1
+       cmpb    #0x02
+       beq     wait_drq_1      ; write
        sta     <FDCREG         ; issue the command
        nop                     ; give the FDC a moment to think
        exg     a,a
        exg     a,a
-       ldb     DIRECT,x
-       cmpb    #0x01           ; read ?
-       beq     fdio_in
-       cmpb    #0x02
-       beq     wait_drq        ; write
 ;
 ;      Status registers
 ;
@@ -176,6 +177,11 @@ fdxferdone:
 ;
 ;      Relies on B being 2...
 ;
+wait_drq_1:
+       sta     <FDCREG         ; issue the command
+       nop                     ; give the FDC a moment to think
+       exg     a,a
+       exg     a,a
 wait_drq:
        bitb    <FDCREG
        bne     drq_on
@@ -207,6 +213,11 @@ drq_go:
 ;
 ;      Read from the disk
 ;
+fdio_in_1:
+       sta     <FDCREG         ; issue the command
+       nop                     ; give the FDC a moment to think
+       exg     a,a
+       exg     a,a
 fdio_in:
        ldx     DATA,x
 fdio_dwait:
@@ -412,4 +423,4 @@ pia_stash:
        .byte   0
        .byte   0
 _fd_tab:
-       .byte   0,0,0,0
+       .byte   0xFF,0xFF,0xFF,0xFF