msx2: add MegaSD driver
authorgeijoenr <enric.geijo@gmail.com>
Sun, 4 Jan 2015 01:24:28 +0000 (02:24 +0100)
committergeijoenr <enric.geijo@gmail.com>
Sun, 4 Jan 2015 02:03:58 +0000 (03:03 +0100)
using the generic devsd driver maybe is not the fastest option because we need
to switch slots many times when sending commands, but it works as expected and
performance is acceptable for now.

Kernel/platform-msx2/Makefile
Kernel/platform-msx2/config.h
Kernel/platform-msx2/devices.c
Kernel/platform-msx2/devmegasd.c [new file with mode: 0644]
Kernel/platform-msx2/fuzix.lnk

index 7a5ae7d..7f22686 100644 (file)
@@ -1,18 +1,24 @@
 
-CSRCS = devtty.c devfd.c devhd.c devlpr.c
-CSRCS += devices.c main.c
-
+CSRCS = ../dev/devsd.c ../dev/mbr.c devfd.c devhd.c devlpr.c
+CSRCS += devices.c main.c devtty.c
+DSRCS = devmegasd.c
 ASRCS = msx2.s crt0.s vdp.s
 ASRCS += tricks.s commonmem.s bootrom.s
 
+CROSS_CCOPTS += -I../dev/
+
 COBJS = $(CSRCS:.c=.rel)
 AOBJS = $(ASRCS:.s=.rel)
-OBJS  = $(COBJS) $(AOBJS)
+DOBJS = $(DSRCS:.c=.rel)
+OBJS  = $(COBJS) $(AOBJS) $(DOBJS)
 
 JUNK = $(CSRCS:.c=.lst) $(CSRCS:.c=.asm) $(CSRCS:.c=.sym) $(ASRCS:.s=.lst) $(ASRCS:.s=.sym) $(CSRCS:.c=.rst) $(ASRCS:.s=.rst)
 
 all:   $(OBJS)
 
+$(DOBJS): %.rel: %.c
+       $(CROSS_CC) $(CROSS_CCOPTS) -c $<
+
 $(COBJS): %.rel: %.c
        $(CROSS_CC) $(CROSS_CCOPTS) --codeseg CODE2 -c $<
 
index f5a0c83..ae55549 100644 (file)
@@ -40,3 +40,6 @@
 #define TTYDEV   BOOT_TTY /* Device used by kernel for messages, panics */
 #define NBUFS    10       /* Number of block buffers */
 #define NMOUNTS         4        /* Number of mounts at a time */
+
+#define DEVICE_SD
+#define SD_DRIVE_COUNT 1
index eec4c57..1fd53bf 100644 (file)
@@ -8,17 +8,20 @@
 #include <tty.h>
 #include <vt.h>
 #include <devtty.h>
+#include <../dev/devsd.h>
+
+extern int megasd_probe();
 
 struct devsw dev_tab[] =  /* The device driver switch table */
 {
   /* 0: /dev/fd                Floppy disc block devices */
-  {  fd_open,     no_close,    fd_read,   fd_write,   no_ioctl },
-  /* 1: /dev/hd                Hard disc block devices (and RAM etc) */
-  {  hd_open,     no_close,    hd_read,   hd_write,   no_ioctl },
+  {  no_open,     no_close,    no_rdwr,   no_rdwr,   no_ioctl },
+  /* 1: /dev/sd                MegaSD Interface */
+  {  devsd_open,     no_close,    devsd_read,   devsd_write,   no_ioctl },
   /* 2: /dev/tty       TTY devices */
   {  tty_open,     tty_close,   tty_read,  tty_write,  vt_ioctl },
   /* 3: /dev/lpr       Printer devices */
-  {  lpr_open,     no_close,   no_rdwr,   lpr_write,  no_ioctl  },
+  {  no_open,     no_close,   no_rdwr,   no_rdwr,  no_ioctl  },
   /* 4: /dev/mem etc   System devices (one offs) */
   {  no_open,      no_close,    sys_read, sys_write, sys_ioctl  },
   /* Pack to 7 with nxio if adding private devices and start at 8 */
@@ -29,11 +32,15 @@ bool validdev(uint16_t dev)
     /* This is a bit uglier than needed but the right hand side is
        a constant this way */
     if(dev > ((sizeof(dev_tab)/sizeof(struct devsw)) << 8) + 255)
-       return false;
+        return false;
     else
         return true;
 }
 
 void device_init(void)
 {
+    if (megasd_probe()) {
+        /* probe for megaflash rom sd */
+        devsd_init();
+    }
 }
