disciple: sector wrap, notes on +D
authorAlan Cox <alan@linux.intel.com>
Sat, 14 Feb 2015 16:43:58 +0000 (16:43 +0000)
committerAlan Cox <alan@linux.intel.com>
Sat, 14 Feb 2015 16:43:58 +0000 (16:43 +0000)
Kernel/platform-zx128/devfd.c
Kernel/platform-zx128/disciple.s

index 45ab1c1..a4407a0 100644 (file)
@@ -10,8 +10,7 @@
 #define OPDIR_WRITE    2
 
 #define FD_READ                0x80
-#define FD_WRITE       0xA0
-#define FD_WRITE_PCOMP 0xA4
+#define FD_WRITE       0xA2
 
 /*
  *     TODO:
@@ -19,8 +18,6 @@
  *     - detect SS v DS
  */
 
-static uint8_t motorct;
-
 /* We are a bit rude with this as we just bash it without sharing */
 __sfr __at 0x1F control;
 
@@ -39,6 +36,7 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
     uint8_t *driveptr = fd_tab + minor;
     uint8_t nblock;
     uint8_t cval;
+    uint8_t sec;
 
     if(rawflag == 2)
         goto bad2;
@@ -60,7 +58,7 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
 
     fd_cmd[0] = is_read ? FD_READ : FD_WRITE;
     fd_cmd[1] = block / 20;
-    fd_cmd[2] = (block % 20) + 1;
+    sec = (block % 20) + 1;
     fd_cmd[3] = is_read ? OPDIR_READ: OPDIR_WRITE;
     fd_cmd[4] = dptr & 0xFF;
     fd_cmd[5] = dptr >> 8;
@@ -72,10 +70,13 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
 
 
     while (ct < nblock) {
-        if (fd_cmd[2] > 10)
+        if (sec > 10) {
             control = cval | 2;
-        else
+            fd_cmd[2] = sec - 10;
+        } else {
             control = cval;
+            fd_cmd[2] = sec;
+        }
         if (!is_read && fd_cmd[1] > 64)
             fd_cmd[0] |= 4;    /* Write precompensation on */
 
@@ -89,9 +90,13 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
         /* FIXME: need to do SD v DD detection */
         if (tries == 4)
             goto bad;
-        /* FIXME: this doesn't work for a big raw read that changes track */
         fd_cmd[5]+= 2; /* Move on 512 bytes in the buffer */
-        fd_cmd[2]++;   /* Next sector */
+        sec++;
+        /* Step a track */
+        if (sec > 20) {
+            sec = 1;
+            fd_cmd[1]++;
+        }
         ct++;
     }
     return 1;
index 6b10b0e..2a7dc40 100644 (file)
 ;      0x58 - step in
 ;      0xA0 - write + 0x02 for spin up etc, + 0x08? for precomp
 ;      0xD0 - reset (then wait about 1mS)
+;
+;
+;      This code ought to work on the Plus-D as well with a few changes
+;
+;      The +D uses ports
+;      0xE3    status/cmd
+;      0xEB    track
+;      0xF3    sector
+;      0xFB    data
+;      0xEF    control
+;      bits 0-1: drive select
+;      bit 7: side select
 ;
 
        .globl _fd_reset
        .globl _fd_operation
-       .globl _fd_motor_on
-       .globl _fd_motor_off
        .globl _fd_selected
        .globl _fd_tab
        .globl _fd_cmd
@@ -335,35 +345,10 @@ _fd_operation:
        ld      h, #0
        pop     ix
        ret
-;
-;      C interface fd_motor_on(uint16_t drivesel)
-;
-;      Selects this drive and turns on the motors. Also pass in the
-;      choice of density
-;
-;      bits 0-3:       select that drive
-;      bit 4:          side (must rewrite each drive change)
-;      bit 5:          precompensation (not set here but in the I/O ops)
-;      bit 6:          synchronize I/O by stalling the CPU (don't set this)
-;      bit 7:          set for double density (MFM)
-;
-;
-_fd_motor_on:
-       ret
-
-;
-;      C interface fd_motor_off(void)
-;
-;      Turns off the drive motors, deselects all drives
-;
-_fd_motor_off:
-       ret
 
        .area _COMMONDATA
 curdrive:
        .db     0xff
-motor_running:
-       .db     0
 fdcctrl:
        .db     0
 fdc_active: