summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDragorn421 <Dragorn421@users.noreply.github.com>2024-08-28 09:38:42 +0200
committerGitHub <noreply@github.com>2024-08-28 09:38:42 +0200
commit68818044db4f6c644ca8be80f0ad4b54a7587f44 (patch)
treec4fb993f82cc4513f5cd584aa7ba68b0965751ab
parentaa97586659dbd24174258e0437ab9411a9747d3d (diff)
[ntsc-1.2] Decompile fault.c (#2046)
* wip decomp ntsc-1.2 fault.c * more ntsc-1.2 fault.c * decompiled fault_v1.c * name fault_v1 functions, wip * try to clean up build system (two versions of the fault system coexisting) * cleanup * cleanup2 * fix build gc-eu-mq-dbg * match 2 more, ty anon * matched * review * more review * fixup spec * `(uintptr_t)ptr op int` instead of `ptr op (type*)int` * move fault.h out of global headers, properly include fault.h and versions.h * compile all fault_*.c files regardless of version by overriding FAULT_VERSION * n64 FaultMgr.framebuffer s32 -> u16* * FaultMgr.framebuffer -> FaultMgr.fb * make gc FaultMgr.fb u16* (yes, thats everything) * bss * fix Fault_Printf return type * noop FaultDrawer_SetFontColor, FaultDrawer_SetCharPad in fault_n64 * fault_color_ stuff is only for fault_gc * rm empty line in makefile * I guess `D_80105A90_unknown` is `[sg]TotalAllocFailures` * bss * `Fault_WaitInput` -> `Fault_WaitForInput` * use named fault funcs in pointers array * FAULT_OOT{N64,GC} -> FAULT_{N64,GC} * Apply suggestions from code review Co-authored-by: Derek Hensley <hensley.derek58@gmail.com> Co-authored-by: Anghelo Carvajal <angheloalf95@gmail.com> * review, sync fault_{gc,n64} * Apply `FPCSR_CE` suggestions from code review Co-authored-by: Derek Hensley <hensley.derek58@gmail.com> --------- Co-authored-by: Derek Hensley <hensley.derek58@gmail.com> Co-authored-by: Anghelo Carvajal <angheloalf95@gmail.com>
-rw-r--r--Makefile10
-rw-r--r--include/fault.h44
-rw-r--r--include/padmgr.h7
-rw-r--r--include/variables.h2
-rw-r--r--include/versions.h8
-rw-r--r--include/z64.h1
-rw-r--r--spec10
-rw-r--r--src/boot/assert.c1
-rw-r--r--src/boot/logutils.c1
-rw-r--r--src/boot/z_std_dma.c1
-rw-r--r--src/code/__osMalloc.c5
-rw-r--r--src/code/code_n64dd_800AD4C0.c7
-rw-r--r--src/code/fault_gc.c (renamed from src/code/fault.c)33
-rw-r--r--src/code/fault_gc_drawer.c (renamed from src/code/fault_drawer.c)10
-rw-r--r--src/code/fault_n64.c845
-rw-r--r--src/code/game.c3
-rw-r--r--src/code/graph.c1
-rw-r--r--src/code/main.c1
-rw-r--r--src/code/padmgr.c5
-rw-r--r--src/code/sched.c1
-rw-r--r--src/code/sys_matrix.c3
-rw-r--r--src/code/z_actor.c1
-rw-r--r--src/code/z_actor_dlftbls.c1
-rw-r--r--src/code/z_collision_check.c6
-rw-r--r--src/code/z_message.c1
-rw-r--r--src/code/z_play.c5
-rw-r--r--src/overlays/actors/ovl_En_Mag/z_en_mag.c1
-rw-r--r--src/overlays/actors/ovl_Fishing/z_fishing.c2
-rw-r--r--src/overlays/actors/ovl_player_actor/z_player.c6
-rw-r--r--tools/disasm/ntsc-1.2/files_code.csv8
-rw-r--r--tools/disasm/ntsc-1.2/functions.txt64
-rw-r--r--tools/disasm/ntsc-1.2/variables.txt4
-rwxr-xr-xtools/m2ctx.py11
-rw-r--r--undefined_syms.txt2
34 files changed, 1031 insertions, 80 deletions
diff --git a/Makefile b/Makefile
index 33c7cf21c..02ca4fbd5 100644
--- a/Makefile
+++ b/Makefile
@@ -439,10 +439,12 @@ $(BUILD_DIR)/src/code/relocation.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/sleep.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/system_malloc.o: OPTFLAGS := -O2
-$(BUILD_DIR)/src/code/fault.o: CFLAGS += -trapuv
-$(BUILD_DIR)/src/code/fault.o: OPTFLAGS := -O2 -g3
-$(BUILD_DIR)/src/code/fault_drawer.o: CFLAGS += -trapuv
-$(BUILD_DIR)/src/code/fault_drawer.o: OPTFLAGS := -O2 -g3
+$(BUILD_DIR)/src/code/fault_n64.o: CFLAGS += -trapuv
+$(BUILD_DIR)/src/code/fault_gc.o: CFLAGS += -trapuv
+$(BUILD_DIR)/src/code/fault_gc.o: OPTFLAGS := -O2 -g3
+$(BUILD_DIR)/src/code/fault_gc_drawer.o: CFLAGS += -trapuv
+$(BUILD_DIR)/src/code/fault_gc_drawer.o: OPTFLAGS := -O2 -g3
+
$(BUILD_DIR)/src/code/ucode_disas.o: OPTFLAGS := -O2 -g3
ifeq ($(PLATFORM),N64)
diff --git a/include/fault.h b/include/fault.h
index df125487e..996f1f8d6 100644
--- a/include/fault.h
+++ b/include/fault.h
@@ -4,7 +4,9 @@
#include "ultra64.h"
#include "attributes.h"
#include "padmgr.h"
+#include "versions.h"
+#if FAULT_VERSION == FAULT_GC
// These are the same as the 3-bit ansi color codes
#define FAULT_COLOR_BLACK 0
#define FAULT_COLOR_RED 1
@@ -23,6 +25,7 @@
#define FAULT_ESC '\x1A'
#define FAULT_COLOR(n) "\x1A" FAULT_COLOR_EXPAND_AND_STRINGIFY(FAULT_COLOR_ ## n)
+#endif
typedef struct FaultClient {
/* 0x00 */ struct FaultClient* next;
@@ -31,11 +34,13 @@ typedef struct FaultClient {
/* 0x0C */ void* arg1;
} FaultClient; // size = 0x10
+#if FAULT_VERSION == FAULT_GC
typedef struct FaultAddrConvClient {
/* 0x00 */ struct FaultAddrConvClient* next;
/* 0x04 */ void* callback;
/* 0x08 */ void* arg;
} FaultAddrConvClient; // size = 0xC
+#endif
// Initialization
@@ -51,15 +56,32 @@ NORETURN void Fault_AddHungupAndCrash(const char* file, int line);
void Fault_AddClient(FaultClient* client, void* callback, void* arg0, void* arg1);
void Fault_RemoveClient(FaultClient* client);
+#if FAULT_VERSION == FAULT_GC
void Fault_AddAddrConvClient(FaultAddrConvClient* client, void* callback, void* arg);
void Fault_RemoveAddrConvClient(FaultAddrConvClient* client);
+#endif
// For use in Fault Client callbacks
-void Fault_WaitForInput(void);
-void Fault_FillScreenBlack(void);
void Fault_SetFrameBuffer(void* fb, u16 w, u16 h);
+void Fault_WaitForInput(void);
+
+#if FAULT_VERSION == FAULT_N64
+
+// Not implemented. Silently noop-ing is fine, these are not essential for functionality.
+#define FaultDrawer_SetFontColor(color) (void)0
+#define FaultDrawer_SetCharPad(padW, padH) (void)0
+
+void Fault_SetCursor(s32 x, s32 y);
+s32 Fault_Printf(const char* fmt, ...);
+void Fault_DrawText(s32 x, s32 y, const char* fmt, ...);
+#define FaultDrawer_SetCursor Fault_SetCursor
+#define FaultDrawer_Printf Fault_Printf
+#define FaultDrawer_DrawText Fault_DrawText
+
+#elif FAULT_VERSION == FAULT_GC
+
void FaultDrawer_SetForeColor(u16 color);
void FaultDrawer_SetBackColor(u16 color);
void FaultDrawer_SetFontColor(u16 color);
@@ -69,9 +91,19 @@ s32 FaultDrawer_VPrintf(const char* fmt, va_list args);
s32 FaultDrawer_Printf(const char* fmt, ...);
void FaultDrawer_DrawText(s32 x, s32 y, const char* fmt, ...);
+#endif
+
+#if FAULT_VERSION == FAULT_N64
+
+extern vs32 gFaultMsgId;
+
+#define FAULT_MSG_ID gFaultMsgId
+
+#elif FAULT_VERSION == FAULT_GC
+
typedef struct FaultMgr {
/* 0x000 */ OSThread thread;
- /* 0x1B0 */ char unk_1B0[0x600]; // probably an unused internal thread stack for `Fault_ClientRunTask`/`clientThreadSp`
+ /* 0x1B0 */ char unk_1B0[0x600];
/* 0x7B0 */ OSMesgQueue queue;
/* 0x7C8 */ OSMesg msg;
/* 0x7CC */ u8 exit;
@@ -84,10 +116,14 @@ typedef struct FaultMgr {
/* 0x7DC */ FaultAddrConvClient* addrConvClients;
/* 0x7E0 */ char unk_7E0[0x4];
/* 0x7E4 */ Input inputs[MAXCONTROLLERS];
- /* 0x844 */ void* fb;
+ /* 0x844 */ u16* fb;
/* 0x848 */ void* clientThreadSp;
} FaultMgr; // size = 0x850
extern FaultMgr gFaultMgr;
+#define FAULT_MSG_ID gFaultMgr.msgId
+
+#endif
+
#endif
diff --git a/include/padmgr.h b/include/padmgr.h
index 0e7be4cda..efd245c7d 100644
--- a/include/padmgr.h
+++ b/include/padmgr.h
@@ -3,6 +3,7 @@
#include "ultra64.h"
#include "irqmgr.h"
+#include "versions.h"
typedef enum ControllerPakType {
CONT_PAK_NONE,
@@ -50,9 +51,9 @@ void PadMgr_Init(PadMgr* padMgr, OSMesgQueue* serialEventQueue, IrqMgr* irqMgr,
// Fetching inputs
-// This function cannot be prototyped here without AVOID_UB because it is called incorrectly in fault.c (see bug in
-// `Fault_PadCallback`)
-#ifdef AVOID_UB
+// This function cannot be prototyped here in all configurations because it is called incorrectly in fault_gc.c
+// (see bug in `Fault_PadCallback`)
+#if FAULT_VERSION == FAULT_N64 || defined(AVOID_UB)
void PadMgr_RequestPadData(PadMgr* padmgr, Input* inputs, s32 gameRequest);
#endif
diff --git a/include/variables.h b/include/variables.h
index 87ac90bd9..739a76818 100644
--- a/include/variables.h
+++ b/include/variables.h
@@ -248,4 +248,6 @@ extern u64 gGfxSPTaskStack[SP_DRAM_STACK_SIZE64]; // 0x400 bytes
extern GfxPool gGfxPools[2]; // 0x24820 bytes
extern u8 gAudioHeap[0x38000]; // 0x38000 bytes
+extern u32 gTotalAllocFailures;
+
#endif
diff --git a/include/versions.h b/include/versions.h
index b135ae390..a000cf0bc 100644
--- a/include/versions.h
+++ b/include/versions.h
@@ -16,4 +16,12 @@
#define GC_EU_MQ 12
#define GC_JP_CE 13
+#define FAULT_N64 1 // in OoT N64
+#define FAULT_GC 2 // in OoT GC
+#if PLATFORM_N64
+#define FAULT_VERSION FAULT_N64
+#else
+#define FAULT_VERSION FAULT_GC
+#endif
+
#endif
diff --git a/include/z64.h b/include/z64.h
index 39325ad9a..b84ce02a1 100644
--- a/include/z64.h
+++ b/include/z64.h
@@ -52,7 +52,6 @@
#include "regs.h"
#include "irqmgr.h"
#include "padmgr.h"
-#include "fault.h"
#include "sched.h"
#include "rumble.h"
#include "mempak.h"
diff --git a/spec b/spec
index 434f3281c..cf936194b 100644
--- a/spec
+++ b/spec
@@ -2,6 +2,8 @@
* ROM spec file
*/
+#include "include/versions.h"
+
beginseg
name "makerom"
include "$(BUILD_DIR)/src/makerom/rom_header.o"
@@ -530,8 +532,12 @@ beginseg
#if OOT_DEBUG
include "$(BUILD_DIR)/src/code/debug_malloc.o"
#endif
- include "$(BUILD_DIR)/src/code/fault.o"
- include "$(BUILD_DIR)/src/code/fault_drawer.o"
+#if FAULT_VERSION == FAULT_N64
+ include "$(BUILD_DIR)/src/code/fault_n64.o"
+#elif FAULT_VERSION == FAULT_GC
+ include "$(BUILD_DIR)/src/code/fault_gc.o"
+ include "$(BUILD_DIR)/src/code/fault_gc_drawer.o"
+#endif
include "$(BUILD_DIR)/src/code/kanread.o"
#if OOT_DEBUG
include "$(BUILD_DIR)/src/code/ucode_disas.o"
diff --git a/src/boot/assert.c b/src/boot/assert.c
index fa206fc36..e58f2cc1e 100644
--- a/src/boot/assert.c
+++ b/src/boot/assert.c
@@ -1,4 +1,5 @@
#include "global.h"
+#include "fault.h"
NORETURN void __assert(const char* assertion, const char* file, int line) {
char msg[256];
diff --git a/src/boot/logutils.c b/src/boot/logutils.c
index ba43fbe7f..a501a32bc 100644
--- a/src/boot/logutils.c
+++ b/src/boot/logutils.c
@@ -1,4 +1,5 @@
#include "global.h"
+#include "fault.h"
#include "terminal.h"
#if PLATFORM_N64 || OOT_DEBUG
diff --git a/src/boot/z_std_dma.c b/src/boot/z_std_dma.c
index c331ea0c8..caec2809c 100644
--- a/src/boot/z_std_dma.c
+++ b/src/boot/z_std_dma.c
@@ -19,6 +19,7 @@
* to be uncompressed and the request queue and address translation is skipped.
*/
#include "global.h"
+#include "fault.h"
#include "terminal.h"
#if PLATFORM_N64
#include "n64dd.h"
diff --git a/src/code/__osMalloc.c b/src/code/__osMalloc.c
index 951a4b077..69a39f872 100644
--- a/src/code/__osMalloc.c
+++ b/src/code/__osMalloc.c
@@ -1,4 +1,5 @@
#include "global.h"
+#include "fault.h"
#include "terminal.h"
#define FILL_ALLOC_BLOCK_FLAG (1 << 0)
@@ -53,12 +54,12 @@
#define CHECK_FREE_BLOCK(arena, node) (void)0
// Number of allocation failures across all arenas.
-u32 sTotalAllocFailures = 0;
+u32 gTotalAllocFailures = 0; // "Arena_failcnt"
#define CHECK_ALLOC_FAILURE(arena, ptr) \
do { \
if ((ptr) == NULL) { \
- sTotalAllocFailures++; \
+ gTotalAllocFailures++; \
(arena)->allocFailures++; \
} \
} while (0)
diff --git a/src/code/code_n64dd_800AD4C0.c b/src/code/code_n64dd_800AD4C0.c
index 091597a04..a5c9005e1 100644
--- a/src/code/code_n64dd_800AD4C0.c
+++ b/src/code/code_n64dd_800AD4C0.c
@@ -1,10 +1,9 @@
#include "global.h"
+#include "fault.h"
#include "n64dd.h"
// TODO functions of unknown prototype
extern char func_801C8510_unknown[];
-extern char func_800AE170_unknown[];
-extern char func_800ADCD8_unknown[];
extern char osGetIntMask[];
extern char osSetTime[];
@@ -14,8 +13,8 @@ n64ddStruct_800FF4B0_pointers D_800FF4B0 = {
NULL,
Fault_RemoveClient,
Fault_AddClient,
- func_800AE170_unknown,
- func_800ADCD8_unknown,
+ FaultDrawer_DrawText,
+ Fault_WaitForInput,
Fault_AddHungupAndCrashImpl,
Fault_AddHungupAndCrash,
func_800ADC08,
diff --git a/src/code/fault.c b/src/code/fault_gc.c
index 3251bb832..f78bc152d 100644
--- a/src/code/fault.c
+++ b/src/code/fault_gc.c
@@ -40,11 +40,19 @@
* DPad-Up may be pressed to enable sending fault pages over osSyncPrintf as well as displaying them on-screen.
* DPad-Down disables sending fault pages over osSyncPrintf.
*/
+
+// Include versions.h first and redefine FAULT_VERSION
+// This allows this file to compile even when versions.h uses FAULT_N64
+#include "versions.h"
+#undef FAULT_VERSION
+#define FAULT_VERSION FAULT_GC
+
#include "global.h"
+#include "fault.h"
#include "terminal.h"
#include "alloca.h"
-#pragma increment_block_number "gc-eu:64 gc-eu-mq:64 gc-eu-mq-dbg:0 gc-jp:64 gc-jp-ce:64 gc-jp-mq:64 gc-us:64" \
+#pragma increment_block_number "gc-eu:64 gc-eu-mq:64 gc-eu-mq-dbg:222 gc-jp:64 gc-jp-ce:64 gc-jp-mq:64 gc-us:64" \
"gc-us-mq:64"
void FaultDrawer_Init(void);
@@ -453,9 +461,9 @@ void Fault_DrawCornerRec(u16 color) {
void Fault_PrintFReg(s32 idx, f32* value) {
u32 raw = *(u32*)value;
- s32 exp = ((raw & 0x7F800000) >> 0x17) - 0x7F;
+ s32 exp = ((raw & 0x7F800000) >> 23) - 127;
- if ((exp >= -0x7E && exp < 0x80) || raw == 0) {
+ if ((exp > -127 && exp <= 127) || raw == 0) {
FaultDrawer_Printf("F%02d:%14.7e ", idx, *value);
} else {
// Print subnormal floats as their ieee-754 hex representation
@@ -465,9 +473,9 @@ void Fault_PrintFReg(s32 idx, f32* value) {
void Fault_LogFReg(s32 idx, f32* value) {
u32 raw = *(u32*)value;
- s32 exp = ((raw & 0x7F800000) >> 0x17) - 0x7F;
+ s32 exp = ((raw & 0x7F800000) >> 23) - 127;
- if ((exp >= -0x7E && exp < 0x80) || raw == 0) {
+ if ((exp > -127 && exp <= 127) || raw == 0) {
osSyncPrintf("F%02d:%14.7e ", idx, *value);
} else {
osSyncPrintf("F%02d: %08x(16) ", idx, *(u32*)value);
@@ -510,10 +518,10 @@ void Fault_PrintThreadContext(OSThread* thread) {
__OSThreadContext* ctx;
s16 causeStrIdx = _SHIFTR((u32)thread->context.cause, 2, 5);
- if (causeStrIdx == 23) { // Watchpoint
+ if (causeStrIdx == (EXC_WATCH >> CAUSE_EXCSHIFT)) {
causeStrIdx = 16;
}
- if (causeStrIdx == 31) { // Virtual coherency on data
+ if (causeStrIdx == (EXC_VCED >> CAUSE_EXCSHIFT)) {
causeStrIdx = 17;
}
@@ -572,10 +580,10 @@ void Fault_LogThreadContext(OSThread* thread) {
__OSThreadContext* ctx;
s16 causeStrIdx = _SHIFTR((u32)thread->context.cause, 2, 5);
- if (causeStrIdx == 23) { // Watchpoint
+ if (causeStrIdx == (EXC_WATCH >> CAUSE_EXCSHIFT)) {
causeStrIdx = 16;
}
- if (causeStrIdx == 31) { // Virtual coherency on data
+ if (causeStrIdx == (EXC_VCED >> CAUSE_EXCSHIFT)) {
causeStrIdx = 17;
}
@@ -670,10 +678,12 @@ void Fault_WaitForButtonCombo(void) {
if (1) {}
if (1) {}
+ // KeyWaitB (LRZ Up Down Up Down Left Left Right Right B A START)
osSyncPrintf(
VT_FGCOL(WHITE) "KeyWaitB (LRZ " VT_FGCOL(WHITE) "上" VT_FGCOL(YELLOW) "下 " VT_FGCOL(YELLOW) "上" VT_FGCOL(WHITE) "下 " VT_FGCOL(WHITE) "左" VT_FGCOL(
YELLOW) "左 " VT_FGCOL(YELLOW) "右" VT_FGCOL(WHITE) "右 " VT_FGCOL(GREEN) "B" VT_FGCOL(BLUE) "A" VT_FGCOL(RED) "START" VT_FGCOL(WHITE) ")" VT_RST
"\n");
+ // KeyWaitB'(LR Left Right START)
osSyncPrintf(VT_FGCOL(WHITE) "KeyWaitB'(LR左" VT_FGCOL(YELLOW) "右 +" VT_FGCOL(RED) "START" VT_FGCOL(
WHITE) ")" VT_RST "\n");
@@ -1104,7 +1114,7 @@ void Fault_ResumeThread(OSThread* thread) {
thread->context.cause = 0;
thread->context.fpcsr = 0;
thread->context.pc += sizeof(u32);
- *((u32*)thread->context.pc) = 0x0000000D; // write in a break instruction
+ *(u32*)thread->context.pc = 0x0000000D; // write in a break instruction
osWritebackDCache((void*)thread->context.pc, 4);
osInvalICache((void*)thread->context.pc, 4);
osStartThread(thread);
@@ -1178,9 +1188,11 @@ void Fault_ThreadEntry(void* arg) {
if (msg == FAULT_MSG_CPU_BREAK) {
sFaultInstance->msgId = (u32)FAULT_MSG_CPU_BREAK;
+ // Fault Manager: OS_EVENT_CPU_BREAK received
osSyncPrintf("フォルトマネージャ:OS_EVENT_CPU_BREAKを受信しました\n");
} else if (msg == FAULT_MSG_FAULT) {
sFaultInstance->msgId = (u32)FAULT_MSG_FAULT;
+ // Fault Manager: OS_EVENT_FAULT received
osSyncPrintf("フォルトマネージャ:OS_EVENT_FAULTを受信しました\n");
} else if (msg == FAULT_MSG_UNK) {
Fault_UpdatePad();
@@ -1188,6 +1200,7 @@ void Fault_ThreadEntry(void* arg) {
continue;
} else {
sFaultInstance->msgId = (u32)FAULT_MSG_UNK;
+ // Fault Manager: Unknown message received
osSyncPrintf("フォルトマネージャ:不明なメッセージを受信しました\n");
}
diff --git a/src/code/fault_drawer.c b/src/code/fault_gc_drawer.c
index 6b85edb43..bb53bb133 100644
--- a/src/code/fault_drawer.c
+++ b/src/code/fault_gc_drawer.c
@@ -4,7 +4,15 @@
* Implements routines for drawing text with a fixed font directly to a framebuffer, used in displaying
* the crash screen implemented by fault.c
*/
+
+// Include versions.h first and redefine FAULT_VERSION
+// This allows this file to compile even when versions.h uses FAULT_N64
+#include "versions.h"
+#undef FAULT_VERSION
+#define FAULT_VERSION FAULT_GC
+
#include "global.h"
+#include "fault.h"
#include "terminal.h"
typedef struct FaultDrawer {
@@ -99,6 +107,8 @@ FaultDrawer sFaultDrawerDefault = {
NULL,
};
+#pragma increment_block_number "gc-eu:128 gc-eu-mq:128"
+
FaultDrawer sFaultDrawer;
char D_8016B6C0[0x20];
diff --git a/src/code/fault_n64.c b/src/code/fault_n64.c
new file mode 100644
index 000000000..74e963377
--- /dev/null
+++ b/src/code/fault_n64.c
@@ -0,0 +1,845 @@
+// Include versions.h first and redefine FAULT_VERSION
+// This allows this file to compile even when versions.h uses FAULT_GC
+#include "versions.h"
+#undef FAULT_VERSION
+#define FAULT_VERSION FAULT_N64
+
+#include "global.h"
+#include "fault.h"
+#include "terminal.h"
+
+typedef struct FaultMgr {
+ OSThread thread;
+ char unk_1B0[0x400];
+ OSMesgQueue queue;
+ OSMesg msg;
+ u16* fb;
+ u16 fbWidth;
+ u16 fbDepth;
+ FaultClient* clients;
+} FaultMgr; // size = 0x5D8
+
+typedef struct FaultCursorCoords {
+ s32 x;
+ s32 y;
+} FaultCursorCoords; // size = 0x8
+
+u32 sFaultDrawerFont[] = {
+ 0x00DFFD00, 0x0AEEFFA0, 0x0DF22DD0, 0x06611DC0, 0x01122DD0, 0x06719900, 0x011EED10, 0x077EF700, 0x01562990,
+ 0x05589760, 0x0DD22990, 0x05599770, 0x04DFFD40, 0x026EF700, 0x00000000, 0x00000000, 0x08BFFB00, 0x0EFFFFC0,
+ 0x0BF00FB0, 0x0FF00330, 0x0FF00FF0, 0x0FF00220, 0x0CFBBF60, 0x0FFCCE20, 0x0DD44FF0, 0x0FF00220, 0x0FF00FF0,
+ 0x0FF00330, 0x0CFBBF40, 0x0EF77740, 0x00000000, 0x00000000, 0x00DFFD00, 0x0AEEFFA0, 0x0DF22DD0, 0x06611DC0,
+ 0x01122DD0, 0x06719900, 0x011EED10, 0x077EF700, 0x01562990, 0x05589760, 0x0DD22990, 0x05599770, 0x04DFFD40,
+ 0x026EF700, 0x00000000, 0x00000000, 0x08BFFB00, 0x000DE000, 0x0BF00FB0, 0x005DE600, 0x0FF00FF0, 0x055CC660,
+ 0x0CFBBF60, 0x773FF377, 0x0DD44FF0, 0xBB3FF3BB, 0x0FF00FF0, 0x099CCAA0, 0x0CFBBF40, 0x009DEA00, 0x00000000,
+ 0x000DE000, 0x04C22C40, 0x028D5020, 0x0CCAACC0, 0x21F91710, 0x04C22C40, 0x12493400, 0x00820800, 0x01975110,
+ 0x088A8880, 0x04615241, 0x00800800, 0x43117530, 0x00A20800, 0x60055600, 0x00000000, 0x04400040, 0x00221100,
+ 0x00000080, 0x000FB000, 0x00000880, 0x040DA400, 0x00008800, 0x08CDE880, 0x022AA220, 0x08CDE880, 0x02AA2220,
+ 0x040DA400, 0x0CD10000, 0x000FB000, 0x8C510000, 0x00221100, 0x81100000, 0x00DFFD00, 0x0AEEFFA0, 0x0DF22DD0,
+ 0x06611DC0, 0x01122DD0, 0x06719900, 0x011EED10, 0x077EF700, 0x01562990, 0x05589760, 0x0DD22990, 0x05599770,
+ 0x04DFFD40, 0x026EF700, 0x00000000, 0x00000000, 0x00333300, 0x04489980, 0x033CC330, 0x00CD1088, 0x033CC330,
+ 0x02BF62A8, 0x00333320, 0x01104C80, 0x01100330, 0x0015C800, 0x033CC330, 0x02673220, 0x003FF300, 0x04409900,
+ 0x00880000, 0x00000000, 0x05DFFD10, 0x07FFFF60, 0x1CE00EC1, 0x0FF00990, 0x1EE11661, 0x0FF00110, 0x1EF45621,
+ 0x0FF66710, 0x1EF23661, 0x0FF08990, 0x1EF10FE1, 0x0FF00990, 0x16ECCE21, 0x07FBBB20, 0x01111110, 0x00000000,
+ 0x09B66FD0, 0x27D88E60, 0x0992ED10, 0x2FF02EE0, 0x099AE510, 0x2FF62EE0, 0x099B7510, 0x2FD64EE0, 0x0DDAE510,
+ 0x2FD04EE0, 0x0DD2ED10, 0x2FD00EE0, 0x09F66F90, 0x27D99F70, 0x00000000, 0x00000000, 0x07FFFF00, 0x8F711FF0,
+ 0x2FD00FF0, 0x8F711FF0, 0x2FD00770, 0x8E611EE0, 0x27DDDF60, 0x8E691EE0, 0x27764AA0, 0x8EE99EE0, 0x2FD06E80,
+ 0x8AE7FEA0, 0x07FA8E60, 0x88277A80, 0x00000000, 0x00000000, 0x077CCFF0, 0x13266011, 0x077CCFF0, 0x03766510,
+ 0x0239D720, 0x04533540, 0x002FF200, 0x01133110, 0x005FB100, 0x00033000, 0x055EE550, 0x01133110, 0x055EEDD0,
+ 0x02233000, 0x00088880, 0x8AABB888, 0x00001100, 0x00044510, 0x04623320, 0x00440110, 0x04C89AA0, 0x00EEAB10,
+ 0x0CE66720, 0x0EF55FB0, 0x0EE00660, 0x0BF62B90, 0x0EE00660, 0x03FC8990, 0x04EEEEA0, 0x00773BB0, 0x00000000,
+ 0x08888800, 0x09900000, 0x00111000, 0x09922440, 0x00011000, 0x09908800, 0x26EFDE20, 0x099BB540, 0x2EC33CE2,
+ 0x0D9A2550, 0x2EC33CE2, 0x0DDAA550, 0x2EC33CE2, 0x09D6ED10, 0x26CBBC62, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00011000, 0x05FBFFE0, 0x8E6116E8, 0x0FF40330, 0x8F7117F8, 0x07FC8B30, 0x8E6996E8,
+ 0x05733BA0, 0x8A6DD6A8, 0x0DD88A20, 0x08A779B2, 0x01100220, 0x00000000, 0x00000080, 0x8A011000, 0x00000800,
+ 0x80A11000, 0x07744F70, 0x80A99000, 0x0231DF20, 0x84E60004, 0x0027DA20, 0xC8AA4C40, 0x00573B20, 0x00A11800,
+ 0x05546F50, 0x00A99800, 0x02222080, 0x02001888,
+};
+
+const char* sExceptionNames[] = {
+ "Interrupt",
+ "TLB modification",
+ "TLB exception on load",
+ "TLB exception on store",
+ "Address error on load",
+ "Address error on store",
+ "Bus error on inst.",
+ "Bus error on data",
+ "System call exception",
+ "Breakpoint exception",
+ "Reserved instruction",
+ "Coprocessor unusable",
+ "Arithmetic overflow",
+ "Trap exception",
+ "Virtual coherency on inst.",
+ "Floating point exception",
+ "Watchpoint exception",
+ "Virtual coherency on data",
+};
+
+const char* sFpExceptionNames[] = {
+ "Unimplemented operation", "Invalid operation", "Division by zero", "Overflow", "Underflow", "Inexact operation",
+};
+
+u16 sFaultFontColor = GPACK_RGBA5551(255, 255, 255, 1);
+
+Input sFaultInputs[MAXCONTROLLERS];
+
+FaultMgr gFaultMgr;
+
+STACK(sFaultStack, 0x400);
+StackEntry sFaultStackInfo;
+FaultCursorCoords sFaultCursorPos;
+
+vs32 sFaultExit;
+vs32 gFaultMsgId;
+vs32 sFaultDisplayEnable;
+OSThread* sFaultFaultedThread;
+s32 B_80122570[0x10];
+
+void Fault_SleepImpl(u32 ms) {
+ Sleep_Msec(ms);
+}
+
+void Fault_WaitForInputImpl(void) {
+ Input* inputs = sFaultInputs;
+ u16 btnPress;
+
+ do {
+ Fault_SleepImpl(0x10);
+ PadMgr_RequestPadData(&gPadMgr, inputs, 0);
+ btnPress = inputs[0].press.button;
+ } while (!CHECK_BTN_ANY(btnPress, (BTN_A | BTN_B | BTN_START | BTN_CRIGHT | BTN_CLEFT | BTN_CDOWN | BTN_CUP)));
+}
+
+void Fault_WaitForInput(void) {
+ Fault_WaitForInputImpl();
+}
+
+void Fault_DrawRec(s32 x, s32 y, s32 w, s32 h, u16 color) {
+ s32 i;
+ s32 j;
+ u16* fbPtr;
+
+ fbPtr = gFaultMgr.fb + (gFaultMgr.fbWidth * y) + x;
+
+ for (i = 0; i < h; i++) {
+ j = 0;
+ for (j = 0; j < w; j++) {
+ *fbPtr = color;
+ fbPtr++;
+ }
+ fbPtr += gFaultMgr.fbWidth - w;
+ }
+ osWritebackDCacheAll();
+}
+
+void Fault_DrawRecBlack(s32 x, s32 y, s32 w, s32 h) {
+ Fault_DrawRec(x, y, w, h, GPACK_RGBA5551(0, 0, 0, 1));
+}
+
+void Fault_DrawCharImpl(s32 x, s32 y, char c) {
+ u32* dataPtr;
+ s32 shift = c % 4;
+ s32 i;
+ s32 j;
+ u16* fbPtr;
+ u32 data;
+
+ dataPtr = sFaultDrawerFont + ((c / 8 * 0x10) + ((c & 4) >> 2));
+ fbPtr = gFaultMgr.fb + (gFaultMgr.fbWidth * y) + x;
+
+ for (i = 0; i < 8; i++) {
+ u32 mask;
+
+ mask = (1 << 28) << shift;
+ data = *dataPtr;
+ for (j = 0; j < 8; j++) {
+ if (mask & data) {
+ *fbPtr = sFaultFontColor;
+ }
+ fbPtr++;
+ mask >>= 4;
+ }
+ dataPtr += 2;
+ fbPtr += gFaultMgr.fbWidth - 8;
+ }
+ osWritebackDCacheAll();
+}
+
+void Fault_DrawChar(s32 x, s32 y, u8 c) {
+ Fault_DrawCharImpl(x, y, c);
+}
+
+void Fault_DrawCornerRec(u16 color) {
+ Fault_DrawRec(22, 16, 8, 1, color);
+}
+
+void Fault_DrawCornerRecRed(void) {
+ Fault_DrawCornerRec(GPACK_RGBA5551(255, 0, 0, 1));
+}
+
+void Fault_DrawCornerRecYellow(void) {
+ Fault_DrawCornerRec(GPACK_RGBA5551(255, 255, 0, 1));
+}
+
+void func_800AE05C(void) {
+}
+
+void* Fault_PrintCallbackDraw(void* arg, const char* str, size_t len) {
+ FaultCursorCoords* coords = arg;
+
+ for (; len != 0; len--, str++) {
+ if (*str == '\n') {
+ coords->x = 320;
+ } else {
+ Fault_DrawChar(coords->x, coords->y, *str);
+ coords->x += 6;
+ }
+ if (coords->x > 276) {
+ coords->x = 22;
+ coords->y += 8;
+ if (coords->y > 208) {
+ Fault_WaitForInputImpl();
+ Fault_DrawRecBlack(22, 16, 276, 208);
+ coords->y = 16;
+ }
+ }
+ }
+ return coords;
+}
+
+void Fault_DrawText(s32 x, s32 y, const char* fmt, ...) {
+ va_list args;
+ FaultCursorCoords coords;
+
+ va_start(args, fmt);
+
+ coords.x = x - 8;
+ coords.y = y;
+ _Printf(Fault_PrintCallbackDraw, &coords, fmt, args);
+
+ va_end(args);
+}
+
+void Fault_SetCursor(s32 x, s32 y) {
+ sFaultCursorPos.x = x;
+ sFaultCursorPos.y = y;
+}
+
+void func_800AE1F8(void) {
+ Fault_DrawRecBlack(22, 16, 276, 208);
+ sFaultCursorPos.x = 22;
+ sFaultCursorPos.y = 16;
+}
+
+s32 Fault_Printf(const char* fmt, ...) {
+ s32 ret;
+ va_list args;
+
+ va_start(args, fmt);
+ ret = _Printf(Fault_PrintCallbackDraw, &sFaultCursorPos, fmt, args);
+ va_end(args);
+
+ return ret;
+}
+
+void Fault_PrintFReg(s32 x, s32 y, s32 idx, f32* value) {
+ u32 raw = *(u32*)value;
+ s32 exp = ((raw & 0x7F800000) >> 23) - 127;
+
+ if (((exp > -127) && (exp <= 127)) || (raw == 0)) {
+ Fault_DrawText(x, y, "F%02d:%.7e", idx, *value);
+ } else {
+ Fault_DrawText(x, y, "F%02d:-------------", idx);
+ }
+}
+
+void Fault_LogFReg(s32 idx, f32* value) {
+ u32 raw = *(u32*)value;
+ s32 exp = ((raw & 0x7F800000) >> 23) - 127;
+
+ if (((exp >= -0x7E) && (exp < 0x80)) || (raw == 0)) {
+ osSyncPrintf("F%02d:%.7e ", idx, *value);
+ } else {
+ osSyncPrintf("F%02d:------------- ", idx);
+ }
+}
+
+void Fault_PrintFPCSR(s32 x, s32 y, s32 value) {
+ s32 i;
+ u32 mask = FPCSR_CE;
+
+ Fault_DrawText(x, y, "FPCSR:%08xH", value);
+
+ for (i = 0; i < 6; i++) {
+ if (value & mask) {
+ Fault_DrawText(x + 100, y, "(%s)", sFpExceptionNames[i]);
+ break;
+ }
+
+ mask >>= 1;
+ }
+}
+
+void Fault_LogFPCSR(s32 value) {
+ s32 i;
+ u32 mask = FPCSR_CE;
+
+ osSyncPrintf("FPCSR:%08xH ", value);
+
+ for (i = 0; i < 6; i++) {
+ if (value & mask) {
+ osSyncPrintf("(%s)\n", sFpExceptionNames[i]);
+ break;
+ }
+
+ mask >>= 1;
+ }
+}
+
+void Fault_PrintThreadContext(OSThread* thread) {
+ __OSThreadContext* ctx = &thread->context;
+ s32 y;
+ s16 causeStrIdx = _SHIFTR((u32)thread->context.cause, 2, 5);
+
+ if (causeStrIdx == (EXC_WATCH >> CAUSE_EXCSHIFT)) {
+ causeStrIdx = 16;
+ }
+ if (causeStrIdx == (EXC_VCED >> CAUSE_EXCSHIFT)) {
+ causeStrIdx = 17;
+ }
+
+ Fault_DrawRecBlack(22, 16, 276, 24);
+
+ y = 20;
+ Fault_DrawText(30, y, "THREAD:%d (%d:%s)", thread->id, causeStrIdx, sExceptionNames[causeStrIdx]);
+
+ y += 9;
+ Fault_DrawText(30, y, "PC:%08xH SR:%08xH VA:%08xH", ctx->pc, ctx->sr, ctx->badvaddr);
+
+ y += 13;
+ Fault_DrawRecBlack(22, 40, 276, 184);
+ Fault_DrawText(30, y, "AT:%08xH V0:%08xH V1:%08xH", (u32)ctx->at, (u32)ctx->v0, (u32)ctx->v1);
+ y += 9;
+ Fault_DrawText(30, y, "A0:%08xH A1:%08xH A2:%08xH", (u32)ctx->a0, (u32)ctx->a1, (u32)ctx->a2);
+ y += 9;
+ Fault_DrawText(30, y, "A3:%08xH T0:%08xH T1:%08xH", (u32)ctx->a3, (u32)ctx->t0, (u32)ctx->t1);
+ y += 9;
+ Fault_DrawText(30, y, "T2:%08xH T3:%08xH T4:%08xH", (u32)ctx->t2, (u32)ctx->t3, (u32)ctx->t4);
+ y += 9;
+ Fault_DrawText(30, y, "T5:%08xH T6:%08xH T7:%08xH", (u32)ctx->t5, (u32)ctx->t6, (u32)ctx->t7);
+ y += 9;
+ Fault_DrawText(30, y, "S0:%08xH S1:%08xH S2:%08xH", (u32)ctx->s0, (u32)ctx->s1, (u32)ctx->s2);
+ y += 9;
+ Fault_DrawText(30, y, "S3:%08xH S4:%08xH S5:%08xH", (u32)ctx->s3, (u32)ctx->s4, (u32)ctx->s5);
+ y += 9;
+ Fault_DrawText(30, y, "S6:%08xH S7:%08xH T8:%08xH", (u32)ctx->s6, (u32)ctx->s7, (u32)ctx->t8);
+ y += 9;
+ Fault_DrawText(30, y, "T9:%08xH GP:%08xH SP:%08xH", (u32)ctx->t9, (u32)ctx->gp, (u32)ctx->sp);
+ y += 9;
+ Fault_DrawText(30, y, "S8:%08xH RA:%08xH LO:%08xH", (u32)ctx->s8, (u32)ctx->ra, (u32)ctx->lo);
+
+ y += 13;
+ Fault_PrintFPCSR(30, y, ctx->fpcsr);
+
+ y += 13;
+ Fault_PrintFReg(30, y, 0, &ctx->fp0.f.f_even);
+ Fault_PrintFReg(160, y, 2, &ctx->fp2.f.f_even);
+ y += 9;
+ Fault_PrintFReg(30, y, 4, &ctx->fp4.f.f_even);
+ Fault_PrintFReg(160, y, 6, &ctx->fp6.f.f_even);
+ y += 9;
+ Fault_PrintFReg(30, y, 8, &ctx->fp8.f.f_even);
+ Fault_PrintFReg(160, y, 10, &ctx->fp10.f.f_even);
+ y += 9;
+ Fault_PrintFReg(30, y, 12, &ctx->fp12.f.f_even);
+ Fault_PrintFReg(160, y, 14, &ctx->fp14.f.f_even);
+ y += 9;
+ Fault_PrintFReg(30, y, 16, &ctx->fp16.f.f_even);
+ Fault_PrintFReg(160, y, 18, &ctx->fp18.f.f_even);
+ y += 9;
+ Fault_PrintFReg(30, y, 20, &ctx->fp20.f.f_even);
+ Fault_PrintFReg(160, y, 22, &ctx->fp22.f.f_even);
+ y += 9;
+ Fault_PrintFReg(30, y, 24, &ctx->fp24.f.f_even);
+ Fault_PrintFReg(160, y, 26, &ctx->fp26.f.f_even);
+ y += 9;
+ Fault_PrintFReg(30, y, 28, &ctx->fp28.f.f_even);
+ Fault_PrintFReg(160, y, 30, &ctx->fp30.f.f_even);
+
+ osWritebackDCacheAll();
+}
+
+void Fault_LogThreadContext(OSThread* thread) {
+ __OSThreadContext* ctx = &thread->context;
+ s16 causeStrIdx = _SHIFTR((u32)thread->context.cause, 2, 5);
+
+ if (causeStrIdx == (EXC_WATCH >> CAUSE_EXCSHIFT)) {
+ causeStrIdx = 16;
+ }
+ if (causeStrIdx == (EXC_VCED >> CAUSE_EXCSHIFT)) {
+ causeStrIdx = 17;
+ }
+
+ osSyncPrintf("\n");
+ osSyncPrintf("THREAD ID:%d (%d:%s)\n", thread->id, causeStrIdx, sExceptionNames[causeStrIdx]);
+ osSyncPrintf("PC:%08xH SR:%08xH VA:%08xH\n", ctx->pc, ctx->sr, ctx->badvaddr);
+ osSyncPrintf("AT:%08xH V0:%08xH V1:%08xH\n", (u32)ctx->at, (u32)ctx->v0, (u32)ctx->v1);
+ osSyncPrintf("A0:%08xH A1:%08xH A2:%08xH\n", (u32)ctx->a0, (u32)ctx->a1, (u32)ctx->a2);
+ osSyncPrintf("A3:%08xH T0:%08xH T1:%08xH\n", (u32)ctx->a3, (u32)ctx->t0, (u32)ctx->t1);
+ osSyncPrintf("T2:%08xH T3:%08xH T4:%08xH\n", (u32)ctx->t2, (u32)ctx->t3, (u32)ctx->t4);
+ osSyncPrintf("T5:%08xH T6:%08xH T7:%08xH\n", (u32)ctx->t5, (u32)ctx->t6, (u32)ctx->t7);
+ osSyncPrintf("S0:%08xH S1:%08xH S2:%08xH\n", (u32)ctx->s0, (u32)ctx->s1, (u32)ctx->s2);
+ osSyncPrintf("S3:%08xH S4:%08xH S5:%08xH\n", (u32)ctx->s3, (u32)ctx->s4, (u32)ctx->s5);
+ osSyncPrintf("S6:%08xH S7:%08xH T8:%08xH\n", (u32)ctx->s6, (u32)ctx->s7, (u32)ctx->t8);
+ osSyncPrintf("T9:%08xH GP:%08xH SP:%08xH\n", (u32)ctx->t9, (u32)ctx->gp, (u32)ctx->sp);
+ osSyncPrintf("S8:%08xH RA:%08xH LO:%08xH\n", (u32)ctx->s8, (u32)ctx->ra, (u32)ctx->lo);
+ osSyncPrintf("\n");
+
+ Fault_LogFPCSR((s32)ctx->fpcsr);
+ osSyncPrintf("\n");
+ Fault_LogFReg(0, &ctx->fp0.f.f_even);
+ Fault_LogFReg(2, &ctx->fp2.f.f_even);
+ osSyncPrintf("\n");
+ Fault_LogFReg(4, &ctx->fp4.f.f_even);
+ Fault_LogFReg(6, &ctx->fp6.f.f_even);
+ osSyncPrintf("\n");
+ Fault_LogFReg(8, &ctx->fp8.f.f_even);
+ Fault_LogFReg(10, &ctx->fp10.f.f_even);
+ osSyncPrintf("\n");
+ Fault_LogFReg(12, &ctx->fp12.f.f_even);
+ Fault_LogFReg(14, &ctx->fp14.f.f_even);
+ osSyncPrintf("\n");
+ Fault_LogFReg(16, &ctx->fp16.f.f_even);
+ Fault_LogFReg(18, &ctx->fp18.f.f_even);
+ osSyncPrintf("\n");
+ Fault_LogFReg(20, &ctx->fp20.f.f_even);
+ Fault_LogFReg(22, &ctx->fp22.f.f_even);
+ osSyncPrintf("\n");
+ Fault_LogFReg(24, &ctx->fp24.f.f_even);
+ Fault_LogFReg(26, &ctx->fp26.f.f_even);
+ osSyncPrintf("\n");
+ Fault_LogFReg(28, &ctx->fp28.f.f_even);
+ Fault_LogFReg(30, &ctx->fp30.f.f_even);
+ osSyncPrintf("\n");
+}
+
+OSThread* Fault_FindFaultedThread(void) {
+ OSThread* thread = __osGetActiveQueue();
+
+ // OS_PRIORITY_THREADTAIL indicates the end of the thread queue
+ while (thread->priority != OS_PRIORITY_THREADTAIL) {
+ if (thread->priority > OS_PRIORITY_IDLE && thread->priority < OS_PRIORITY_APPMAX &&
+ (thread->flags & (OS_FLAG_CPU_BREAK | OS_FLAG_FAULT))) {
+ return thread;
+ }
+ thread = thread->tlnext;
+ }
+ return NULL;
+}
+
+void Fault_WaitForButtonCombo(void) {
+ Input* inputs = sFaultInputs;
+ s32 btnPress;
+ s32 btnCur;
+ OSTime comboStartTime;
+ s32 x;
+ s32 y;
+ s32 count;
+ s32 pad[4];
+
+ // KeyWaitB (LRZ Up Down Up Down Left Left Right Right B A START)
+ osSyncPrintf(
+ VT_FGCOL(WHITE) "KeyWaitB (LRZ " VT_FGCOL(WHITE) "上" VT_FGCOL(YELLOW) "下 " VT_FGCOL(YELLOW) "上" VT_FGCOL(WHITE) "下 " VT_FGCOL(WHITE) "左" VT_FGCOL(
+ YELLOW) "左 " VT_FGCOL(YELLOW) "右" VT_FGCOL(WHITE) "右 " VT_FGCOL(GREEN) "B" VT_FGCOL(BLUE) "A" VT_FGCOL(RED) "START" VT_FGCOL(WHITE) ")" VT_RST
+ "\n");
+ x = 0;
+ y = 0;
+ count = 0;
+ while (x != 11) {
+ if ((count % 30) == 1) {}
+ if ((count % 30) == 0) {
+ Fault_DrawCornerRecYellow();
+ }
+ count++;
+
+ Fault_SleepImpl(1000 / 60);
+ PadMgr_RequestPadData(&gPadMgr, inputs, 0);
+ btnCur = inputs[0].cur.button;
+ btnPress = inputs[0].press.button;
+ if ((btnCur == 0) && (y == 1)) {
+ y = 0;
+ osSyncPrintf("x=%d y=%d\n", x, y);
+ } else if (btnPress != 0) {
+ if (y == 1) {
+ x = 0;
+ osSyncPrintf("x=%d y=%d\n", x, y);
+ }
+ switch (x) {
+ case 0:
+ if ((btnCur == (BTN_Z | BTN_L | BTN_R)) && (btnPress == BTN_Z)) {
+ x = 1;
+ y = 1;
+ comboStartTime = osGetTime();
+ }
+ break;
+
+ case 1:
+ if (btnPress == BTN_DUP) {
+ x = 2;
+ } else {
+ x = 0;
+ }
+ break;
+
+ case 2:
+ if (btnPress == BTN_CDOWN) {
+ x = 3;
+ y = 1;
+ } else {
+ x = 0;
+ }
+ break;
+
+ case 3:
+ if (btnPress == BTN_CUP) {
+ x = 4;
+ } else {
+ x = 0;
+ }
+ break;
+
+ case 4:
+ if (btnPress == BTN_DDOWN) {
+ x = 5;
+ y = 1;
+ } else {
+ x = 0;
+ }
+ break;
+
+ case 5:
+ if (btnPress == BTN_DLEFT) {
+ x = 6;
+ } else {
+ x = 0;
+ }
+ break;
+
+ case 6:
+ if (btnPress == BTN_CLEFT) {
+ x = 7;
+ y = 1;
+ } else {
+ x = 0;
+ }
+ break;
+
+ case 7:
+ if (btnPress == BTN_CRIGHT) {
+ x = 8;
+ } else {
+ x = 0;
+ }
+ break;
+
+ case 8:
+ if (btnPress == BTN_DRIGHT) {
+ x = 9;
+ y = 1;
+ } else {
+ x = 0;
+ }
+ break;
+
+ case 9:
+ if (btnPress == (BTN_A | BTN_B)) {
+ x = 10;
+ } else if (btnPress == BTN_A) {
+ x = 91;
+ } else if (btnPress == BTN_B) {
+ x = 92;
+ } else {
+ x = 0;
+ }
+ break;
+
+ case 91:
+ if (btnPress == BTN_B) {
+ x = 10;
+ } else {
+ x = 0;
+ }
+ break;
+
+ case 92:
+ if (btnPress == BTN_A) {
+ x = 10;
+ } else {
+ x = 0;
+ }
+ break;
+
+ case 10:
+ if ((btnCur == (BTN_A | BTN_B | BTN_START)) && (btnPress == BTN_START)) {
+ f32 comboTimeSeconds = OS_CYCLES_TO_USEC(osGetTime() - comboStartTime) / 1000000.0f;
+
+ // Input time %f seconds
+ osSyncPrintf("入力時間 %f 秒\n", comboTimeSeconds);
+ if (comboTimeSeconds <= 50.0f) {
+ x = 11;
+ } else {
+ x = 0;
+ }
+ } else {
+ x = 0;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+}
+
+void func_800AF0E0(void) {
+ s32 i;
+
+ Fault_DrawRecBlack(22, 16, 276, 208);
+ Fault_DrawText(40, 30, "SegmentBaseAddress");
+
+ for (i = 0; i < ARRAY_COUNT(gSegments); i++) {
+ Fault_DrawText(40, 40 + 8 * i, "%2d:%08x", i, gSegments[i]);
+ }
+ Fault_DrawText(40, 180, "Arena_failcnt = %d", gTotalAllocFailures);
+}
+
+void Fault_DrawMemDumpContents(const char* title, void* memory, u32 arg2) {
+ s32 x;
+ s32 y;
+ u32* ptr = (u32*)((uintptr_t)memory & ~3);
+
+ Fault_DrawRecBlack(22, 16, 276, 208);
+ Fault_DrawText(36, 18, "%s %08x", title != NULL ? title : "PrintDump", ptr);
+
+ if (((uintptr_t)ptr >= PHYS_TO_K0(0x000000)) && ((uintptr_t)ptr <= PHYS_TO_K0(0x400000))) {
+ for (y = 28; y < 226; y += 9) {
+ Fault_DrawText(28, y, "%06x", ptr);
+ for (x = 82; x < 290; x += 52) {
+ Fault_DrawText(x, y, "%08x", *(ptr++));
+ }
+ }
+ }
+}
+
+void Fault_DrawMemDumpPC(OSThread* thread) {
+ u32* pc = (u32*)thread->context.pc;
+
+ if (((uintptr_t)pc >= 0x80000020) && ((uintptr_t)pc <= 0x80400000)) {
+ Fault_DrawMemDumpContents("PC Trace", pc - 0x20, 0);
+ }
+}
+
+void Fault_DrawMemDumpSP(OSThread* thread) {
+ u32* sp = (u32*)(u32)thread->context.sp;
+
+ if (((uintptr_t)sp >= 0x80000020) && ((uintptr_t)sp <= 0x80400000)) {
+ Fault_DrawMemDumpContents("Stack Trace", sp, 0);
+ }
+}
+
+void func_800AF3DC(void) {
+ s32 i;
+
+ Fault_DrawRecBlack(22, 16, 276, 208);
+ Fault_DrawText(36, 18, "ROM DEBUG");
+
+ for (i = 0; i < ARRAY_COUNT(B_80122570); i++) {
+ Fault_DrawText(((i % 4) * 52) + 82, ((i / 4) * 9) + 28, "%08x", B_80122570[i]);
+ }
+}
+
+void Fault_ResumeThread(OSThread* thread) {
+ thread->context.cause = 0;
+ thread->context.fpcsr = 0;
+ thread->context.pc += sizeof(u32);
+ *(u32*)thread->context.pc = 0x0000000D; // write in a break instruction
+ osWritebackDCache((void*)thread->context.pc, 4);
+ osInvalICache((void*)thread->context.pc, 4);
+ osStartThread(thread);
+}
+
+void func_800AF558(void) {
+ osViBlack(false);
+ if ((uintptr_t)osViGetCurrentFramebuffer() >= 0x80100000) {
+ gFaultMgr.fb = osViGetCurrentFramebuffer();
+ } else {
+ gFaultMgr.fb = (u16*)(PHYS_TO_K0(osMemSize) - sizeof(u16[SCREEN_HEIGHT][SCREEN_WIDTH]));
+ osViSwapBuffer(gFaultMgr.fb);
+ }
+}
+
+void Fault_AddClient(FaultClient* client, void* callback, void* arg0, void* arg1) {
+ FaultMgr* faultMgr = &gFaultMgr;
+ OSIntMask mask;
+
+ mask = osSetIntMask(OS_IM_NONE);
+
+ client->callback = callback;
+ client->arg0 = arg0;
+ client->arg1 = arg1;
+ client->next = faultMgr->clients;
+ faultMgr->clients = client;
+
+ osSetIntMask(mask);
+}
+
+void Fault_RemoveClient(FaultClient* client) {
+ u32 mask;
+ FaultClient* iterClient = gFaultMgr.clients;
+ FaultClient* lastClient = NULL;
+
+ mask = osSetIntMask(OS_IM_NONE);
+ while (iterClient != NULL) {
+ if (iterClient == client) {
+ if (lastClient != NULL) {
+ lastClient->next = client->next;
+ } else {
+ gFaultMgr.clients = client->next;
+ }
+ break;
+ } else {
+ lastClient = iterClient;
+ iterClient = iterClient->next;
+ }
+ }
+ osSetIntMask(mask);
+}
+
+void Fault_ProcessClients(void) {
+ s32 i;
+ FaultClient* client;
+
+ client = gFaultMgr.clients;
+ i = 0;
+ while (client != NULL) {
+ if (client->callback != NULL) {
+ Fault_DrawRecBlack(22, 16, 276, 208);
+ Fault_DrawText(30, 20, "CallBack (%d) %08x %08x %08x", i++, client, client->arg0, client->arg1);
+ ((void (*)(void*, void*))client->callback)(client->arg0, client->arg1);
+ Fault_WaitForInput();
+ }
+ client = client->next;
+ }
+}
+
+#define FAULT_MSG_CPU_BREAK ((OSMesg)1)
+#define FAULT_MSG_FAULT ((OSMesg)2)
+#define FAULT_MSG_UNK ((OSMesg)3)
+
+void Fault_ThreadEntry(void* arg0) {
+ OSMesg msg;
+ OSThread* faultedThread;
+
+ osSetEventMesg(OS_EVENT_CPU_BREAK, &gFaultMgr.queue, FAULT_MSG_CPU_BREAK);
+ osSetEventMesg(OS_EVENT_FAULT, &gFaultMgr.queue, FAULT_MSG_FAULT);
+ while (true) {
+ do {
+ osRecvMesg(&gFaultMgr.queue, &msg, OS_MESG_BLOCK);
+ if (msg == FAULT_MSG_CPU_BREAK) {
+ gFaultMsgId = (s32)FAULT_MSG_CPU_BREAK;
+ // Fault Manager: OS_EVENT_CPU_BREAK received
+ osSyncPrintf("フォルトマネージャ:OS_EVENT_CPU_BREAKを受信しました\n");
+ } else if (msg == FAULT_MSG_FAULT) {
+ gFaultMsgId = (s32)FAULT_MSG_FAULT;
+ // Fault Manager: OS_EVENT_FAULT received
+ osSyncPrintf("フォルトマネージャ:OS_EVENT_FAULTを受信しました\n");
+ } else {
+ gFaultMsgId = (s32)FAULT_MSG_UNK;
+ // Fault Manager: Unknown message received
+ osSyncPrintf("フォルトマネージャ:不明なメッセージを受信しました\n");
+ }
+ faultedThread = __osGetCurrFaultedThread();
+ osSyncPrintf("__osGetCurrFaultedThread()=%08x\n", faultedThread);
+ if (faultedThread == NULL) {
+ faultedThread = Fault_FindFaultedThread();
+ osSyncPrintf("FindFaultedThread()=%08x\n", faultedThread);
+ }
+ } while (faultedThread == NULL);
+ sFaultFaultedThread = faultedThread;
+ Fault_LogThreadContext(faultedThread);
+ osSyncPrintf("%d %s %d:%s = %d\n", osGetThreadId(NULL), "fault.c", 1454, "fault_display_enable",
+ sFaultDisplayEnable);
+ while (!sFaultDisplayEnable) {
+ Fault_SleepImpl(1000);
+ }
+ Fault_SleepImpl(500);
+ Fault_DrawCornerRecRed();
+ Fault_WaitForButtonCombo();
+ do {
+ func_800AF558();
+ Fault_PrintThreadContext(faultedThread);
+ Fault_WaitForInput();
+ func_800AF0E0();
+ Fault_WaitForInput();
+ func_800AF3DC();
+ Fault_WaitForInput();
+ Fault_DrawMemDumpSP(faultedThread);
+ Fault_WaitForInput();
+ Fault_DrawMemDumpPC(faultedThread);
+ Fault_WaitForInput();
+ Fault_ProcessClients();
+ } while (!sFaultExit);
+ while (!sFaultExit) {}
+ Fault_ResumeThread(faultedThread);
+ }
+}
+
+void Fault_SetFrameBuffer(void* fb, u16 w, u16 h) {
+ gFaultMgr.fb = fb;
+ gFaultMgr.fbWidth = w;
+ gFaultMgr.fbDepth = h;
+}
+
+void Fault_Init(void) {
+ sFaultDisplayEnable = 1;
+ gFaultMgr.fb = (u16*)(PHYS_TO_K0(osMemSize) - sizeof(u16[SCREEN_HEIGHT][SCREEN_WIDTH]));
+ gFaultMgr.fbWidth = SCREEN_WIDTH;
+ gFaultMgr.fbDepth = 16;
+ gFaultMgr.clients = 0;
+ osCreateMesgQueue(&gFaultMgr.queue, &gFaultMgr.msg, 1);
+ StackCheck_Init(&sFaultStackInfo, sFaultStack, STACK_TOP(sFaultStack), 0, 0x100, "fault");
+ osCreateThread(&gFaultMgr.thread, THREAD_ID_FAULT, Fault_ThreadEntry, NULL, STACK_TOP(sFaultStack),
+ THREAD_PRI_FAULT);
+ osStartThread(&gFaultMgr.thread);
+}
+
+void Fault_AddHungupAndCrashImpl(const char* exp1, const char* exp2) {
+ gFaultMsgId = 4;
+ osSyncPrintf("HungUp on Thread %d", osGetThreadId(NULL));
+ osSyncPrintf("%s\n", exp1 != NULL ? exp1 : "(NULL)");
+ osSyncPrintf("%s\n", exp2 != NULL ? exp2 : "(NULL)");
+ while (sFaultDisplayEnable == 0) {
+ Fault_SleepImpl(1000);
+ }
+ Fault_SleepImpl(500);
+ Fault_WaitForButtonCombo();
+ do {
+ func_800AF558();
+ Fault_DrawRecBlack(22, 16, 276, 34);
+ Fault_DrawText(24, 18, "HungUp on Thread %d", osGetThreadId(NULL));
+ Fault_DrawText(24, 28, "%s", exp1 != NULL ? exp1 : "(NULL)");
+ Fault_DrawText(24, 38, "%s", exp2 != NULL ? exp2 : "(NULL)");
+ Fault_WaitForInput();
+ Fault_ProcessClients();
+ } while (true);
+}
+
+void Fault_AddHungupAndCrash(const char* file, int line) {
+ char msg[256];
+
+ sprintf(msg, "HungUp %s:%d", file, line);
+ Fault_AddHungupAndCrashImpl(msg, NULL);
+}
diff --git a/src/code/game.c b/src/code/game.c
index 7a53acdda..37283ac5a 100644
--- a/src/code/game.c
+++ b/src/code/game.c
@@ -1,4 +1,7 @@
#include "global.h"
+#if OOT_DEBUG
+#include "fault.h"
+#endif
#include "terminal.h"
#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128"
diff --git a/src/code/graph.c b/src/code/graph.c
index f6cf66b12..1f9ba5e30 100644
--- a/src/code/graph.c
+++ b/src/code/graph.c
@@ -1,4 +1,5 @@
#include "global.h"
+#include "fault.h"
#include "terminal.h"
#define GFXPOOL_HEAD_MAGIC 0x1234
diff --git a/src/code/main.c b/src/code/main.c
index 2e46ae825..fa6b5f672 100644
--- a/src/code/main.c
+++ b/src/code/main.c
@@ -1,4 +1,5 @@
#include "global.h"
+#include "fault.h"
#include "terminal.h"
#include "versions.h"
#if PLATFORM_N64
diff --git a/src/code/padmgr.c b/src/code/padmgr.c
index 75fb125ba..75db1fd4f 100644
--- a/src/code/padmgr.c
+++ b/src/code/padmgr.c
@@ -29,6 +29,7 @@
* done while waiting for this operation to complete.
*/
#include "global.h"
+#include "fault.h"
#include "terminal.h"
#define PADMGR_LOG(controllerNum, msg) \
@@ -236,7 +237,7 @@ void PadMgr_RumbleStop(PadMgr* padMgr) {
if (osMotorInit(serialEventQueue, &padMgr->rumblePfs[i], i) == 0) {
// If there is a rumble pak attached to this controller, stop it
- if (gFaultMgr.msgId == 0 && padMgr->rumbleOnTimer != 0) {
+ if (FAULT_MSG_ID == 0 && padMgr->rumbleOnTimer != 0) {
PADMGR_LOG(i, T("振動パック 停止", "Stop rumble pak"));
}
osMotorStop(&padMgr->rumblePfs[i]);
@@ -399,7 +400,7 @@ void PadMgr_HandleRetrace(PadMgr* padMgr) {
}
padMgr->validCtrlrsMask = mask;
- if (gFaultMgr.msgId != 0) {
+ if (FAULT_MSG_ID != 0) {
// If fault is active, no rumble
PadMgr_RumbleStop(padMgr);
} else if (padMgr->rumbleOffTimer > 0) {
diff --git a/src/code/sched.c b/src/code/sched.c
index ef34a4f6a..1deaa74b2 100644
--- a/src/code/sched.c
+++ b/src/code/sched.c
@@ -40,6 +40,7 @@
* @see irqmgr.c
*/
#include "global.h"
+#include "fault.h"
#define RSP_DONE_MSG 667
#define RDP_DONE_MSG 668
diff --git a/src/code/sys_matrix.c b/src/code/sys_matrix.c
index 550b39e4e..ce9846086 100644
--- a/src/code/sys_matrix.c
+++ b/src/code/sys_matrix.c
@@ -1,4 +1,7 @@
#include "global.h"
+#if OOT_DEBUG
+#include "fault.h"
+#endif
// clang-format off
Mtx gMtxClear = gdSPDefMtx(
diff --git a/src/code/z_actor.c b/src/code/z_actor.c
index f531ba6d6..ef90f6002 100644
--- a/src/code/z_actor.c
+++ b/src/code/z_actor.c
@@ -1,4 +1,5 @@
#include "global.h"
+#include "fault.h"
#include "quake.h"
#include "terminal.h"
diff --git a/src/code/z_actor_dlftbls.c b/src/code/z_actor_dlftbls.c
index ff162db4b..b5a00068b 100644
--- a/src/code/z_actor_dlftbls.c
+++ b/src/code/z_actor_dlftbls.c
@@ -1,4 +1,5 @@
#include "global.h"
+#include "fault.h"
// Linker symbol declarations (used in the table below)
#define DEFINE_ACTOR(name, _1, _2, _3) DECLARE_OVERLAY_SEGMENT(name)
diff --git a/src/code/z_collision_check.c b/src/code/z_collision_check.c
index 1680d9066..b80ac0bb5 100644
--- a/src/code/z_collision_check.c
+++ b/src/code/z_collision_check.c
@@ -5,6 +5,8 @@
#include "overlays/effects/ovl_Effect_Ss_HitMark/z_eff_ss_hitmark.h"
+#pragma increment_block_number "gc-eu:64 gc-eu-mq:64 gc-jp:64 gc-jp-ce:64 gc-jp-mq:64 gc-us:64 gc-us-mq:64"
+
typedef s32 (*ColChkResetFunc)(PlayState*, Collider*);
typedef void (*ColChkApplyFunc)(PlayState*, CollisionCheckContext*, Collider*);
typedef void (*ColChkVsFunc)(PlayState*, CollisionCheckContext*, Collider*, Collider*);
@@ -2193,6 +2195,8 @@ void CollisionCheck_ATTrisVsACCyl(PlayState* play, CollisionCheckContext* colChk
}
}
+#pragma increment_block_number "gc-eu:252 gc-eu-mq:252 gc-jp:252 gc-jp-ce:252 gc-jp-mq:252 gc-us:252 gc-us-mq:252"
+
void CollisionCheck_ATCylVsACQuad(PlayState* play, CollisionCheckContext* colChkCtx, Collider* atCol, Collider* acCol) {
static TriNorm tri1;
static TriNorm tri2;
@@ -2694,8 +2698,6 @@ typedef enum ColChkMassType {
/* 2 */ MASSTYPE_NORMAL
} ColChkMassType;
-#pragma increment_block_number "gc-eu:252 gc-eu-mq:252 gc-jp:252 gc-jp-ce:252 gc-jp-mq:252 gc-us:252 gc-us-mq:252"
-
/**
* Get mass type. Immovable colliders cannot be pushed, while heavy colliders can only be pushed by heavy and immovable
* colliders.
diff --git a/src/code/z_message.c b/src/code/z_message.c
index 3f8bc19b9..a610f036f 100644
--- a/src/code/z_message.c
+++ b/src/code/z_message.c
@@ -1,6 +1,7 @@
#include "global.h"
#include "message_data_static.h"
#include "terminal.h"
+#include "versions.h"
#include "assets/textures/parameter_static/parameter_static.h"
#include "versions.h"
diff --git a/src/code/z_play.c b/src/code/z_play.c
index ee39e07b7..0c106f610 100644
--- a/src/code/z_play.c
+++ b/src/code/z_play.c
@@ -1,11 +1,16 @@
#include "global.h"
+#if OOT_DEBUG
+#include "fault.h"
+#endif
#include "quake.h"
#include "terminal.h"
#include "versions.h"
#include "z64frame_advance.h"
+#pragma increment_block_number "gc-eu:8 gc-eu-mq:8 gc-jp:8 gc-jp-ce:8 gc-jp-mq:8 gc-us:8 gc-us-mq:8"
+
TransitionTile gTransitionTile;
s32 gTransitionTileState;
VisMono gPlayVisMono;
diff --git a/src/overlays/actors/ovl_En_Mag/z_en_mag.c b/src/overlays/actors/ovl_En_Mag/z_en_mag.c
index bbcf39362..94e298ad8 100644
--- a/src/overlays/actors/ovl_En_Mag/z_en_mag.c
+++ b/src/overlays/actors/ovl_En_Mag/z_en_mag.c
@@ -5,6 +5,7 @@
*/
#include "z_en_mag.h"
+#include "versions.h"
#include "assets/objects/object_mag/object_mag.h"
#if PLATFORM_N64
#include "n64dd.h"
diff --git a/src/overlays/actors/ovl_Fishing/z_fishing.c b/src/overlays/actors/ovl_Fishing/z_fishing.c
index 834f1aed7..a22980926 100644
--- a/src/overlays/actors/ovl_Fishing/z_fishing.c
+++ b/src/overlays/actors/ovl_Fishing/z_fishing.c
@@ -14,7 +14,7 @@
#include "cic6105.h"
#endif
-#pragma increment_block_number "gc-eu:164 gc-eu-mq:164 gc-jp:166 gc-jp-ce:166 gc-jp-mq:166 gc-us:166 gc-us-mq:166"
+#pragma increment_block_number "gc-eu:174 gc-eu-mq:174 gc-jp:176 gc-jp-ce:176 gc-jp-mq:176 gc-us:176 gc-us-mq:176"
#define FLAGS ACTOR_FLAG_4
diff --git a/src/overlays/actors/ovl_player_actor/z_player.c b/src/overlays/actors/ovl_player_actor/z_player.c
index a0766c4fe..145425804 100644
--- a/src/overlays/actors/ovl_player_actor/z_player.c
+++ b/src/overlays/actors/ovl_player_actor/z_player.c
@@ -354,19 +354,19 @@ void Player_Action_CsAction(Player* this, PlayState* play);
// .bss part 1
-#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128"
+#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128"
static s32 D_80858AA0;
// TODO: There's probably a way to match BSS ordering with less padding by spreading the variables out and moving
// data around. It would be easier if we had more options for controlling BSS ordering in debug.
-#pragma increment_block_number "gc-eu:192 gc-eu-mq:192 gc-jp:192 gc-jp-ce:192 gc-jp-mq:192 gc-us:192 gc-us-mq:192"
+#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:192 gc-jp-ce:192 gc-jp-mq:192 gc-us:192 gc-us-mq:192"
static s32 D_80858AA4;
static Vec3f sInteractWallCheckResult;
static Input* sControlInput;
-#pragma increment_block_number "gc-eu:224 gc-eu-mq:224 gc-jp:224 gc-jp-ce:224 gc-jp-mq:224 gc-us:224 gc-us-mq:224"
+#pragma increment_block_number "gc-eu:192 gc-eu-mq:192 gc-jp:224 gc-jp-ce:224 gc-jp-mq:224 gc-us:224 gc-us-mq:224"
// .data
diff --git a/tools/disasm/ntsc-1.2/files_code.csv b/tools/disasm/ntsc-1.2/files_code.csv
index 9e18dc024..65c2757db 100644
--- a/tools/disasm/ntsc-1.2/files_code.csv
+++ b/tools/disasm/ntsc-1.2/files_code.csv
@@ -108,7 +108,7 @@ DB80,8001F260,src/code/z_actor
9BD80,800AD460,src/code/irqmgr
9C3A0,800ADA80,src/code/code_n64dd_800AD410
9C450,800ADB30,src/code/code_n64dd_800AD4C0
-9C540,800ADC20,src/code/fault
+9C540,800ADC20,src/code/fault_n64
9E710,800AFDF0,src/code/kanread
9F1F0,800B08D0,src/audio/lib/synthesis
A2380,800B3A60,src/audio/lib/heap
@@ -276,7 +276,7 @@ EDD90,800FF470,src/code/sys_ucode
EDDA0,800FF480,src/code/sys_rumble
EDDB0,800FF490,src/code/irqmgr
EDDD0,800FF4B0,src/code/code_n64dd_800AD4C0
-EE280,800FF960,src/code/fault
+EE280,800FF960,src/code/fault_n64
EE300,800FF9E0,src/audio/lib/data
F0710,80101DF0,src/audio/lib/synthesis
F0740,80101E20,src/audio/lib/load
@@ -363,7 +363,7 @@ F7E00,801094E0,src/code/sys_math3d
F7E90,80109570,src/code/sys_math_atan
F7EA0,80109580,src/code/sys_matrix
F7ED0,801095B0,src/code/irqmgr
-F7EF0,801095D0,src/code/fault
+F7EF0,801095D0,src/code/fault_n64
F8780,80109E60,src/audio/lib/synthesis
F87A0,80109E80,src/audio/lib/heap
F87D0,80109EB0,src/audio/lib/load
@@ -440,7 +440,7 @@ offset,vram,.bss
1103F0,80121AD0,src/code/sys_matrix
110400,80121AE0,src/code/code_n64dd_800AD410
110410,80121AF0,src/code/code_n64dd_800AD4C0
-110420,80121B00,src/code/fault
+110420,80121B00,src/code/fault_n64
110EF0,801225D0,src/audio/lib/load
110FB0,80122690,src/audio/general
1111B0,80122890,src/audio/sfx
diff --git a/tools/disasm/ntsc-1.2/functions.txt b/tools/disasm/ntsc-1.2/functions.txt
index f63400871..b6423476a 100644
--- a/tools/disasm/ntsc-1.2/functions.txt
+++ b/tools/disasm/ntsc-1.2/functions.txt
@@ -2313,40 +2313,40 @@ func_800ADBD0 = 0x800ADBD0; // type:func
func_800ADC00 = 0x800ADC00; // type:func
func_800ADC08 = 0x800ADC08; // type:func
Fault_SleepImpl = 0x800ADC20; // type:func
-func_800ADC5C_unknown = 0x800ADC5C; // type:func
-func_800ADCD8_unknown = 0x800ADCD8; // type:func
-func_800ADD14_unknown = 0x800ADD14; // type:func
-func_800ADDF0_unknown = 0x800ADDF0; // type:func
-func_800ADE30_unknown = 0x800ADE30; // type:func
-func_800ADF4C_unknown = 0x800ADF4C; // type:func
-func_800ADF90_unknown = 0x800ADF90; // type:func
-func_800ADFE4_unknown = 0x800ADFE4; // type:func
-func_800AE020_unknown = 0x800AE020; // type:func
-func_800AE05C_unknown = 0x800AE05C; // type:func
-func_800AE064_unknown = 0x800AE064; // type:func
-func_800AE170_unknown = 0x800AE170; // type:func
-func_800AE1E0_unknown = 0x800AE1E0; // type:func
-func_800AE1F8_unknown = 0x800AE1F8; // type:func
-func_800AE258_unknown = 0x800AE258; // type:func
-func_800AE2B8_unknown = 0x800AE2B8; // type:func
-func_800AE35C_unknown = 0x800AE35C; // type:func
-func_800AE408_unknown = 0x800AE408; // type:func
-func_800AE4C0_unknown = 0x800AE4C0; // type:func
-func_800AE558_unknown = 0x800AE558; // type:func
-func_800AE998_unknown = 0x800AE998; // type:func
-func_800AEC94_unknown = 0x800AEC94; // type:func
-func_800AED1C_unknown = 0x800AED1C; // type:func
-func_800AF0E0_unknown = 0x800AF0E0; // type:func
-func_800AF1C4_unknown = 0x800AF1C4; // type:func
-func_800AF304_unknown = 0x800AF304; // type:func
-func_800AF370_unknown = 0x800AF370; // type:func
-func_800AF3DC_unknown = 0x800AF3DC; // type:func
-func_800AF4DC_unknown = 0x800AF4DC; // type:func
-func_800AF558_unknown = 0x800AF558; // type:func
+Fault_WaitForInputImpl = 0x800ADC5C; // type:func
+Fault_WaitForInput = 0x800ADCD8; // type:func
+Fault_DrawRec = 0x800ADD14; // type:func
+Fault_DrawRecBlack = 0x800ADDF0; // type:func
+Fault_DrawCharImpl = 0x800ADE30; // type:func
+Fault_DrawChar = 0x800ADF4C; // type:func
+Fault_DrawCornerRec = 0x800ADF90; // type:func
+Fault_DrawCornerRecRed = 0x800ADFE4; // type:func
+Fault_DrawCornerRecYellow = 0x800AE020; // type:func
+func_800AE05C = 0x800AE05C; // type:func
+Fault_PrintCallbackDraw = 0x800AE064; // type:func
+Fault_DrawText = 0x800AE170; // type:func
+Fault_SetCursor = 0x800AE1E0; // type:func
+func_800AE1F8 = 0x800AE1F8; // type:func
+Fault_Printf = 0x800AE258; // type:func
+Fault_PrintFReg = 0x800AE2B8; // type:func
+Fault_LogFReg = 0x800AE35C; // type:func
+Fault_PrintFPCSR = 0x800AE408; // type:func
+Fault_LogFPCSR = 0x800AE4C0; // type:func
+Fault_PrintThreadContext = 0x800AE558; // type:func
+Fault_LogThreadContext = 0x800AE998; // type:func
+Fault_FindFaultedThread = 0x800AEC94; // type:func
+Fault_WaitForButtonCombo = 0x800AED1C; // type:func
+func_800AF0E0 = 0x800AF0E0; // type:func
+Fault_DrawMemDumpContents = 0x800AF1C4; // type:func
+Fault_DrawMemDumpPC = 0x800AF304; // type:func
+Fault_DrawMemDumpSP = 0x800AF370; // type:func
+func_800AF3DC = 0x800AF3DC; // type:func
+Fault_ResumeThread = 0x800AF4DC; // type:func
+func_800AF558 = 0x800AF558; // type:func
Fault_AddClient = 0x800AF5EC; // type:func
Fault_RemoveClient = 0x800AF674; // type:func
-func_800AF720_unknown = 0x800AF720; // type:func
-func_800AF7F0_unknown = 0x800AF7F0; // type:func
+Fault_ProcessClients = 0x800AF720; // type:func
+Fault_ThreadEntry = 0x800AF7F0; // type:func
Fault_SetFrameBuffer = 0x800AFA90; // type:func
Fault_Init = 0x800AFABC; // type:func
Fault_AddHungupAndCrashImpl = 0x800AFBC4; // type:func
diff --git a/tools/disasm/ntsc-1.2/variables.txt b/tools/disasm/ntsc-1.2/variables.txt
index 9d08423a8..5bd31b21d 100644
--- a/tools/disasm/ntsc-1.2/variables.txt
+++ b/tools/disasm/ntsc-1.2/variables.txt
@@ -22,6 +22,10 @@ _n64ddSegmentRomEnd = 0x00B9DA70;
D_801DA410 = 0x801DA410;
D_801E8090 = 0x801E8090;
D_800FF4B0 = 0x800FF4B0; // size:0xB0 type:n64ddStruct_800FF4B0_pointers
+gPadMgr = 0x8011DBD0; // size:0x468 type:PadMgr
+gFaultMgr = 0x80121B60; // size:0x5D8 type:FaultMgr_v1
+sFaultInputs = 0x80121B00; // size:0x60 type:Input[4]
+gTotalAllocFailures = 0x80105A90; // size:0x4 type:u32
gBitFlags = 0x800F9240; // size:0x80 type:u32[32]
gSfxDefaultPos = 0x801049D4; // size:0xC type:Vec3f
gSfxDefaultFreqAndVolScale = 0x801049E0; // size:0x4 type:f32
diff --git a/tools/m2ctx.py b/tools/m2ctx.py
index 7e5c522c8..6d8a6163f 100755
--- a/tools/m2ctx.py
+++ b/tools/m2ctx.py
@@ -25,16 +25,16 @@ def get_c_file(directory):
return file
-def import_c_file(in_file):
+def import_c_file(in_file, version):
in_file = os.path.relpath(in_file, root_dir)
- cpp_command = ["gcc", "-E", "-P", "-Iinclude", "-Isrc", "-undef", "-DM2CTX", "-D__sgi", "-D_LANGUAGE_C",
+ cpp_command = ["gcc", "-nostdinc", "-E", "-P", "-Iinclude", "-Iinclude/libc", "-Isrc", f"-Ibuild/{version}", "-I.", f"-Iextracted/{version}", "-undef", "-DM2CTX", "-D__sgi", "-D_LANGUAGE_C",
"-DNON_MATCHING", "-D_Static_assert(x, y)=", "-D__attribute__(x)=", in_file]
try:
return subprocess.check_output(cpp_command, cwd=root_dir, encoding="utf-8")
except subprocess.CalledProcessError:
print(
"Failed to preprocess input file, when running command:\n"
- + cpp_command,
+ + " ".join(cpp_command),
file=sys.stderr,
)
sys.exit(1)
@@ -45,8 +45,11 @@ def main():
description="Creates a ctx.c file for mips2c. "
"Output will be saved as oot/ctx.c")
parser.add_argument('filepath', help="path of c file to be processed")
+ parser.add_argument("-v", "--oot-version", dest="oot_version", required=True)
args = parser.parse_args()
+ version = args.oot_version
+
if args.filepath:
c_file_path = args.filepath
print("Using file: {}".format(c_file_path))
@@ -60,7 +63,7 @@ def main():
c_file_path = os.path.join(c_dir_path, c_file)
print("Using file: {}".format(c_file_path))
- output = import_c_file(c_file_path)
+ output = import_c_file(c_file_path, version)
with open(os.path.join(root_dir, "ctx.c"), "w", encoding="UTF-8") as f:
f.write(output)
diff --git a/undefined_syms.txt b/undefined_syms.txt
index 52c0dff6c..ef44a7fb8 100644
--- a/undefined_syms.txt
+++ b/undefined_syms.txt
@@ -22,8 +22,6 @@ func_800AE258_unknown = 0x800AE258;
func_800AE1E0_unknown = 0x800AE1E0;
// code_n64dd_800AD410.c
-func_800ADCD8_unknown = 0x800ADCD8;
-func_800AE170_unknown = 0x800AE170;
osGetIntMask = 0x800CFBB0;
osSetTime = 0x800D3660;
func_801C7740_unknown = 0x801C7740;