diff --git a/Kernel/platform-msx2/devmegasd.c b/Kernel/platform-msx2/devmegasd.c
new file mode 100644 (file)
index 0000000..1ba0da4
--- /dev/null
@@ -0,0 +1,158 @@
+/*-----------------------------------------------------------------------*/
+/* MegaSD driver for MegaFlashROM SCC+ SD                                */
+/*-----------------------------------------------------------------------*/
+
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <timer.h>
+#include <stdbool.h>
+#include "config.h"
+
+/*
+ * MegaFlashRom SCC+ SD contains an slot expander with several devices.
+ * The MegaSD interface is in subslot 3 and it contains an ASCII 8Kb mapper
+ * with the sdcard io registers mapped into page 0x40
+ */
+
+#define MSD_MAGIC_ADDR 0x4110
+#define MSD_MAGIC_PAGE 0x0e
+
+#define MSD_PAGE      0x40
+#define MSD_SUBSLOT   0x3
+
+#define MFR_BANKSEL0  0x6000
+#define MFR_BANKSEL1  0x6800
+
+/* bank 0 is in 0x4000-0x5fff and the sd interface mapped io */
+
+#define MSD_RDWR      0x4000
+#define MSD_CS        0x5000
+#define MSD_DEVSEL    0x5800
+
+#define readb(x)            *((volatile uint8_t *)x)
+#define writeb(val,x)       *((volatile uint8_t *)x) = val
+
+#ifdef DEVICE_SD
+
+extern int mapslot_bank1(uint8_t slot);
+extern uint8_t slotram;
+
+/* slot and subslot containing the sd interface */
+uint8_t slotmfr;
+
+int megasd_probe()
+{
+    uint8_t *sigp = (uint8_t *) MSD_MAGIC_ADDR;
+    uint8_t slot = 1;
+
+    kprintf("MegaSD...");
+
+    for (slot = 1; slot < 3; slot++) {
+        /* try to find MegaFlashRom signature in slots 1 and 2 */
+        slotmfr = 0x80 | MSD_SUBSLOT << 2 | slot;
+        mapslot_bank1(slotmfr);
+        writeb(MSD_MAGIC_PAGE, MFR_BANKSEL0);
+        if (sigp[0] == 'M' && sigp[1] == 'e' && sigp[2] == 'g' && sigp[3] == 'a')
+            goto found;
+    }
+    mapslot_bank1(slotram);
+    kprintf("not found\n");
+    return 0;
+
+found:
+    mapslot_bank1(slotram);
+    kprintf("found in slot %d-3\n", slot);
+    return 1;
+}
+
+void sd_spi_map_interface()
+{
+    mapslot_bank1(slotmfr);
+    writeb(MSD_PAGE, MFR_BANKSEL0);
+}
+
+void sd_spi_unmap_interface()
+{
+    mapslot_bank1(slotram);
+}
+
+void sd_spi_clock(uint8_t drive, bool go_fast)
+{
+    drive; /* not used */
+    go_fast;
+}
+
+void sd_spi_raise_cs(uint8_t drive)
+{
+    drive; /* not used */
+
+    sd_spi_map_interface();
+    writeb(drive, MSD_DEVSEL);
+
+    /* reading from MSD_CS raises CS for all cards */
+
+    readb(MSD_CS);
+
+    sd_spi_unmap_interface();
+}
+
+void sd_spi_lower_cs(uint8_t drive)
+{
+    drive; /* not used */
+
+    /* happens automatically when sending */
+}
+
+void sd_spi_transmit_byte(uint8_t drive, unsigned char byte)
+{
+    drive; /* not used */
+
+    sd_spi_map_interface();
+
+    writeb(byte, MSD_RDWR);
+
+    sd_spi_unmap_interface();
+}
+
+uint8_t sd_spi_receive_byte(uint8_t drive)
+{
+    unsigned char c;
+    drive; /* not used */
+
+    sd_spi_map_interface();
+
+    c = readb(MSD_RDWR);
+
+    sd_spi_unmap_interface();
+
+    return c;
+}
+
+bool sd_spi_receive_block(uint8_t drive, uint8_t *ptr, unsigned int length)
+{
+    drive; /* not used */
+
+    sd_spi_map_interface();
+
+    while(length--) *ptr++ = readb(MSD_RDWR);
+
+    sd_spi_unmap_interface();
+
+    return true;
+}
+
+bool sd_spi_transmit_block(uint8_t drive, uint8_t *ptr, int length)
+{
+    drive; /* not used */
+
+    sd_spi_map_interface();
+
+    while(length--) writeb(*(ptr++), MSD_RDWR);
+
+    sd_spi_unmap_interface();
+
+    return true;
+}
+
+#endif
index bfb5a28..3d1bad0 100644 (file)
@@ -18,9 +18,6 @@ platform-msx2/main.rel
 timer.rel
 kdata.rel
 platform-msx2/devtty.rel
-platform-msx2/devfd.rel
-platform-msx2/devhd.rel
-platform-msx2/devlpr.rel
 platform-msx2/devices.rel
 devio.rel
 filesys.rel
@@ -39,4 +36,7 @@ vt.rel
 devsys.rel
 usermem.rel
 usermem_std-z80.rel
+platform-msx2/devsd.rel
+platform-msx2/devmegasd.rel
+platform-msx2/mbr.rel
 -e