diff --git a/build.sh b/build.sh
index 01e1a29..3ae8020 100755
--- a/build.sh
+++ b/build.sh
@@ -25,9 +25,9 @@ SKIP_FPGA_REBUILD=false
build_cic () {
if [ "$BUILT_CIC" = true ]; then return; fi
- pushd sw/cic
+ pushd sw/cic > /dev/null
avra UltraCIC-III.asm -D attiny45
- popd
+ popd > /dev/null
BUILT_CIC=true
}
@@ -35,12 +35,12 @@ build_cic () {
build_n64 () {
if [ "$BUILT_N64" = true ]; then return; fi
- pushd sw/n64
+ pushd sw/n64 > /dev/null
if [ "$FORCE_CLEAN" = true ]; then
make clean
fi
- make all -j
- popd
+ make all -j USER_FLAGS="-D__SC64_VERSION=\"$__SC64_VERSION\""
+ popd > /dev/null
BUILT_N64=true
}
@@ -48,12 +48,12 @@ build_n64 () {
build_riscv () {
if [ "$BUILT_RISCV" = true ]; then return; fi
- pushd sw/riscv
+ pushd sw/riscv > /dev/null
if [ "$FORCE_CLEAN" = true ]; then
make clean -j
fi
- make all
- popd
+ make all USER_FLAGS="-D__SC64_VERSION=\"$__SC64_VERSION\""
+ popd > /dev/null
BUILT_RISCV=true
}
@@ -64,13 +64,13 @@ build_fpga () {
build_n64
build_riscv
- pushd fw
+ pushd fw > /dev/null
if [ "$SKIP_FPGA_REBUILD" = true ] && [ -f output_files/SummerCart64.sof ]; then
quartus_cpf -c SummerCart64.cof
else
quartus_sh --flow compile ./SummerCart64.qpf
fi
- popd
+ popd > /dev/null
BUILT_FPGA=true
}
@@ -80,11 +80,11 @@ build_update () {
build_fpga
- pushd fw/output_files
+ 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
- popd
+ popd > /dev/null
BUILT_UPDATE=true
}
diff --git a/docker_build.sh b/docker_build.sh
index f80869e..38271b1 100755
--- a/docker_build.sh
+++ b/docker_build.sh
@@ -1,8 +1,18 @@
#!/bin/bash
+GIT_SHA=$(git rev-parse --short HEAD)
+GIT_TAG=$(git describe --tags --exact-match 2> /dev/null)
+
+if [ ! -z "$GIT_TAG" ]; then
+ __SC64_VERSION="git tag: $GIT_TAG"
+else
+ __SC64_VERSION="git sha: $GIT_SHA"
+fi
+
docker run \
--rm \
--user $(id -u):$(id -g) \
--mount type=bind,src="$(pwd)",target="/workdir" \
+ -e __SC64_VERSION="$__SC64_VERSION" \
ghcr.io/polprzewodnikowy/sc64env:v1.2 \
./build.sh $@
diff --git a/fw/SummerCart64.cof b/fw/SummerCart64.cof
index e3d8f89..ebd1b9d 100644
--- a/fw/SummerCart64.cof
+++ b/fw/SummerCart64.cof
@@ -27,7 +27,7 @@
0
0
2
- ../sw/n64/build/SummerLoader64.hex
+ ../sw/n64/build/n64boot.hex
../sw/riscv/build/governor.hex
305152
diff --git a/sw/n64/Makefile b/sw/n64/Makefile
index 8b384cc..b7b497d 100644
--- a/sw/n64/Makefile
+++ b/sw/n64/Makefile
@@ -1,28 +1,56 @@
+TOOLCHAIN = mips64-elf-
+CC = $(TOOLCHAIN)gcc
+CXX = $(TOOLCHAIN)g++
+OBJCOPY = $(TOOLCHAIN)objcopy
+OBJDUMP = $(TOOLCHAIN)objdump
+SIZE = $(TOOLCHAIN)size
+
+FLAGS = -march=vr4300 -mtune=vr4300 -falign-functions=32 $(USER_FLAGS)
+CFLAGS = -Os -Wall -ffunction-sections -fdata-sections -ffreestanding -MMD -MP
+LDFLAGS = -lc -nostartfiles -Wl,--gc-sections
+
+SRC_DIR = src
BUILD_DIR = build
-SOURCE_DIR = src
-PROGRAM_NAME = SummerLoader64
-include $(N64_INST)/include/n64.mk
+SRC_FILES = startup.S main.c sc64.c boot.c crc32.c
-src = main.c sc64.c boot.c crc32.c
+SRCS = $(addprefix $(SRC_DIR)/, $(SRC_FILES))
+OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(patsubst %,%.o,$(SRCS))))
+DEPS = $(OBJS:.o=.d)
-all: $(BUILD_DIR)/$(PROGRAM_NAME).hex
+VPATH = $(SRC_DIR)
-$(BUILD_DIR)/$(PROGRAM_NAME).elf: $(src:%.c=$(BUILD_DIR)/%.o)
+$(@info $(shell mkdir -p ./$(BUILD_DIR) &> /dev/null))
-$(PROGRAM_NAME).z64: N64_ROM_TITLE="$(PROGRAM_NAME)"
+$(BUILD_DIR)/%.S.o: %.S
+ $(CC) -x assembler-with-cpp $(FLAGS) $(CFLAGS) -c $< -o $@
-$(BUILD_DIR)/$(PROGRAM_NAME).hex: $(PROGRAM_NAME).z64
- sed '$$ s/\x00*$$//' $(PROGRAM_NAME).z64 > $(BUILD_DIR)/$(PROGRAM_NAME)_stripped.z64
- @if [ $$(stat -L -c %s $(BUILD_DIR)/$(PROGRAM_NAME)_stripped.z64) -gt 92160 ]; then\
- echo "\n Error: stripped file size is larger than 90kB thus cannot fit inside FPGA flash.\n"; exit 1;\
- fi
- truncate --size=90k $(BUILD_DIR)/$(PROGRAM_NAME)_stripped.z64
- $(N64_OBJCOPY) -I binary -O ihex $(BUILD_DIR)/$(PROGRAM_NAME)_stripped.z64 $(BUILD_DIR)/$(PROGRAM_NAME).hex
+$(BUILD_DIR)/%.c.o: %.c
+ $(CC) $(FLAGS) $(CFLAGS) -c $< -o $@
+
+$(BUILD_DIR)/n64boot.elf: $(OBJS) N64.ld
+ $(CXX) $(FLAGS) $(LDFLAGS) -TN64.ld $(OBJS) -o $@
+ @$(OBJDUMP) -D $@ > $(BUILD_DIR)/n64boot.lst
+
+$(BUILD_DIR)/n64boot.bin: $(BUILD_DIR)/n64boot.elf
+ @$(OBJCOPY) -O binary $< $@
+ @truncate --size=90k $@
+ @chksum64 $@ > /dev/null
+
+$(BUILD_DIR)/n64boot.hex: $(BUILD_DIR)/n64boot.bin
+ @$(OBJCOPY) -I binary -O ihex $< $@
+
+print_size: $(BUILD_DIR)/n64boot.elf
+ @echo 'Size of modules:'
+ @$(SIZE) -B -d -t --common $(OBJS)
+ @echo 'Size of n64boot:'
+ @$(SIZE) -B -d $<
+
+all: $(BUILD_DIR)/n64boot.hex print_size
clean:
- rm -rf ./$(BUILD_DIR) ./$(PROGRAM_NAME).z64
+ @rm -rf ./$(BUILD_DIR)/*
--include $(wildcard $(BUILD_DIR)/*.d)
+.PHONY: all clean print_size
-.PHONY: all clean
+-include $(DEPS)
diff --git a/sw/n64/N64.ld b/sw/n64/N64.ld
new file mode 100644
index 0000000..056d014
--- /dev/null
+++ b/sw/n64/N64.ld
@@ -0,0 +1,47 @@
+MEMORY {
+ rdram (rwx) : org = 0x80300000, len = 1M
+ flash (r) : org = 0xB0000000, len = 90k
+}
+
+ENTRY(entry_handler)
+
+SECTIONS {
+ .flash : {
+ KEEP(*(.text.bootcode));
+ } > flash
+
+ .text : {
+ *(.text.entry_handler)
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.rdata .rodata .rodata.* .gnu.linkonce.r.*)
+ } > rdram AT > flash
+
+ .data : {
+ . = ALIGN(8);
+ _sdata = .;
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(8);
+ _ssdata = .;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ *(.lit8)
+ *(.lit4)
+ } > rdram AT > flash
+
+ .bss : {
+ . = ALIGN(8);
+ _sbss = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon .scommon.*)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(8);
+ _ebss = .;
+ } > rdram
+
+ /DISCARD/ : {
+ *(.MIPS.*)
+ }
+
+ _gp = MIN(_ssdata + 0x8000, MAX(_sdata + 0x8000, _ebss - 0x8000));
+ _sp = ORIGIN(rdram) + LENGTH(rdram);
+}
diff --git a/sw/n64/blob/ipl3.bin b/sw/n64/blob/ipl3.bin
new file mode 100644
index 0000000..a53352e
Binary files /dev/null and b/sw/n64/blob/ipl3.bin differ
diff --git a/sw/n64/src/startup.S b/sw/n64/src/startup.S
new file mode 100644
index 0000000..448f85a
--- /dev/null
+++ b/sw/n64/src/startup.S
@@ -0,0 +1,71 @@
+#define STR(x) #x
+#define XSTR(s) STR(s)
+#define VERSION XSTR(__SC64_VERSION)
+
+.section .text.bootcode
+header_pi_config:
+ .word 0x80371240
+
+header_clock_rate:
+ .word 0x0000000F
+
+header_load_addr:
+ .word entry_handler
+
+header_release_addr:
+ .word 0x00000000
+
+header_crc:
+ .fill 2, 4, 0
+
+ .org 0x18, 0x00
+
+header_text_info:
+ .ascii "byMFinPL"
+ .ascii "SummerLoader64 "
+ .ascii VERSION
+
+ .org 0x40, 0x20
+
+ipl3:
+ .incbin "blob/ipl3.bin"
+
+
+.section .text.entry_handler
+.set noreorder
+entry_handler:
+ .global entry_handler
+
+ li $a0, 0x08
+ sw $a0, 0xBFC007FC
+
+ la $gp, _gp
+ la $sp, _sp
+
+init_bss:
+ la $a0, _sbss
+ la $a1, _ebss
+ bge $a0, $a1, 2f
+ nop
+1:
+ sd $zero, 0($a0)
+ addi $a0, $a0, 8
+ blt $a0, $a1, 1b
+ nop
+2:
+
+init_bss_cache:
+ la $a0, _sbss
+ la $a1, _ebss
+ bge $a0, $a1, 2f
+ nop
+1:
+ cache 0x15, 0($a0)
+ addi $a0, $a0, 16
+ blt $a0, $a1, 1b
+ nop
+2:
+
+run:
+ j main
+ nop
diff --git a/sw/pc/sc64.py b/sw/pc/sc64.py
index fbe8498..021637d 100644
--- a/sw/pc/sc64.py
+++ b/sw/pc/sc64.py
@@ -442,7 +442,7 @@ if __name__ == "__main__":
print(f"Setting CIC seed to [{hex(cic_seed) if cic_seed != 0xFFFF else 'Unknown'}]")
sc64.set_cic_seed(cic_seed)
- print(f"Setting 64DD emulation to [{'Enabled' if skip_bootloader else 'Disabled'}]")
+ print(f"Setting 64DD emulation to [{'Enabled' if dd_enable else 'Disabled'}]")
sc64.set_dd_enable(dd_enable)
if (rom_file):
diff --git a/sw/riscv/Makefile b/sw/riscv/Makefile
index c7a619c..1253a1b 100644
--- a/sw/riscv/Makefile
+++ b/sw/riscv/Makefile
@@ -1,5 +1,6 @@
TOOLCHAIN = riscv32-unknown-elf-
CC = $(TOOLCHAIN)gcc
+CXX = $(TOOLCHAIN)g++
OBJCOPY = $(TOOLCHAIN)objcopy
OBJDUMP = $(TOOLCHAIN)objdump
SIZE = $(TOOLCHAIN)size
@@ -21,27 +22,33 @@ VPATH = $(SRC_DIR)
$(@info $(shell mkdir -p ./$(BUILD_DIR) &> /dev/null))
-all: $(BUILD_DIR)/governor.hex
+$(BUILD_DIR)/%.S.o: %.S
+ $(CC) -x assembler-with-cpp $(FLAGS) $(CFLAGS) -c $< -o $@
$(BUILD_DIR)/%.c.o: %.c
$(CC) $(FLAGS) $(CFLAGS) -c $< -o $@
-$(BUILD_DIR)/%.S.o: %.S
- $(CC) -x assembler $(FLAGS) $(CFLAGS) -c $< -o $@
+$(BUILD_DIR)/governor.elf: $(OBJS) SC64.ld
+ $(CXX) $(FLAGS) $(LDFLAGS) -TSC64.ld $(OBJS) -o $@
+ @$(OBJDUMP) -D $@ > $(BUILD_DIR)/governor.lst
-$(BUILD_DIR)/governor.hex: $(OBJS) SC64.ld
- $(CC) $(FLAGS) $(LDFLAGS) -TSC64.ld $(OBJS) -o $(BUILD_DIR)/governor.elf
- $(OBJDUMP) -D $(BUILD_DIR)/governor.elf > $(BUILD_DIR)/governor.map
- $(OBJCOPY) -O binary $(BUILD_DIR)/governor.elf $(BUILD_DIR)/governor.bin
- $(OBJCOPY) -I binary -O ihex $(BUILD_DIR)/governor.bin $@
+$(BUILD_DIR)/governor.bin: $(BUILD_DIR)/governor.elf
+ @$(OBJCOPY) -O binary $< $@
+
+$(BUILD_DIR)/governor.hex: $(BUILD_DIR)/governor.bin
+ @$(OBJCOPY) -I binary -O ihex $< $@
+
+print_size: $(BUILD_DIR)/governor.elf
@echo 'Size of modules:'
- @$(SIZE) -B -t --common $(OBJS)
+ @$(SIZE) -B -d -t --common $(OBJS)
@echo 'Size of governor:'
- @$(SIZE) -B $(BUILD_DIR)/governor.elf
+ @$(SIZE) -B -d $<
+
+all: $(BUILD_DIR)/governor.hex print_size
clean:
- rm -rf ./$(BUILD_DIR)/*
+ @rm -rf ./$(BUILD_DIR)/*
-.PHONY: all clean
+.PHONY: all clean print_size
-include $(DEPS)
diff --git a/sw/riscv/SC64.ld b/sw/riscv/SC64.ld
index 30e29bd..2e8471e 100644
--- a/sw/riscv/SC64.ld
+++ b/sw/riscv/SC64.ld
@@ -15,7 +15,7 @@ SECTIONS {
. = ALIGN(4);
_stext = .;
*(.text .text.* .gnu.linkonce.t.*)
- *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.rdata .rodata .rodata.* .gnu.linkonce.r.*)
. = ALIGN(4);
_etext = .;
} > ram AT > rom
@@ -37,7 +37,7 @@ SECTIONS {
. = ALIGN(4);
_sbss = .;
*(.sbss .sbss.* .gnu.linkonce.sb.*)
- *(.scommon)
+ *(.scommon .scommon.*)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
diff --git a/sw/riscv/src/startup.S b/sw/riscv/src/startup.S
index 0eb3670..b7dd186 100644
--- a/sw/riscv/src/startup.S
+++ b/sw/riscv/src/startup.S
@@ -1,5 +1,8 @@
-.section .text.reset_handler
+#define STR(x) #x
+#define XSTR(s) STR(s)
+#define VERSION XSTR(__SC64_VERSION)
+.section .text.reset_handler
reset_handler:
.global reset_handler
@@ -10,6 +13,17 @@ reset_handler:
la sp, __stack_pointer$
+ j init_text
+
+ .org 0x18, 0x00
+
+header_text_info:
+ .ascii "byMFinPL"
+ .ascii "SummerGovernor64"
+ .ascii VERSION
+
+ .org 0x40, 0x20
+
init_text:
la a0, _sitext
la a1, _stext