diff --git a/build.sh b/build.sh
index 6a0adb0..196ab45 100755
--- a/build.sh
+++ b/build.sh
@@ -15,6 +15,7 @@ FILES=(
BUILT_CIC=false
BUILT_N64=false
BUILT_RISCV=false
+BUILT_SW=false
BUILT_FPGA=false
BUILT_UPDATE=false
BUILT_RELEASE=false
@@ -44,7 +45,6 @@ build_n64 () {
if [ ! -z "${GIT_BRANCH+x}" ]; then N64_FLAGS+=" -DGIT_BRANCH='\"$GIT_BRANCH\"'"; fi
if [ ! -z "${GIT_TAG+x}" ]; then N64_FLAGS+=" -DGIT_TAG='\"$GIT_TAG\"'"; fi
if [ ! -z "${GIT_SHA+x}" ]; then N64_FLAGS+=" -DGIT_SHA='\"$GIT_SHA\"'"; fi
- if [ ! -z "${GIT_MESSAGE+x}" ]; then N64_FLAGS+=" -DGIT_MESSAGE='\"$GIT_MESSAGE\"'"; fi
make all -j USER_FLAGS="$N64_FLAGS"
popd > /dev/null
@@ -64,15 +64,29 @@ build_riscv () {
BUILT_RISCV=true
}
-build_fpga () {
- if [ "$BUILT_FPGA" = true ]; then return; fi
+build_sw () {
+ if [ "$BUILT_SW" = true ]; then return; fi
build_n64
build_riscv
+ pushd fw > /dev/null
+ mkdir -p output_files > /dev/null
+ cat ../sw/n64/build/n64boot.bin ../sw/riscv/build/governor.bin > output_files/SC64_software.bin
+ objcopy -I binary -O ihex output_files/SC64_software.bin output_files/SC64_software.hex
+ popd
+
+ BUILT_SW=true
+}
+
+build_fpga () {
+ if [ "$BUILT_FPGA" = true ]; then return; fi
+
+ build_sw
+
pushd fw > /dev/null
if [ "$SKIP_FPGA_REBUILD" = true ] && [ -f output_files/SummerCart64.sof ]; then
- quartus_cpf -c SummerCart64.cof
+ echo Skipping FPGA build
else
if [ "$DEBUG_ENABLED" = true ]; then
quartus_sh --set VERILOG_MACRO="DEBUG" ./SummerCart64.qpf
@@ -91,9 +105,8 @@ build_update () {
build_fpga
pushd fw/output_files > /dev/null
- cat sc64_firmware_ufm_auto.rpd sc64_firmware_cfm0_auto.rpd > SC64_update_tmp.bin
- objcopy -I binary -O binary --reverse-bytes=4 SC64_update_tmp.bin SC64_update.bin
- rm SC64_update_tmp.bin
+ objcopy -I binary -O binary --reverse-bytes=4 sc64_firmware_cfm0_auto.rpd SC64_firmware.bin
+ cat SC64_software.bin SC64_firmware.bin > SC64_update.bin
popd > /dev/null
BUILT_UPDATE=true
@@ -120,7 +133,8 @@ print_usage () {
echo " cic - assemble UltraCIC-III software"
echo " n64 - compile N64 bootloader software"
echo " riscv - compile cart governor software"
- echo " fpga - compile FPGA design (triggers 'n64' and 'riscv' build)"
+ echo " sw - compile all software (triggers 'n64' and 'riscv' build)"
+ echo " fpga - compile FPGA design (triggers 'sw' build)"
echo " update - convert programming .pof file to raw binary for self-upgrade (triggers 'fpga' build)"
echo " release - collect and zip files for release (triggers 'cic' and 'update' build)"
echo " -c | --force-clean"
@@ -142,6 +156,7 @@ fi
TRIGGER_CIC=false
TRIGGER_N64=false
TRIGGER_RISCV=false
+TRIGGER_SW=false
TRIGGER_FPGA=false
TRIGGER_UPDATE=false
TRIGGER_RELEASE=false
@@ -157,6 +172,9 @@ while test $# -gt 0; do
riscv)
TRIGGER_RISCV=true
;;
+ sw)
+ TRIGGER_SW=true
+ ;;
fpga)
TRIGGER_FPGA=true
;;
@@ -193,6 +211,7 @@ if [ "$DEBUG_ENABLED" = true ]; then USER_FLAGS+=" -DDEBUG"; fi
if [ "$TRIGGER_CIC" = true ]; then build_cic; fi
if [ "$TRIGGER_N64" = true ]; then build_n64; fi
if [ "$TRIGGER_RISCV" = true ]; then build_riscv; fi
+if [ "$TRIGGER_SW" = true ]; then build_sw; fi
if [ "$TRIGGER_FPGA" = true ]; then build_fpga; fi
if [ "$TRIGGER_UPDATE" = true ]; then build_update; fi
if [ "$TRIGGER_RELEASE" = true ]; then build_release; fi
diff --git a/docker_build.sh b/docker_build.sh
index b4391c9..33e5dcb 100755
--- a/docker_build.sh
+++ b/docker_build.sh
@@ -16,7 +16,6 @@ fi
GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
GIT_TAG=$(git describe --tags 2> /dev/null)
GIT_SHA=$(git rev-parse HEAD)
-GIT_MESSAGE=$(git log -1 --pretty=format:%s)
if [ -t 1 ]; then
DOCKER_OPTIONS="-it"
@@ -27,6 +26,5 @@ docker exec \
-e GIT_BRANCH="$GIT_BRANCH" \
-e GIT_TAG="$GIT_TAG" \
-e GIT_SHA="$GIT_SHA" \
- -e GIT_MESSAGE="$GIT_MESSAGE" \
$CONTAINER_NAME \
./build.sh $@
diff --git a/fw/SummerCart64.cof b/fw/SummerCart64.cof
index ebd1b9d..d10644c 100644
--- a/fw/SummerCart64.cof
+++ b/fw/SummerCart64.cof
@@ -27,9 +27,7 @@
0
0
2
- ../sw/n64/build/n64boot.hex
- ../sw/riscv/build/governor.hex
- 305152
+ output_files/SC64_software.hex
1
diff --git a/fw/rtl/n64/n64_bootloader.sv b/fw/rtl/n64/n64_bootloader.sv
index 0f5942e..76565a4 100644
--- a/fw/rtl/n64/n64_bootloader.sv
+++ b/fw/rtl/n64/n64_bootloader.sv
@@ -89,7 +89,7 @@ module n64_bootloader (
bus.ack = source_request == T_N64 && data_ack;
bus.rdata = 16'd0;
- if (bus.ack && bus.address >= 32'h10000000 && bus.address < 32'h10016800) begin
+ if (bus.ack && bus.address >= 32'h10000000 && bus.address < 32'h10010000) begin
if (bus.address[1]) bus.rdata = {data_rdata[23:16], data_rdata[31:24]};
else bus.rdata = {data_rdata[7:0], data_rdata[15:8]};
end
diff --git a/fw/rtl/system/sc64.sv b/fw/rtl/system/sc64.sv
index 9facdb1..224d5c2 100644
--- a/fw/rtl/system/sc64.sv
+++ b/fw/rtl/system/sc64.sv
@@ -33,7 +33,7 @@ package sc64;
parameter bit [31:0] SC64_VER = 32'h53437632;
parameter int CLOCK_FREQUENCY = 32'd100_000_000;
- parameter bit [31:0] CPU_RESET_VECTOR = {4'(ID_CPU_FLASH), 28'h0035800};
+ parameter bit [31:0] CPU_RESET_VECTOR = {4'(ID_CPU_FLASH), 28'h0010000};
parameter int UART_BAUD_RATE = 32'd1_000_000;
`ifdef DEBUG
diff --git a/sw/n64/Makefile b/sw/n64/Makefile
index cdad8c1..23caa7b 100644
--- a/sw/n64/Makefile
+++ b/sw/n64/Makefile
@@ -15,16 +15,16 @@ BUILD_DIR = build
SRC_FILES = \
startup.S \
- ipl2.S \
- exception.S \
boot.c \
crc32.c \
error.c \
exception.c \
+ exception.S \
font.c \
init.c \
interrupt.c \
io.c \
+ ipl2.S \
main.c \
sc64.c \
storage.c \
@@ -56,7 +56,7 @@ $(BUILD_DIR)/n64boot.elf: $(OBJS) N64.ld
$(BUILD_DIR)/n64boot.bin: $(BUILD_DIR)/n64boot.elf
@$(OBJCOPY) -O binary $< $@
@chksum64 $@ > /dev/null
- @truncate --size=90k $@
+ @truncate --size=64k $@
$(BUILD_DIR)/n64boot.hex: $(BUILD_DIR)/n64boot.bin
@$(OBJCOPY) -I binary -O ihex $< $@
diff --git a/sw/n64/N64.ld b/sw/n64/N64.ld
index 52415fb..b4d0349 100644
--- a/sw/n64/N64.ld
+++ b/sw/n64/N64.ld
@@ -1,12 +1,12 @@
MEMORY {
- rdram (rwx) : org = 0x80300000, len = 1M
- flash (r) : org = 0xB0000000, len = 90k
+ rdram (rwx) : org = 0x803E0000, len = 128k
+ flash (r) : org = 0xB0000000, len = 64k
}
ENTRY(entry_handler)
__exception_stack_size = 8k;
-__stack_size = 64k;
+__stack_size = 16k;
SECTIONS {
.flash : {
diff --git a/sw/n64/src/exception.c b/sw/n64/src/exception.c
index 72c9db7..54bab75 100644
--- a/sw/n64/src/exception.c
+++ b/sw/n64/src/exception.c
@@ -76,6 +76,8 @@ typedef struct {
#define START_X_OFFSET (19)
+extern const io32_t entry_handler __attribute__((section(".data")));
+
static const vi_regs_t vi_config[] = {{
.CR = VI_CR_TYPE_32,
.H_WIDTH = SCREEN_WIDTH,
@@ -106,12 +108,14 @@ static const vi_regs_t vi_config[] = {{
.V_SCALE = ((0x100 * SCREEN_HEIGHT) / 60),
}};
-static io32_t *exception_framebuffer = (io32_t *) (0x0026A000UL);
+static io32_t *exception_framebuffer;
static void exception_init_screen (void) {
const vi_regs_t *cfg = &vi_config[OS_INFO->tv_type];
+ exception_framebuffer = (io32_t *) (((io32_t) (&entry_handler)) - (SCREEN_WIDTH * SCREEN_HEIGHT * sizeof(io32_t)));
+
for (int y = 0; y < SCREEN_HEIGHT; y++) {
for (int x = 0; x < SCREEN_WIDTH; x++) {
uint32_t color;
@@ -237,8 +241,7 @@ void exception_fatal_handler (uint32_t exception_code, uint32_t interrupt_mask,
exception_print("----- SummerCart64 n64boot -----\n");
exception_print("branch: %s\n", version->git_branch);
exception_print("tag: %s\n", version->git_tag);
- exception_print("sha: %s\n", version->git_sha);
- exception_print("msg: %s\n\n", version->git_message);
+ exception_print("sha: %s\n\n", version->git_sha);
exception_print("%s at pc: 0x%08lX\n", exception_get_description(exception_code), e->epc.u32);
exception_print("sr: 0x%08lX cr: 0x%08lX hw: 0x%08lX [%4s]\n", e->sr, e->cr, sc64_version, (char *) (&sc64_version));
exception_print("zr: 0x%08lX at: 0x%08lX v0: 0x%08lX v1: 0x%08lX\n", e->zr.u32, e->at.u32, e->v0.u32, e->v1.u32);
diff --git a/sw/n64/src/storage.c b/sw/n64/src/storage.c
index 3774ff8..220c8ca 100644
--- a/sw/n64/src/storage.c
+++ b/sw/n64/src/storage.c
@@ -4,6 +4,11 @@
#include "fatfs/ff.h"
+#define ROM_ENTRY_OFFSET (8)
+#define ROM_CODE_OFFSET (4096)
+#define ROM_MAX_LOAD_SIZE (1 * 1024 * 1024)
+
+
static const char *fatfs_error_codes[] = {
"Succeeded",
"A hard error occurred in the low level disk I/O layer",
@@ -28,35 +33,47 @@ static const char *fatfs_error_codes[] = {
};
-#define FF_CHECK(x, message) { \
- FRESULT fatfs_result = x; \
- if (fatfs_result != FR_OK) { \
- error_display("%s:\n %s\n", message, fatfs_error_codes[fatfs_result]); \
+#define FF_CHECK(x, message, ...) { \
+ fresult = x; \
+ if (fresult != FR_OK) { \
+ error_display(message " [%s]:\n %s\n", __VA_ARGS__ __VA_OPT__(,) #x, fatfs_error_codes[fresult]); \
} \
}
void storage_run_menu (storage_backend_t storage_backend) {
+ void (* menu)(void);
+ FRESULT fresult;
FATFS fs;
FIL fil;
+ UINT br;
+ FSIZE_t size = ROM_MAX_LOAD_SIZE;
+ const TCHAR *path = "";
if (storage_backend == STORAGE_BACKEND_SD) {
- FF_CHECK(f_mount(&fs, "0:", 1), "Couldn't mount SD drive");
- FF_CHECK(f_chdrive("0:"), "Couldn't chdrive to SD drive");
+ path = "0:";
} else if (storage_backend == STORAGE_BACKEND_USB) {
- FF_CHECK(f_mount(&fs, "1:", 1), "Couldn't mount USB drive");
- FF_CHECK(f_chdrive("1:"), "Couldn't chdrive to USB drive");
+ path = "1:";
} else {
error_display("Unknown storage backend [%d]\n", storage_backend);
}
- FF_CHECK(f_open(&fil, "sc64menu.elf", FA_READ), "Couldn't open menu file");
-
- // TODO: Implement ELF loader here
-
+ FF_CHECK(f_mount(&fs, path, 1), "Couldn't mount drive");
+ FF_CHECK(f_chdrive(path), "Couldn't chdrive");
+ FF_CHECK(f_open(&fil, "sc64menu.n64", FA_READ), "Couldn't open menu file");
+ FF_CHECK(f_lseek(&fil, ROM_ENTRY_OFFSET), "Couldn't seek to entry point offset");
+ FF_CHECK(f_read(&fil, &menu, sizeof(menu), &br), "Couldn't read entry point");
+ FF_CHECK(f_lseek(&fil, ROM_CODE_OFFSET), "Couldn't seek to code start offset");
+ if ((f_size(&fil) - ROM_CODE_OFFSET) < size) {
+ size = (f_size(&fil) - ROM_CODE_OFFSET);
+ }
+ FF_CHECK(f_read(&fil, menu, size, &br), "Couldn't read menu file");
+ FF_CHECK(br != size, "Read size is different than expected");
FF_CHECK(f_close(&fil), "Couldn't close menu file");
deinit();
- // menu();
+ menu();
+
+ while (1);
}
diff --git a/sw/n64/src/version.c b/sw/n64/src/version.c
index 1f1b0ef..47401e4 100644
--- a/sw/n64/src/version.c
+++ b/sw/n64/src/version.c
@@ -1,7 +1,7 @@
#include "version.h"
-version_t version = {
+static version_t version = {
#ifdef GIT_BRANCH
.git_branch = GIT_BRANCH,
#else
@@ -17,11 +17,6 @@ version_t version = {
#else
#warning "No GIT_SHA provided"
#endif
-#ifdef GIT_MESSAGE
- .git_message = GIT_MESSAGE,
-#else
-#warning "No GIT_MESSAGE provided"
-#endif
};
diff --git a/sw/n64/src/version.h b/sw/n64/src/version.h
index 8b875ed..439e320 100644
--- a/sw/n64/src/version.h
+++ b/sw/n64/src/version.h
@@ -6,7 +6,6 @@ typedef const struct {
const char *git_branch;
const char *git_tag;
const char *git_sha;
- const char *git_message;
} version_t;
diff --git a/sw/riscv/Makefile b/sw/riscv/Makefile
index 6ce172d..4d24214 100644
--- a/sw/riscv/Makefile
+++ b/sw/riscv/Makefile
@@ -46,7 +46,7 @@ $(BUILD_DIR)/governor.elf: $(OBJS) SC64.ld
@$(OBJDUMP) -D $@ > $(BUILD_DIR)/governor.lst
$(BUILD_DIR)/governor.bin: $(BUILD_DIR)/governor.elf
- @$(OBJCOPY) -O binary $< $@
+ @$(OBJCOPY) -O binary --gap-fill 0xFF --pad-to 0x10016800 $< $@
$(BUILD_DIR)/governor.hex: $(BUILD_DIR)/governor.bin
@$(OBJCOPY) -I binary -O ihex $< $@
diff --git a/sw/riscv/SC64.ld b/sw/riscv/SC64.ld
index bae2abd..8b3874a 100644
--- a/sw/riscv/SC64.ld
+++ b/sw/riscv/SC64.ld
@@ -1,6 +1,6 @@
MEMORY {
ram (rwx) : org = 0x00000000, len = 16k
- rom (rx) : org = 0x10035800, len = 16k
+ rom (rx) : org = 0x10010000, len = 26k
}
ENTRY(reset_handler)