zx128: Start filling out disciple floppy disc support
authorAlan Cox <alan@linux.intel.com>
Sat, 14 Feb 2015 16:24:56 +0000 (16:24 +0000)
committerAlan Cox <alan@linux.intel.com>
Sat, 14 Feb 2015 16:24:56 +0000 (16:24 +0000)
Kernel/Makefile
Kernel/platform-zx128/Makefile
Kernel/platform-zx128/devfd.c [new file with mode: 0644]
Kernel/platform-zx128/devices.c
Kernel/platform-zx128/disciple.s
Kernel/platform-zx128/fuzix.lnk

index 4297113..a59aaee 100644 (file)
@@ -17,7 +17,7 @@ TARGET_LIST = platform-nc100 platform-micropack platform-pcw8256 platform-socz80
 #export TARGET = ubee
 #export TARGET = z80pack
 #export TARGET = z80pack-lite
-#export TARGET= zx128
+export TARGET= zx128
 
 export VERSION = "0.1"
 export SUBVERSION = "ac1"
index 37f4a14..6ceddc4 100644 (file)
@@ -1,7 +1,7 @@
-CSRCS = devtty.c devices.c main.c devmdv.c
+CSRCS = devtty.c devices.c main.c devmdv.c devfd.c
 DSRCS = ../dev/devide.c ../dev/mbr.c ../dev/blkdev.c
 DDSRCS = ../dev/devide_discard.c
-ASRCS = crt0.s zx128.s zxvideo.s microdrive.s
+ASRCS = crt0.s zx128.s zxvideo.s microdrive.s disciple.s
 ASRCS += tricks.s commonmem.s
 
 COBJS = $(CSRCS:.c=.rel)
diff --git a/Kernel/platform-zx128/devfd.c b/Kernel/platform-zx128/devfd.c
new file mode 100644 (file)
index 0000000..45ab1c1
--- /dev/null
@@ -0,0 +1,125 @@
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <devfd.h>
+
+#define MAX_FD 2
+
+#define OPDIR_NONE     0
+#define OPDIR_READ     1
+#define OPDIR_WRITE    2
+
+#define FD_READ                0x80
+#define FD_WRITE       0xA0
+#define FD_WRITE_PCOMP 0xA4
+
+/*
+ *     TODO:
+ *     - detect SD v DD and handle 256 byte sectors
+ *     - 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;
+
+/* Extern as they live in asm space */
+extern uint8_t fd_tab[MAX_FD];
+extern uint8_t fd_selected;
+extern uint8_t fd_cmd[6];
+
+static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
+{
+    blkno_t block;
+    uint16_t dptr;
+    int ct = 0;
+    int tries;
+    uint8_t err = 0;
+    uint8_t *driveptr = fd_tab + minor;
+    uint8_t nblock;
+    uint8_t cval;
+
+    if(rawflag == 2)
+        goto bad2;
+
+    /* 10 sectors per track, two sides, 512 bytes sector double density */
+    /* FIXME fd_map support
+    fd_map = rawflag;*/
+    if (rawflag == 0) {
+        dptr = (uint16_t)udata.u_buf->bf_data;
+        block = udata.u_buf->bf_blk;
+        nblock = 1;
+    } else {
+        if ((udata.u_offset|udata.u_count) & 0x1FF)
+            goto bad2;
+        dptr = (uint16_t)udata.u_base;
+        block = udata.u_offset >> 9;
+        nblock = udata.u_count >> 9;
+    }
+
+    fd_cmd[0] = is_read ? FD_READ : FD_WRITE;
+    fd_cmd[1] = block / 20;
+    fd_cmd[2] = (block % 20) + 1;
+    fd_cmd[3] = is_read ? OPDIR_READ: OPDIR_WRITE;
+    fd_cmd[4] = dptr & 0xFF;
+    fd_cmd[5] = dptr >> 8;
+
+    cval = (minor ^ 1) | 4;
+
+    if (*driveptr == 0xFF)
+        fd_reset(driveptr);
+
+
+    while (ct < nblock) {
+        if (fd_cmd[2] > 10)
+            control = cval | 2;
+        else
+            control = cval;
+        if (!is_read && fd_cmd[1] > 64)
+            fd_cmd[0] |= 4;    /* Write precompensation on */
+
+        for (tries = 0; tries < 4 ; tries++) {
+            err = fd_operation(driveptr);
+            if (err == 0)
+                break;
+            if (tries > 1)
+                fd_reset(driveptr);
+        }
+        /* 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 */
+        ct++;
+    }
+    return 1;
+bad:
+    kprintf("fd%d: error %x\n", minor, err);
+bad2:
+    udata.u_error = EIO;
+    return -1;
+}
+
+int fd_open(uint8_t minor, uint16_t flag)
+{
+    flag;
+    if(minor >= MAX_FD) {
+        udata.u_error = ENODEV;
+        return -1;
+    }
+    return 0;
+}
+
+int fd_read(uint8_t minor, uint8_t rawflag, uint8_t flag)
+{
+    flag;
+    return fd_transfer(minor, true, rawflag);
+}
+
+int fd_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
+{
+    flag;
+    return fd_transfer(minor, false, rawflag);
+}
index ed4d964..11595f8 100644 (file)
@@ -5,13 +5,14 @@
 #include <devsys.h>
 #include <vt.h>
 #include <devmdv.h>
+#include <devfd.h>
 #include <devide.h>
 #include <blkdev.h>
 
 struct devsw dev_tab[] =  /* The device driver switch table */
 {
   /* 0: /dev/fd                Floppy disc block devices */
-  {  no_open,      no_close,     no_rdwr,   no_rdwr,   no_ioctl },
+  {  fd_open,      no_close,     fd_read,  fd_write,   no_ioctl },
 #ifdef CONFIG_IDE
   /* 1: /dev/hd                Hard disc block devices */
   {  blkdev_open,  no_close,     blkdev_read,   blkdev_write,   blkdev_ioctl },
index 1bd7300..6b10b0e 100644 (file)
@@ -359,6 +359,7 @@ _fd_motor_on:
 _fd_motor_off:
        ret
 
+       .area _COMMONDATA
 curdrive:
        .db     0xff
 motor_running:
index 56a58d1..5f6295f 100644 (file)
@@ -22,6 +22,8 @@ usermem.rel
 platform-zx128/devices.rel
 platform-zx128/devmdv.rel
 platform-zx128/microdrive.rel
+platform-zx128/devfd.rel
+platform-zx128/disciple.rel
 devio.rel
 filesys.rel
 process.rel