From: geijoenr Date: Sun, 4 Jan 2015 01:24:28 +0000 (+0100) Subject: msx2: add MegaSD driver X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=76dbc270be3271e65ccea4e824fc435ec81fddb7;p=FUZIX.git msx2: add MegaSD driver 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. --- diff --git a/Kernel/platform-msx2/Makefile b/Kernel/platform-msx2/Makefile index 7a5ae7d0..7f22686b 100644 --- a/Kernel/platform-msx2/Makefile +++ b/Kernel/platform-msx2/Makefile @@ -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 $< diff --git a/Kernel/platform-msx2/config.h b/Kernel/platform-msx2/config.h index f5a0c83b..ae555496 100644 --- a/Kernel/platform-msx2/config.h +++ b/Kernel/platform-msx2/config.h @@ -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 diff --git a/Kernel/platform-msx2/devices.c b/Kernel/platform-msx2/devices.c index eec4c57a..1fd53bf6 100644 --- a/Kernel/platform-msx2/devices.c +++ b/Kernel/platform-msx2/devices.c @@ -8,17 +8,20 @@ #include #include #include +#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 index 00000000..1ba0da4f --- /dev/null +++ b/Kernel/platform-msx2/devmegasd.c @@ -0,0 +1,158 @@ +/*-----------------------------------------------------------------------*/ +/* MegaSD driver for MegaFlashROM SCC+ SD */ +/*-----------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#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 diff --git a/Kernel/platform-msx2/fuzix.lnk b/Kernel/platform-msx2/fuzix.lnk index bfb5a283..3d1bad0c 100644 --- a/Kernel/platform-msx2/fuzix.lnk +++ b/Kernel/platform-msx2/fuzix.lnk @@ -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