diff --git a/.github/workflows/build-ed64-example-rom.yml b/.github/workflows/build-ed64-example-rom.yml index 1525fa4c..59a19e1d 100644 --- a/.github/workflows/build-ed64-example-rom.yml +++ b/.github/workflows/build-ed64-example-rom.yml @@ -4,26 +4,33 @@ on: [push, pull_request] jobs: build: runs-on: ubuntu-latest + strategy: + matrix: + releasetype: [ 'debug', 'release' ] steps: - uses: actions/checkout@v2 name: Checkout Code - name: Install Libdragon container run: | - sudo npm install -g libdragon + # TODO: the sample needs updating. This is the last known compatible version! + # Remove the @1.3.15 to run at latest. + # And, this would also involve having a git subtree of the libdragon version. + # which would make it easier to show "custom" changes to source. + sudo npm install -g libdragon@1.3.15 libdragon download - name: Setup Build environment run: | cd ${{ github.workspace }}/ED64-XIO/ - mkdir bin && mkdir obj + mkdir bin && mkdir bin/release && mkdir bin/debug && mkdir obj libdragon start - name: Build ROM - run: cd ${{ github.workspace }}/ED64-XIO/ && libdragon make + run: cd ${{ github.workspace }}/ED64-XIO/ && libdragon make ${{ matrix.releasetype }} - name: Upload Artifact uses: actions/upload-artifact@v1.0.0 with: - name: ED64-XIO-SAMPLE_N64_ROM - path: ${{ github.workspace }}/ED64-XIO/bin/ED64-XIO-SAMPLE.v64 \ No newline at end of file + name: ED64-XIO-SAMPLE_N64_ROM-${{ matrix.releasetype }} + path: ${{ github.workspace }}/ED64-XIO/bin/${{ matrix.releasetype }}/ED64-XIO-SAMPLE.v64 diff --git a/ED64-XIO/Makefile b/ED64-XIO/Makefile index f0dc2464..0c9fbe7c 100644 --- a/ED64-XIO/Makefile +++ b/ED64-XIO/Makefile @@ -1,4 +1,14 @@ -RM = rm -rf +PROG_NAME = ED64-XIO-SAMPLE +ROMSIZE = 256K + + +ifdef SystemRoot +FIXPATH = $(subst /,\,$1) +RM = DEL /Q +else +FIXPATH = $1 +RM = rm -f +endif ROOTDIR = $(N64_INST) GCCN64PREFIX = $(ROOTDIR)/bin/mips64-elf- @@ -6,60 +16,72 @@ CHKSUM64PATH = $(ROOTDIR)/bin/chksum64 MKDFSPATH = $(ROOTDIR)/bin/mkdfs N64TOOL = $(ROOTDIR)/bin/n64tool -FFDIR := ff -SRCDIR := src -INCDIR := inc -RESDIR := res +CC = $(GCCN64PREFIX)gcc +AS = $(GCCN64PREFIX)as +LD = $(GCCN64PREFIX)ld +OBJCOPY = $(GCCN64PREFIX)objcopy + +SRCDIR = src +SRCDIR_EDLIB = $(SRCDIR)/edlib +SRCDIR_FFLIB = ff +LIBDIR = lib +INCDIR = inc +INCDIR_EDLIB = inc/edlib +RESDIR = res OBJDIR = obj BINDIR = bin -PROG_NAME = ED64-XIO-SAMPLE - -HDDIR :=$(ROOTDIR)/mips64-elf/lib +HEADERDIR :=$(ROOTDIR)/mips64-elf/lib HEADERNAME = header HEADERTITLE = $(PROG_NAME) -CC = $(GCCN64PREFIX)gcc -AS = $(GCCN64PREFIX)as -LD = $(GCCN64PREFIX)ld -OBJCOPY = $(GCCN64PREFIX)objcopy - LINK_FLAGS = -L$(ROOTDIR)/lib -L$(ROOTDIR)/mips64-elf/lib -ldragon -lc -lm -ldragonsys -Tn64.ld -FLAGS = -std=gnu99 -march=vr4300 -mtune=vr4300 -O2 -Wall -Wno-pointer-sign -I$(ROOTDIR)/mips64-elf/include -Iedlib -I$(FFDIR) -I$(INCDIR) -G0 -ASFLAGS = -mtune=vr4300 -march=vr4300 +ASFLAGS := -mtune=vr4300 -march=vr4300 +CCFLAGS := -std=gnu99 $(ASFLAGS) $(OPTIMIZE_FLAG) -Wall -Wno-pointer-sign -I$(ROOTDIR)/mips64-elf/include -I$(SRCDIR_FFLIB) -I$(INCDIR) -I$(INCDIR_EDLIB) -SOURCES_FF := $(wildcard $(FFDIR)/*.c) -SOURCES_S := $(wildcard $(SRCDIR)/*.s) +SOURCES_ASM := $(wildcard $(SRCDIR)/*.s) SOURCES := $(wildcard $(SRCDIR)/*.c) +SOURCES_EDLIB := $(wildcard $(SRCDIR_EDLIB)/*.c) +SOURCES_FFLIB := $(wildcard $(SRCDIR_FFLIB)/*.c) -OBJECTS_FF := $(SOURCES_FF:$(FFDIR)/%.c=$(OBJDIR)/%.o) -OBJECTS_S := $(SOURCES_S:$(SRCDIR)/%.s=$(OBJDIR)/%.o) +OBJECTS_ASM := $(SOURCES_ASM:$(SRCDIR)/%.s=$(OBJDIR)/%.o) OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o) +OBJECTS_EDLIB := $(SOURCES_EDLIB:$(SRCDIR_EDLIB)/%.c=$(OBJDIR)/%.o) +OBJECTS_FFLIB := $(SOURCES_FFLIB:$(SRCDIR_FFLIB)/%.c=$(OBJDIR)/%.o) $(PROG_NAME).v64: $ $(PROG_NAME).elf $(OBJCOPY) $(BINDIR)/$(PROG_NAME).elf $(BINDIR)/$(PROG_NAME).bin -O binary - $(N64TOOL) -l 256K -t $(HEADERTITLE) -h $(HDDIR)/$(HEADERNAME) -o $(BINDIR)/$(PROG_NAME).v64 $(BINDIR)/$(PROG_NAME).bin + $(N64TOOL) -l $(ROMSIZE) -t $(HEADERTITLE) -h $(HEADERDIR)/$(HEADERNAME) -o $(BINDIR)/$(PROG_NAME).v64 $(BINDIR)/$(PROG_NAME).bin $(CHKSUM64PATH) $(BINDIR)/$(PROG_NAME).v64 -$(PROG_NAME).elf : $(OBJECTS_FF) $(OBJECTS_S) $(OBJECTS) - $(LD) -o $(BINDIR)/$(PROG_NAME).elf $(OBJECTS_FF) $(OBJECTS_S) $(OBJECTS) $(LINK_FLAGS) +$(PROG_NAME).elf : $(OBJECTS_ASM) $(OBJECTS) $(OBJECTS_EDLIB) $(OBJECTS_FFLIB) + $(LD) -o $(BINDIR)/$(PROG_NAME).elf $(OBJECTS_ASM) $(OBJECTS) $(OBJECTS_EDLIB) $(OBJECTS_FFLIB) $(LINK_FLAGS) -$(OBJECTS_FF): $(OBJDIR)/%.o : $(FFDIR)/%.c - $(CC) $(FLAGS) -c $< -o $@ - -$(OBJECTS_S): $(OBJDIR)/%.o : $(SRCDIR)/%.s +$(OBJECTS_ASM): $(OBJDIR)/%.o : $(SRCDIR)/%.s $(CC) $(ASFLAGS) -c $< -o $@ $(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c - $(CC) $(FLAGS) -c $< -o $@ + $(CC) $(CCFLAGS) -c $< -o $@ + +$(OBJECTS_EDLIB): $(OBJDIR)/%.o : $(SRCDIR_EDLIB)/%.c + $(CC) $(CCFLAGS) -c $< -o $@ + +$(OBJECTS_FFLIB): $(OBJDIR)/%.o : $(SRCDIR_FFLIB)/%.c + $(CC) $(CCFLAGS) -c $< -o $@ + +release: BINDIR := bin/release +release: OPTIMIZE_FLAG = -O2 -g0 +release: $(PROG_NAME).v64 + +debug: BINDIR := bin/debug +debug: OPTIMIZE_FLAG = -O0 -DDEBUG -g +debug: $(PROG_NAME).v64 -all: $(PROG_NAME).v64 +all: $(release) clean: - $(RM) $(BINDIR)/*.v64 - $(RM) $(BINDIR)/*.elf - $(RM) $(OBJDIR)/*.o - $(RM) $(BINDIR)/*.bin - $(RM) $(BINDIR)/*.dfs \ No newline at end of file + $(info "Cleaning $(PROG_NAME) build folders...") + @$(RM) $(call FIXPATH,$(BINDIR)/**/*) + @$(RM) $(call FIXPATH,$(OBJDIR)/*.o) \ No newline at end of file diff --git a/ED64-XIO/README.md b/ED64-XIO/README.md index 7cde7c60..27ff31c4 100644 --- a/ED64-XIO/README.md +++ b/ED64-XIO/README.md @@ -5,7 +5,7 @@ FPGA firmware included in ED64 Menu OS version 3.04 or newer required to use thi [Table of Contents](/../../docs/table_of_contents.md) ## Features: -* Simple file manager and game loading from disk +* Simple file manager and ROM loading from SD card * Use files with FatFs lib * USB communications * ED64 hardware version identification diff --git a/ED64-XIO/ff/diskio.c b/ED64-XIO/ff/diskio.c index 5220e0ff..6c4f61f5 100644 --- a/ED64-XIO/ff/diskio.c +++ b/ED64-XIO/ff/diskio.c @@ -13,8 +13,8 @@ /* Definitions of physical drive number for each drive */ -#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */ -#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */ +#define DEV_SD 0 /* Example: Map SD card to physical drive 0 */ +#define DEV_RAM 1 /* Example: Map Ramdisk to physical drive 1 */ #define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */ //extern SD_HandleTypeDef hsd; @@ -33,7 +33,7 @@ DSTATUS disk_status( } /*-----------------------------------------------------------------------*/ -/* Inidialize a Drive */ +/* Initialize a Drive */ /*-----------------------------------------------------------------------*/ @@ -41,7 +41,7 @@ DSTATUS disk_initialize( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { - dresp = diskInit(); + dresp = sd_disk_init(); dstat = 0; if (dresp)dstat = STA_NOINIT; @@ -62,7 +62,7 @@ DRESULT disk_read( UINT count /* Number of sectors to read */ ) { - dresp = diskRead(buff, sector, count); + dresp = sd_disk_read(buff, sector, count); if (dresp)return RES_ERROR; return RES_OK; } @@ -83,7 +83,7 @@ DRESULT disk_write( ) { - dresp = diskWrite((BYTE *) buff, sector, count); + dresp = sd_disk_write((BYTE *) buff, sector, count); if (dresp)return RES_ERROR; return RES_OK; } @@ -105,7 +105,7 @@ DRESULT disk_ioctl( switch (cmd) { case CTRL_SYNC: - res = diskCloseRW(); + res = sd_disk_close_rw(); dresp = res; res = res == 0 ? RES_OK : RES_ERROR; break; @@ -129,3 +129,10 @@ DRESULT disk_ioctl( return res; } +DWORD get_fattime (void) +{ + //TODO: add ability to use the X7 or V3 RTC. + return ((DWORD)(FF_NORTC_YEAR - 1980) << 25 | + (DWORD)FF_NORTC_MON << 21 | + (DWORD)FF_NORTC_MDAY << 16); +} diff --git a/ED64-XIO/ff/diskio.h b/ED64-XIO/ff/diskio.h index e4ead783..fd84b0e6 100644 --- a/ED64-XIO/ff/diskio.h +++ b/ED64-XIO/ff/diskio.h @@ -31,6 +31,7 @@ DSTATUS disk_status (BYTE pdrv); DRESULT disk_read (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count); DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count); DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); +DWORD get_fattime (void); /* Disk Status Bits (DSTATUS) */ diff --git a/ED64-XIO/ff/ffconf.h b/ED64-XIO/ff/ffconf.h index bf54fadc..635fa309 100644 --- a/ED64-XIO/ff/ffconf.h +++ b/ED64-XIO/ff/ffconf.h @@ -68,7 +68,7 @@ / Locale and Namespace Configurations /---------------------------------------------------------------------------*/ -#define FF_CODE_PAGE 932 +#define FF_CODE_PAGE 437 /* This option specifies the OEM code page to be used on the target system. / Incorrect code page setting can cause a file open failure. / @@ -168,7 +168,7 @@ #define FF_STR_VOLUME_ID 0 -#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3" +#define FF_VOLUME_STRS "SD"//,"RAM","USB","NAND","CF","SD2","USB2","USB3" /* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings. / When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive / number in the path name. FF_VOLUME_STRS defines the volume ID strings for each @@ -228,16 +228,16 @@ / buffer in the filesystem object (FATFS) is used for the file data transfer. */ -#define FF_FS_EXFAT 1 +#define FF_FS_EXFAT 0 /* This option switches support for exFAT filesystem. (0:Disable or 1:Enable) / To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1) / Note that enabling exFAT discards ANSI C (C89) compatibility. */ #define FF_FS_NORTC 1 -#define FF_NORTC_MON 8 -#define FF_NORTC_MDAY 23 -#define FF_NORTC_YEAR 2019 +#define FF_NORTC_MON 3 +#define FF_NORTC_MDAY 11 +#define FF_NORTC_YEAR 2021 /* The option FF_FS_NORTC switches timestamp functiton. If the system does not have / any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable / the timestamp function. Every object modified by FatFs will have a fixed timestamp diff --git a/ED64-XIO/ff/fileio.c b/ED64-XIO/ff/fileio.c deleted file mode 100644 index 79b1f2a0..00000000 --- a/ED64-XIO/ff/fileio.c +++ /dev/null @@ -1,97 +0,0 @@ - -#include "everdrive.h" - -u8 fileRead() { - - u8 *path = "ED64/OS64.v64"; - struct controller_data cd; - u8 buff[256]; - FIL f; - UINT br; - u8 resp; - - gCleanScreen(); - gRepaint(); - - - resp = f_open(&f, path, FA_READ); - if (resp)return resp; - - resp = f_read(&f, buff, sizeof (buff), &br); - if (resp)return resp; - - resp = f_close(&f); - if (resp)return resp; - - - gCleanScreen(); - gConsPrint("Data readed from: "); - gAppendString(path); - gConsPrint("Press B to exit"); - - gConsPrint(""); - for (int i = 0; i < sizeof (buff); i++) { - if (i % 16 == 0)gConsPrint(""); - gAppendHex8(buff[i]); - } - - - gRepaint(); - while (1) { - gVsync(); - controller_scan(); - cd = get_keys_down(); - - if (cd.c[0].B) { - break; - } - } - - return 0; -} - -u8 fileWrite() { - - u8 *path = "test.txt"; - u8 *msg = "This is test message"; - struct controller_data cd; - FIL f; - UINT bw; - u8 resp; - u32 str_len; - - gCleanScreen(); - gRepaint(); - - for (str_len = 0; msg[str_len] != 0; str_len++); - - resp = f_open(&f, path, FA_WRITE | FA_CREATE_ALWAYS); - if (resp)return resp; - - resp = f_write(&f, msg, str_len, &bw); - if (resp)return resp; - - resp = f_close(&f); - if (resp)return resp; - - - gCleanScreen(); - gConsPrint(msg); - gConsPrint(""); - gConsPrint("String above was written to the "); - gConsPrint(path); - gConsPrint("Press B to exit"); - - gRepaint(); - while (1) { - gVsync(); - controller_scan(); - cd = get_keys_down(); - - if (cd.c[0].B) { - break; - } - } - - return 0; -} \ No newline at end of file diff --git a/ED64-XIO/ff/usb.c b/ED64-XIO/ff/usb.c deleted file mode 100644 index 749d6a31..00000000 --- a/ED64-XIO/ff/usb.c +++ /dev/null @@ -1,148 +0,0 @@ - -#include "everdrive.h" - -u8 usbResp(u8 resp); -void usbCmdCmemFill(u8 *cmd); -u8 usbCmdRomWR(u8 *cmd); - -void usbTerminal() { - - u8 data[4 + 1]; - u8 tout; - struct controller_data cd; - - gCleanScreen(); - gConsPrint("USB COM terminal demo"); - gConsPrint("Press B to exit"); - gRepaint(); - - data[4] = 1; - - while (1) { - - gVsync(); - controller_scan(); - cd = get_keys_down(); - if (cd.c[0].B)return; - - if (!bi_usb_can_rd())continue; - - //read from virtual serial port. - //size must be a multiple of 4. use 512B blocks for best performance - tout = bi_usb_rd(data, 4); - if (tout)continue; - - //send echo string back to the serial port - bi_usb_wr(data, 4); - - gConsPrint(data); - gRepaint(); - } -} - -void usbLoadGame() { - - u8 resp, usb_cmd; - u8 cmd[16]; - struct controller_data cd; - - gCleanScreen(); - gConsPrint("Waiting for game data..."); - gConsPrint("Press B to exit"); - gRepaint(); - - while (1) { - - gVsync(); - controller_scan(); - cd = get_keys_down(); - if (cd.c[0].B)return; - - if (!bi_usb_can_rd())continue; - - resp = bi_usb_rd(cmd, 16); - if (resp)continue; - //resp = bi_usb_rd(cmd + 16, 512 - 16); - //if (resp)return resp; - - if (cmd[0] != 'c')continue; - if (cmd[1] != 'm')continue; - if (cmd[2] != 'd')continue; - usb_cmd = cmd[3]; - - //host send this command during the everdrive seek - if (usb_cmd == 't') { - usbResp(0); - } - - //start the game - if (usb_cmd == 's') { - bi_game_cfg_set(SAVE_EEP16K); //set save type - boot_simulator(CIC_6102); //run the game - } - - //fill ro memory. used if rom size less than 2MB (required for correct crc values) - if (usb_cmd == 'c') { - usbCmdCmemFill(cmd); - } - - //write to ROM memory - if (usb_cmd == 'W') { - usbCmdRomWR(cmd); - } - - } - -} - -u8 usbResp(u8 resp) { - - u8 buff[16]; - buff[0] = 'c'; - buff[1] = 'm'; - buff[2] = 'd'; - buff[3] = 'r'; - buff[4] = resp; - return bi_usb_wr(buff, sizeof (buff)); -} - -void usbCmdCmemFill(u8 *cmd) { - - u16 i; - u32 addr = *(u32 *) & cmd[4]; - u32 slen = *(u32 *) & cmd[8]; - u32 val = *(u32 *) & cmd[12]; - u32 buff[512 / 4]; - - for (i = 0; i < 512 / 4; i++) { - buff[i] = val; - } - - while (slen--) { - sysPI_wr(buff, addr, 512); - addr += 512; - } -} - -u8 usbCmdRomWR(u8 *cmd) { - - u8 resp; - u8 buff[512]; - u32 addr = *(u32 *) & cmd[4]; //destination address - u32 slen = *(u32 *) & cmd[8]; //size in sectors (512B) - - if (slen == 0)return 0; - - bi_usb_rd_start(); //begin first block receiving (512B) - - while (slen--) { - - resp = bi_usb_rd_end(buff); //wait for block receiving completion and read it to the buffer - if (slen != 0)bi_usb_rd_start(); //begin next block receiving while previous block transfers to the ROM - if (resp)return resp; - sysPI_wr(buff, addr, 512); //copy received block to the rom memory - addr += 512; - } - - return 0; -} \ No newline at end of file diff --git a/ED64-XIO/inc/bios.h b/ED64-XIO/inc/bios.h index 074fc273..aa5749c6 100644 --- a/ED64-XIO/inc/bios.h +++ b/ED64-XIO/inc/bios.h @@ -1,81 +1,86 @@ -/* - * File: bios.h - * Author: krik - * - * Created on September 22, 2013, 2:34 PM - */ - -#ifndef BIOS_H -#define BIOS_H - -#include "sys.h" - -#define BI_SIZE_ROM 0x4000000 //rom size -#define BI_SIZE_BRM 0x20000 //backup ram size - -#define BI_ADDR_ROM (KSEG1 | 0x10000000) -#define BI_ADDR_BRM (KSEG1 | 0x08000000) - -#define BI_ERR_I2C_CMD 0xB0 -#define BI_ERR_I2C_TOUT 0xB1 -#define BI_ERR_USB_TOUT 0xB2 -#define BI_ERR_FPG_CFG 0xB3 - -//sd controller speed select. LO speed only for init procedure -#define BI_DISK_SPD_LO 0x00 -#define BI_DISK_SPD_HI 0x01 +/* +* Copyright (c) Krikzz and Contributors. +* See LICENSE file in the project root for full license information. +*/ -//bootloader flags -#define BI_BCFG_BOOTMOD 0x01 -#define BI_BCFG_SD_INIT 0x02 -#define BI_BCFG_SD_TYPE 0x04 -#define BI_BCFG_GAMEMOD 0x08 -#define BI_BCFG_CICLOCK 0x8000 +#ifndef ED64_BIOS_H +#define ED64_BIOS_H -//dd table to know data areas which should be saved -#define BI_DD_TBL_SIZE 2048 -#define BI_DD_PGE_SIZE 0x8000 +#ifdef __cplusplus +extern "C" { +#endif -#define CART_ID_V2 0xED640007 -#define CART_ID_V3 0xED640008 -#define CART_ID_X7 0xED640013 -#define CART_ID_X5 0xED640014 - -//game cfg register flags -#define SAVE_OFF 0x0000 -#define SAVE_EEP4K 0x0001 -#define SAVE_EEP16K 0x0002 -#define SAVE_SRM32K 0x0003 -#define SAVE_SRM96K 0x0004 -#define SAVE_FLASH 0x0005 -#define SAVE_SRM128K 0x0006 -#define SAVE_DD64 0x0010 - - - -void bi_init(); -u8 bi_usb_can_rd(); -u8 bi_usb_can_wr(); -u8 bi_usb_rd(void *dst, u32 len); -u8 bi_usb_wr(void *src, u32 len); -void bi_usb_rd_start(); -u8 bi_usb_rd_end(void *dst); - - -void bi_sd_speed(u8 speed); -void bi_sd_bitlen(u8 val); -u8 bi_sd_cmd_rd(); -void bi_sd_cmd_wr(u8 val); -u8 bi_sd_dat_rd(); -void bi_sd_dat_wr(u8 val); -u8 bi_sd_to_ram(void *dst, u16 slen); -u8 bi_sd_to_rom(u32 dst, u16 slen); -u8 bi_ram_to_sd(void *src, u16 slen); +#include "sys.h" -void bi_game_cfg_set(u8 type); //set save type -void bi_wr_swap(u8 swap_on); -u32 bi_get_cart_id(); +#define ED64_SIZE_ROM 0x4000000 /*rom size */ +#define ED64_SIZE_BRM 0x20000 // backup ram size */ +#define ED64_ADDR_ROM (KSEG1 | 0x10000000) +#define ED64_ADDR_BRM (KSEG1 | 0x08000000) +#define ED64_ERR_I2C_CMD 0xB0 +#define ED64_ERR_I2C_TOUT 0xB1 +#define ED64_ERR_USB_TOUT 0xB2 +#define ED64_ERR_FPG_CFG 0xB3 -#endif /* BIOS_H */ +/* +SD card controller speed select. +LOW speed is only for initilization procedure. +HIGH speed should be used for all other functions. +*/ +#define ED64_SDIO_SPEED_LOW 0x00 +#define ED64_SDIO_SPEED_HIGH 0x01 + +/* bootloader flags */ +#define ED64_BCFG_BOOTMOD 0x01 +#define ED64_BCFG_SD_INIT 0x02 +#define ED64_BCFG_SD_TYPE 0x04 +#define ED64_BCFG_GAMEMOD 0x08 +#define ED64_BCFG_CICLOCK 0x8000 + +/* 64dd ROM table to know which data areas should be saved */ +#define ED64_64DD_TBL_SIZE 2048 +#define ED64_64DD_PGE_SIZE 0x8000 + +#define ED64_CART_ID_V2 0xED640007 +#define ED64_CART_ID_V3 0xED640008 +#define ED64_CART_ID_X7 0xED640013 +#define ED64_CART_ID_X5 0xED640014 + +/* rom cfg register flags */ +#define ED64_SAVE_OFF 0x0000 +#define ED64_SAVE_EEP4K 0x0001 +#define ED64_SAVE_EEP16K 0x0002 +#define ED64_SAVE_SRM32K 0x0003 +#define ED64_SAVE_SRM96K 0x0004 +#define ED64_SAVE_FLASH 0x0005 +#define ED64_SAVE_SRM128K 0x0006 +#define ED64_SAVE_DD64 0x0010 + +void ed64_bios_init(); +u8 ed64_bios_usb_can_read(); +u8 ed64_bios_usb_can_write(); +u8 ed64_bios_usb_read(void *dst, u32 len); +u8 ed64_bios_usb_write(void *src, u32 len); +void ed64_bios_usb_read_start(); +u8 ed64_bios_usb_read_end(void *dst); + +void ed64_bios_sdio_speed(u8 speed); +void ed64_bios_sdio_bitlength(u8 val); +u8 ed64_bios_sdio_cmd_read(); +void ed64_bios_sdio_cmd_write(u8 val); +u8 ed64_bios_sd_data_read(); +void ed64_bios_sdio_data_write(u8 val); +u8 ed64_bios_sdio_to_ram(void *dst, u16 slen); +u8 ed64_bios_sdio_to_rom(u32 dst, u16 slen); +u8 ed64_bios_ram_to_sdio(void *src, u16 slen); + +void ed64_bios_rom_savetype_set(u8 type); /* set save type */ +void ed64_bios_write_endian_swap(u8 swap_on); +u32 ed64_bios_get_cart_id(); + +#ifdef __cplusplus +} +#endif + +#endif /* ED64_BIOS_H */ diff --git a/ED64-XIO/inc/disk.h b/ED64-XIO/inc/disk.h index f58ce541..db30981f 100644 --- a/ED64-XIO/inc/disk.h +++ b/ED64-XIO/inc/disk.h @@ -1,28 +1,32 @@ -/* - * File: disk.h - * Author: igor - * - * Created on September 11, 2020, 7:00 PM - */ +/* +* Copyright (c) Krikzz and Contributors. +* See LICENSE file in the project root for full license information. +*/ -#ifndef DISK_H -#define DISK_H +#ifndef ED64_SD_DISKIO_H +#define ED64_SD_DISKIO_H +#ifdef __cplusplus +extern "C" { +#endif -#define DISK_ERR_INIT 0xD0 -#define DISK_ERR_CTO 0xD1 -#define DISK_ERR_RD1 0xD2//cmd tout -#define DISK_ERR_RD2 0xD2//io error -#define DISK_ERR_WR1 0xD3//cmd tout -#define DISK_ERR_WR2 0xD3//io error +#define DISK_ERR_INIT 0xD0 /* command initialization error */ +#define DISK_ERR_CTO 0xD1 /* command CTO error */ +#define DISK_ERR_RD1 0xD2 /* command timeout */ +#define DISK_ERR_RD2 0xD2 /* IO error */ +#define DISK_ERR_WR1 0xD3 /* command timeout */ +#define DISK_ERR_WR2 0xD3 /* IO error */ -u8 diskInit(); -u8 diskReadToRam(u32 sd_addr, void *dst, u16 slen); -u8 diskReadToRom(u32 sd_addr, u32 dst, u16 slen); -u8 diskRead(void *dst, u32 saddr, u32 slen); -u8 diskWrite(void *src, u32 saddr, u32 slen); -u8 diskCloseRW(); -u8 diskStop(); +u8 sd_disk_init(); +u8 sd_disk_read_to_ram(u32 sd_addr, void *dst, u16 slen); +u8 sd_disk_read_to_rom(u32 sd_addr, u32 dst, u16 slen); +u8 sd_disk_read(void *dst, u32 saddr, u32 slen); +u8 sd_disk_write(void *src, u32 saddr, u32 slen); +u8 sd_disk_close_rw(); +// u8 sd_disk_stop(); +#ifdef __cplusplus +} +#endif -#endif /* DISK_H */ +#endif /* ED64_SD_DISKIO_H */ diff --git a/ED64-XIO/inc/everdrive.h b/ED64-XIO/inc/everdrive.h index 289743a3..90f86ceb 100644 --- a/ED64-XIO/inc/everdrive.h +++ b/ED64-XIO/inc/everdrive.h @@ -1,23 +1,30 @@ -/* - * File: everdrive.h - * Author: igor - * - * Created on September 11, 2020, 6:59 PM - */ +/* +* Copyright (c) Krikzz and Contributors. +* See LICENSE file in the project root for full license information. +*/ -#ifndef EVERDRIVE_H -#define EVERDRIVE_H +#ifndef ED_ROM_SAMPLE_H +#define ED_ROM_SAMPLE_H + +#ifdef __cplusplus +extern "C" { +#endif -#include "sys.h" #include "bios.h" #include "disk.h" #include "ff.h" +#include "sys.h" + + +void rom_boot_simulator(u8 cic); +u8 fmanager_display(); +void usb_terminal(); +void usb_load_rom(); +u8 fm_file_read(); +u8 fm_file_write(); -void boot_simulator(u8 cic); -u8 fmanager(); -void usbTerminal(); -void usbLoadGame(); -u8 fileRead(); -u8 fileWrite(); +#ifdef __cplusplus +} +#endif -#endif /* EVERDRIVE_H */ +#endif /* ED_ROM_SAMPLE_H */ diff --git a/ED64-XIO/inc/sys.h b/ED64-XIO/inc/sys.h index 4e46dffd..001a5a38 100644 --- a/ED64-XIO/inc/sys.h +++ b/ED64-XIO/inc/sys.h @@ -1,34 +1,19 @@ -/* - * File: sys.h - * Author: igor - * - * Created on September 9, 2019, 2:44 AM - */ +/* +* Copyright (c) Krikzz and Contributors. +* See LICENSE file in the project root for full license information. +*/ #ifndef SYS_H -#define SYS_H +#define SYS_H +#ifdef __cplusplus +extern "C" { +#endif - -#define u8 unsigned char -#define u16 unsigned short -#define u32 unsigned long -#define u64 unsigned long long - -#define vu8 volatile unsigned char -#define vu16 volatile unsigned short -#define vu32 volatile unsigned long -#define vu64 volatile unsigned long long - -#define s8 signed char -#define s16 short -#define s32 long -#define s64 long long - +#include "types.h" #include "libdragon.h" -#include "string.h" #include "stdlib.h" - +#include "string.h" #define CIC_6101 1 #define CIC_6102 2 @@ -38,115 +23,113 @@ #define CIC_6106 6 #define CIC_5167 7 -#define REGION_PAL 0 -#define REGION_NTSC 1 -#define REGION_MPAL 2 - -#define KSEG0 0x80000000 -#define KSEG1 0xA0000000 - -#define VI_BASE_REG 0x04400000 -#define VI_CONTROL (VI_BASE_REG + 0x00) -#define VI_FRAMEBUFFER (VI_BASE_REG + 0x04) -#define VI_WIDTH (VI_BASE_REG + 0x08) -#define VI_V_INT (VI_BASE_REG + 0x0C) -#define VI_CUR_LINE (VI_BASE_REG + 0x10) -#define VI_TIMING (VI_BASE_REG + 0x14) -#define VI_V_SYNC (VI_BASE_REG + 0x18) -#define VI_H_SYNC (VI_BASE_REG + 0x1C) -#define VI_H_SYNC2 (VI_BASE_REG + 0x20) -#define VI_H_LIMITS (VI_BASE_REG + 0x24) -#define VI_COLOR_BURST (VI_BASE_REG + 0x28) -#define VI_H_SCALE (VI_BASE_REG + 0x2C) -#define VI_VSCALE (VI_BASE_REG + 0x30) - -#define PI_BSD_DOM1_LAT_REG (PI_BASE_REG+0x14) -#define PI_BSD_DOM1_PWD_REG (PI_BASE_REG+0x18) -#define PI_BSD_DOM1_PGS_REG (PI_BASE_REG+0x1C) /* page size */ -#define PI_BSD_DOM1_RLS_REG (PI_BASE_REG+0x20) - -#define PI_BSD_DOM2_LAT_REG (PI_BASE_REG+0x24) /* Domain 2 latency */ -#define PI_BSD_DOM2_PWD_REG (PI_BASE_REG+0x28) /* pulse width */ -#define PI_BSD_DOM2_PGS_REG (PI_BASE_REG+0x2C) /* page size */ -#define PI_BSD_DOM2_RLS_REG (PI_BASE_REG+0x30) /* release duration */ - -#define PHYS_TO_K1(x) ((u32)(x)|KSEG1) /* physical to kseg1 */ -#define IO_WRITE(addr,data) (*(vu32 *)PHYS_TO_K1(addr)=(u32)(data)) -#define IO_READ(addr) (*(vu32 *)PHYS_TO_K1(addr)) - -#define PI_STATUS_REG (PI_BASE_REG+0x10) -#define PI_BASE_REG 0x04600000 - -#define VI_BASE_REG 0x04400000 -#define VI_STATUS_REG (VI_BASE_REG+0x00) -#define VI_CONTROL_REG VI_STATUS_REG -#define VI_CURRENT_REG (VI_BASE_REG+0x10) +#define REGION_PAL 0 +#define REGION_NTSC 1 +#define REGION_MPAL 2 + +#define KSEG0 0x80000000 +#define KSEG1 0xA0000000 + +#define VI_BASE_REG 0x04400000 +#define VI_CONTROL (VI_BASE_REG + 0x00) +#define VI_FRAMEBUFFER (VI_BASE_REG + 0x04) +#define VI_WIDTH (VI_BASE_REG + 0x08) +#define VI_V_INT (VI_BASE_REG + 0x0C) +#define VI_CUR_LINE (VI_BASE_REG + 0x10) +#define VI_TIMING (VI_BASE_REG + 0x14) +#define VI_V_SYNC (VI_BASE_REG + 0x18) +#define VI_H_SYNC (VI_BASE_REG + 0x1C) +#define VI_H_SYNC2 (VI_BASE_REG + 0x20) +#define VI_H_LIMITS (VI_BASE_REG + 0x24) +#define VI_COLOR_BURST (VI_BASE_REG + 0x28) +#define VI_H_SCALE (VI_BASE_REG + 0x2C) +#define VI_VSCALE (VI_BASE_REG + 0x30) + +#define PI_BSD_DOM1_LAT_REG (PI_BASE_REG + 0x14) +#define PI_BSD_DOM1_PWD_REG (PI_BASE_REG + 0x18) +#define PI_BSD_DOM1_PGS_REG (PI_BASE_REG + 0x1C) /* page size */ +#define PI_BSD_DOM1_RLS_REG (PI_BASE_REG + 0x20) + +#define PI_BSD_DOM2_LAT_REG (PI_BASE_REG + 0x24) /* Domain 2 latency */ +#define PI_BSD_DOM2_PWD_REG (PI_BASE_REG + 0x28) /* pulse width */ +#define PI_BSD_DOM2_PGS_REG (PI_BASE_REG + 0x2C) /* page size */ +#define PI_BSD_DOM2_RLS_REG (PI_BASE_REG + 0x30) /* release duration */ + +#define PHYS_TO_K1(x) ((u32)(x) | KSEG1) /* physical to kseg1 */ +#define IO_WRITE(addr, data) (*(vu32 *)PHYS_TO_K1(addr) = (u32)(data)) +#define IO_READ(addr) (*(vu32 *)PHYS_TO_K1(addr)) + +#define PI_STATUS_REG (PI_BASE_REG + 0x10) +#define PI_BASE_REG 0x04600000 + +#define VI_BASE_REG 0x04400000 +#define VI_STATUS_REG (VI_BASE_REG + 0x00) +#define VI_CONTROL_REG VI_STATUS_REG +#define VI_CURRENT_REG (VI_BASE_REG + 0x10) #define RGB(r, g, b) ((r << 11) | (g << 6) | (b << 1)) typedef struct { - vu32 region; - vu32 rom_type; - vu32 base_addr; - vu32 rst_type; - vu32 cic_type; - vu32 os_ver; - vu32 ram_size; - vu32 app_buff; + vu32 region; + vu32 rom_type; + vu32 base_addr; + vu32 rst_type; + vu32 cic_type; + vu32 os_ver; + vu32 ram_size; + vu32 app_buff; } BootStrap; typedef struct { - u32 w; - u32 h; - u32 pixel_w; - u32 pixel_h; - u32 char_h; - u32 buff_len; - u32 buff_sw; - u16 * buff[2]; - u16 *current; - u16 *bgr_ptr; + u32 w; + u32 h; + u32 pixel_w; + u32 pixel_h; + u32 char_h; + u32 buff_len; + u32 buff_sw; + u16 *buff[2]; + u16 *current; + u16 *bgr_ptr; } Screen; -#define G_SCREEN_W 40 //screen.w -#define G_SCREEN_H 30 //screen.h - - -void sysInit(); -void sysPI_rd(void *ram, unsigned long pi_address, unsigned long len); -void sysPI_wr(void *ram, unsigned long pi_address, unsigned long len); - - - -#define G_SCREEN_W 40 //screen.w -#define G_SCREEN_H 30 //screen.h -#define G_BORDER_X 2 -#define G_BORDER_Y 2 -#define G_MAX_STR_LEN (G_SCREEN_W - G_BORDER_X*2) - -#define PAL_B1 0x1000 -#define PAL_B2 0x2000 -#define PAL_B3 0x3000 -#define PAL_G1 0x1400 -#define PAL_G2 0x2400 -#define PAL_G3 0x3400 - -#define PAL_BR 0x5000 -#define PAL_BG 0x6000 -#define PAL_WG 0x1700 -#define PAL_RB 0x0500 - -void gCleanScreen(); -void gConsPrint(u8 *str); -void gSetXY(u8 x, u8 y); -void gSetPal(u16 pal); -void gAppendString(u8 *str); -void gAppendChar(u8 chr); -void gAppendHex8(u8 val); -void gAppendHex16(u16 val); -void gAppendHex32(u32 val); -void gAppendHex32(u32 val); -void gRepaint(); -void gVsync(); - -#endif /* SYS_H */ +void sys_n64_init(); +void sys_n64_pi_read(void *ram, unsigned long pi_address, unsigned long len); +void sys_n64_pi_write(void *ram, unsigned long pi_address, unsigned long len); + +#define TV_SCREEN_W 40 /* screen width (horizontal) */ +#define TV_SCREEN_H 30 /* screen height (vertical) */ +#define G_BORDER_X 2 +#define G_BORDER_Y 2 +#define G_MAX_STR_LEN (TV_SCREEN_W - G_BORDER_X * 2) + +#define REGION_PAL_B1 0x1000 +#define REGION_PAL_B2 0x2000 +#define REGION_PAL_B3 0x3000 +#define REGION_PAL_G1 0x1400 +#define REGION_PAL_G2 0x2400 +#define REGION_PAL_G3 0x3400 + +#define REGION_PAL_BR 0x5000 +#define REGION_PAL_BG 0x6000 +#define REGION_PAL_WG 0x1700 +#define REGION_PAL_RB 0x0500 + +void screen_clear(); +void screen_print(u8 *str); +void screen_set_xy_pos(u8 x, u8 y); +void screen_set_pal(u16 pal); +void screen_append_str_print(u8 *str); +void screen_append_char_print(u8 chr); +void screen_append_hex8_print(u8 val); +void screen_append_hex16_print(u16 val); +void screen_append_hex32_print(u32 val); +void screen_append_hex32_print(u32 val); +void screen_repaint(); +void screen_vsync(); + +#ifdef __cplusplus +} +#endif + +#endif /* SYS_H */ diff --git a/ED64-XIO/inc/types.h b/ED64-XIO/inc/types.h new file mode 100644 index 00000000..0f159f82 --- /dev/null +++ b/ED64-XIO/inc/types.h @@ -0,0 +1,32 @@ +/* +* Copyright (c) Krikzz and Contributors. +* See LICENSE file in the project root for full license information. +*/ + +#ifndef ED64_TYPES_H +#define ED64_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define u8 unsigned char +#define u16 unsigned short +#define u32 unsigned long +#define u64 unsigned long long + +#define vu8 volatile unsigned char +#define vu16 volatile unsigned short +#define vu32 volatile unsigned long +#define vu64 volatile unsigned long long + +#define s8 signed char +#define s16 short +#define s32 long +#define s64 long long + +#ifdef __cplusplus +} +#endif + +#endif /*ED64_TYPES_H */ \ No newline at end of file diff --git a/ED64-XIO/src/bios.c b/ED64-XIO/src/bios.c index 1525371c..a69d4f91 100644 --- a/ED64-XIO/src/bios.c +++ b/ED64-XIO/src/bios.c @@ -1,4 +1,7 @@ - +/* +* Copyright (c) Krikzz and Contributors. +* See LICENSE file in the project root for full license information. +*/ #include "bios.h" @@ -84,105 +87,163 @@ #define REG_ADDR(reg) (KSEG1 | REG_BASE | (reg)) -u32 bi_reg_rd(u16 reg); -void bi_reg_wr(u16 reg, u32 val); -void bi_usb_init(); -u8 bi_usb_busy(); +u32 ed64_bios_register_read(u16 reg); +void ed64_bios_register_write(u16 reg, u32 val); +void ed64_bios_usb_init(); +u8 ed64_bios_usb_busy(); + +u16 ed64_bios_sd_cfg; -u16 bi_sd_cfg; -void bi_init() { +/** + * @brief Initializes the ED64 cart + * + * @return 0 on successful or a other value on failure. (will probably just hang on failure!) + */ +void ed64_bios_init() { - //setup n64 bus timings for better performance + /* setup n64 bus timings for better performance */ IO_WRITE(PI_BSD_DOM1_LAT_REG, 0x04); IO_WRITE(PI_BSD_DOM1_PWD_REG, 0x0C); - //unlock regs - bi_reg_wr(REG_KEY, 0xAA55); + /* unlock regs */ + ed64_bios_register_write(REG_KEY, 0xAA55); - bi_reg_wr(REG_SYS_CFG, 0); + ed64_bios_register_write(REG_SYS_CFG, 0); - //flush usb - bi_usb_init(); + /* flush usb */ + ed64_bios_usb_init(); - bi_sd_cfg = 0; - bi_reg_wr(REG_SD_STATUS, bi_sd_cfg); + ed64_bios_sd_cfg = 0; + ed64_bios_register_write(REG_SD_STATUS, ed64_bios_sd_cfg); - //turn off backup ram - bi_game_cfg_set(SAVE_OFF); -} + /* turn off backup ram */ + ed64_bios_rom_savetype_set(ED64_SAVE_OFF); -void bi_reg_wr(u16 reg, u32 val) { + /* Always successful for now */ + return 0; +} - sysPI_wr(&val, REG_ADDR(reg), 4); +/** + * @brief Write a register to the ED64 + * + * @param[in] reg + * The register to write to + * @param[in] val + * The value of the register + * + */ +void ed64_bios_register_write(u16 reg, u32 val) { + + sys_n64_pi_write(&val, REG_ADDR(reg), 4); } -u32 bi_reg_rd(u16 reg) { +/** + * @brief Read a register from the ED64 + * + * @return Value of the register + */ +u32 ed64_bios_register_read(u16 reg) { u32 val; - sysPI_rd(&val, REG_ADDR(reg), 4); + sys_n64_pi_read(&val, REG_ADDR(reg), 4); return val; } -void bi_usb_init() { + +/****************************************************************************** +* USB functions +******************************************************************************/ + +/** + * @brief Initialize the USB CDC hardware + * + * @return 0 on successful or an error value on failure + */ +void ed64_bios_usb_init() { u8 buff[512]; u8 resp; - bi_reg_wr(REG_USB_CFG, USB_CMD_RD_NOP); //turn off usb r/w activity + ed64_bios_register_write(REG_USB_CFG, USB_CMD_RD_NOP); /* turn off usb r/w activity */ - //flush fifo buffer - while (bi_usb_can_rd()) { - resp = bi_usb_rd(buff, 512); + /* flush fifo buffer */ + while (ed64_bios_usb_can_read()) { + resp = ed64_bios_usb_read(buff, 512); if (resp)break; } } -u8 bi_usb_can_rd() { +/** + * @brief Checks if USB CDC is available for read + * + * @return 0 on successful or 1 on failure + */ +u8 ed64_bios_usb_can_read() { - u32 status = bi_reg_rd(REG_USB_CFG) & (USB_STA_PWR | USB_STA_RXF); + u32 status = ed64_bios_register_read(REG_USB_CFG) & (USB_STA_PWR | USB_STA_RXF); if (status == USB_STA_PWR)return 1; return 0; } -u8 bi_usb_can_wr() { +/** + * @brief Checks if USB CDC is available for write + * + * @return 0 on successful or 1 on failure + */ +u8 ed64_bios_usb_can_write() { - u32 status = bi_reg_rd(REG_USB_CFG) & (USB_STA_PWR | USB_STA_TXE); + u32 status = ed64_bios_register_read(REG_USB_CFG) & (USB_STA_PWR | USB_STA_TXE); if (status == USB_STA_PWR)return 1; return 0; } -u8 bi_usb_busy() { +/** + * @brief Checks if USB CDC is busy + * + * @return 0 on successful or other value on failure + */ +u8 ed64_bios_usb_busy() { u32 tout = 0; - while ((bi_reg_rd(REG_USB_CFG) & USB_STA_ACT) != 0) { + while ((ed64_bios_register_read(REG_USB_CFG) & USB_STA_ACT) != 0) { if (tout++ != 8192)continue; - bi_reg_wr(REG_USB_CFG, USB_CMD_RD_NOP); - return BI_ERR_USB_TOUT; + ed64_bios_register_write(REG_USB_CFG, USB_CMD_RD_NOP); + return ED64_ERR_USB_TOUT; } return 0; } -u8 bi_usb_rd(void *dst, u32 len) { +/** + * @brief Reads from USB (CDC) + * + * @param[in] dst + * Destination pointer to copy to + * @param[in] len + * Length in bytes to copy + * + * @return 0 on successful or other value on failure + */ +u8 ed64_bios_usb_read(void *dst, u32 len) { u8 resp = 0; u16 blen, baddr; while (len) { - blen = 512; //rx block len + blen = 512; /* rx block len */ if (blen > len)blen = len; - baddr = 512 - blen; //address in fpga internal buffer. requested data length equal to 512-int buffer addr + baddr = 512 - blen; /* address in fpga internal buffer. requested data length equal to 512-int buffer addr */ - bi_reg_wr(REG_USB_CFG, USB_CMD_RD | baddr); //usb read request. fpga will receive usb bytes until the buffer address reaches 512 + ed64_bios_register_write(REG_USB_CFG, USB_CMD_RD | baddr); /* usb read request. fpga will receive usb bytes until the buffer address reaches 512 */ - resp = bi_usb_busy(); //wait until requested data amount will be transferred to the internal buffer - if (resp)break; //timeout + resp = ed64_bios_usb_busy(); /* wait until requested data amount will be transferred to the internal buffer */ + if (resp)break; /* timeout */ - sysPI_rd(dst, REG_ADDR(REG_USB_DAT + baddr), blen); //get data from internal buffer + sys_n64_pi_read(dst, REG_ADDR(REG_USB_DAT + baddr), blen); /* get data from internal buffer */ dst += blen; len -= blen; @@ -191,26 +252,36 @@ u8 bi_usb_rd(void *dst, u32 len) { return resp; } -u8 bi_usb_wr(void *src, u32 len) { +/** + * @brief Writes to USB (CDC) + * + * @param[in] src + * Source pointer to copy from + * @param[in] len + * Length in bytes to copy + * + * @return 0 on successful or other value on failure + */ +u8 ed64_bios_usb_write(void *src, u32 len) { u8 resp = 0; u16 blen, baddr; - bi_reg_wr(REG_USB_CFG, USB_CMD_WR_NOP); + ed64_bios_register_write(REG_USB_CFG, USB_CMD_WR_NOP); while (len) { - blen = 512; //tx block len + blen = 512; /* tx block len */ if (blen > len)blen = len; - baddr = 512 - blen; //address in fpga internal buffer. data length equal to 512-int buffer addr + baddr = 512 - blen; /* address in fpga internal buffer. data length equal to 512-int buffer addr */ - sysPI_wr(src, REG_ADDR(REG_USB_DAT + baddr), blen); //copy data to the internal buffer + sys_n64_pi_write(src, REG_ADDR(REG_USB_DAT + baddr), blen); /* copy data to the internal buffer */ src += 512; - bi_reg_wr(REG_USB_CFG, USB_CMD_WR | baddr); //usb write request + ed64_bios_register_write(REG_USB_CFG, USB_CMD_WR | baddr); /* usb write request */ - resp = bi_usb_busy(); //wait until the requested data amount is transferred - if (resp)break; //timeout + resp = ed64_bios_usb_busy(); /* wait until the requested data amount is transferred */ + if (resp)break; /* timeout */ len -= blen; } @@ -218,90 +289,153 @@ u8 bi_usb_wr(void *src, u32 len) { return resp; } -void bi_usb_rd_start() { +/** + * @brief Starts read from USB (CDC) + * + */ +void ed64_bios_usb_read_start() { - bi_reg_wr(REG_USB_CFG, USB_CMD_RD | 512); + ed64_bios_register_write(REG_USB_CFG, USB_CMD_RD | 512); } -u8 bi_usb_rd_end(void *dst) { +/** + * @brief Ends read from USB (CDC) + * + * @return 0 on successful or other value on failure + */ +u8 ed64_bios_usb_read_end(void *dst) { - u8 resp = bi_usb_busy(); + u8 resp = ed64_bios_usb_busy(); if (resp)return resp; - sysPI_rd(dst, REG_ADDR(REG_USB_DAT), 512); + sys_n64_pi_read(dst, REG_ADDR(REG_USB_DAT), 512); return 0; } -//****************************************************************************** sdio -//****************************************************************************** -//****************************************************************************** -void sdCrc16(void *src, u16 *crc_out); - -void bi_sd_speed(u8 speed) { - - if (speed == BI_DISK_SPD_LO) { - bi_sd_cfg &= ~SD_CFG_SPD; +/****************************************************************************** +* sdio functions +******************************************************************************/ +void ed64_bios_sd_crc16(void *src, u16 *crc_out); + +/** + * @brief Sets the SDIO bus speed + * + * @param[in] speed + * the bus speed required + */ +void ed64_bios_sdio_speed(u8 speed) { + + if (speed == ED64_SDIO_SPEED_LOW) { + ed64_bios_sd_cfg &= ~SD_CFG_SPD; } else { - bi_sd_cfg |= SD_CFG_SPD; + ed64_bios_sd_cfg |= SD_CFG_SPD; } - bi_reg_wr(REG_SD_STATUS, bi_sd_cfg); + ed64_bios_register_write(REG_SD_STATUS, ed64_bios_sd_cfg); } -u16 bi_old_sd_mode; -//this function gives time for setting stable values on open bus - -void bi_sd_switch_mode(u16 mode) { - - if (bi_old_sd_mode == mode)return; - bi_old_sd_mode = mode; - u16 old_sd_cfg = bi_sd_cfg; - bi_sd_bitlen(0); - bi_reg_wr(mode, 0xffff); - bi_sd_cfg = old_sd_cfg; - bi_reg_wr(REG_SD_STATUS, old_sd_cfg); +/** + * @brief Depricated: gives time for setting stable values on open bus + * + */ +u16 ed64_bios_old_sd_mode; + +/** + * @brief Switches the SDIO speed + * + * @param[in] mode + * LOW or High + * + */ +void ed64_bios_sd_switch_mode(u16 mode) { + + if (ed64_bios_old_sd_mode == mode)return; + ed64_bios_old_sd_mode = mode; + + u16 old_sd_cfg = ed64_bios_sd_cfg; + ed64_bios_sdio_bitlength(0); + ed64_bios_register_write(mode, 0xffff); + ed64_bios_sd_cfg = old_sd_cfg; + ed64_bios_register_write(REG_SD_STATUS, old_sd_cfg); } -void bi_sd_bitlen(u8 val) { +/** + * @brief Writes the SDIO bit length + * + */ +void ed64_bios_sdio_bitlength(u8 val) { - bi_sd_cfg &= ~SD_CFG_BITLEN; - bi_sd_cfg |= (val & SD_CFG_BITLEN); - bi_reg_wr(REG_SD_STATUS, bi_sd_cfg); + ed64_bios_sd_cfg &= ~SD_CFG_BITLEN; + ed64_bios_sd_cfg |= (val & SD_CFG_BITLEN); + ed64_bios_register_write(REG_SD_STATUS, ed64_bios_sd_cfg); } -void bi_sd_busy() { - while ((bi_reg_rd(REG_SD_STATUS) & SD_STA_BUSY) != 0); +/** + * @brief Checks if the SD Card is busy + * + */ +void ed64_bios_sd_busy() { + while ((ed64_bios_register_read(REG_SD_STATUS) & SD_STA_BUSY) != 0); } -void bi_sd_cmd_wr(u8 val) { - bi_sd_switch_mode(REG_SD_CMD_WR); - bi_reg_wr(REG_SD_CMD_WR, val); - bi_sd_busy(); +/** + * @brief Writes a command to SDIO + * + */ +void ed64_bios_sdio_cmd_write(u8 val) { + ed64_bios_sd_switch_mode(REG_SD_CMD_WR); + ed64_bios_register_write(REG_SD_CMD_WR, val); + ed64_bios_sd_busy(); } -u8 bi_sd_cmd_rd() { - - bi_sd_switch_mode(REG_SD_CMD_RD); - bi_reg_wr(REG_SD_CMD_RD, 0xffff); - bi_sd_busy(); - return bi_reg_rd(REG_SD_CMD_RD); +/** + * @brief Reads a command from SDIO + * + * + * @return the result of the command read + */ +u8 ed64_bios_sdio_cmd_read() { + + ed64_bios_sd_switch_mode(REG_SD_CMD_RD); + ed64_bios_register_write(REG_SD_CMD_RD, 0xffff); + ed64_bios_sd_busy(); + return ed64_bios_register_read(REG_SD_CMD_RD); } -void bi_sd_dat_wr(u8 val) { - bi_sd_switch_mode(REG_SD_DAT_WR); - bi_reg_wr(REG_SD_DAT_WR, 0x00ff | (val << 8)); - //bi_sd_busy(); +/** + * @brief Writes data to SDIO + * + */ +void ed64_bios_sdio_data_write(u8 val) { + ed64_bios_sd_switch_mode(REG_SD_DAT_WR); + ed64_bios_register_write(REG_SD_DAT_WR, 0x00ff | (val << 8)); + //ed64_bios_sd_busy(); } -u8 bi_sd_dat_rd() { - - bi_sd_switch_mode(REG_SD_DAT_RD); - bi_reg_wr(REG_SD_DAT_RD, 0xffff); - //bi_sd_busy(); - return bi_reg_rd(REG_SD_DAT_RD); +/** + * @brief Reads data from SDIO + * + * + * @return the result of the data read + */ +u8 ed64_bios_sd_data_read() { + + ed64_bios_sd_switch_mode(REG_SD_DAT_RD); + ed64_bios_register_write(REG_SD_DAT_RD, 0xffff); + //ed64_bios_sd_busy(); + return ed64_bios_register_read(REG_SD_DAT_RD); } -u8 bi_sd_to_ram(void *dst, u16 slen) { +/** + * @brief Reads memory from the SD card to RAM space + * + * @param[in] dst + * Destination pointer to write to + * @param[in] slen + * Length in bytes to copy + * + */ +u8 ed64_bios_sdio_to_ram(void *dst, u16 slen) { u16 i; u8 crc[8]; @@ -311,9 +445,9 @@ u8 bi_sd_to_ram(void *dst, u16 slen) { while (slen--) { - bi_sd_bitlen(1); + ed64_bios_sdio_bitlength(1); i = 1; - while (bi_sd_dat_rd() != 0xf0) { + while (ed64_bios_sd_data_read() != 0xf0) { i++; if (i == 0) { IO_WRITE(PI_BSD_DOM1_PWD_REG, old_pwd); @@ -321,11 +455,11 @@ u8 bi_sd_to_ram(void *dst, u16 slen) { } } - bi_sd_bitlen(4); + ed64_bios_sdio_bitlength(4); - bi_sd_switch_mode(REG_SD_DAT_RD); - sysPI_rd(dst, REG_ADDR(REG_SDIO_ARD), 512); - sysPI_rd(crc, REG_ADDR(REG_SDIO_ARD), 8); + ed64_bios_sd_switch_mode(REG_SD_DAT_RD); + sys_n64_pi_read(dst, REG_ADDR(REG_SDIO_ARD), 512); + sys_n64_pi_read(crc, REG_ADDR(REG_SDIO_ARD), 8); dst += 512; } @@ -335,16 +469,27 @@ u8 bi_sd_to_ram(void *dst, u16 slen) { return 0; } -u8 bi_sd_to_rom(u32 dst, u16 slen) { + +/** + * @brief Reads memory from the SD card to ROM space + * + * @param[in] dst + * Source pointer to copy from + * @param[in] slen + * Length in bytes to copy + * + * @return 0 on successful or other value on failure + */ +u8 ed64_bios_sdio_to_rom(u32 dst, u16 slen) { u16 resp = DMA_STA_BUSY; - bi_reg_wr(REG_DMA_ADDR, dst); - bi_reg_wr(REG_DMA_LEN, slen); + ed64_bios_register_write(REG_DMA_ADDR, dst); + ed64_bios_register_write(REG_DMA_LEN, slen); - bi_sd_switch_mode(REG_SD_DAT_RD); + ed64_bios_sd_switch_mode(REG_SD_DAT_RD); while ((resp & DMA_STA_BUSY)) { - resp = bi_reg_rd(REG_DMA_STA); + resp = ed64_bios_register_read(REG_DMA_STA); } if ((resp & DMA_STA_ERROR))return 1; @@ -352,29 +497,39 @@ u8 bi_sd_to_rom(u32 dst, u16 slen) { return 0; } -u8 bi_ram_to_sd(void *src, u16 slen) { +/** + * @brief Writes memory from RAM to the SD card + * + * @param[in] src + * Source pointer to copy from + * @param[in] slen + * Length in bytes to copy + * + * @return 0 on successful or other value on failure + */ +u8 ed64_bios_ram_to_sdio(void *src, u16 slen) { u8 resp; u16 crc[4]; while (slen--) { - sdCrc16(src, crc); + ed64_bios_sd_crc16(src, crc); - bi_sd_bitlen(2); - bi_sd_dat_wr(0xff); - bi_sd_dat_wr(0xf0); + ed64_bios_sdio_bitlength(2); + ed64_bios_sdio_data_write(0xff); + ed64_bios_sdio_data_write(0xf0); - bi_sd_bitlen(4); - sysPI_wr(src, REG_ADDR(REG_SDIO_ARD), 512); - sysPI_wr(crc, REG_ADDR(REG_SDIO_ARD), 8); + ed64_bios_sdio_bitlength(4); + sys_n64_pi_write(src, REG_ADDR(REG_SDIO_ARD), 512); + sys_n64_pi_write(crc, REG_ADDR(REG_SDIO_ARD), 8); src += 512; - bi_sd_bitlen(1); - bi_sd_dat_wr(0xff); + ed64_bios_sdio_bitlength(1); + ed64_bios_sdio_data_write(0xff); for (int i = 0;; i++) { - resp = bi_sd_dat_rd(); + resp = ed64_bios_sd_data_read(); if ((resp & 1) == 0)break; if (i == 1024)return 1; } @@ -382,18 +537,18 @@ u8 bi_ram_to_sd(void *src, u16 slen) { resp = 0; for (int i = 0; i < 3; i++) { resp <<= 1; - resp |= bi_sd_dat_rd() & 1; + resp |= ed64_bios_sd_data_read() & 1; } resp &= 7; if (resp != 0x02) { - if (resp == 5)return 2; //crc error + if (resp == 5)return 2; /* crc error */ return 3; } for (int i = 0;; i++) { - if (bi_sd_dat_rd() == 0xff)break; + if (ed64_bios_sd_data_read() == 0xff)break; if (i == 65535)return 4; } } @@ -402,7 +557,15 @@ u8 bi_ram_to_sd(void *src, u16 slen) { return 0; } -void sdCrc16(void *src, u16 *crc_out) { +/** + * @brief CRC for SD + * + * @param[in] src + * Source pointer to read + * @param[out] crc_out + * Destination pointer containing the CRC value + */ +void ed64_bios_sd_crc16(void *src, u16 *crc_out) { u16 i; u16 u; @@ -531,24 +694,42 @@ void sdCrc16(void *src, u16 *crc_out) { } -//****************************************************************************** +/****************************************************************************** +* Misc functions +******************************************************************************/ -void bi_game_cfg_set(u8 type) { +/** + * @brief Sets the save type on the ED64 cart + * + * @param[in] type + * The save type to set + */ +void ed64_bios_rom_savetype_set(u8 type) { - bi_reg_wr(REG_GAM_CFG, type); + ed64_bios_register_write(REG_GAM_CFG, type); } -//swaps bytes copied from SD card. only affects reads to ROM area -void bi_wr_swap(u8 swap_on) { +/** + * @brief Allows swapping bytes copied from SD card. Only affects reads to ROM area + * + * @param[in] swap_on + * Swaps bytes if true + */ +void ed64_bios_write_endian_swap(u8 swap_on) { if (swap_on) { - bi_reg_wr(REG_SYS_CFG, CFG_SWAP_ON); + ed64_bios_register_write(REG_SYS_CFG, CFG_SWAP_ON); } else { - bi_reg_wr(REG_SYS_CFG, 0); + ed64_bios_register_write(REG_SYS_CFG, 0); } } -u32 bi_get_cart_id() { +/** + * @brief Identifies the ED64 cartridge + * + * @return the cartridge ID + */ +u32 ed64_bios_get_cart_id() { - return bi_reg_rd(REG_EDID); + return ed64_bios_register_read(REG_EDID); } diff --git a/ED64-XIO/src/disk.c b/ED64-XIO/src/disk.c index b173e15f..f955c113 100644 --- a/ED64-XIO/src/disk.c +++ b/ED64-XIO/src/disk.c @@ -1,28 +1,32 @@ +/* +* Copyright (c) Krikzz and Contributors. +* See LICENSE file in the project root for full license information. +*/ #include "everdrive.h" -#define CMD0 0x40 // software reset -#define CMD1 0x41 // brings card out of idle state -#define CMD8 0x48 // Reserved -#define CMD12 0x4C // stop transmission on multiple block read -#define CMD17 0x51 // read single block -#define CMD18 0x52 // read multiple block -#define CMD58 0x7A // reads the OCR register +#define CMD0 0x40 /* software reset */ +#define CMD1 0x41 /* brings card out of idle state */ +#define CMD8 0x48 /* Reserved */ +#define CMD12 0x4C /* stop transmission on multiple block read */ +#define CMD17 0x51 /* read single block */ +#define CMD18 0x52 /* read multiple block */ +#define CMD58 0x7A /* reads the OCR register */ #define CMD55 0x77 #define CMD41 0x69 -#define CMD24 0x58 // writes a single block -#define CMD25 0x59 // writes a multi block +#define CMD24 0x58 /* writes a single block */ +#define CMD25 0x59 /* writes a multi block */ #define ACMD41 0x69 #define ACMD6 0x46 #define SD_V2 2 #define SD_HC 1 -#define CMD2 0x42 //read cid -#define CMD3 0x43 //read rca +#define CMD2 0x42 /*read cid */ +#define CMD3 0x43 /*read rca */ #define CMD7 0x47 #define CMD9 0x49 -#define CMD6 0x46 //set hi speed +#define CMD6 0x46 /*set hi speed */ #define R1 1 #define R2 2 @@ -39,19 +43,26 @@ u32 crc7(u8 *buff, u32 len); -u8 diskCmdSD(u8 cmd, u32 arg); -u8 diskReadResp(u8 cmd); -u8 diskOpenRead(u32 saddr); -u8 diskCloseRW(); +u8 sd_disk_cmd(u8 cmd, u32 arg); +u8 sd_disk_read_resp(u8 cmd); +u8 sd_disk_open_read(u32 saddr); +u8 sd_disk_close_rw(); u8 sd_resp_buff[18]; u32 disk_cur_addr; u8 disk_card_type; u8 disk_mode; -//****************************************************************************** disk base +/****************************************************************************** +* sdcard disk base functions +*******************************************************************************/ -u8 diskInit() { +/** + * @brief Initializes the sdcard interface + * + * @return 0 on successful or a other value on failure. + */ +u8 sd_disk_init() { u16 i; volatile u8 resp = 0; @@ -61,16 +72,16 @@ u8 diskInit() { disk_card_type = 0; disk_mode = DISK_MODE_NOP; - bi_sd_speed(BI_DISK_SPD_LO); + ed64_bios_sdio_speed(ED64_SDIO_SPEED_LOW); - bi_sd_bitlen(8); - for (i = 0; i < 40; i++)bi_sd_cmd_wr(0xff); - diskCmdSD(CMD0, 0x1aa); + ed64_bios_sdio_bitlength(8); + for (i = 0; i < 40; i++)ed64_bios_sdio_cmd_write(0xff); + sd_disk_cmd(CMD0, 0x1aa); - for (i = 0; i < 40; i++)bi_sd_cmd_wr(0xff); + for (i = 0; i < 40; i++)ed64_bios_sdio_cmd_write(0xff); - resp = diskCmdSD(CMD8, 0x1aa); + resp = sd_disk_cmd(CMD8, 0x1aa); if (resp != 0 && resp != DISK_ERR_CTO) { @@ -85,10 +96,10 @@ u8 diskInit() { for (i = 0; i < wait_max; i++) { - resp = diskCmdSD(CMD55, 0); + resp = sd_disk_cmd(CMD55, 0); if (resp)return DISK_ERR_INIT; if ((sd_resp_buff[3] & 1) != 1)continue; - resp = diskCmdSD(CMD41, 0x40300000); + resp = sd_disk_cmd(CMD41, 0x40300000); if ((sd_resp_buff[1] & 128) == 0)continue; break; @@ -97,9 +108,9 @@ u8 diskInit() { i = 0; do { - resp = diskCmdSD(CMD55, 0); + resp = sd_disk_cmd(CMD55, 0); if (resp)return DISK_ERR_INIT; - resp = diskCmdSD(CMD41, 0x40300000); + resp = sd_disk_cmd(CMD41, 0x40300000); if (resp)return DISK_ERR_INIT; } while (sd_resp_buff[1] < 1 && i++ < wait_max); @@ -112,40 +123,50 @@ u8 diskInit() { - resp = diskCmdSD(CMD2, 0); + resp = sd_disk_cmd(CMD2, 0); if (resp)return DISK_ERR_INIT; - resp = diskCmdSD(CMD3, 0); + resp = sd_disk_cmd(CMD3, 0); if (resp)return DISK_ERR_INIT; - resp = diskCmdSD(CMD7, 0); + resp = sd_disk_cmd(CMD7, 0); rca = (sd_resp_buff[1] << 24) | (sd_resp_buff[2] << 16) | (sd_resp_buff[3] << 8) | (sd_resp_buff[4] << 0); - resp = diskCmdSD(CMD9, rca); //get csd + resp = sd_disk_cmd(CMD9, rca); /* get csd */ if (resp)return DISK_ERR_INIT; - resp = diskCmdSD(CMD7, rca); + resp = sd_disk_cmd(CMD7, rca); if (resp)return DISK_ERR_INIT; - resp = diskCmdSD(CMD55, rca); + resp = sd_disk_cmd(CMD55, rca); if (resp)return DISK_ERR_INIT; - resp = diskCmdSD(CMD6, 0x02); + resp = sd_disk_cmd(CMD6, 0x02); if (resp)return DISK_ERR_INIT; - bi_sd_speed(BI_DISK_SPD_HI); + ed64_bios_sdio_speed(ED64_SDIO_SPEED_HIGH); return 0; } -u8 diskCmdSD(u8 cmd, u32 arg) { +/** + * @brief Sends an SDIO command + * + * @param[in] cmd + * The command + * @param[in] arg + * The value to write + * + * @return 0 on successful or a other value on failure. + */ +u8 sd_disk_cmd(u8 cmd, u32 arg) { u8 p = 0; @@ -159,49 +180,59 @@ u8 diskCmdSD(u8 cmd, u32 arg) { buff[p++] = (arg >> 0); crc = crc7(buff, 5) | 1; - bi_sd_bitlen(8); + ed64_bios_sdio_bitlength(8); - bi_sd_cmd_wr(0xff); - bi_sd_cmd_wr(cmd); - bi_sd_cmd_wr(arg >> 24); - bi_sd_cmd_wr(arg >> 16); - bi_sd_cmd_wr(arg >> 8); - bi_sd_cmd_wr(arg); - bi_sd_cmd_wr(crc); + ed64_bios_sdio_cmd_write(0xff); + ed64_bios_sdio_cmd_write(cmd); + ed64_bios_sdio_cmd_write(arg >> 24); + ed64_bios_sdio_cmd_write(arg >> 16); + ed64_bios_sdio_cmd_write(arg >> 8); + ed64_bios_sdio_cmd_write(arg); + ed64_bios_sdio_cmd_write(crc); if (cmd == CMD18)return 0; - return diskReadResp(cmd); + return sd_disk_read_resp(cmd); } -u8 diskReadResp(u8 cmd) { + +/** + * @brief Reads the SD card response + * + * @param[in] cmd + * The command to read + * + * @return 0 on successful or a other value on failure. + */ +u8 sd_disk_read_resp(u8 cmd) { u16 i; u8 resp_len = cmd == CMD2 || cmd == CMD9 ? 17 : 6; i = 0; - sd_resp_buff[0] = bi_sd_cmd_rd(); - bi_sd_bitlen(1); + sd_resp_buff[0] = ed64_bios_sdio_cmd_read(); + ed64_bios_sdio_bitlength(1); - while ((sd_resp_buff[0] & 0xC0) != 0) {//wait for resp begin. first two bits should be zeros - sd_resp_buff[0] = bi_sd_cmd_rd(); + while ((sd_resp_buff[0] & 0xC0) != 0) { /* wait for resp begin. first two bits should be zeros */ + sd_resp_buff[0] = ed64_bios_sdio_cmd_read(); if (i++ == DISK_CMD_TOUT)return DISK_ERR_CTO; } - bi_sd_bitlen(8); + ed64_bios_sdio_bitlength(8); for (i = 1; i < resp_len; i++) { - sd_resp_buff[i] = bi_sd_cmd_rd(); //8 + sd_resp_buff[i] = ed64_bios_sdio_cmd_read(); //8 } return 0; } + u32 crc7(u8 *buff, u32 len) { u32 a, crc = 0; @@ -217,17 +248,27 @@ u32 crc7(u8 *buff, u32 len) { return (crc & 0xfe); } -//****************************************************************************** read op +/****************************************************************************** +* sdcard read functions +*******************************************************************************/ -u8 diskOpenRead(u32 saddr) { +/** + * @brief Reads the SD card + * + * @param[in] saddr + * The start memory address + * + * @return 0 on successful or a other value on failure. + */ +u8 sd_disk_open_read(u32 saddr) { u8 resp; if (disk_mode == DISK_MODE_RD && saddr == disk_cur_addr)return 0; - diskCloseRW(); + sd_disk_close_rw(); disk_cur_addr = saddr; if ((disk_card_type & SD_HC) == 0)saddr *= 512; - resp = diskCmdSD(CMD18, saddr); + resp = sd_disk_cmd(CMD18, saddr); if (resp)return resp; disk_mode = DISK_MODE_RD; @@ -235,81 +276,141 @@ u8 diskOpenRead(u32 saddr) { return 0; } -u8 diskReadToRam(u32 sd_addr, void *dst, u16 slen) { +/** + * @brief Reads the SD card to RAM + * + * @param[in] dst + * destination pointer to copy to + * + * @param[in] saddr + * The start memory address + * + * @param[in] slen + * Length in bytes to copy + * + * @return 0 on successful or a other value on failure. + */ +u8 sd_disk_read_to_ram(u32 sd_addr, void *dst, u16 slen) { u8 resp = 0; - resp = diskOpenRead(sd_addr); + resp = sd_disk_open_read(sd_addr); if (resp)return DISK_ERR_RD1; disk_cur_addr += slen; - resp = bi_sd_to_ram(dst, slen); + resp = ed64_bios_sdio_to_ram(dst, slen); if (resp)return DISK_ERR_RD2; return 0; } -u8 diskReadToRom(u32 sd_addr, u32 dst, u16 slen) { +/** + * @brief Reads the SD card to ROM + * + * @param[in] dst + * destination pointer to copy to + * + * @param[in] saddr + * The start memory address + * + * @param[in] slen + * Length in bytes to copy + * + * @return 0 on successful or a other value on failure. + */ +u8 sd_disk_read_to_rom(u32 sd_addr, u32 dst, u16 slen) { u8 resp = 0; - resp = diskOpenRead(sd_addr); + resp = sd_disk_open_read(sd_addr); if (resp)return DISK_ERR_RD1; disk_cur_addr += slen; - resp = bi_sd_to_rom(dst, slen); + resp = ed64_bios_sdio_to_rom(dst, slen); if (resp)return DISK_ERR_RD2; return 0; } -u8 diskRead(void *dst, u32 saddr, u32 slen) { +/** + * @brief Reads the SD card + * + * @param[in] dst + * destination pointer to copy to + * + * @param[in] saddr + * The start memory address + * + * @param[in] slen + * Length in bytes to copy + * + * @return 0 on successful or a other value on failure. + */ +u8 sd_disk_read(void *dst, u32 saddr, u32 slen) { if (((u32) dst & 0x1FFFFFFF) < 0x800000) { - return diskReadToRam(saddr, dst, slen); + return sd_disk_read_to_ram(saddr, dst, slen); } else { - return diskReadToRom(saddr, ((u32) dst) & 0x3FFFFFF, slen); + return sd_disk_read_to_rom(saddr, ((u32) dst) & 0x3FFFFFF, slen); } } -//****************************************************************************** var -u8 diskCloseRW() { +/****************************************************************************** +* sdcard var functions +*******************************************************************************/ + +/** + * @brief Closes the SD card + * + * @return 0 on successful or a other value on failure. + */ +u8 sd_disk_close_rw() { u8 resp; u16 i; if (disk_mode == DISK_MODE_NOP)return 0; - resp = diskCmdSD(CMD12, 0); + resp = sd_disk_cmd(CMD12, 0); disk_mode = DISK_MODE_NOP; if (resp)return resp; - bi_sd_bitlen(1); - bi_sd_dat_rd(); - bi_sd_dat_rd(); - bi_sd_dat_rd(); - bi_sd_bitlen(2); + ed64_bios_sdio_bitlength(1); + ed64_bios_sd_data_read(); + ed64_bios_sd_data_read(); + ed64_bios_sd_data_read(); + ed64_bios_sdio_bitlength(2); i = 65535; while (--i) { - if (bi_sd_dat_rd() == 0xff)break; + if (ed64_bios_sd_data_read() == 0xff)break; } return 0; } -//****************************************************************************** write op +/****************************************************************************** +* sdcard write functions +*******************************************************************************/ -u8 diskOpenWrite(u32 saddr) { +/** + * @brief Writes to the SD card + * + * @param[in] saddr + * The start memory address + * + * @return 0 on successful or a other value on failure. + */ +u8 sd_disk_open_write(u32 saddr) { u8 resp; if (disk_mode == DISK_MODE_WR && saddr == disk_cur_addr)return 0; - diskCloseRW(); + sd_disk_close_rw(); disk_cur_addr = saddr; if ((disk_card_type & SD_HC) == 0)saddr *= 512; - resp = diskCmdSD(CMD25, saddr); + resp = sd_disk_cmd(CMD25, saddr); if (resp)return resp; disk_mode = DISK_MODE_WR; @@ -317,18 +418,30 @@ u8 diskOpenWrite(u32 saddr) { return 0; } -u8 diskWrite(void *src, u32 saddr, u32 slen) { +/** + * @brief Writes to the SD card + * + * @param[in] src + * Source pointer to copy from + * + * @param[in] saddr + * The start memory address + * + * @param[in] slen + * Length in bytes to copy + * + * @return 0 on successful or a other value on failure. + */ +u8 sd_disk_write(void *src, u32 saddr, u32 slen) { u8 resp; - resp = diskOpenWrite(saddr); + resp = sd_disk_open_write(saddr); if (resp)return DISK_ERR_WR1; disk_cur_addr += slen; - resp = bi_ram_to_sd(src, slen); + resp = ed64_bios_ram_to_sdio(src, slen); if (resp)return DISK_ERR_WR2; return 0; } - -//****************************************************************************** diff --git a/ED64-XIO/src/fileio.c b/ED64-XIO/src/fileio.c new file mode 100644 index 00000000..c454be7c --- /dev/null +++ b/ED64-XIO/src/fileio.c @@ -0,0 +1,115 @@ +/* +* Copyright (c) Krikzz and Contributors. +* See LICENSE file in the project root for full license information. +*/ + +#include "everdrive.h" + +u8 fm_file_read() { + + u8 *path = "ED64/OS64.v64"; /* this file is garanteed to exist! */ + struct controller_data cd; + u8 buff[256]; + FIL f; + UINT br; + u8 resp; + + screen_clear(); + screen_repaint(); + + + resp = f_open(&f, path, FA_READ); + if (resp)return resp; + + resp = f_read(&f, buff, sizeof (buff), &br); + if (resp)return resp; + + resp = f_close(&f); + if (resp)return resp; + + + screen_clear(); + screen_print("Read 256 bytes from file: "); + screen_print("\"SD:/"); + screen_append_str_print(path); + screen_append_str_print("\""); + screen_print(""); + screen_print(""); + for (int i = 0; i < sizeof (buff); i++) { + if (i % 16 == 0)screen_print(""); + screen_append_hex8_print(buff[i]); + } + screen_print(""); + screen_print(""); + screen_print("Press (B) to exit"); + + + screen_repaint(); + for ( ;; ) { /* forever [equivalent to: "while (1)"] */ + screen_vsync(); + controller_scan(); + cd = get_keys_down(); + + if (cd.c[0].B) { + break; + } + } + + return 0; +} + +u8 fm_file_write() { + + u8 *path = "test.txt"; + u8 *msg = "This is an example to show text can be written to a file!"; + struct controller_data cd; + FIL f; + UINT bw; + u8 resp; + u32 str_len; + + screen_clear(); + screen_repaint(); + + for (str_len = 0; msg[str_len] != 0; str_len++); + + resp = f_open(&f, path, FA_WRITE | FA_CREATE_ALWAYS); + if (resp)return resp; + + resp = f_write(&f, msg, str_len, &bw); + if (resp)return resp; + + resp = f_close(&f); + if (resp)return resp; + + + screen_clear(); + screen_print("Sucessfully written the text: "); + screen_print(""); + screen_print("\""); + screen_append_str_print(msg); + screen_append_str_print("\""); + screen_print(""); + screen_print(""); + screen_print("To the file: "); + screen_print("\"SD:/"); + screen_append_str_print(path); + screen_append_str_print("\""); + screen_print(""); + screen_print(""); + screen_print(""); + screen_print("Press (B) to exit"); + + screen_repaint(); + for ( ;; ) { /* forever [equivalent to: "while (1)"] */ + screen_vsync(); + controller_scan(); + cd = get_keys_down(); + + if (cd.c[0].B) { + break; + } + } + + return 0; +} \ No newline at end of file diff --git a/ED64-XIO/src/fmanager.c b/ED64-XIO/src/fmanager.c index df368066..a1ad044d 100644 --- a/ED64-XIO/src/fmanager.c +++ b/ED64-XIO/src/fmanager.c @@ -1,42 +1,46 @@ +/* +* Copyright (c) Krikzz and Contributors. +* See LICENSE file in the project root for full license information. +*/ #include "everdrive.h" -u8 fmLoadDir(u8 *path, FILINFO *inf, u32 max_items); -u8 fmLoadGame(u8 *path); +u8 fm_load_dir(u8 *path, FILINFO *inf, u32 max_items); +u8 fm_load_rom(u8 *path); #define MAX_DIR_SIZE 20 #define MAX_STR_LEN 36 -u8 fmanager() { +u8 fmanager_display() { FILINFO inf[MAX_DIR_SIZE]; u32 selector = 0; struct controller_data cd; u8 resp; - //open root dir - resp = fmLoadDir("", inf, MAX_DIR_SIZE); + /* open root dir */ + resp = fm_load_dir("", inf, MAX_DIR_SIZE); if (resp)return resp; - while (1) { + for ( ;; ) { /* forever [equivalent to: "while (1)"] */ - //print items - gCleanScreen(); + /* print items */ + screen_clear(); for (int i = 0; i < MAX_DIR_SIZE && inf[i].fname[0]; i++) { - gConsPrint(selector == i ? ">" : " "); + screen_print(selector == i ? ">" : " "); u8 tmp = inf[i].fname[MAX_STR_LEN]; - inf[i].fname[MAX_STR_LEN] = 0; //make sure that the printed string doesn't exceed max len - gAppendString(inf[i].fname); + inf[i].fname[MAX_STR_LEN] = 0; /* make sure that the printed string doesn't exceed max len */ + screen_append_str_print(inf[i].fname); inf[i].fname[MAX_STR_LEN] = tmp; } - gRepaint(); + screen_repaint(); - //controls - while (1) { + /* controls */ + for ( ;; ) { /* forever [equivalent to: "while (1)"] */ - gVsync(); + screen_vsync(); controller_scan(); cd = get_keys_down(); @@ -54,15 +58,15 @@ u8 fmanager() { if (cd.c[0].A && !(inf[selector].fattrib & AM_DIR)) { - gCleanScreen(); - gConsPrint("loading..."); - gRepaint(); + screen_clear(); + screen_print("loading..."); + screen_repaint(); - resp = fmLoadGame(inf[selector].fname); + resp = fm_load_rom(inf[selector].fname); if (resp)return resp; - bi_game_cfg_set(SAVE_EEP16K); //set save type - boot_simulator(CIC_6102); //run the game + ed64_bios_rom_savetype_set(ED64_SAVE_EEP16K); /* set save type */ + rom_boot_simulator(CIC_6102); /* run the ROM */ } } } @@ -70,7 +74,7 @@ u8 fmanager() { return 0; } -u8 fmLoadDir(u8 *path, FILINFO *inf, u32 max_items) { +u8 fm_load_dir(u8 *path, FILINFO *inf, u32 max_items) { u8 resp; DIR dir; @@ -83,7 +87,7 @@ u8 fmLoadDir(u8 *path, FILINFO *inf, u32 max_items) { resp = f_readdir(&dir, &inf[i]); if (resp)return resp; - if (inf[i].fname[0] == 0)break; //no directory items anymore + if (inf[i].fname[0] == 0)break; /* no directory items anymore */ } resp = f_closedir(&dir); @@ -92,7 +96,7 @@ u8 fmLoadDir(u8 *path, FILINFO *inf, u32 max_items) { return 0; } -u8 fmLoadGame(u8 *path) { +u8 fm_load_rom(u8 *path) { FIL f; u8 resp; @@ -105,7 +109,7 @@ u8 fmLoadGame(u8 *path) { fsize = f.obj.objsize - f.fptr; - //read rom header + /* read rom header */ resp = f_read(&f, header, sizeof (header), &br); if (resp)return resp; @@ -114,16 +118,16 @@ u8 fmLoadGame(u8 *path) { if (resp)return resp; if (header[1] == 0x80) { - //enable byte swapping for disk operations if rom image has swapped byte order - //affects only reading to ROM address space - bi_wr_swap(1); + /* enable byte swapping for disk operations if rom image has swapped byte order + affects only reading to ROM address space */ + ed64_bios_write_endian_swap(1); } - //warning! file can be read directly to rom but not to bram - resp = f_read(&f, (void *) BI_ADDR_ROM, fsize, &br); + /* warning! file can be read directly to rom but not to bram */ + resp = f_read(&f, (void *) ED64_ADDR_ROM, fsize, &br); if (resp)return resp; - bi_wr_swap(0); + ed64_bios_write_endian_swap(0); if (resp)return resp; resp = f_close(&f); diff --git a/ED64-XIO/src/main.c b/ED64-XIO/src/main.c index cde25ee5..78920243 100644 --- a/ED64-XIO/src/main.c +++ b/ED64-XIO/src/main.c @@ -1,37 +1,40 @@ - +/* +* Copyright (c) Krikzz and Contributors. +* See LICENSE file in the project root for full license information. +*/ #include "everdrive.h" -void edid(); -void printError(u8 err); -u8 demoMenu(); +void main_display_edid(); +void main_display_error(u8 err); +u8 main_display_menu(); int main(void) { u8 resp; FATFS fs; - sysInit(); - bi_init(); + sys_n64_init(); + ed64_bios_init(); - gCleanScreen(); - gConsPrint("FAT init..."); - gRepaint(); + screen_clear(); + screen_print("File system initilizing..."); + screen_repaint(); - //mount disk + /* mount disk */ memset(&fs, 0, sizeof (fs)); resp = f_mount(&fs, "", 1); - if (resp)printError(resp); + if (resp)main_display_error(resp); - while (1) { - resp = demoMenu(); - if (resp)printError(resp); + for ( ;; ) { /* forever [equivalent to: "while (1)"] */ + resp = main_display_menu(); + if (resp)main_display_error(resp); } } -u8 demoMenu() { +u8 main_display_menu() { enum { MENU_FILE_MANAGER, @@ -48,28 +51,28 @@ u8 demoMenu() { u32 selector = 0; u8 resp; - menu[MENU_FILE_MANAGER] = "File Manager"; - menu[MENU_FILE_READ] = "File Read"; - menu[MENU_FILE_WRITE] = "File Write"; + menu[MENU_FILE_MANAGER] = "File Explorer"; + menu[MENU_FILE_READ] = "File Read (\"SD:/ED64/OS64.v64\")"; + menu[MENU_FILE_WRITE] = "File Write (\"SD:/test.txt\")"; menu[MENU_USB_TERMINAL] = "USB Terminal"; - menu[MENU_USB_LOADER] = "USB Loader"; - menu[MENU_EDID] = "EverDrive ID"; + menu[MENU_USB_LOADER] = "USB ROM Loader"; + menu[MENU_EDID] = "ED64 Hardware Rev ID"; - while (1) { + for ( ;; ) { /* forever [equivalent to: "while (1)"] */ - gCleanScreen(); + screen_clear(); for (int i = 0; i < MENU_SIZE; i++) { - gConsPrint(" "); + screen_print(" "); if (i == selector) { - gAppendString(">"); + screen_append_str_print(">"); } else { - gAppendString(" "); + screen_append_str_print(" "); } - gAppendString(menu[i]); + screen_append_str_print(menu[i]); } - gRepaint(); + screen_repaint(); controller_scan(); cd = get_keys_down(); @@ -83,80 +86,79 @@ u8 demoMenu() { if (!cd.c[0].A)continue; - //browse files in root dir and launch the game + /* browse files in root dir and launch the ROM */ if (selector == MENU_FILE_MANAGER) { - resp = fmanager(); + resp = fmanager_display(); if (resp)return resp; } - //read data from file + /* read data from file */ if (selector == MENU_FILE_READ) { - resp = fileRead(); + resp = fm_file_read(); if (resp)return resp; } - //write string to the test.txt file + /* write string to the test.txt file */ if (selector == MENU_FILE_WRITE) { - resp = fileWrite(); + resp = fm_file_write(); if (resp)return resp; } - //simple communication via USB. receive and transmit strings. - //Send some strings via virtual COM port and they will be printed on screen. - //string length should be multiple of 4 + /* Simple communication via USB. receive and transmit strings. + Send some strings via virtual COM port and they will be printed on screen. + String length should be multiple of 4 */ if (selector == MENU_USB_TERMINAL) { - usbTerminal(); + usb_terminal(); } - //usb client demo compatible with usb64.exe + /* usb client demo compatible with usb64.exe */ if (selector == MENU_USB_LOADER) { - usbLoadGame(); + usb_load_rom(); } - //everdrive hardware identification + /* everdrive hardware identification */ if (selector == MENU_EDID) { - edid(); + main_display_edid(); } } } -void edid() { +void main_display_edid() { struct controller_data cd; - u32 id = bi_get_cart_id(); + u32 id = ed64_bios_get_cart_id(); - gCleanScreen(); - gConsPrint("Device ID "); - gAppendHex32(id); - gConsPrint(""); - gConsPrint("Device Name "); + screen_clear(); + screen_print("ED64 H/W Rev ID: "); + screen_append_hex32_print(id); + screen_print("ED64 H/W Rev Name: "); switch (id) { - case CART_ID_V2: - gAppendString("EverDrive 64 V2.5"); + case ED64_CART_ID_V2: + screen_append_str_print("EverDrive 64 V2.5"); break; - case CART_ID_V3: - gAppendString("EverDrive 64 V3"); + case ED64_CART_ID_V3: + screen_append_str_print("EverDrive 64 V3"); break; - case CART_ID_X7: - gAppendString("EverDrive 64 X7"); + case ED64_CART_ID_X7: + screen_append_str_print("EverDrive 64 X7"); break; - case CART_ID_X5: - gAppendString("EverDrive 64 X5"); + case ED64_CART_ID_X5: + screen_append_str_print("EverDrive 64 X5"); break; default: - gAppendString("Unknown"); + screen_append_str_print("Unknown"); break; } - gConsPrint(""); - gConsPrint("Press B to exit"); - gRepaint(); - while (1) { - gVsync(); + screen_print(""); + screen_print("Press (B) to exit"); + screen_repaint(); + for ( ;; ) { /* forever [equivalent to: "while (1)"] */ + screen_vsync(); controller_scan(); cd = get_keys_down(); @@ -168,27 +170,27 @@ void edid() { } -void printError(u8 err) { +void main_display_error(u8 err) { - gCleanScreen(); - gConsPrint("error: "); - gAppendHex8(err); - gRepaint(); + screen_clear(); + screen_print("error: "); + screen_append_hex8_print(err); + screen_repaint(); while (1); } -void boot_simulator(u8 cic) { +void rom_boot_simulator(u8 cic) { static u16 cheats_on; /* 0 = off, 1 = select, 2 = all */ - static u8 game_cic; + static u8 rom_cic; - game_cic = cic; + rom_cic = cic; cheats_on = 0; - // Start game via CIC boot code + /* Start ROM via CIC boot code */ asm __volatile__( ".set noreorder;" @@ -294,7 +296,7 @@ void boot_simulator(u8 cic) { "lui $t3, 0xB000;" : // outputs - : "r" (game_cic), // inputs + : "r" (rom_cic), // inputs "r" (cheats_on) : "$4", "$5", "$6", "$8", // clobber "$11", "$19", "$20", "$21", diff --git a/ED64-XIO/src/sys.c b/ED64-XIO/src/sys.c index 4eada69a..6d69abb7 100644 --- a/ED64-XIO/src/sys.c +++ b/ED64-XIO/src/sys.c @@ -1,3 +1,7 @@ +/* +* Copyright (c) Krikzz and Contributors. +* See LICENSE file in the project root for full license information. +*/ #include "sys.h" @@ -59,7 +63,7 @@ const u32 pal_320[] = { #define SYS_MAX_PIXEL_W 320 #define SYS_MAX_PIXEL_H 240 -void sysDisplayInit(); +void sys_n64_region_init(); void sysPI_rd_safe(void *ram, unsigned long pi_address, unsigned long len); void sysPI_wr_safe(void *ram, unsigned long pi_address, unsigned long len); @@ -80,7 +84,7 @@ u16 pal[16] = { 0x0000, 0x0000, 0x0000, 0x0aa0 }; -void sysInit() { +void sys_n64_init() { disable_interrupts(); set_AI_interrupt(0); @@ -115,11 +119,11 @@ void sysInit() { screen.current = screen.buff[screen.buff_sw]; screen.bgr_ptr = 0; - sysDisplayInit(); + sys_n64_region_init(); } -void sysDisplayInit() { +void sys_n64_region_init() { u32 i; u32 *v_setup; @@ -154,7 +158,7 @@ void sysDisplayInit() { enable_interrupts(); } -void sysPI_rd(void *ram, unsigned long pi_address, unsigned long len) { +void sys_n64_pi_read(void *ram, unsigned long pi_address, unsigned long len) { pi_address &= 0x1FFFFFFF; @@ -171,7 +175,7 @@ void sysPI_rd(void *ram, unsigned long pi_address, unsigned long len) { enable_interrupts(); } -void sysPI_wr(void *ram, unsigned long pi_address, unsigned long len) { +void sys_n64_pi_write(void *ram, unsigned long pi_address, unsigned long len) { pi_address &= 0x1FFFFFFF; @@ -189,15 +193,17 @@ void sysPI_wr(void *ram, unsigned long pi_address, unsigned long len) { } -//****************************************************************************** gfx -u16 *g_disp_ptr; -u16 g_cur_pal; -u16 g_cons_ptr; -u8 g_last_x; -u8 g_last_y; -u16 gfx_buff[G_SCREEN_W * G_SCREEN_H]; +/****************************************************************************** + * graphics +******************************************************************************/ +u16 *screen_display_ptr; +u16 screen_cur_pal; +u16 screen_cons_ptr; +u8 screen_last_x; +u8 screen_last_y; +u16 gfx_buff[TV_SCREEN_W * TV_SCREEN_H]; -void gDrawChar8X8(u32 val, u32 x, u32 y) { +void screen_draw_char_8X8(u32 val, u32 x, u32 y) { u64 tmp; u32 font_val; @@ -232,7 +238,7 @@ void gDrawChar8X8(u32 val, u32 x, u32 y) { } } -void gRepaint() { +void screen_repaint() { u16 *chr_ptr = gfx_buff; @@ -243,83 +249,83 @@ void gRepaint() { for (u32 y = 0; y < screen.h; y++) { for (u32 x = 0; x < screen.w; x++) { - gDrawChar8X8(*chr_ptr++, x, y); + screen_draw_char_8X8(*chr_ptr++, x, y); } } data_cache_hit_writeback(screen.current, screen.buff_len * 2); - gVsync(); + screen_vsync(); vregs[1] = (vu32) screen.current; } -void gVsync() { +void screen_vsync() { while (vregs[4] == 0x200); while (vregs[4] != 0x200); } -void gAppendHex4(u8 val); +void screen_append_hex4_print(u8 val); -void gCleanScreen() { +void screen_clear() { - g_cur_pal = 0; - gSetXY(G_BORDER_X, G_BORDER_Y); - for (int i = 0; i < G_SCREEN_W * G_SCREEN_H; i++)gfx_buff[i] = PAL_B3; - gSetPal(PAL_B1); + screen_cur_pal = 0; + screen_set_xy_pos(G_BORDER_X, G_BORDER_Y); + for (int i = 0; i < TV_SCREEN_W * TV_SCREEN_H; i++)gfx_buff[i] = REGION_PAL_B3; + screen_set_pal(REGION_PAL_B1); } -void gSetPal(u16 pal) { - g_cur_pal = pal; +void screen_set_pal(u16 pal) { + screen_cur_pal = pal; } -void gAppendString(u8 *str) { - while (*str != 0)*g_disp_ptr++ = *str++ + g_cur_pal; +void screen_append_str_print(u8 *str) { + while (*str != 0)*screen_display_ptr++ = *str++ + screen_cur_pal; } -void gAppendChar(u8 chr) { +void screen_append_char_print(u8 chr) { - *g_disp_ptr++ = chr + g_cur_pal; + *screen_display_ptr++ = chr + screen_cur_pal; } -void gAppendHex4(u8 val) { +void screen_append_hex4_print(u8 val) { val += (val < 10 ? '0' : '7'); - *g_disp_ptr++ = val + g_cur_pal; + *screen_display_ptr++ = val + screen_cur_pal; } -void gAppendHex8(u8 val) { +void screen_append_hex8_print(u8 val) { - gAppendHex4(val >> 4); - gAppendHex4(val & 15); + screen_append_hex4_print(val >> 4); + screen_append_hex4_print(val & 15); } -void gAppendHex16(u16 val) { +void screen_append_hex16_print(u16 val) { - gAppendHex8(val >> 8); - gAppendHex8(val); + screen_append_hex8_print(val >> 8); + screen_append_hex8_print(val); } -void gAppendHex32(u32 val) { +void screen_append_hex32_print(u32 val) { - gAppendHex16(val >> 16); - gAppendHex16(val); + screen_append_hex16_print(val >> 16); + screen_append_hex16_print(val); } -void gSetXY(u8 x, u8 y) { +void screen_set_xy_pos(u8 x, u8 y) { - g_cons_ptr = x + y * G_SCREEN_W; - g_disp_ptr = &gfx_buff[g_cons_ptr]; - g_last_x = x; - g_last_y = y; + screen_cons_ptr = x + y * TV_SCREEN_W; + screen_display_ptr = &gfx_buff[screen_cons_ptr]; + screen_last_x = x; + screen_last_y = y; } -void gConsPrint(u8 *str) { +void screen_print(u8 *str) { - g_disp_ptr = &gfx_buff[g_cons_ptr]; - g_cons_ptr += G_SCREEN_W; - g_last_y++; - gAppendString(str); + screen_display_ptr = &gfx_buff[screen_cons_ptr]; + screen_cons_ptr += TV_SCREEN_W; + screen_last_y++; + screen_append_str_print(str); } diff --git a/ED64-XIO/src/usb.c b/ED64-XIO/src/usb.c new file mode 100644 index 00000000..6b2e145e --- /dev/null +++ b/ED64-XIO/src/usb.c @@ -0,0 +1,157 @@ +/* +* Copyright (c) Krikzz and Contributors. +* See LICENSE file in the project root for full license information. +*/ + +#include "everdrive.h" + +u8 usb_cmd_resp(u8 resp); +void usb_cmd_cmem_fill(u8 *cmd); +u8 usb_cmd_rom_wr(u8 *cmd); + +void usb_terminal() { + + u8 data[4 + 1]; + u8 tout; + struct controller_data cd; + + screen_clear(); + screen_print("USB CDC terminal demo"); + screen_print(""); + screen_print("Waiting to receive data..."); + screen_print(""); + screen_print(""); + screen_print("Press (B) to exit"); + screen_repaint(); + + data[4] = 1; + + for ( ;; ) { /* forever [equivalent to: "while (1)"] */ + + screen_vsync(); + controller_scan(); + cd = get_keys_down(); + if (cd.c[0].B)return; + + if (!ed64_bios_usb_can_read())continue; + + /* read from virtual serial port. + Size must be a multiple of 4. + Use 512B blocks for best performance */ + tout = ed64_bios_usb_read(data, 4); + if (tout)continue; + + /* Send echo string back to the serial port */ + ed64_bios_usb_write(data, 4); + + screen_print(data); + screen_repaint(); + } +} + +void usb_load_rom() { + + u8 resp, usb_cmd; + u8 cmd[16]; + struct controller_data cd; + + screen_clear(); + screen_print("Waiting for ROM data..."); + screen_print("Press (B) to exit"); + screen_repaint(); + + for ( ;; ) { /* forever [equivalent to: "while (1)"] */ + + screen_vsync(); + controller_scan(); + cd = get_keys_down(); + if (cd.c[0].B)return; + + if (!ed64_bios_usb_can_read())continue; + + resp = ed64_bios_usb_read(cmd, 16); + if (resp)continue; + //resp = ed64_bios_usb_read(cmd + 16, 512 - 16); + //if (resp)return resp; + + if (cmd[0] != 'c')continue; + if (cmd[1] != 'm')continue; + if (cmd[2] != 'd')continue; + usb_cmd = cmd[3]; + + /* Host send this command during the everdrive seek */ + if (usb_cmd == 't') { + usb_cmd_resp(0); + } + + /* start the rom */ + if (usb_cmd == 's') { + ed64_bios_rom_savetype_set(ED64_SAVE_EEP16K); /* set save type */ + rom_boot_simulator(CIC_6102); /* run the ROM */ + } + + /* Fill ro memory. Used if ROM size less than 2MB (required for correct crc values) */ + if (usb_cmd == 'c') { + usb_cmd_cmem_fill(cmd); + } + + /* write to ROM memory */ + if (usb_cmd == 'W') { + usb_cmd_rom_wr(cmd); + } + + } + +} + +u8 usb_cmd_resp(u8 resp) { + + u8 buff[16]; + buff[0] = 'c'; + buff[1] = 'm'; + buff[2] = 'd'; + buff[3] = 'r'; + buff[4] = resp; + return ed64_bios_usb_write(buff, sizeof (buff)); +} + +void usb_cmd_cmem_fill(u8 *cmd) { + + u16 i; + u32 addr = *(u32 *) & cmd[4]; + u32 slen = *(u32 *) & cmd[8]; + u32 val = *(u32 *) & cmd[12]; + u32 buff[512 / 4]; + + for (i = 0; i < 512 / 4; i++) { + buff[i] = val; + } + + while (slen--) { + sys_n64_pi_write(buff, addr, 512); + addr += 512; + } +} + +u8 usb_cmd_rom_wr(u8 *cmd) { + + u8 resp; + u8 buff[512]; + u32 addr = *(u32 *) & cmd[4]; /* destination address */ + u32 slen = *(u32 *) & cmd[8]; /* size in sectors (512B) */ + + if (slen == 0)return 0; + + ed64_bios_usb_read_start(); /* begin first block receiving (512B) */ + + while (slen--) { + + resp = ed64_bios_usb_read_end(buff); /* wait for block receiving completion and read it to the buffer */ + if (slen != 0)ed64_bios_usb_read_start(); /* begin next block receiving while previous block transfers to the ROM */ + if (resp)return resp; + sys_n64_pi_write(buff, addr, 512); /* copy received block to the rom memory */ + addr += 512; + } + + return 0; +} \ No newline at end of file diff --git a/docs/real_time_clock.md b/docs/real_time_clock.md index 57357737..76208e6d 100644 --- a/docs/real_time_clock.md +++ b/docs/real_time_clock.md @@ -9,10 +9,10 @@ WIP! (Krikzz input required) ## Getting the RTC -The ED64 uses the same calls as used by other games that need the RTC on the N64. -When emulating a game that uses the RTC, an entry needs to be present in the default database, or ED64 folder called `save_db.txt` (there by default, although user configurable). +The ED64 uses the same calls as used by other ROMs that need the RTC on the N64. +When emulating a ROM that uses the RTC, an entry needs to be present in the default database, or ED64 folder called `save_db.txt` (there by default, although user configurable). An example for the 64DD would be a line entry: -`DD=31 All 64DD games SRAM+RTC` which ensures that the RTC is enabled and that the save type is SRAM. +`DD=31 All 64DD ROMs SRAM+RTC` which ensures that the RTC is enabled and that the save type is SRAM. Please refer to the [Config Database](rom_config_database.md) for more information. diff --git a/docs/rom_config_database.md b/docs/rom_config_database.md index 6011eb74..b92debb7 100644 --- a/docs/rom_config_database.md +++ b/docs/rom_config_database.md @@ -8,18 +8,18 @@ On Windows, the byte `0x3F` uses the save type at high nibble, and the extra con | ROM ID | = | SAVE TYPE | CONFIG | DEVELOPER OVERRIDE | DESCRIPTION | |:- |---|--- |--- |--- |--- | -|ED | = | 3 | 1 | `0x31` | 64DD game SRAM+RTC | +|ED | = | 3 | 1 | `0x31` | 64DD ROM SRAM+RTC | |ED | = | 1 | 2 | `0x12` | EEP4K+region-free | |ED | = | 1 | 2 | `0x13` | EEP4K+region-free+RTC | ## Usage -The ROM ID or CRC HI can be used for game detection (check "ROM Info" from the Everdrive OS menu for the value needed). +The ROM ID or CRC HI can be used for ROM detection (check "ROM Info" from the Everdrive OS menu for the value needed). The line is depicted in this order: | ROM ID or CRC-HIGH | = | SAVE TYPE | CONFIG | DESCRIPTION | |:- |---|--- |--- |--- | -|DD | = | 3 | 1 | All 64DD games SRAM+RTC | +|DD | = | 3 | 1 | All 64DD ROMs SRAM+RTC | |0xABA51D09 | = | 1 | 2 | 40 Winks EEP4K+region-free | @@ -41,7 +41,7 @@ Note: The CONFIG options can be mixed using addition (1+2=3 for rtc+region). |:- |--- | --- | | 0 | Off | | | 1 | Rtc | | -| 2 | Region free ROM | Use native system region for game launch. For applications without region lock. | +| 2 | Region free ROM | Use native system region for ROM launch. For applications without region lock. | | 3 | All | Rtc and native system region are enabled. | @@ -59,5 +59,5 @@ An example `save_db.txt` file would look like: ------------------------ ID detection ------------------------------ N6=10 Dr. Mario. ROM ID detection EEP4K AF=51 Doubutsu no Mori FLASHRAM+RTC -DD=31 All 64DD games SRAM+RTC +DD=31 All 64DD cart conversion ROMs SRAM+RTC ```