diff --git a/common.py b/common.py index dfd3b6fa..0cb7f39c 100644 --- a/common.py +++ b/common.py @@ -320,7 +320,9 @@ CPLFLAGS = [ ] COMMON_DEFINES = [ "-d _LANGUAGE_C", - "-d F3DEX_GBI_2" + "-d F3DEX_GBI_2", + "-d NDEBUG", + "-d DEBUG=0" ] DOL_DEFINES = COMMON_DEFINES + [] REL_DEFINES = COMMON_DEFINES + [] @@ -329,6 +331,11 @@ BASE_DOL_CFLAGS = CFLAGS + [ "-sdata 8", f"-sdata2 {DOL_SDATA2_SIZE}" ] + DOL_DEFINES +BOOT_CFLAGS = CFLAGS + [ + "-inline on", + "-sdata 0", + "-sdata2 0" +] + DOL_DEFINES BASE_REL_CFLAGS = CFLAGS + [ "-sdata 0", f"-sdata2 {REL_SDATA2_SIZE}", @@ -377,6 +384,7 @@ JSYSTEM_BASE = [ JSYSTEM_CFLAGS = ' '.join(JSYSTEM_BASE + LOCAL_CFLAGS) DOL_CFLAGS = ' '.join(BASE_DOL_CFLAGS + LOCAL_CFLAGS) +DOL_BOOT_CFLAGS = ' '.join(BOOT_CFLAGS + LOCAL_CFLAGS); # TODO: this uses C++ but there's some issues with ppcdis, real flags: ' '.join(CPLFLAGS + BOOT_CFLAGS + LOCAL_CFLAGS); SDK_FLAGS = ' '.join(SDK_CFLAG + LOCAL_CFLAGS) ALIGN16 = ' '.join(BASE_DOL_CFLAGS + LOCAL_CFLAGS + ALIGN16_CFLAG) DOL_CPPFLAGS = ' '.join(CPLFLAGS + BASE_DOL_CFLAGS + LOCAL_CFLAGS) diff --git a/config/analysis_overrides.yml b/config/analysis_overrides.yml index 3c43cf5e..3d09e5dc 100644 --- a/config/analysis_overrides.yml +++ b/config/analysis_overrides.yml @@ -1,6 +1,8 @@ blocked_pointers: - 0x800A8440 - 0x800A8514 +blocked_targets: + - 0x800A97E0 # boot.c local static const tbl, also start of .rodata forced_types: 0x80003534: FUNCTION 0x80005468: FUNCTION diff --git a/config/assets.yml b/config/assets.yml index 1c9e5ac2..4d01fead 100644 --- a/config/assets.yml +++ b/config/assets.yml @@ -3,7 +3,7 @@ config/dol.yml: addrs: [0x800b05e8, 0x800b05f4] __DateTime__: addrs: [0x800b05f4, 0x800b0608] - nintendo_hi_0.aw: + nintendo_hi_0: addrs: [0x800c3140, 0x800cca40] config/rel.yml: wipe1_v: diff --git a/config/dol_slices.yml b/config/dol_slices.yml index 41fac12e..33737b2e 100644 --- a/config/dol_slices.yml +++ b/config/dol_slices.yml @@ -9,6 +9,11 @@ TRK/mem_TRK.c: .init: [0x800034e0, 0x80003534] asm/__exception.s: .init: [0x80003534, 0x80005468] +boot.c: + .text: [0x800056c0, 0x8000663c] + .rodata: [0x800a97e0, 0x800a97e8] + .data: [0x800af860, 0x800afe50] + .bss: [0x800e2280, 0x800e2318] version.c: .data: [0x800b05e8, 0x800b0608] jaudio_NES/dummyprobe.c: diff --git a/config/rel_slices.yml b/config/rel_slices.yml index b8703268..586ad7d1 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -2,6 +2,9 @@ sys_vimgr.c: .text: [0x803703F8, 0x80370418] m_cockroach.c: .text: [0x80385430, 0x80385A80] +#m_controller.c: # TODO: uncomment when fsqrt's $localstatic$ issue is resolved +# .text: [0x80395BE8, 0x80396120] +# .rodata: [0x80641D20, 0x80641D50] m_debug_hayakawa.c: .text: [0x803965E4, 0x803973E8] .rodata: [0x80641D50, 0x80641D90] diff --git a/config/symbols.yml b/config/symbols.yml index 879137c3..e62e1973 100644 --- a/config/symbols.yml +++ b/config/symbols.yml @@ -3719,6 +3719,8 @@ global: 0x80218660: __osDisableShutdownTime 0x80218668: __osDisableShutdownLevel 0x80218670: __osShutdownTime + 0x80218680: __osResetSwitchPressed + 0x80218681: __osResetKeyStep 0x80218688: __osContinitialized 0x80218690: rootHeap__9JFWSystem 0x80218694: systemHeap__9JFWSystem diff --git a/configure.py b/configure.py index ae329ba1..0385a56b 100644 --- a/configure.py +++ b/configure.py @@ -615,6 +615,10 @@ class CSource(Source): self.cflags = c.JSYSTEM_CFLAGS self.cc = c.CC self.frank = False + elif path == "src/boot.c": + self.cflags = c.DOL_BOOT_CFLAGS + self.cc = c.CC + self.frank = False elif path.startswith("src/jaudio_NES"): self.cc = c.CC self.cflags = c.DOL_CPPFLAGS diff --git a/include/JSystem/JKernel/JKRDvdRipper.h b/include/JSystem/JKernel/JKRDvdRipper.h index 6e963737..65f8231d 100644 --- a/include/JSystem/JKernel/JKRDvdRipper.h +++ b/include/JSystem/JKernel/JKRDvdRipper.h @@ -2,17 +2,12 @@ #define JKRDVDRIPPER_H #include "types.h" +#include "JSystem/JKernel/JKREnum.h" #include "JSystem/JKernel/JKRDvdFile.h" #define SZP_BUFFERSIZE 1024 #define REF_BUFFERSIZE 0x1120 -enum JKRExpandSwitch { - EXPAND_SWITCH_DEFAULT, /* Do nothing? treated same as 2 */ - EXPAND_SWITCH_DECOMPRESS, /* Check for compression and decompress */ - EXPAND_SWITCH_NONE /* Do nothing */ -}; - struct SZPHeader { u32 magic; u32 decompSize; diff --git a/include/JSystem/JKernel/JKREnum.h b/include/JSystem/JKernel/JKREnum.h new file mode 100644 index 00000000..8652231b --- /dev/null +++ b/include/JSystem/JKernel/JKREnum.h @@ -0,0 +1,20 @@ +#ifndef JKRENUM_H +#define JKRENUM_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum JKRExpandSwitch { + EXPAND_SWITCH_DEFAULT, /* Do nothing? treated same as 2 */ + EXPAND_SWITCH_DECOMPRESS, /* Check for compression and decompress */ + EXPAND_SWITCH_NONE /* Do nothing */ +} JKRExpandSwitch; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/MSL_C/math.h b/include/MSL_C/math.h new file mode 100644 index 00000000..72e16597 --- /dev/null +++ b/include/MSL_C/math.h @@ -0,0 +1,20 @@ +#ifndef MATH_H +#define MATH_H + +#include "types.h" +#include "MSL_C/w_math.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PI 3.14159265358979323846 +#define F_PI ((f32)PI) + +#define SQRTF(f) (__frsqrte(f)) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/boot.h b/include/boot.h index 39c54d8b..060350aa 100644 --- a/include/boot.h +++ b/include/boot.h @@ -2,12 +2,35 @@ #define BOOT_H #include "types.h" +#include "dolphin/os/OSModule.h" +#include "dolphin/os/OSTime.h" #ifdef __cplusplus extern "C" { #endif -extern const char* boot_copyDate; +typedef struct boot_tbl_s { + const char* msg; + u16 param_upper; + u16 param_lower; +} boot_tbl_t; + +extern u32 convert_partial_address(u32 partial_addr); +extern void HotResetIplMenu(); + +extern void* boot_copyDate; +extern void* HotStartEntry; +extern OSTime InitialStartTime; +extern u8 boot_sound_initializing; + +typedef void(*HotStartProc)(); + +#define NMISaveArea (void*)0x811FFFC0 +OSModuleHeader* BaseModule : 0x800030C8; + +// TODO: this macro should probably go elsewhere +#define MAKE_PARTIAL_ADDRESS(segment, ofs) \ + (((segment) << 28) + (ofs & 0x01FFFFFF)) #ifdef __cplusplus } diff --git a/include/dolphin/os.h b/include/dolphin/os.h index fd69093f..02b32f29 100644 --- a/include/dolphin/os.h +++ b/include/dolphin/os.h @@ -6,6 +6,7 @@ #include "dolphin/os/OSInterrupt.h" #include "dolphin/os/OSMessage.h" #include "libforest/osreport.h" /* OSReport funcs */ +#include "dolphin/os/OSReset.h" #include "va_args.h" #ifdef __cplusplus @@ -37,7 +38,7 @@ extern void __OSCacheInit(); #define DOLPHIN_ASSERT(assertion) #endif -void OSResetSystem(u32, u32, u32); // goes in reset, but eh +//void OSResetSystem(u32, u32, u32); // goes in reset, but eh void OSInit(void); #define OS_CONSOLE_RETAIL4 0x00000004 diff --git a/include/dolphin/os/OSInterrupt.h b/include/dolphin/os/OSInterrupt.h index e149c15a..943cfa85 100644 --- a/include/dolphin/os/OSInterrupt.h +++ b/include/dolphin/os/OSInterrupt.h @@ -5,6 +5,10 @@ #include "dolphin/os/OSException.h" #include "types.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef s16 __OSInterrupt; typedef u32 OSInterruptMask; @@ -124,4 +128,9 @@ u32 __OSUnmaskInterrupts(u32); u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current); void __OSDispatchInterrupt(OSException exception, OSContext* context); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/dolphin/os/OSModule.h b/include/dolphin/os/OSModule.h new file mode 100644 index 00000000..ba06e28f --- /dev/null +++ b/include/dolphin/os/OSModule.h @@ -0,0 +1,72 @@ +#ifndef DOLPHIN_OSMODULE_H +#define DOLPHIN_OSMODULE_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OSModuleInfo_s OSModuleInfo; + +typedef struct OSModuleQueue_s { + OSModuleInfo* head; + OSModuleInfo* tail; +} OSModuleQueue; + +typedef struct OSModuleLink_s { + OSModuleInfo* next; + OSModuleInfo* prev; +} OSModuleLink; + +typedef struct OSModuleInfo_s { + u32 id; + OSModuleLink link; + u32 numSections; + u32 sectionInfoOfs; + u32 nameOfs; + u32 nameSize; + u32 version; +} OSModuleInfo; + +typedef struct OSModuleHeader_s { + OSModuleInfo info; + u32 bssSize; + u32 relOfs; + u32 impOfs; + u32 impSize; + + u8 prologSection; + u8 epilogSection; + u8 unresolvedSection; + u8 bssSection; + + u32 prolog; + u32 epilog; + u32 unresolved; + /* OS_MODULE_VERSION >= 2 */ + + u32 align; + u32 bssAlign; +} OSModuleHeader; + +typedef struct OSSectionInfo_s { + u32 offset; + u32 size; +} OSSectionInfo; + +#define OSGetSectionInfo(module) \ + ((OSSectionInfo*) (((OSModuleInfo*) (module))->sectionInfoOfs)) + +#define OS_SECTIONINFO_EXEC 1 +#define OS_SECTIONINFO_OFFSET(offset) ((offset) & ~OS_SECTIONINFO_EXEC) + +void OSSetStringTable (const void* strTable); +BOOL OSLink(OSModuleInfo* module, void* bss); +BOOL OSUnlink(OSModuleInfo* module); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/os/OSReset.h b/include/dolphin/os/OSReset.h new file mode 100644 index 00000000..a5d74d43 --- /dev/null +++ b/include/dolphin/os/OSReset.h @@ -0,0 +1,25 @@ +#ifndef OSRESET_H +#define OSRESET_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define OS_RESETCODE_RESTART 0x80000000 + +#define OS_RESET_RESTART 0 +#define OS_RESET_HOTRESET 1 /* Soft reset */ +#define OS_RESET_SHUTDOWN 2 + +u32 OSGetResetCode(); +void OSResetSystem(int reset, u32 resetCode, BOOL forceMenu); +BOOL OSGetResetSwitchState(); +void OSGetSaveRegion(void** start, void** end); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/pad.h b/include/dolphin/pad.h new file mode 100644 index 00000000..1c1980df --- /dev/null +++ b/include/dolphin/pad.h @@ -0,0 +1,28 @@ +#ifndef DOLPHIN_PAD_H +#define DOLPHIN_PAD_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PAD_BUTTON_LEFT 0x0001 +#define PAD_BUTTON_RIGHT 0x0002 +#define PAD_BUTTON_DOWN 0x0004 +#define PAD_BUTTON_UP 0x0008 +#define PAD_TRIGGER_Z 0x0010 +#define PAD_TRIGGER_R 0x0020 +#define PAD_TRIGGER_L 0x0040 +#define PAD_BUTTON_A 0x0100 +#define PAD_BUTTON_B 0x0200 +#define PAD_BUTTON_X 0x0400 +#define PAD_BUTTON_Y 0x0800 +#define PAD_BUTTON_MENU 0x1000 +#define PAD_BUTTON_START 0x1000 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/vi.h b/include/dolphin/vi.h index d3a5beb5..f80f35d3 100644 --- a/include/dolphin/vi.h +++ b/include/dolphin/vi.h @@ -10,6 +10,7 @@ extern "C" { void VISetBlack(BOOL); void VIWaitForRetrace(); void VIConfigurePan(u16 x_origin, u16 y_origin, u16 width, u16 height); +u32 VIGetRetraceCount(); #ifdef __cplusplus }; diff --git a/include/dvderr.h b/include/dvderr.h index 4157afa4..733aede1 100644 --- a/include/dvderr.h +++ b/include/dvderr.h @@ -10,6 +10,7 @@ extern "C" { #endif extern BOOL dvderr_draw(); +extern void dvderr_init(); #ifdef __cplusplus }; diff --git a/include/game.h b/include/game.h index a1a7c626..98ab71ee 100644 --- a/include/game.h +++ b/include/game.h @@ -2,6 +2,7 @@ #define GAME_H #include "types.h" +#include "game_h.h" #include "TwoHeadArena.h" #include "graph.h" #include "gamealloc.h" @@ -13,7 +14,7 @@ extern "C" { #endif /* sizeof(struct game_s) == 0xE0 */ -typedef struct game_s { +struct game_s { /* 0x0000 */ GRAPH* graph; /* 0x0004 */ void (*exec)(struct game_s* ); /* 0x0008 */ void (*cleanup)(struct game_s*); @@ -30,7 +31,7 @@ typedef struct game_s { /* 0x00A0 */ u32 frame_counter; /* 0x00A4 */ int disable_prenmi; /* 0x00A8 */ MCON mcon; -} GAME; +}; extern void game_ct(GAME*, void (*)(GAME*), GRAPH*); extern void game_dt(GAME* game); diff --git a/include/game_h.h b/include/game_h.h new file mode 100644 index 00000000..b9927e97 --- /dev/null +++ b/include/game_h.h @@ -0,0 +1,16 @@ +#ifndef GAME_H_H +#define GAME_H_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct game_s GAME; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/initial_menu.h b/include/initial_menu.h new file mode 100644 index 00000000..4003c8ce --- /dev/null +++ b/include/initial_menu.h @@ -0,0 +1,17 @@ +#ifndef INITIAL_MENU_H +#define INITIAL_MENU_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void initial_menu_init(); +extern void initial_menu_cleanup(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/jaudio_NES/game64.h b/include/jaudio_NES/game64.h new file mode 100644 index 00000000..c7430c6f --- /dev/null +++ b/include/jaudio_NES/game64.h @@ -0,0 +1,18 @@ +#ifndef GAME64_H +#define GAME64_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void Na_InitAudio(void (*fatal_callback)(), u8* load_addr, size_t load_size, u8* bootsound, size_t bootsound_size, BOOL cut_flag); +extern void Na_GameFrame(); +extern u8 Na_CheckNeosBoot(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libc64/malloc.h b/include/libc64/malloc.h index dbd3ce7a..03c765cd 100644 --- a/include/libc64/malloc.h +++ b/include/libc64/malloc.h @@ -10,6 +10,13 @@ extern "C" { extern void* malloc(size_t size); extern void free(void* ptr); +extern void MallocInit(void* base, size_t len); +extern void MallocCleanup(); +extern int MallocIsInitalized(); +extern void GetFreeArena(size_t* max_size, size_t* free_size, size_t* alloc_size); +extern int CheckArena(); /* @unused */ +extern void DisplayArena(); + #ifdef __cplusplus } #endif diff --git a/include/libc64/sleep.h b/include/libc64/sleep.h index 68e6a0c4..09d85103 100644 --- a/include/libc64/sleep.h +++ b/include/libc64/sleep.h @@ -4,6 +4,16 @@ #include "types.h" #include "dolphin/os/OSTime.h" + +#ifdef __cplusplus +extern "C" { +#endif + void csleep(OSTime c); void msleep(int); + +#ifdef __cplusplus +} +#endif + #endif \ No newline at end of file diff --git a/include/libforest/batconfig.h b/include/libforest/batconfig.h index 732a494a..13c5b37b 100644 --- a/include/libforest/batconfig.h +++ b/include/libforest/batconfig.h @@ -5,7 +5,18 @@ #include "dolphin/os/OSMemory.h" #include "dolphin/os/OSInterrupt.h" + +#ifdef __cplusplus +extern "C" { +#endif + asm void Config24MB(); asm void Config48MB(); void ReconfigBATs(); + + +#ifdef __cplusplus +} +#endif + #endif \ No newline at end of file diff --git a/include/libforest/emu64/emu64_wrapper.h b/include/libforest/emu64/emu64_wrapper.h index 3e239bdc..ad4225b0 100644 --- a/include/libforest/emu64/emu64_wrapper.h +++ b/include/libforest/emu64/emu64_wrapper.h @@ -15,6 +15,8 @@ extern void emu64_init(); extern void emu64_refresh(); extern void emu64_cleanup(); +extern void emu64_texture_cache_data_entry_set(u8* cache_start, u8* cache_end); + #ifdef __cplusplus } #endif diff --git a/include/libforest/fault.h b/include/libforest/fault.h index 6bd6cd82..f5d29ae0 100644 --- a/include/libforest/fault.h +++ b/include/libforest/fault.h @@ -23,14 +23,17 @@ extern "C"{ #define FAULT_PAD_READ_SUCCESS 0 #define FAULT_PAD_READ_FAILED -1 -typedef struct { +typedef void (*FaultCallback)(const char* msg, u32 param); +typedef struct fault_client_s fault_client; + +struct fault_client_s { fault_client* next; FaultCallback callback; const char* msg; u32 param; u8 priority; u8 flags; -} fault_client; +}; typedef struct { u8 _0, _1, _2, _3; @@ -38,11 +41,10 @@ typedef struct { fault_client* first_client; } fault; -typedef void (*FaultCallback)(const char* msg, u32 param); extern void fault_AddClientEx(fault_client* client, FaultCallback callback, const char* msg, u32 param, u8 priority, u8 flags); extern void fault_AddClient(fault_client* client, FaultCallback callback, const char* msg, u32 param); -static void fault_Printf(const char* msg, ...); +extern void fault_Printf(const char* msg, ...); static void fault_DrawUpdate(); extern void fault_WaitTime(u32 waitTime); extern int fault_ReadPad(u32* outTriggers, u32* outButtons); diff --git a/include/libforest/osreport.h b/include/libforest/osreport.h index 6026f41e..99a189a3 100644 --- a/include/libforest/osreport.h +++ b/include/libforest/osreport.h @@ -6,6 +6,10 @@ #include "dolphin/os/OSMutex.h" #include "dolphin/os/OSThread.h" +#ifdef __cplusplus +extern "C" { +#endif + #define DEBUG_MODE 0 #define RETAIL_MODE 1 @@ -32,4 +36,8 @@ extern void OSDVDFatalError(); #define OSChangeToRetail() (OSChangeBootMode(RETAIL_MODE)) #define OSChangeToDebug() (OSChangeBootMode(DEBUG_MODE)) +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/libjsys/jsyswrapper.h b/include/libjsys/jsyswrapper.h index dd56aebc..344cc84a 100644 --- a/include/libjsys/jsyswrapper.h +++ b/include/libjsys/jsyswrapper.h @@ -2,11 +2,18 @@ #define JSYSWRAPPER_H #include "types.h" +#include "JSystem/JKernel/JKREnum.h" #ifdef __cplusplus extern "C" { #endif +extern void JW_Init(); +extern void JW_Init2(); +extern void* JW_Alloc(size_t size, int align); +extern void JW_Free(void* ptr); +extern s32 JW_Resize(void* ptr, size_t new_size); +extern size_t JW_GetMemBlockSize(void* ptr); extern void JW_BeginFrame(); extern void JW_EndFrame(); extern void JW_JUTReport(int x, int y, int show_count, const char* fmt, ...); @@ -14,13 +21,21 @@ extern void JW_SetLowResoMode(BOOL enable); extern void JW_SetProgressiveMode(BOOL enable); extern u32 JW_GetAramAddress(int resource_no); extern u8* _JW_GetResourceAram(u32 aram_addr, u8* dst, size_t size); +extern void JW_SetFamicomMode(int enabled); +extern void JW_Cleanup(); extern void* JC_JFWSystem_getSystemConsole(); extern void* JC_JFWSystem_getRootHeap(); +extern void* JC_JFWSystem_getSystemHeap(); extern int JC_JKRHeap_dump(void* heap); extern s32 JC_JKRHeap_getTotalFreeSize(void* heap); +extern void JC_JKRExpHeap_changeGroupID(void* expheap, u8 groupId); + +extern void* JC__JKRDvdToMainRam_byName(const char* name, u8* buf, JKRExpandSwitch expandSwitch); +extern BOOL JC__JKRDetachResource(void* ptr); + extern int JC_JUTConsole_isVisible(void* console); extern void JC_JUTConsole_setVisible(void* console, BOOL visible); extern void JC_JUTConsole_clear(void* console); @@ -31,6 +46,14 @@ extern int JC_JUTConsole_getOutput(void* console); extern int JC_JUTConsole_getLineOffset(void* console); extern void JC_JUTConsole_dumpToTerminal(void* console, int lines); extern void JC_JUTConsole_setOutput(void* console, int output); +extern void JC_JUTConsole_scrollToLastLine(void* console); +extern void JC_JUTConsole_scrollToFirstLine(void* console); +extern void JC_JUTConsole_scroll(void* console, int amount); +extern u32 JC_JUTConsole_getHeight(void* console); +extern u32 JC_JUTConsole_getUsedLine(void* console); + +extern void* JC_JUTConsoleManager_getManager(); +extern void JC_JUTConsoleManager_drawDirect(void* manager, int direct); extern void* JC_JUTDbPrint_getManager(); extern void JC_JUTDbPrint_setVisible(void* dbprint, BOOL visible); @@ -39,6 +62,17 @@ extern void* JC_JUTProcBar_getManager(); extern void JC_JUTProcBar_setVisible(void* procbar, BOOL visible); extern void JC_JUTProcBar_setVisibleHeapBar(void* procbar, BOOL visible); +extern void* JC_JUTException_getManager(); +extern void* JC_JUTException_getConsole(); +extern BOOL JC_JUTException_isEnablePad(void* manager); +extern void JC_JUTException_readPad(void* mgr, u32* trigger, u32* button); +extern void JC_JUTException_waitTime(u32 time); +extern void JC_JUTException_enterAllPad(void* manager); +extern void JC_JUTException_setMapFile(const char* path); + +extern void JC_JUTAssertion_changeDevice(int device); +extern void JC_JUTAssertion_changeDisplayTime(int displayTime); + #ifdef __cplusplus } #endif diff --git a/include/libultra/contreaddata.h b/include/libultra/contreaddata.h new file mode 100644 index 00000000..95d88199 --- /dev/null +++ b/include/libultra/contreaddata.h @@ -0,0 +1,16 @@ +#ifndef CONTREADDATA_H +#define CONTREADDATA_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern u8 __osResetSwitchPressed; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libultra/initialize.h b/include/libultra/initialize.h new file mode 100644 index 00000000..d9c9667e --- /dev/null +++ b/include/libultra/initialize.h @@ -0,0 +1,16 @@ +#ifndef INITIALIZE_H +#define INITIALIZE_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void __osInitialize_common(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libultra/libultra.h b/include/libultra/libultra.h index 422426db..47b42766 100644 --- a/include/libultra/libultra.h +++ b/include/libultra/libultra.h @@ -8,6 +8,11 @@ #define N64_SCREEN_HEIGHT 240 #define N64_SCREEN_WIDTH 320 + +#ifdef __cplusplus +extern "C" { +#endif + int bcmp (void *v1, void *v2, u32 size); void bcopy(void *src, void *dst, size_t n); void bzero(void *ptr, size_t size); @@ -19,4 +24,9 @@ OSTime osGetTime(void); extern s32 osAppNMIBuffer[]; extern int osShutdown; + +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/libultra/shutdown.h b/include/libultra/shutdown.h new file mode 100644 index 00000000..f25fc8f1 --- /dev/null +++ b/include/libultra/shutdown.h @@ -0,0 +1,16 @@ +#ifndef SHUTDOWN_H +#define SHUTDOWN_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void osShutdownStart(int shutdown_type); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_controller.h b/include/m_controller.h index 86eda7ab..73b55dc4 100644 --- a/include/m_controller.h +++ b/include/m_controller.h @@ -2,6 +2,7 @@ #define M_CONTROLLER_H #include "types.h" +#include "game_h.h" #ifdef __cplusplus extern "C" { @@ -46,6 +47,23 @@ typedef struct controller_s { /* 0x34 */ f32 last_adjusted_pR; } MCON; +#define STICK_MIN 9.899495f +#define STICK_MAX 61.0f +#define STICK_UNCORRECTED_SCALE (1.0f / STICK_MAX) +#define STICK_CORRECTED_SCALE (1.0f / (STICK_MAX - STICK_MIN)) + +extern void mCon_ct(); +extern void mCon_dt(); +extern void mCon_calc(MCON* mcon, f32 stick_x, f32 stick_y); +extern void mCon_main(GAME* game); + +extern int chkButton(u16 button); +extern u16 getButton(); +extern int chkTrigger(u16 button); +extern u16 getTrigger(); +extern int getJoystick_X(); +extern int getJoystick_Y(); + #ifdef __cplusplus } #endif diff --git a/include/m_nmibuf.h b/include/m_nmibuf.h index 2c6d9e44..5af7888c 100644 --- a/include/m_nmibuf.h +++ b/include/m_nmibuf.h @@ -50,6 +50,16 @@ extern "C" { #define APPNMI_TESTMODE_GET() APPNMI_GET(64) #define APPNMI_TESTMODE_FLP() APPNMI_FLP(64) +#define APPNMI_EXTENDEDMEMORY_SET() APPNMI_SET(128) +#define APPNMI_EXTENDEDMEMORY_CLR() APPNMI_CLR(128) +#define APPNMI_EXTENDEDMEMORY_GET() APPNMI_GET(128) +#define APPNMI_EXTENDEDMEMORY_FLP() APPNMI_FLP(128) + +#define APPNMI_SHOPPROMOVERSION_SET() APPNMI_SET(256) +#define APPNMI_SHOPPROMOVERSION_CLR() APPNMI_CLR(256) +#define APPNMI_SHOPPROMOVERSION_GET() APPNMI_GET(256) +#define APPNMI_SHOPPROMOVERSION_FLP() APPNMI_FLP(256) + /* Not fully sure this is the right name */ #define APPNMI_HOTRESET_SET() (osAppNMIBuffer[APPNMI_FLAGS_IDX] |= 0x200) #define APPNMI_HOTRESET_CLR() (osAppNMIBuffer[APPNMI_FLAGS_IDX] &= ~0x200) diff --git a/include/nintendo_hi_0.h b/include/nintendo_hi_0.h new file mode 100644 index 00000000..6c11eafc --- /dev/null +++ b/include/nintendo_hi_0.h @@ -0,0 +1,18 @@ +#ifndef NINTENDO_HI_0_H +#define NINTENDO_HI_0_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NINTENDO_HI_0_SIZE 0x9900 +#define NINTENDO_HI_0_AW_SIZE 0x66A0 +extern u8 nintendo_hi_0[NINTENDO_HI_0_SIZE]; // This should be nintendo_hi_0.aw + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/sys_math.h b/include/sys_math.h new file mode 100644 index 00000000..2c5feaf5 --- /dev/null +++ b/include/sys_math.h @@ -0,0 +1,18 @@ +#ifndef SYS_MATH_H +#define SYS_MATH_H + +#include "types.h" +#include "MSL_C/math.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern s16 atans_table(f32 x, f32 y); +extern f32 atanf_table(f32 x, f32 y); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rel/m_controller.c b/rel/m_controller.c new file mode 100644 index 00000000..dbe93033 --- /dev/null +++ b/rel/m_controller.c @@ -0,0 +1,157 @@ +#include "m_controller.h" +#include "game.h" +#include "m_lib.h" +#include "m_event.h" +#include "MSL_C/w_math.h" + +/** + * @brief Constructor for MCON. + **/ +extern void mCon_ct() { } + +/** + * @brief Destructor for MCON. + **/ +extern void mCon_dt() { } + +/** + * @brief Controller input processing function. + * Only processes port 1 controller. + * + * @param mcon Pointer to MCON struct which will be updated + * @param stick_x Joystick X position + * @param stick_y Joystick Y position + **/ +extern void mCon_calc(MCON* mcon, f32 stick_x, f32 stick_y) { + f32 t; + + mcon->last_move_pX = mcon->move_pX; + mcon->last_move_pY = mcon->move_pY; + mcon->last_move_pR = mcon->move_pR; + mcon->last_move_angle = mcon->move_angle; + + mcon->last_adjusted_pX = mcon->adjusted_pX; + mcon->last_adjusted_pY = mcon->adjusted_pY; + mcon->last_adjusted_pR = mcon->adjusted_pR; + + t = sqrtf(stick_x * stick_x + stick_y * stick_y); + + if (t <= STICK_MIN) { + mcon->move_pX = 0.0f; + mcon->move_pY = 0.0f; + mcon->move_pR = 0.0f; + + mcon->adjusted_pX = 0.0f; + mcon->adjusted_pY = 0.0f; + mcon->adjusted_pR = 0.0f; + } + else { + s16 stick_angle = atans_table(stick_x, stick_y); + if (t > STICK_MAX) { + stick_x = cos_s(stick_angle) * STICK_MAX; + stick_y = sin_s(stick_angle) * STICK_MAX; + t = STICK_MAX; + } + + mcon->move_angle = stick_angle; + mcon->move_pX = check_percent_abs(stick_x, STICK_MIN, STICK_MAX, STICK_UNCORRECTED_SCALE, 0); + mcon->move_pY = check_percent_abs(stick_y, STICK_MIN, STICK_MAX, STICK_UNCORRECTED_SCALE, 0); + mcon->move_pR = check_percent_abs( t, STICK_MIN, STICK_MAX, STICK_UNCORRECTED_SCALE, 0); + + mcon->adjusted_pX = check_percent_abs(stick_x, STICK_MIN, STICK_MAX, STICK_CORRECTED_SCALE, 1); + mcon->adjusted_pY = check_percent_abs(stick_y, STICK_MIN, STICK_MAX, STICK_CORRECTED_SCALE, 1); + mcon->adjusted_pR = check_percent_abs( t, STICK_MIN, STICK_MAX, STICK_CORRECTED_SCALE, 1); + } +} + +/** + * @brief Controller main process. + * + * @param game Pointer to current GAME structure + **/ +extern void mCon_main(GAME* game) { + f32 stick_x = getJoystick_X(); + f32 stick_y = getJoystick_Y(); + + mCon_calc(&game->mcon, stick_x, stick_y); +} + +/** + * @brief Checks if a specific button combination currently pressed. + * + * @param mask Button combination to check + * @return TRUE when the button combination is pressed, FALSE otherwise + **/ +extern int chkButton(u16 mask) { + if (mEv_CheckTitleDemo() > 0) { + return FALSE; + } + + return (mask & (gamePT->pads[0].now.button)) == mask; +} + +/** + * @brief Gets the currently pressed buttons. + * + * @return Pressed buttons + **/ +extern u16 getButton() { + if (mEv_CheckTitleDemo() > 0) { + return BUTTON_NONE; + } + + return gamePT->pads[0].now.button; +} + +/** + * @brief Checks if a specific button combination was pressed this frame. + * + * @param mask Button combination to check + * @return TRUE when the button combination was pressed this frame, FALSE otherwise + **/ +extern int chkTrigger(u16 mask) { + if (mEv_CheckTitleDemo() > 0) { + return FALSE; + } + + return (mask & (gamePT->pads[0].on.button)) == mask; +} + +/** + * @brief Gets the buttons pressed on the current frame. + * + * @return Buttons pressed on the current frame + **/ +extern u16 getTrigger() { + if (mEv_CheckTitleDemo() > 0) { + return BUTTON_NONE; + } + + return gamePT->pads[0].on.button; +} + +/** + * @brief Gets the current joystick X position. + * + * @return Joystick X position + **/ +extern int getJoystick_X() { + if (mEv_CheckTitleDemo() > 0) { + return 0; + } + + return gamePT->pads[0].now.stick_x; +} + +/** + * @brief Gets the current joystick Y position. + * + * @return Joystick Y position + **/ +extern int getJoystick_Y() { + if (mEv_CheckTitleDemo() > 0) { + return 0; + } + + return gamePT->pads[0].now.stick_y; +} diff --git a/src/boot.c b/src/boot.c index 24b658ff..a93df866 100644 --- a/src/boot.c +++ b/src/boot.c @@ -1,132 +1,669 @@ #include "boot.h" + +#include "dolphin/dvd.h" +#include "dolphin/os.h" +#include "dolphin/os/OSArena.h" +#include "dolphin/os/OSContext.h" +#include "dolphin/os/OSModule.h" +#include "dolphin/os/OSReset.h" +#include "dolphin/pad.h" +#include "libforest/fault.h" +#include "jaudio_NES/game64.h" +#include "libc64/malloc.h" +#include "libc64/sleep.h" +#include "libforest/osreport.h" +#include "libforest/emu64/emu64_wrapper.h" +#include "libjsys/jsyswrapper.h" +#include "libultra/initialize.h" +#include "libultra/contreaddata.h" +#include "libultra/libultra.h" +#include "libultra/shutdown.h" +#include "m_nmibuf.h" +#include "nintendo_hi_0.h" +#include "sys_math.h" #include "terminal.h" -static u8 nintendo_hi_0[0x9900]; // This should be nintendo_hi_0.aw -extern u32 *StringTable; +#include "dolphin/vi.h" +#include "_mem.h" +#include "initial_menu.h" +#include "libforest/batconfig.h" +#include "dolphin/os/OSAlarm.h" +#include "dvderr.h" +#include "libforest/osreport.h" -u32 soundArenaAlloc(void){ - return 0; -} +static OSModuleHeader* moduleA; +static void* StringTable; // swapped with fakemain_check +static BOOL fakemain_check; +OSTime InitialStartTime; /* TODO: this appears to be N64's type of OSTime (u64), and not Dolphin's (s64) */ +void* boot_copyDate; +void* HotStartEntry; +u8 boot_sound_initializing; -u32 search_partial_address(u32 add){ - //TODO -} +/** + * @brief Stubbed function. Was responsible for allocated space for sound. + * + * @return void* nullptr + */ +void* soundArenaAlloc(size_t size) { return nullptr; } -u32 convert_partial_address(u32 add){ - //TODO -} +/** + * @brief Tries to find an absolute address within any loaded modules. + * + * @param addr The address to search for + * @param module_id Out module id + * @param section_idx Out module section index + * @param section_addr Out module section offset + * @param module_name_ofs Out module name offset + * @return s32 success + */ +s32 search_partial_address(u32 addr, u32* module_id, u32* section_idx, u32* section_addr, u32* module_name_ofs) { + u32 section_size; + OSModuleHeader* module_p; + u32 section; + u32 section_ofs; + OSSectionInfo* section_info; -int LoadStringTable(char table){ //https://decomp.me/scratch/7syDa - - OSReport("ストリングテーブル読み込み開始\n"); - osGetTime(); - StringTable = JC__JKRDvdToMainRam_byName(table, 0, 1); - - if (StringTable == 0){ - OSDVDFatalError(); + if (addr == 0) { + return -1; /* failed */ + } + + module_p = BaseModule; + while (module_p != nullptr) { + section_info = OSGetSectionInfo(module_p); + for (section = 0; section < module_p->info.numSections; + section_info++, section++) { + section_size = section_info->size; + if (section_size != 0) { + section_ofs = OS_SECTIONINFO_OFFSET(section_info->offset); + if ((section_ofs <= addr) && (addr < section_ofs + section_size)) { + if (module_id != nullptr) { + *module_id = module_p->info.id; + } + if (section_idx != nullptr) { + *section_idx = section; + } + if (section_addr != nullptr) { + *section_addr = addr - section_ofs; + } + if (module_name_ofs != nullptr) { + *module_name_ofs = module_p->info.nameOfs; + } + + return 0; /* success */ + } + } } - OSSetStringTable(StringTable); - osGetTime(); - OSReport("ストリングテーブル読み込み 完了\n"); - return 0; + + module_p = (OSModuleHeader*)module_p->info.link.next; + } + + return -1; /* failed */ } -void UnLink(u32 linkre){ - //TODO +/** + * @brief Attempts to convert an absolute address to a module_id-section_idx-section_offset pair. + * + * @param addr Address to attempt conversion on + * @return u32 convertedAddress + */ +extern u32 convert_partial_address(u32 addr) { + u32 module_id, section_idx, section_ofs; + + if (search_partial_address(addr, &module_id, §ion_idx, §ion_ofs, nullptr) == 0) { + return MAKE_PARTIAL_ADDRESS(section_idx, section_ofs); + } + + return addr; } -void LoadLink(u32 link){ -//TODO +/** + * @brief Loads a debug string table for debugging. + * + * @param table Path to the string table. + * @return int success + */ +int LoadStringTable(const char* table) { // https://decomp.me/scratch/7syDa + + OSReport("ストリングテーブル読み込み開始\n"); /* Starting string table load */ + osGetTime(); /* This was probably a variable to a 'begin time' printf */ + StringTable = JC__JKRDvdToMainRam_byName(table, nullptr, EXPAND_SWITCH_DECOMPRESS); + + if (StringTable == nullptr) { + OSDVDFatalError(); + } + + OSSetStringTable(StringTable); + osGetTime(); /* This was probably a variable to an 'end time' printf */ + OSReport("ストリングテーブル読み込み 完了\n"); /* String table loading complete */ + return 0; } -void audioFatalCallback(void) { - -OSReport("audioFatalCallback\x1B\x5B\x6D\n"); -OSDVDFatalError(); - -} - -void sound_initial(void){ - -Na_InitAudio(audioFatalCallback, 0, 0, nintendo_hi_0, 0x66a0, 0); -OSReport("sizeof(nintendo_hi_0)=%08x\n", 0x9900); -OSReport("実際のnintendo_hi_0.awのサイズ=%08x \n", 0x66a0); -OSReport("ニンテンド\x81%x発生タイムラグまで寝てます(%dms)%x/n", VT_CSI, VT_RST, 0x9c4); -msleep(0x9c4); - -} - -} - -void sound_initial2(void) { - -while(!(Na_CheckNeosBoot() & 0xFF)){ - VIWaitForRetrace(); - Na_GameFrame(); -} -bzero(&nintendo_hi_0, sizeof(nintendo_hi_0)); - -} - -void HotResetIplMenu(void) { - if((osAppNMIBuffer[15] & 0x10) != 0){ - OSChangeBootMode(1); +/** + * @brief Utility function to "un-link" a relocatable module (rel). + * + * @param module Handle to the module header to unload. + */ +extern void UnLink(OSModuleHeader* module) { + if (module != nullptr) { + if (module->epilog != 0) { + OSReport("エピローグ開始\n"); /* epilog start */ + ((void (*)())module->epilog)(); + OSReport("エピローグ完了\n"); /* epilog complete */ } - OSResetSystem(1,osAppNMIBuffer[15], 1); + + OSReport("アンリンク中\n"); /* unlinking */ + OSUnlink(&module->info); + OSReport("アンリンク完了\n"); /* unlinking complete */ + } + + JW_Free(module); } -void fault_callback_keyCheck(u32 key){ //https://decomp.me/scratch/MMa4E - //To Finish -} +/** + * @brief Relocatable module (reL) loading utility function. Loads a module by its file name. + * May return nullptr if unable to load the module for whatever reason. + * + * @param module_name The file name of the module. + * @return OSModuleHeader* loadedModule + */ +OSModuleHeader* LoadLink(const char* module_name) { + int result; + size_t length; + void* bss; + int alignLength; + OSModuleHeader* module; -void fault_callback_OK(void) { -fault_Printf("\nOK! YOU ARE GREAT!\n"); -fault_WaitTime(0x7d0); -} + bss = nullptr; + OSReport("モジュール(%s)の読み込み中\n", module_name); /* Loading module (%s) */ + module = (OSModuleHeader*)JC__JKRDvdToMainRam_byName(module_name, nullptr, EXPAND_SWITCH_DECOMPRESS); + if (module == nullptr) { + OSReport("モジュール(%s)の読み込みに失敗しました\n", module_name); /* Failed to load module (%s) */ + OSDVDFatalError(); + return module; + } + + OSReport("モジュール(%s)の読み込み完了\n", module_name); /* Module (%s) load complete */ + OSReport("module=%08x\n", module); + result = !!module; + OSReport("result=%08x\n", result); + length = JW_GetMemBlockSize(module); + OSReport("length=%08x\n", length); + JC__JKRDetachResource(module); + if (result) { + bss = soundArenaAlloc(module->bssSize); -void fault_callback_Setumei(void) { -fault_Printf("\n+ KEY to SCROLL UP/DOWN\nB BUTTON: TOP OF CONSOLE\nA BUTTON: BOTTOM OF CONSOLE\n"); -} - -void fault_callback_vimode(void){ -//TODO -} - -void fault_callback_scroll(void){ -//TODO -} - -void adjustOSArena(void) { - - void* arenalo = OSGetArenaLo(); - void* arenahi = OSGetArenaHi(); - - OSReport("ARENA %08x-%08x\%x/n", VT_RST, arenalo, arenahi); - - if(arenahi > (void*)0x81800000) { - if(!(osAppNMIBuffer[15] & 0x80)){ - OSReport("搭載メモリが 24MB を超えていますが、24MB に限定します。%x/n", VT_RST); - arenahi = (void*)0x817ffa80; - } - - else if(arenahi > (void*)0x82000000){ - OSReport("搭載メモリが 32MB を超えています。%x/n", VST_RST); - arenahi = (void*)0x81e00000; - } - - else { - OSReport("搭載メモリが 32MB を超えていますが、32MB に限定します。%x/n", VT_RST); - } + /* This case will never happen because soundArenaAlloc() was stubbed to always return nullptr. */ + if (bss != nullptr) { + OSReport("サウンドアリーナ %08x 使用 bss=%08x\n", module->bssSize, bss); /* Sound Arena %08x used bss=%08x */ + emu64_texture_cache_data_entry_set((u8*)module, (u8*)module + length); } else { - OSReport("搭載メモリが 24MB 以下なので動かない事がありえます。%x/n", VT_RST); + alignLength = ALIGN_NEXT(length, 32); + if (JW_Resize(module, alignLength + module->bssSize) >= 0) { + bss = (u8*)module + alignLength; + emu64_texture_cache_data_entry_set((u8*)module, (u8*)module + alignLength); + } + else { + bss = JW_Alloc(module->bssSize, 32); + if (bss != nullptr) { + emu64_texture_cache_data_entry_set((u8*)module, (u8*)module + length); + } + else { + goto failed; + } + } } - OSSetArenaHi(arenahi); - OSReport("ARENA %08x-%08x%x/n", VT_RST, arenalo, arenahi); - - bzero(arenalo, ((u32)arenahi - (u32)arenalo)); + OSLink(&module->info, bss); + ((void (*)())module->prolog)(); + return module; + } + +failed: + JW_Free(bss); + JW_Free(module); + return nullptr; } -int main(int argc, const char **argv){ //https://decomp.me/scratch/frpgE -// To Finish +/** + * @brief Callback if an error occurs during audio initialization. + * + */ +void audioFatalCallback() { + OSReport("audioFatalCallback" VT_RST "\n"); + OSDVDFatalError(); } + +/** + * @brief First half of audio initialization. Prepares boot sound. + * + */ +void sound_initial() { + Na_InitAudio(audioFatalCallback, nullptr, 0, nintendo_hi_0, 0x66a0, FALSE); + OSReport("sizeof(nintendo_hi_0)=%08x\n", 0x9900); + OSReport("実際のnintendo_hi_0.awのサイズ=%08x \n", 0x66a0); /* Real nintendo_hi_0.aw size=%08x */ + OSReport("ニンテンドー発生タイムラグまで寝てます(%dms)" VT_RST "\n", 2500); /* Sleeping until Nintendo latency time (%dms) occurs */ + msleep(2500); +} + +/** + * @brief Second half of audio initialization. Waits for 'Neos' to finish initialization. + * + */ +void sound_initial2() { + while (!Na_CheckNeosBoot()) { + VIWaitForRetrace(); + Na_GameFrame(); + } + + bzero(&nintendo_hi_0, sizeof(nintendo_hi_0)); +} + +/** + * @brief Performs a hot reset to the IPL menu + * + */ +void HotResetIplMenu() { + if (APPNMI_ZURUMODE3_GET()) { + OSChangeBootMode(RETAIL_MODE); /* Switch back to retail mode before rebooting */ + } + + /* Utilize osAppNMIBuffer[15] as the boot code to recover it & signal hotreset*/ + OSResetSystem(OS_RESET_HOTRESET, osAppNMIBuffer[15], TRUE); +} + +/** + * @brief faultmgr callback which checks for correct debug key input. + * + * @param msg The message displayed for the key combo. + * @param param The key combination separated into two u16s. + */ +void fault_callback_keyCheck(const char* msg, u32 param) { + u32 trigger; + u32 button; + + if (APPNMI_ZURUMODE_GET()) { + fault_Printf("PUSH %s\n", msg); + } + do { + do { + fault_ReadPad(&trigger, &button); + } while ((u16)trigger != (u16)param); + } while ((u16)button != (u16)((param >> 16) | trigger)); +} + +/** + * @brief faultmgr callback which acknowledges correct debug key input. + * + */ +void fault_callback_OK() { + fault_Printf("\nOK! YOU ARE GREAT!\n"); + fault_WaitTime(2000); +} + +/** + * @brief faultmgr callback which prints control text to the console. + * + */ +void fault_callback_Setumei() { + fault_Printf("\n+ KEY to SCROLL UP/DOWN\nB BUTTON : TOP OF CONSOLE\nA BUTTON : BOTTOM OF CONSOLE\n"); +} + +/** + * @brief faultmgr callback which reads PAD input & processes reboot requests. + * + */ +void fault_callback_vimode() { + u32 triggers, buttons; + + APPNMI_RESETEXEMPT2_SET(); + if (!APPNMI_TESTMODE_GET()) { + OSReport("貸し出しバージョンなのでコードは出しません\n"); /* Since this is a loaned version, we will not provide the code */ + OSReport("B+X+STARTでリスタートします\n"); /* B+X+START to restart */ + + do { + if (OSGetResetSwitchState()) { + __osResetSwitchPressed = TRUE; + } else { + if (__osResetSwitchPressed) { + osShutdownStart(OS_RESET_SHUTDOWN); + } + } + + fault_ReadPad(&triggers, &buttons); + if ((buttons == PAD_BUTTON_B) | (PAD_BUTTON_START | PAD_BUTTON_X)) { + osShutdownStart(OS_RESET_SHUTDOWN); + } + } while (TRUE); + } + + JW_SetFamicomMode(FALSE); + JW_SetLowResoMode(FALSE); +} + +#define OVERLINE(con) (((JC_JUTConsole_getUsedLine(con) - JC_JUTConsole_getHeight(con)) + 1) <= JC_JUTConsole_getLineOffset(con)) + +/** + * @brief faultmgr callback to scroll console + * + */ +void fault_callback_scroll() { + u32 button; + u32 trigger; + void* manager; + void* console; + s32 up_speed; + s32 down_speed; + s32 update_console; + u32 retrace_cnt; + int pad_disabled; + + manager = JC_JUTException_getManager(); + console = JC_JUTException_getConsole(); + pad_disabled = !JC_JUTException_isEnablePad(manager); + if (!pad_disabled) { + OSEnableInterrupts(); + up_speed = 0; + down_speed = 0; + do { + JC_JUTException_readPad(manager, &trigger, &button); + update_console = FALSE; + if (trigger == PAD_BUTTON_A) { + JC_JUTConsole_scrollToLastLine(console); + update_console = TRUE; + } + if (trigger == PAD_BUTTON_B) { + JC_JUTConsole_scrollToFirstLine(console); + update_console = TRUE; + } + if (button == PAD_BUTTON_UP) { + JC_JUTConsole_scroll( + console, (up_speed < 3) + ? -1 + : ((up_speed < 5) ? -2 : ((up_speed < 7) ? -4 : -8))); + update_console = TRUE; + down_speed = 0; + up_speed++; + } else if (button == PAD_BUTTON_DOWN) { + JC_JUTConsole_scroll( + console, (down_speed < 3) + ? 1 + : ((down_speed < 5) ? 2 : ((down_speed < 7) ? 4 : 8))); + update_console = TRUE; + up_speed = 0; + down_speed++; + } else { + up_speed = 0; + down_speed = 0; + } + if (update_console == TRUE) { + retrace_cnt = VIGetRetraceCount(); + do { + } while (retrace_cnt == VIGetRetraceCount()); + JC_JUTConsoleManager_drawDirect(JC_JUTConsoleManager_getManager(), 1); + } + JC_JUTException_waitTime(30); + if (OSGetResetSwitchState()) { + osShutdownStart(OS_RESET_RESTART); + } + } while (TRUE); + } + + do { + JC_JUTConsole_scrollToFirstLine(console); + JC_JUTConsoleManager_drawDirect(JC_JUTConsoleManager_getManager(), 1); + JC_JUTException_waitTime(2000); + + do { + u32 height; + for (height = JC_JUTConsole_getHeight(console); height != 0; height--) { + JC_JUTConsole_scroll(console, 1); + JC_JUTConsoleManager_drawDirect(JC_JUTConsoleManager_getManager(), 1); + + if (OVERLINE(console)) { + break; + } + + JC_JUTException_waitTime(20); + } + + JC_JUTException_waitTime(3000); + if (OVERLINE(console)) { + break; + } + } while (TRUE); + } while (TRUE); +} + +/** + * @brief Adjusts the memory arena depending on installed RAM size. + * osAppNMIBuffers's 'extended memory' bitflag must be enabled for extended memory settings. + */ +void adjustOSArena() { + void* arenalo = OSGetArenaLo(); + void* arenahi = OSGetArenaHi(); + + OSReport("ARENA %08x-%08x" VT_RST "\n", arenalo, arenahi); + + if (arenahi > (void*)0x81800000) { + if (!APPNMI_EXTENDEDMEMORY_GET()) { + OSReport("搭載メモリが 24MB を超えていますが、24MB に限定します。" VT_RST "\n"); /* The installed memory exceeds 24MB, but will be limited to 24MB. */ + arenahi = (void*)0x817ffa80; + } else if (arenahi > (void*)0x82000000) { + OSReport("搭載メモリが 32MB を超えていますが、32MB に限定します。" VT_RST "\n"); /* The installed memory exceeds 32MB, but will be limited to 32MB. */ + arenahi = (void*)0x81e00000; + } else { + OSReport("搭載メモリが 32MB を超えています。" VT_RST "\n"); /* The installed memory exceeds 32MB. */ + } + } else { + OSReport("搭載メモリが 24MB 以下なので動かない事がありえます。" VT_RST "\n"); /* Since the installed memory is 24MB or less, there may be issues. */ + } + + OSSetArenaHi(arenahi); + OSReport("ARENA %08x-%08x" VT_RST "\n", arenalo, arenahi); + + bzero(arenalo, ((u32)arenahi - (u32)arenalo)); +} + +/** + * @brief Standard C main function/entry point + * + * @param argc unused + * @param argv unused + * @return int exitCode + */ +int main(int argc, const char** argv) { + static fault_client + my_fault_client1, + my_fault_client2, + my_fault_client3, + my_fault_client4, + my_fault_client5, + my_fault_client6; + + static const boot_tbl_t tbl = { + "L+R+X+Y+Down, START BUTTON", + PAD_TRIGGER_L | PAD_TRIGGER_R | PAD_BUTTON_X | PAD_BUTTON_Y | PAD_BUTTON_DOWN, + PAD_BUTTON_START + }; + + u32 var1; + OSThread* var2; + void* start; + void* end; + DVDDiskID* diskId; + u32* base; + u32* basenext; + + ReconfigBATs(); + if (fakemain_check) { + return -1; + } + + fakemain_check = 1; + +#ifdef NDEBUG + OSReport("NDEBUG defined." VT_RST "\n"); +#else + OSReport("NDEBUG not defined." VT_RST "\n"); +#endif + +#ifdef _DEBUG + OSReport("_DEBUG defined." VT_RST "\n"); +#else + OSReport("_DEBUG not defined." VT_RST "\n"); +#endif + +#ifdef DEBUG + OSReport("DEBUG=%d" VT_RST "\n", DEBUG); +#endif + + InitialStartTime = osGetTime(); + OSInit(); + OSInitAlarm(); + + /* Initialize stack */ + var1 = ((u32)OSGetStackPointer() - 0x100); + var2 = OSGetCurrentThread(); + base = (u32*)var1; + + if ((u8*)base < var2->stackBase) { + basenext = (u32*)var2->stackEnd + 1; + if (base > basenext) { + memset(basenext, 0xfd, (u32)base - (u32)basenext); + } + } + + /* Reset N64 NMI buffer*/ + bzero(osAppNMIBuffer, 16 * sizeof(s32)); + + /* Adjust process based on how the console started */ + switch (OSGetResetCode()) { + case 0: + OSReport("システムパワーオン\n"); /* system power on */ + break; + case OS_RESETCODE_RESTART: + OSReport("リスタート\n"); /* restart */ + OSGetSaveRegion(&start, &end); + OSReport("OSGetSaveRegion %08x %08x\n", start, end); + bcopy(NMISaveArea, osAppNMIBuffer, 16 * sizeof(s32)); + break; + default: + OSReport("ホットリセット\n"); /* hot reset */ + OSReport("OSGetResetCode=0x%08x\n", OSGetResetCode()); + OSReport("リリース版ではリセットコードを無視します\n"); /* In the release version, the reset code is ignored. */ + break; + } + + __osInitialize_common(); + + /* Setup development environment for dev hardware */ + if ((OSGetConsoleType() & OS_CONSOLE_DEVELOPMENT) != 0) { + APPNMI_ZURUMODE3_SET(); + } else if (APPNMI_ZURUMODE3_GET()) { + OSReport("デベロップメントモードに戻します。そしてリセット" VT_RST "\n"); /* Return to development mode, then reset. */ + OSChangeBootMode(0); + OSResetSystem(1, osAppNMIBuffer[15], 0); + } + + /* Initialize zurumode levels */ + diskId = DVDGetCurrentDiskID(); + if (diskId->gameVersion == 0x99) { + APPNMI_DEBUGMODE_SET(); + } + if (diskId->gameVersion >= 0x90) { + APPNMI_TESTMODE_SET(); + } + + if (diskId->gameVersion >= 0x90) { + OSReport("ZURUMODE2 ENABLE\n"); + APPNMI_ZURUMODE2_SET(); + } + + OSReport("osAppNMIBuffer[15]=0x%08x\n", osAppNMIBuffer[15]); + if (APPNMI_RESETEXEMPT2_GET()) { + APPNMI_RESETEXEMPT2_CLR(); + APPNMI_RESETEXEMPT_SET(); + OSReport( + "異常状態でのリセット検出ゆえリセットさん免除フラグをセットしました" VT_RST "\n"); /* Decetected abnormal reset state, so set reset exemption flag. */ + } else { + APPNMI_RESETEXEMPT_CLR(); + } + + APPNMI_RESETEXEMPT2_SET(); + OSReport("どうぶつの森ブートローダ起動\n"); /* Animal Crossing bootloader startup */ + adjustOSArena(); + JW_Init(); + + /* Check enable debug process bars */ + if (APPNMI_DEBUGMODE_GET()) { + JC_JUTProcBar_setVisible(JC_JUTProcBar_getManager(), APPNMI_TESTMODE_GET() != 0); + JC_JUTProcBar_setVisibleHeapBar(JC_JUTProcBar_getManager(), APPNMI_TESTMODE_GET() != 0); + } + + /* Load static.dol symbol map file */ + JC_JUTException_setMapFile("/static.map"); + JC_JUTException_enterAllPad(JC_JUTException_getManager()); + + /* Initialize fault 'class' & clients */ + fault_Init(); + fault_AddClientEx(&my_fault_client5, (FaultCallback)fault_callback_vimode, nullptr, 0, 10, 14); + fault_AddClientEx(&my_fault_client1, (FaultCallback)fault_callback_keyCheck, tbl.msg, (tbl.param_upper << 16) | tbl.param_lower, 10, 14); + fault_AddClientEx(&my_fault_client2, (FaultCallback)fault_callback_OK, nullptr, 0, 10, 14); + fault_AddClientEx(&my_fault_client3, (FaultCallback)fault_callback_Setumei, nullptr, 0, 10, 9); + fault_AddClientEx(&my_fault_client6, (FaultCallback)fault_callback_scroll, nullptr, 0, 1, 9); + fault_AddClient(&my_fault_client4, (FaultCallback)DisplayArena, nullptr, 0); + + /* Toggle JUtility debug console visibility */ + if (APPNMI_TESTMODE_GET()) { + JC_JUTAssertion_changeDevice(3); + JC_JUTDbPrint_setVisible(JC_JUTDbPrint_getManager(), TRUE); + } else { + JC_JUTAssertion_changeDevice(2); + JC_JUTDbPrint_setVisible(JC_JUTDbPrint_getManager(), FALSE); + } + JC_JUTAssertion_changeDisplayTime(600); + + OSReport("InitialStartTime=%u us\n", (u32)OSTicksToMicroseconds((u64)InitialStartTime)); + sound_initial(); + initial_menu_init(); + dvderr_init(); + sound_initial2(); + + if ((OSGetConsoleType() & OS_CONSOLE_DEVELOPMENT) == 0) { + OSReport("以降OSReportを無効\n"); /* OSReport disabled from now on. */ + OSReportDisable(); + } + + OSReport("Loging COPYDATE\n"); + boot_copyDate = JC__JKRDvdToMainRam_byName("/COPYDATE", nullptr, EXPAND_SWITCH_DECOMPRESS); + if (boot_copyDate == nullptr) { + OSDVDFatalError(); + } + + LoadStringTable("/static.str"); + + moduleA = LoadLink("/foresta.rel.szs"); + JW_Init2(); + initial_menu_cleanup(); + if (moduleA == nullptr) { + moduleA = LoadLink("/foresta.rel.szs"); + } + + JC_JKRExpHeap_changeGroupID(JC_JFWSystem_getSystemHeap(), 5); + + while (HotStartEntry != nullptr) { + OSReport("ホットスタート(%08x)\n", HotStartEntry); + HotStartEntry = (*(void* (*)())HotStartEntry)(); + } + + UnLink(moduleA); + moduleA = nullptr; + if (StringTable != nullptr) { + JW_Free(StringTable); + StringTable = nullptr; + } + + OSReport("どうぶつの森ブートローダ終了\n"); /* Animal Crossing bootloader end */ + JW_Cleanup(); + return 0; +} \ No newline at end of file diff --git a/src/libforest/fault.c b/src/libforest/fault.c index cafb9857..d19a1678 100644 --- a/src/libforest/fault.c +++ b/src/libforest/fault.c @@ -54,7 +54,7 @@ extern void fault_AddClient(fault_client* client, FaultCallback callback, const fault_AddClientEx(client, callback, msg, param, FAULT_MIN_PRIORITY, FAULT_FLAG_POSTEXCEPTION); } -static void fault_Printf(const char* fmt, ...) { +extern void fault_Printf(const char* fmt, ...) { void* console; console = JC_JUTException_getConsole(); diff --git a/src/libultra/contreaddata.c b/src/libultra/contreaddata.c new file mode 100644 index 00000000..1d5ebed3 --- /dev/null +++ b/src/libultra/contreaddata.c @@ -0,0 +1,3 @@ +#include "contreaddata.h" + +u8 __osResetSwitchPressed; diff --git a/src/nintendo_hi_0.c b/src/nintendo_hi_0.c new file mode 100644 index 00000000..5ec1abc2 --- /dev/null +++ b/src/nintendo_hi_0.c @@ -0,0 +1,5 @@ +#include "nintendo_hi_0.h" + +u8 nintendo_hi_0[] ATTRIBUTE_ALIGN(32) = { +#include "assets/nintendo_hi_0.inc" +};