diff --git a/Makefile b/Makefile index 7f199bc7..bb645094 100644 --- a/Makefile +++ b/Makefile @@ -166,7 +166,6 @@ ifeq ($(filter $(TARGET_STRING), sm64.jp.f3d_old sm64.us.f3d_old sm64.eu.f3d_new COMPARE := 0 endif - # UNF - whether to use UNFLoader flashcart library # 1 - includes code in ROM # 0 - does not @@ -175,6 +174,23 @@ $(eval $(call validate-option,UNF,0 1)) ifeq ($(UNF),1) DEFINES += UNF=1 SRC_DIRS += src/usb + ULTRALIB := ultra_d +else + ULTRALIB := ultra_rom +endif + + +# ISVPRINT - whether to fake IS-Viewer presence, +# allowing for usage of CEN64 (and possibly Project64) to print messages to terminal. +# 1 - includes code in ROM +# 0 - does not +ISVPRINT ?= 0 +$(eval $(call validate-option,ISVPRINT,0 1)) +ifeq ($(ISVPRINT),1) + DEFINES += ISVPRINT=1 + ULTRALIB := ultra_d +else + ULTRALIB := ultra_rom endif # HVQM - whether to use HVQM fmv library @@ -724,7 +740,7 @@ $(BUILD_DIR)/libz.a: $(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 @$(PRINT) "$(GREEN)Linking ELF file: $(BLUE)$@ $(NO_COL)\n" - $(V)$(LD) -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) -lultra_rom -Llib -lgcc -lnustd -lhvqm2 -lz -lgoddard -u sprintf -u osMapTLB + $(V)$(LD) -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 -lgcc -lnustd -lhvqm2 -lz -lgoddard -u sprintf -u osMapTLB # Build ROM $(ROM): $(ELF) diff --git a/lib/n64/libultra_d.a b/lib/n64/libultra_d.a new file mode 100644 index 00000000..4480c969 Binary files /dev/null and b/lib/n64/libultra_d.a differ diff --git a/sm64.ld b/sm64.ld index e65c7c49..09f80e74 100755 --- a/sm64.ld +++ b/sm64.ld @@ -132,7 +132,11 @@ SECTIONS BUILD_DIR/src/usb*.o(.text); #endif BUILD_DIR/src/audio*.o(.text); +#if defined(ISVPRINT) || defined(UNF) + */libultra_d.a:*.o(.text); +#else */libultra_rom.a:*.o(.text); +#endif */libnustd.a:*.o(.text); */libgcc.a:*.o(.text); #ifdef GZIP @@ -154,7 +158,11 @@ SECTIONS #ifdef GZIP */libz.a:*.o(.*data*); #endif +#if defined(ISVPRINT) || defined(UNF) + */libultra_d.a:*.o(.*data*); +#else */libultra_rom.a:*.o(.*data*); +#endif #ifdef HVQM */libhvqm2.a:*.o(.*data*); #endif @@ -170,7 +178,11 @@ SECTIONS BUILD_DIR/src/usb*.o(.rodata*); #endif BUILD_DIR/src/audio*.o(.rodata*); - */libultra_rom.a:*.o(.rodata*); +#if defined(ISVPRINT) || defined(UNF) + */libultra_d.a:*.o(.*rodata*); +#else + */libultra_rom.a:*.o(.*rodata*); +#endif */libgcc.a:*.o(.rodata*); #ifdef GZIP */libz.a:*.o(.rodata*); @@ -196,9 +208,15 @@ SECTIONS BUILD_DIR/src/gzip*.o(.bss*); #endif BUILD_DIR/src/audio*.o(.*bss*); +#if defined(ISVPRINT) || defined(UNF) + */libultra_d.a:*.o(COMMON); + */libultra_d.a:*.o(.scommon); + */libultra_d.a:*.o(.*bss*); +#else */libultra_rom.a:*.o(COMMON); */libultra_rom.a:*.o(.scommon); */libultra_rom.a:*.o(.*bss*); +#endif #ifdef HVQM */libhvqm2.a:*.o(.bss*); #endif diff --git a/src/audio/internal.h b/src/audio/internal.h index a834532f..4446c6b1 100644 --- a/src/audio/internal.h +++ b/src/audio/internal.h @@ -63,6 +63,10 @@ #define FLOAT_CAST(x) (f32) (s32) (x) #endif +#if defined(ISVPRINT) || defined(UNF) +#define stubbed_printf osSyncPrintf +#else + // No-op printf macro which leaves string literals in rodata in IDO. IDO // doesn't support variadic macros, so instead we let the parameter list // expand to a no-op comma expression. Another possibility is that it might @@ -73,6 +77,7 @@ #else #define stubbed_printf(...) #endif +#endif #ifdef VERSION_EU #define eu_stubbed_printf_0(msg) stubbed_printf(msg) diff --git a/src/game/main.c b/src/game/main.c index ede6fb26..fa082f9f 100644 --- a/src/game/main.c +++ b/src/game/main.c @@ -319,13 +319,11 @@ void thread3_main(UNUSED void *arg) { crash_screen_init(); #endif -#ifdef UNF - debug_printf("Super Mario 64\n"); - debug_printf("Built by: %s\n", __username__); - debug_printf("Date : %s\n", __datetime__); - debug_printf("Compiler: %s\n", __compiler__); - debug_printf("Linker : %s\n", __linker__); -#endif + osSyncPrintf("Super Mario 64\n"); + osSyncPrintf("Built by: %s\n", __username__); + osSyncPrintf("Date : %s\n", __datetime__); + osSyncPrintf("Compiler: %s\n", __compiler__); + osSyncPrintf("Linker : %s\n", __linker__); create_thread(&gSoundThread, 4, thread4_sound, NULL, gThread4Stack + 0x2000, 20); osStartThread(&gSoundThread); @@ -477,14 +475,33 @@ void thread1_idle(UNUSED void *arg) { } } -static void ClearRAM(void) +void ClearRAM(void) { bzero(_mainSegmentEnd, (size_t)osMemSize - (size_t)OS_K0_TO_PHYSICAL(_mainSegmentEnd)); } +#ifdef ISVPRINT +extern u32 gISVDbgPrnAdrs; +extern u32 gISVFlag; + +void osInitialize_fakeisv() { + /* global flag to skip `__checkHardware_isv` from being called. */ + gISVFlag = 0x49533634; // 'IS64' + + /* printf writes go to this address, cen64(1) has this hardcoded. */ + gISVDbgPrnAdrs = 0x13FF0000; + + /* `__printfunc`, used by `osSyncPrintf` will be set. */ + __osInitialize_isv(); +} +#endif + void main_func(void) { ClearRAM(); __osInitialize_common(); +#ifdef ISVPRINT + osInitialize_fakeisv(); +#endif create_thread(&gIdleThread, 1, thread1_idle, NULL, gIdleThreadStack + 0x800, 100); osStartThread(&gIdleThread); diff --git a/src/game/memory.c b/src/game/memory.c index 5dc82ad4..687c99a8 100644 --- a/src/game/memory.c +++ b/src/game/memory.c @@ -346,6 +346,7 @@ void *load_segment_decompress(s32 segment, u8 *srcStart, u8 *srcEnd) { dma_read(compressed, srcStart, srcEnd); dest = main_pool_alloc(*size, MEMORY_POOL_LEFT); if (dest != NULL) { + osSyncPrintf("start decompress\n"); #ifdef GZIP expand_gzip(compressed, dest, compSize, (u32)size); #elif RNC1 @@ -357,6 +358,7 @@ void *load_segment_decompress(s32 segment, u8 *srcStart, u8 *srcEnd) { #elif MIO0 decompress(compressed, dest); #endif + osSyncPrintf("end decompress\n"); set_segment_base_addr(segment, dest); main_pool_free(compressed); } else { diff --git a/src/goddard/renderer.c b/src/goddard/renderer.c index e569b6d8..5093d573 100644 --- a/src/goddard/renderer.c +++ b/src/goddard/renderer.c @@ -869,6 +869,11 @@ f64 stub_renderer_1(UNUSED f64 x) { return 0.0; } + +#if defined(ISVPRINT) || defined(UNF) +#define stubbed_printf osSyncPrintf +#else + /* 249BCC -> 24A19C */ void gd_printf(const char *format, ...) { s32 i; @@ -967,6 +972,7 @@ void gd_printf(const char *format, ...) { fatal_printf("printf too long"); } } +#endif /* 24A19C -> 24A1D4 */ void gd_exit(UNUSED s32 code) { diff --git a/src/goddard/renderer.h b/src/goddard/renderer.h index dfd9fe78..e4c8ed36 100644 --- a/src/goddard/renderer.h +++ b/src/goddard/renderer.h @@ -43,7 +43,12 @@ f32 get_time_scale(void); f64 gd_sin_d(f64 x); f64 gd_cos_d(f64 x); f64 gd_sqrt_d(f64 x); + +#if defined(ISVPRINT) || defined(UNF) +#define gd_printf osSyncPrintf +#else void gd_printf(const char *format, ...); +#endif void gd_exit(UNUSED s32 code) NORETURN; void gd_free(void *ptr); void *gd_allocblock(u32 size); diff --git a/src/usb/debug.h b/src/usb/debug.h index fd39ca73..ebe7ea69 100644 --- a/src/usb/debug.h +++ b/src/usb/debug.h @@ -9,7 +9,7 @@ #define DEBUG_MODE 1 // Enable/Disable debug mode #define DEBUG_INIT_MSG 1 // Print a message when debug mode has initialized #define USE_FAULTTHREAD 1 // Create a fault detection thread (libultra only) - #define OVERWRITE_OSPRINT 0 // Replaces osSyncPrintf calls with debug_printf (libultra only) + #define OVERWRITE_OSPRINT 1 // Replaces osSyncPrintf calls with debug_printf (libultra only) #define MAX_COMMANDS 25 // The max amount of user defined commands possible // Fault thread definitions (libultra only)