From 3ba7236e649835cc342de9875f6bee2b364ee2e2 Mon Sep 17 00:00:00 2001 From: CrashOveride95 Date: Sun, 12 Sep 2021 15:08:08 -0400 Subject: [PATCH 1/5] Only build libz/goddard if required --- Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 36d56e15..5dfe96ef 100644 --- a/Makefile +++ b/Makefile @@ -71,6 +71,8 @@ COMPRESS ?= rnc1 $(eval $(call validate-option,COMPRESS,mio0 yay0 gzip rnc1 rnc2 uncomp)) ifeq ($(COMPRESS),gzip) DEFINES += GZIP=1 + LIBZRULE := $(BUILD_DIR)/libz.a + LIBZLINK := -lz else ifeq ($(COMPRESS),rnc1) DEFINES += RNC1=1 else ifeq ($(COMPRESS),rnc2) @@ -226,6 +228,8 @@ endif GODDARD ?= 0 $(eval $(call validate-option,GODDARD,0 1)) ifeq ($(GODDARD),1) + GODDARDRULE := $(BUILD_DIR)/libgoddard.a + GODDARDLINK := -lgoddard DEFINES += GODDARD=1 endif @@ -761,9 +765,9 @@ $(BUILD_DIR)/libz.a: $(LIBZ_O_FILES) $(V)$(AR) rcs -o $@ $(LIBZ_O_FILES) # Link SM64 ELF file -$(ELF): $(O_FILES) $(YAY0_OBJ_FILES) $(SEG_FILES) $(BUILD_DIR)/$(LD_SCRIPT) undefined_syms.txt $(BUILD_DIR)/libz.a $(BUILD_DIR)/libgoddard.a +$(ELF): $(O_FILES) $(YAY0_OBJ_FILES) $(SEG_FILES) $(BUILD_DIR)/$(LD_SCRIPT) undefined_syms.txt $(LIBZRULE) $(GODDARDRULE) @$(PRINT) "$(GREEN)Linking ELF file: $(BLUE)$@ $(NO_COL)\n" - $(V)$(LD) --gc-sections -L $(BUILD_DIR) -T undefined_syms.txt -T $(BUILD_DIR)/$(LD_SCRIPT) -Map $(BUILD_DIR)/sm64.$(VERSION).map --no-check-sections $(addprefix -R ,$(SEG_FILES)) -o $@ $(O_FILES) -L$(LIBS_DIR) -l$(ULTRALIB) -Llib -Llib/gcclib/$(LIBGCCDIR) -lgcc -lnustd -lhvqm2 -lz -lgoddard -u sprintf -u osMapTLB + $(V)$(LD) --gc-sections -L $(BUILD_DIR) -T undefined_syms.txt -T $(BUILD_DIR)/$(LD_SCRIPT) -Map $(BUILD_DIR)/sm64.$(VERSION).map --no-check-sections $(addprefix -R ,$(SEG_FILES)) -o $@ $(O_FILES) -L$(LIBS_DIR) -l$(ULTRALIB) -Llib -Llib/gcclib/$(LIBGCCDIR) -lgcc -lnustd -lhvqm2 $(LIBZLINK) $(GODDARDLINK) -u sprintf -u osMapTLB # Build ROM $(ROM): $(ELF) From 77dd0045fa33b13527c258d8221b418bb4a8e8ff Mon Sep 17 00:00:00 2001 From: CrashOveride95 Date: Sun, 12 Sep 2021 19:33:32 -0400 Subject: [PATCH 2/5] Fix UNF by moving it's code to engine segment Additionally update UNF code to latest master --- README.md | 2 ++ sm64.ld | 8 ++++---- src/boot/main.c | 7 ++++--- src/boot/memory.c | 4 ---- src/game/game_init.c | 4 ---- src/usb/debug.c | 11 +++++++--- src/usb/usb.c | 48 ++++++++++++++++++++++---------------------- src/usb/usb.h | 2 +- 8 files changed, 43 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 42e6b56c..37499626 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,8 @@ To build with UNF, run make with ``UNF=1``. Further instructions can be found at the [official repository](https://github.com/buu342/N64-UNFLoader) +**NOTE: Closing the UNFLoader window will result in your game eventually hanging due to lacking a USB device to send messages to, so beware of that** + ## Multi-Save support The repository supports SRAM in addition to EEPROM. The standard save data functions are #ifdef'd to accommedate this. diff --git a/sm64.ld b/sm64.ld index b96f01ec..a6d2a0fb 100755 --- a/sm64.ld +++ b/sm64.ld @@ -132,7 +132,6 @@ SECTIONS BUILD_DIR/src/boot*.o(.text); BUILD_DIR/src/hvqm*.o(.text); - BUILD_DIR/src/usb*.o(.text); BUILD_DIR/src/audio*.o(.text); #if defined(ISVPRINT) || defined(UNF) */libultra_d.a:*.o(.text); @@ -148,7 +147,6 @@ SECTIONS /* data */ BUILD_DIR/src/boot*.o(.*data*); - BUILD_DIR/src/usb*.o(.*data*); BUILD_DIR/src/audio*.o(.*data*); #if defined(ISVPRINT) || defined(UNF) */libultra_d.a:*.o(.*data*); @@ -163,7 +161,6 @@ SECTIONS /* rodata */ BUILD_DIR/src/boot*.o(.rodata*); - BUILD_DIR/src/usb*.o(.rodata*); BUILD_DIR/src/audio*.o(.rodata*); #if defined(ISVPRINT) || defined(UNF) */libultra_d.a:*.o(.*rodata*); @@ -181,7 +178,6 @@ SECTIONS { BUILD_DIR/src/boot*.o(.*bss*); BUILD_DIR/src/hvqm*.o(.*bss*); - BUILD_DIR/src/usb*.o(.*bss*); BUILD_DIR/src/audio*.o(.*bss*); #if defined(ISVPRINT) || defined(UNF) */libultra_d.a:*.o(COMMON); @@ -206,19 +202,23 @@ SECTIONS { BUILD_DIR/src/game*.o(.text); BUILD_DIR/src/engine*.o(.text); + BUILD_DIR/src/usb*.o(.text); /* data */ BUILD_DIR/src/game*.o(.*data*); BUILD_DIR/src/engine*.o(.data*); BUILD_DIR/src/engine*.o(.sdata*); + BUILD_DIR/src/usb*.o(.*data*); /* rodata */ BUILD_DIR/src/game*.o(.rodata*); BUILD_DIR/src/engine*.o(.rodata*); + BUILD_DIR/src/usb*.o(.rodata*); } END_SEG(engine) BEGIN_NOLOAD(engine) { BUILD_DIR/src/game*.o(.*bss*); BUILD_DIR/src/engine*.o(.bss*); + BUILD_DIR/src/usb*.o(.*bss*); . = ALIGN(0x40); } END_NOLOAD(engine) diff --git a/src/boot/main.c b/src/boot/main.c index 73b0cc04..65878bd4 100644 --- a/src/boot/main.c +++ b/src/boot/main.c @@ -319,6 +319,10 @@ void thread3_main(UNUSED void *arg) { crash_screen_init(); #endif +#ifdef UNF + debug_initialize(); +#endif + #ifdef DEBUG osSyncPrintf("Super Mario 64\n"); osSyncPrintf("Built by: %s\n", __username__); @@ -462,9 +466,6 @@ void thread1_idle(UNUSED void *arg) { osViSetSpecialFeatures(OS_VI_DITHER_FILTER_ON); osViSetSpecialFeatures(OS_VI_GAMMA_OFF); osCreatePiManager(OS_PRIORITY_PIMGR, &gPIMesgQueue, gPIMesgBuf, ARRAY_COUNT(gPIMesgBuf)); -#ifdef UNF - debug_initialize(); -#endif create_thread(&gMainThread, 3, thread3_main, NULL, gThread3Stack + 0x2000, 100); osStartThread(&gMainThread); diff --git a/src/boot/memory.c b/src/boot/memory.c index 367104b6..90c36741 100644 --- a/src/boot/memory.c +++ b/src/boot/memory.c @@ -17,10 +17,6 @@ #if defined(RNC1) || defined(RNC2) #include #endif -#ifdef UNF -#include "usb/usb.h" -#include "usb/debug.h" -#endif // round up to the next multiple diff --git a/src/game/game_init.c b/src/game/game_init.c index 4337d051..bc5bc79f 100644 --- a/src/game/game_init.c +++ b/src/game/game_init.c @@ -22,10 +22,6 @@ #ifdef HVQM #include #endif -#ifdef UNF -#include "usb/usb.h" -#include "usb/debug.h" -#endif #ifdef SRAM #include "sram.h" #endif diff --git a/src/usb/debug.c b/src/usb/debug.c index 68e0d94c..e6bd4e94 100644 --- a/src/usb/debug.c +++ b/src/usb/debug.c @@ -449,7 +449,11 @@ https://github.com/buu342/N64-UNFLoader ==============================*/ void _debug_assert(const char* expression, const char* file, int line) - { + { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" + volatile char crash; + // Set the assert data assert_expr = expression; assert_line = line; @@ -460,8 +464,9 @@ https://github.com/buu342/N64-UNFLoader debug_printf("Assertion failed in file '%s', line %d.\n", assert_file, assert_line); #endif - // Intentionally cause a null pointer exception - *((char*)(NULL)) = 0; + // Intentionally cause a TLB exception on load/instruction fetch + crash = *(volatile char *)1; +#pragma GCC diagnostic pop } diff --git a/src/usb/usb.c b/src/usb/usb.c index 43bfdb00..46f56cf9 100644 --- a/src/usb/usb.c +++ b/src/usb/usb.c @@ -385,20 +385,7 @@ static void usb_findcart() // Check if we have an EverDrive if (buff == ED7_VERSION || buff == ED3_VERSION) - { - // Initialize the PI - IO_WRITE(PI_STATUS_REG, 3); - IO_WRITE(PI_BSD_DOM1_LAT_REG, 0x40); - IO_WRITE(PI_BSD_DOM1_PWD_REG, 0x12); - IO_WRITE(PI_BSD_DOM1_PGS_REG, 0x07); - IO_WRITE(PI_BSD_DOM1_RLS_REG, 0x03); - IO_WRITE(PI_BSD_DOM2_LAT_REG, 0x05); - IO_WRITE(PI_BSD_DOM2_PWD_REG, 0x0C); - IO_WRITE(PI_BSD_DOM2_PGS_REG, 0x0D); - IO_WRITE(PI_BSD_DOM2_RLS_REG, 0x02); - IO_WRITE(PI_BSD_DOM1_LAT_REG, 0x04); - IO_WRITE(PI_BSD_DOM1_PWD_REG, 0x0C); - + { // Set the USB mode usb_everdrive_writereg(ED_REG_SYSCFG, 0); usb_everdrive_writereg(ED_REG_USBCFG, ED_USBMODE_RDNOP); @@ -453,7 +440,7 @@ void usb_write(int datatype, const void* data, int size) @return The data header, or 0 ==============================*/ -u32 usb_poll() +unsigned long usb_poll() { // If no debug cart exists, stop if (usb_cart == CART_NONE) @@ -604,7 +591,7 @@ static s8 usb_64drive_wait() #endif // Took too long, abort - if((timeout++) > 1000000) + if((timeout++) > 10000) return -1; } while((ret >> 8) & D64_CI_BUSY); @@ -642,9 +629,10 @@ static void usb_64drive_setwritable(u8 enable) Waits for the 64Drive's USB to be idle ==============================*/ -static void usb_64drive_waitidle() +static int usb_64drive_waitidle() { u32 status __attribute__((aligned(8))); + u32 timeout = 0; do { #ifdef LIBDRAGON @@ -657,8 +645,11 @@ static void usb_64drive_waitidle() #endif #endif status = (status >> 4) & D64_USB_BUSY; + if (timeout++ > 128) + return 0; } while(status != D64_USB_IDLE); + return 1; } @@ -724,7 +715,8 @@ static void usb_64drive_write(int datatype, const void* data, int size) int read = 0; // Spin until the write buffer is free and then set the cartridge to write mode - usb_64drive_waitidle(); + if (!usb_64drive_waitidle()) + return; usb_64drive_setwritable(TRUE); // Write data to SDRAM until we've finished @@ -749,7 +741,11 @@ static void usb_64drive_write(int datatype, const void* data, int size) } // Spin until the write buffer is free - usb_64drive_waitidle(); + if (!usb_64drive_waitidle()) + { + usb_64drive_setwritable(FALSE); + return; + } // Set up DMA transfer between RDRAM and the PI #ifdef LIBDRAGON @@ -1062,7 +1058,8 @@ static void usb_everdrive_writedata(void* buff, u32 pi_address, u32 len) static void usb_everdrive_writereg(u64 reg, u32 value) { - usb_everdrive_writedata(&value, ED_GET_REGADD(reg), sizeof(u32)); + u32 val __attribute__((aligned(8))) = value; + usb_everdrive_writedata(&val, ED_GET_REGADD(reg), sizeof(u32)); } @@ -1073,12 +1070,15 @@ static void usb_everdrive_writereg(u64 reg, u32 value) static void usb_everdrive_usbbusy() { + u32 timeout = 0; u32 val __attribute__((aligned(8))); - do + do { usb_everdrive_readreg(ED_REG_USBCFG, &val); - } - while ((val & ED_USBSTAT_ACT) != 0); + if (timeout++ != 8192) + continue; + usb_everdrive_writereg(ED_REG_USBCFG, ED_USBMODE_RDNOP); + } while ((val & ED_USBSTAT_ACT) != 0); } @@ -1690,4 +1690,4 @@ static void usb_sc64_read(void) // Invalidate cache osInvalDCache(usb_buffer, BUFFER_SIZE); #endif -} \ No newline at end of file +} diff --git a/src/usb/usb.h b/src/usb/usb.h index 3b2ea8ab..813b1b28 100644 --- a/src/usb/usb.h +++ b/src/usb/usb.h @@ -80,7 +80,7 @@ @return The data header, or 0 ==============================*/ - extern unsigned int usb_poll(); + extern unsigned long usb_poll(); /*============================== From 7f872116c3bc2283f2c16588154564cc3f58296e Mon Sep 17 00:00:00 2001 From: CrashOveride95 Date: Sun, 12 Sep 2021 20:14:45 -0400 Subject: [PATCH 3/5] Add CI support --- Makefile | 13 +++++++------ README.md | 6 ++++++ tools/BinPNG.py | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 6 deletions(-) create mode 100755 tools/BinPNG.py diff --git a/Makefile b/Makefile index 5dfe96ef..ac9b921e 100644 --- a/Makefile +++ b/Makefile @@ -445,6 +445,7 @@ FILESIZER := $(TOOLS_DIR)/filesizer N64CKSUM := $(TOOLS_DIR)/n64cksum N64GRAPHICS := $(TOOLS_DIR)/n64graphics N64GRAPHICS_CI := $(TOOLS_DIR)/n64graphics_ci +BINPNG := $(TOOLS_DIR)/BinPNG.py TEXTCONV := $(TOOLS_DIR)/textconv AIFF_EXTRACT_CODEBOOK := $(TOOLS_DIR)/aiff_extract_codebook VADPCM_ENC := $(TOOLS_DIR)/vadpcm_enc @@ -588,14 +589,14 @@ $(BUILD_DIR)/%.inc.c: %.png $(V)$(N64GRAPHICS) -s $(TEXTURE_ENCODING) -i $@ -g $< -f $(lastword ,$(subst ., ,$(basename $<))) # Color Index CI8 -$(BUILD_DIR)/%.ci8: %.ci8.png - $(call print,Converting:,$<,$@) - $(V)$(N64GRAPHICS_CI) -i $@ -g $< -f ci8 +$(BUILD_DIR)/%.ci8.inc.c: %.ci8.png + $(call print,Converting CI:,$<,$@) + $(V)$(BINPNG) $< $@ 8 # Color Index CI4 -$(BUILD_DIR)/%.ci4: %.ci4.png - $(call print,Converting:,$<,$@) - $(V)$(N64GRAPHICS_CI) -i $@ -g $< -f ci4 +$(BUILD_DIR)/%.ci4.inc.c: %.ci4.png + $(call print,Converting CI:,$<,$@) + $(V)$(BINPNG) $< $@ 4 #==============================================================================# diff --git a/README.md b/README.md index 37499626..28ff7776 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,12 @@ Requirements are the same as regular SM64, however a GCC MIPS cross compiler is also required. If you're on Debian-like Linux, you can use the ``gcc-mips-linux-gnu`` package. The toolchain that comes with my SDK is also supported. +## Additional Prerequisites + +BinPNG (the CI texture converter) requires some python3 dependencies. Use pip to install them. + +``pip install pypng bitstring`` + ## UNFLoader support The repository supports UNFLoader for debugging. diff --git a/tools/BinPNG.py b/tools/BinPNG.py new file mode 100755 index 00000000..d6b87f56 --- /dev/null +++ b/tools/BinPNG.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +import struct +import png +import math +from bitstring import * +import sys +#convert png to bin + +def MakeCI(file,Bpp): + r = png.Reader(file) + re = r.read() + Pal = re[3]['palette'] + Pbin = [] + shifts = [3,3,3,7] + for p in Pal: + b = [a>>s for a,s in zip(p,shifts)] + if len(p)==4: + b = pack('3*uint:5,uint:1',*b) + else: + b = pack('3*uint:5,uint:1',*b,1) + Pbin.append(b.bytes) + bin = [] + for p in re[2]: + for w in range(0,re[0],(8//Bpp)): + b = p[w:w+(8//Bpp)] + b = pack('%d*uint:%d'%((8//Bpp),Bpp),*b) + bin.append(b.bytes) + return [bin,Pbin] + +if __name__=='__main__': + [texture,palette] = MakeCI(sys.argv[1],int(sys.argv[3])) + pname = sys.argv[2].split('.') + pname.insert(2,'pal') + pname = '.'.join(pname) + p = open(pname,'w') + t = open(sys.argv[2],'w') + [t.write('0x{:02X},'.format(tex[0])) for tex in texture] + [p.write('0x{:02X},0x{:02X},'.format(pal[0],pal[1])) for pal in palette] + t.close() + p.close() \ No newline at end of file From c049b71dadbc2fe608daa80e918cf19362561fdf Mon Sep 17 00:00:00 2001 From: CrashOveride95 Date: Sun, 12 Sep 2021 20:50:29 -0400 Subject: [PATCH 4/5] Fix pallete for CI fast64 --- tools/BinPNG.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/BinPNG.py b/tools/BinPNG.py index d6b87f56..6f9c95c5 100755 --- a/tools/BinPNG.py +++ b/tools/BinPNG.py @@ -31,6 +31,7 @@ if __name__=='__main__': [texture,palette] = MakeCI(sys.argv[1],int(sys.argv[3])) pname = sys.argv[2].split('.') pname.insert(2,'pal') + pname = pname[:3] pname = '.'.join(pname) p = open(pname,'w') t = open(sys.argv[2],'w') From 0ffdab82ce0422b799874a0d0f9cad177419c03b Mon Sep 17 00:00:00 2001 From: Fazana <52551480+FazanaJ@users.noreply.github.com> Date: Mon, 13 Sep 2021 12:05:25 +0100 Subject: [PATCH 5/5] Reverted the libz and goddard commit Couldn't get it to build :pensive: --- Makefile | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 39d3ec10..30c99c92 100644 --- a/Makefile +++ b/Makefile @@ -71,8 +71,6 @@ COMPRESS ?= rnc1 $(eval $(call validate-option,COMPRESS,mio0 yay0 gzip rnc1 rnc2 uncomp)) ifeq ($(COMPRESS),gzip) DEFINES += GZIP=1 - LIBZRULE := $(BUILD_DIR)/libz.a - LIBZLINK := -lz else ifeq ($(COMPRESS),rnc1) DEFINES += RNC1=1 else ifeq ($(COMPRESS),rnc2) @@ -242,8 +240,6 @@ endif GODDARD ?= 0 $(eval $(call validate-option,GODDARD,0 1)) ifeq ($(GODDARD),1) - GODDARDRULE := $(BUILD_DIR)/libgoddard.a - GODDARDLINK := -lgoddard DEFINES += GODDARD=1 endif @@ -802,9 +798,9 @@ $(BUILD_DIR)/goddard.txt: $(BUILD_DIR)/sm64_prelim.elf $(V)python3 tools/getGoddardSize.py $(BUILD_DIR)/sm64_prelim.map $(VERSION) # Link SM64 ELF file -$(ELF): $(BUILD_DIR)/sm64_prelim.elf $(O_FILES) $(YAY0_OBJ_FILES) $(SEG_FILES) $(BUILD_DIR)/$(LD_SCRIPT) undefined_syms.txt $(LIBZRULE) $(GODDARDRULE) +$(ELF): $(BUILD_DIR)/sm64_prelim.elf $(O_FILES) $(YAY0_OBJ_FILES) $(SEG_FILES) $(BUILD_DIR)/$(LD_SCRIPT) undefined_syms.txt $(BUILD_DIR)/libz.a $(BUILD_DIR)/libgoddard.a @$(PRINT) "$(GREEN)Linking ELF file: $(BLUE)$@ $(NO_COL)\n" - $(V)$(LD) --gc-sections -L $(BUILD_DIR) -T undefined_syms.txt -T $(BUILD_DIR)/$(LD_SCRIPT) -T goddard.txt -Map $(BUILD_DIR)/sm64.$(VERSION).map --no-check-sections $(addprefix -R ,$(SEG_FILES)) -o $@ $(O_FILES) -L$(LIBS_DIR) -l$(ULTRALIB) -Llib -Llib/gcclib/$(LIBGCCDIR) -lgcc -lnustd -lhvqm2 $(LIBZLINK) $(GODDARDLINK) -u sprintf -u osMapTLB + $(V)$(LD) --gc-sections -L $(BUILD_DIR) -T undefined_syms.txt -T $(BUILD_DIR)/$(LD_SCRIPT) -T goddard.txt -Map $(BUILD_DIR)/sm64.$(VERSION).map --no-check-sections $(addprefix -R ,$(SEG_FILES)) -o $@ $(O_FILES) -L$(LIBS_DIR) -l$(ULTRALIB) -Llib $(LINK_LIBRARIES) -u sprintf -u osMapTLB -Llib/gcclib/$(LIBGCCDIR) -lgcc -lnustd -lhvqm2 # Build ROM $(ROM): $(ELF)