2022-02-02 21:43:34 +00:00
|
|
|
|
/**
|
|
|
|
|
* @file fault.c
|
|
|
|
|
*
|
|
|
|
|
* This file implements the screen that may be viewed when the game crashes.
|
|
|
|
|
* This is the second version of the crash screen, originally used in Majora's Mask.
|
|
|
|
|
*
|
|
|
|
|
* When the game crashes, a red bar will be drawn to the top-left of the screen, indicating that the
|
|
|
|
|
* crash screen is available for use. Once this bar appears, it is possible to open the crash screen
|
|
|
|
|
* with the following button combination:
|
|
|
|
|
*
|
|
|
|
|
* (L & R & Z) + DPad-Up + C-Down + C-Up + DPad-Down + DPad-Left + C-Left + C-Right + DPad-Right + (B & A & START)
|
|
|
|
|
*
|
|
|
|
|
* When entering this button combination, buttons that are &'d together must all be pressed together.
|
|
|
|
|
* The L & R presses and B & A presses may be interchanged in the order they are pressed.
|
|
|
|
|
*
|
|
|
|
|
* "Clients" may be registered with the crash screen to extend its functionality. There are
|
|
|
|
|
* two kinds of client, "Client" and "AddressConverterClient". Clients contribute one or
|
|
|
|
|
* more pages to the crash debugger, while Address Converter Clients allow the crash screen to look up
|
|
|
|
|
* the virtual addresses of dynamically allocated overlays.
|
|
|
|
|
*
|
|
|
|
|
* The crash screen has multiple pages:
|
|
|
|
|
* - Thread Context
|
|
|
|
|
* This page shows information about the thread on which the program crashed. It displays
|
|
|
|
|
* the cause of the crash, state of general-purpose registers, state of floating-point registers
|
|
|
|
|
* and the floating-point status register. If a floating-point exception caused the crash, it will
|
|
|
|
|
* be displayed next to the floating-point status register.
|
|
|
|
|
* - Stack Trace
|
|
|
|
|
* This page displays a full backtrace from the crashing function back to the start of the thread. It
|
|
|
|
|
* displays the Program Counter for each function and, if applicable, the Virtual Program Counter
|
|
|
|
|
* for relocated functions in overlays.
|
|
|
|
|
* - Client Pages
|
|
|
|
|
* After the stack trace page, currently registered clients are processed and their pages are displayed.
|
|
|
|
|
* - Memory Dump
|
|
|
|
|
* This page implements a scrollable memory dump.
|
|
|
|
|
* - End Screen
|
|
|
|
|
* This page informs you that there are no more pages to display.
|
|
|
|
|
*
|
|
|
|
|
* To navigate the pages, START and A may be used to advance to the next page, and L toggles whether to
|
|
|
|
|
* automatically scroll to the next page after some time has passed.
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2020-10-03 15:22:44 +00:00
|
|
|
|
#include "global.h"
|
|
|
|
|
#include "vt.h"
|
|
|
|
|
#include "alloca.h"
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void FaultDrawer_Init(void);
|
|
|
|
|
void FaultDrawer_SetOsSyncPrintfEnabled(u32 enabled);
|
|
|
|
|
void FaultDrawer_DrawRecImpl(s32 xStart, s32 yStart, s32 xEnd, s32 yEnd, u16 color);
|
|
|
|
|
void FaultDrawer_FillScreen(void);
|
|
|
|
|
void FaultDrawer_SetInputCallback(void (*callback)(void));
|
|
|
|
|
void FaultDrawer_SetDrawerFB(void* fb, u16 w, u16 h);
|
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
|
const char* sExceptionNames[] = {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
"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",
|
|
|
|
|
};
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
const char* sFpExceptionNames[] = {
|
|
|
|
|
"Unimplemented operation", "Invalid operation", "Division by zero", "Overflow", "Underflow", "Inexact operation",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// TODO: import .bss (has reordering issues)
|
|
|
|
|
extern FaultMgr* sFaultInstance;
|
|
|
|
|
extern u8 sFaultAwaitingInput;
|
2022-02-06 18:00:01 +00:00
|
|
|
|
extern STACK(sFaultStack, 0x600);
|
2020-04-13 23:03:10 +00:00
|
|
|
|
extern StackEntry sFaultThreadInfo;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
extern FaultMgr gFaultMgr;
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
/* 0x00 */ s32 (*callback)(void*, void*);
|
|
|
|
|
/* 0x04 */ void* arg0;
|
|
|
|
|
/* 0x08 */ void* arg1;
|
|
|
|
|
/* 0x0C */ s32 ret;
|
|
|
|
|
/* 0x10 */ OSMesgQueue* queue;
|
|
|
|
|
/* 0x14 */ OSMesg msg;
|
|
|
|
|
} FaultClientTask; // size = 0x18
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void Fault_SleepImpl(u32 msec) {
|
|
|
|
|
u64 cycles = (msec * OS_CPU_COUNTER) / 1000ull;
|
2021-10-03 03:17:09 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Sleep_Cycles(cycles);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-02-14 00:49:40 +00:00
|
|
|
|
void Fault_ClientProcessThread(void* arg) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
FaultClientTask* task = (FaultClientTask*)arg;
|
2021-02-14 00:49:40 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Run the callback
|
|
|
|
|
if (task->callback != NULL) {
|
|
|
|
|
task->ret = task->callback(task->arg0, task->arg1);
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Send completion notification
|
|
|
|
|
if (task->queue != NULL) {
|
|
|
|
|
osSendMesg(task->queue, task->msg, OS_MESG_BLOCK);
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void Fault_ClientRunTask(FaultClientTask* task) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
OSMesgQueue queue;
|
|
|
|
|
OSMesg msg;
|
|
|
|
|
OSMesg recMsg;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
OSThread* thread = NULL;
|
2020-03-18 00:09:21 +00:00
|
|
|
|
OSTimer timer;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
u32 timerMsgVal = 666;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
|
|
|
|
osCreateMesgQueue(&queue, &msg, 1);
|
2022-02-02 21:43:34 +00:00
|
|
|
|
task->queue = &queue;
|
|
|
|
|
task->msg = NULL;
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (sFaultInstance->clientThreadSp != NULL) {
|
|
|
|
|
// Run the fault client callback on a separate thread
|
2020-03-18 00:09:21 +00:00
|
|
|
|
thread = alloca(sizeof(OSThread));
|
2022-02-02 21:43:34 +00:00
|
|
|
|
|
2022-04-09 00:20:23 +00:00
|
|
|
|
osCreateThread(thread, THREAD_ID_FAULT, Fault_ClientProcessThread, task, sFaultInstance->clientThreadSp,
|
|
|
|
|
THREAD_PRI_FAULT_CLIENT);
|
2020-03-18 00:09:21 +00:00
|
|
|
|
osStartThread(thread);
|
2020-03-22 21:19:43 +00:00
|
|
|
|
} else {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Run the fault client callback on this thread
|
|
|
|
|
Fault_ClientProcessThread(task);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Await done
|
2020-03-22 21:19:43 +00:00
|
|
|
|
while (true) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
osSetTimer(&timer, OS_SEC_TO_CYCLES(1), 0, &queue, (OSMesg)timerMsgVal);
|
2021-11-07 16:58:50 +00:00
|
|
|
|
osRecvMesg(&queue, &recMsg, OS_MESG_BLOCK);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
|
if (recMsg != (OSMesg)666) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
break;
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (!sFaultAwaitingInput) {
|
|
|
|
|
task->ret = -1;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
osStopTimer(&timer);
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Destroy thread if a thread was used
|
2020-03-22 21:19:43 +00:00
|
|
|
|
if (thread != NULL) {
|
2020-03-18 00:09:21 +00:00
|
|
|
|
osStopThread(thread);
|
|
|
|
|
osDestroyThread(thread);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
s32 Fault_ProcessClient(void* callback, void* arg0, void* arg1) {
|
|
|
|
|
FaultClientTask task;
|
2021-10-03 03:17:09 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
task.callback = callback;
|
|
|
|
|
task.arg0 = arg0;
|
|
|
|
|
task.arg1 = arg1;
|
|
|
|
|
task.ret = 0;
|
|
|
|
|
Fault_ClientRunTask(&task);
|
|
|
|
|
return task.ret;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
/**
|
|
|
|
|
* Registers a fault client.
|
|
|
|
|
*
|
|
|
|
|
* Clients contribute at least one page to the crash screen, drawn by `callback`.
|
|
|
|
|
* Arguments are passed on to the callback through `arg0` and `arg1`.
|
|
|
|
|
*
|
|
|
|
|
* The callback is intended to be
|
|
|
|
|
* `void (*callback)(void* arg0, void* arg1)`
|
|
|
|
|
*/
|
|
|
|
|
void Fault_AddClient(FaultClient* client, void* callback, void* arg0, void* arg1) {
|
2020-03-18 00:09:21 +00:00
|
|
|
|
OSIntMask mask;
|
2020-09-14 17:57:17 +00:00
|
|
|
|
s32 alreadyExists = false;
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
mask = osSetIntMask(OS_IM_NONE);
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Ensure the client is not already registered
|
2020-09-14 17:57:17 +00:00
|
|
|
|
{
|
2022-02-02 21:43:34 +00:00
|
|
|
|
FaultClient* iterClient = sFaultInstance->clients;
|
2021-10-03 03:17:09 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
while (iterClient != NULL) {
|
|
|
|
|
if (iterClient == client) {
|
2020-09-14 17:57:17 +00:00
|
|
|
|
alreadyExists = true;
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
2022-02-02 21:43:34 +00:00
|
|
|
|
iterClient = iterClient->next;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client->callback = callback;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
client->arg0 = arg0;
|
|
|
|
|
client->arg1 = arg1;
|
|
|
|
|
client->next = sFaultInstance->clients;
|
|
|
|
|
sFaultInstance->clients = client;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
|
|
|
|
end:
|
|
|
|
|
osSetIntMask(mask);
|
2020-03-23 23:11:21 +00:00
|
|
|
|
if (alreadyExists) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf(VT_COL(RED, WHITE) "fault_AddClient: %08x は既にリスト中にある\n" VT_RST, client);
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
/**
|
|
|
|
|
* Removes a fault client so that the page is no longer displayed if a crash occurs.
|
|
|
|
|
*/
|
2020-03-17 04:31:30 +00:00
|
|
|
|
void Fault_RemoveClient(FaultClient* client) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
FaultClient* iterClient = sFaultInstance->clients;
|
|
|
|
|
FaultClient* lastClient = NULL;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
OSIntMask mask;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
s32 listIsEmpty = false;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
mask = osSetIntMask(OS_IM_NONE);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
while (iterClient != NULL) {
|
|
|
|
|
if (iterClient == client) {
|
|
|
|
|
if (lastClient != NULL) {
|
|
|
|
|
lastClient->next = client->next;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
} else {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
sFaultInstance->clients = client;
|
|
|
|
|
if (sFaultInstance->clients) {
|
|
|
|
|
sFaultInstance->clients = client->next;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
} else {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
listIsEmpty = true;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-02-02 21:43:34 +00:00
|
|
|
|
lastClient = iterClient;
|
|
|
|
|
iterClient = iterClient->next;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
osSetIntMask(mask);
|
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
|
if (listIsEmpty) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf(VT_COL(RED, WHITE) "fault_RemoveClient: %08x リスト不整合です\n" VT_RST, client);
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
/**
|
|
|
|
|
* Registers an address converter client. This enables the crash screen to look up virtual
|
|
|
|
|
* addresses of overlays relocated during runtime. Address conversion is carried out by
|
|
|
|
|
* `callback`, which either returns a virtual address or NULL if the address could not
|
|
|
|
|
* be converted.
|
|
|
|
|
*
|
|
|
|
|
* The callback is intended to be
|
|
|
|
|
* `uintptr_t (*callback)(uintptr_t addr, void* arg)`
|
|
|
|
|
* The callback may return 0 if it could not convert the address
|
|
|
|
|
* The callback may return -1 to be unregistered
|
|
|
|
|
*/
|
|
|
|
|
void Fault_AddAddrConvClient(FaultAddrConvClient* client, void* callback, void* arg) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
OSIntMask mask;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
s32 alreadyExists = false;
|
2020-07-18 09:55:35 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
mask = osSetIntMask(OS_IM_NONE);
|
2020-07-18 09:55:35 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Ensure the client is not already registered
|
2020-09-14 17:57:17 +00:00
|
|
|
|
{
|
2022-02-02 21:43:34 +00:00
|
|
|
|
FaultAddrConvClient* iterClient = sFaultInstance->addrConvClients;
|
2021-10-03 03:17:09 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
while (iterClient != NULL) {
|
|
|
|
|
if (iterClient == client) {
|
2020-09-14 17:57:17 +00:00
|
|
|
|
alreadyExists = true;
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
2022-02-02 21:43:34 +00:00
|
|
|
|
iterClient = iterClient->next;
|
2020-07-18 09:55:35 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client->callback = callback;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
client->arg = arg;
|
|
|
|
|
client->next = sFaultInstance->addrConvClients;
|
|
|
|
|
sFaultInstance->addrConvClients = client;
|
2020-07-18 09:55:35 +00:00
|
|
|
|
|
|
|
|
|
end:
|
|
|
|
|
osSetIntMask(mask);
|
|
|
|
|
if (alreadyExists) {
|
|
|
|
|
osSyncPrintf(VT_COL(RED, WHITE) "fault_AddressConverterAddClient: %08x は既にリスト中にある\n" VT_RST, client);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
|
|
|
|
void Fault_RemoveAddrConvClient(FaultAddrConvClient* client) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
FaultAddrConvClient* iterClient = sFaultInstance->addrConvClients;
|
|
|
|
|
FaultAddrConvClient* lastClient = NULL;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
OSIntMask mask;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
s32 listIsEmpty = false;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
mask = osSetIntMask(OS_IM_NONE);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
while (iterClient != NULL) {
|
|
|
|
|
if (iterClient == client) {
|
|
|
|
|
if (lastClient != NULL) {
|
|
|
|
|
lastClient->next = client->next;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
} else {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
sFaultInstance->addrConvClients = client;
|
|
|
|
|
|
|
|
|
|
if (sFaultInstance->addrConvClients != NULL) {
|
|
|
|
|
sFaultInstance->addrConvClients = client->next;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
} else {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
listIsEmpty = true;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-02-02 21:43:34 +00:00
|
|
|
|
lastClient = iterClient;
|
|
|
|
|
iterClient = iterClient->next;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
osSetIntMask(mask);
|
|
|
|
|
|
|
|
|
|
if (listIsEmpty) {
|
2020-03-22 21:19:43 +00:00
|
|
|
|
osSyncPrintf(VT_COL(RED, WHITE) "fault_AddressConverterRemoveClient: %08x は既にリスト中にある\n" VT_RST,
|
|
|
|
|
client);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
/**
|
|
|
|
|
* Converts `addr` to a virtual address via the registered
|
|
|
|
|
* address converter clients
|
|
|
|
|
*/
|
|
|
|
|
uintptr_t Fault_ConvertAddress(uintptr_t addr) {
|
|
|
|
|
s32 ret;
|
|
|
|
|
FaultAddrConvClient* client = sFaultInstance->addrConvClients;
|
|
|
|
|
|
|
|
|
|
while (client != NULL) {
|
|
|
|
|
if (client->callback != NULL) {
|
2022-06-16 00:15:44 +00:00
|
|
|
|
ret = Fault_ProcessClient(client->callback, (void*)addr, client->arg);
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (ret == -1) {
|
|
|
|
|
Fault_RemoveAddrConvClient(client);
|
2020-07-18 09:55:35 +00:00
|
|
|
|
} else if (ret != 0) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
return (uintptr_t)ret;
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
2022-02-02 21:43:34 +00:00
|
|
|
|
client = client->next;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void Fault_Sleep(u32 msec) {
|
|
|
|
|
Fault_SleepImpl(msec);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-09-03 00:52:13 +00:00
|
|
|
|
#ifndef AVOID_UB
|
|
|
|
|
void PadMgr_RequestPadData(Input* inputs, s32 gameRequest);
|
|
|
|
|
#endif
|
2022-02-02 21:43:34 +00:00
|
|
|
|
|
2022-09-03 00:52:13 +00:00
|
|
|
|
void Fault_PadCallback(Input* inputs) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
//! @bug This function is not called correctly, it is missing a leading PadMgr* argument. This
|
|
|
|
|
//! renders the crash screen unusable.
|
|
|
|
|
//! In Majora's Mask, PadMgr functions were changed to not require this argument, and this was
|
|
|
|
|
//! likely just not addressed when backporting.
|
2022-09-03 00:52:13 +00:00
|
|
|
|
#ifndef AVOID_UB
|
|
|
|
|
PadMgr_RequestPadData(inputs, false);
|
|
|
|
|
#else
|
|
|
|
|
// Guarantee crashing behavior: false -> NULL, previous value in a2 is more often non-zero than zero
|
|
|
|
|
PadMgr_RequestPadData((PadMgr*)inputs, NULL, true);
|
|
|
|
|
#endif
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void Fault_UpdatePadImpl(void) {
|
2022-09-03 00:52:13 +00:00
|
|
|
|
sFaultInstance->padCallback(sFaultInstance->inputs);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
/**
|
|
|
|
|
* Awaits user input
|
|
|
|
|
*
|
|
|
|
|
* L toggles auto-scroll
|
|
|
|
|
* DPad-Up enables osSyncPrintf output
|
|
|
|
|
* DPad-Down disables osSyncPrintf output
|
|
|
|
|
* A and DPad-Right continues and returns true
|
|
|
|
|
* DPad-Left continues and returns false
|
|
|
|
|
*/
|
|
|
|
|
u32 Fault_WaitForInputImpl(void) {
|
2022-09-03 00:52:13 +00:00
|
|
|
|
Input* input = &sFaultInstance->inputs[0];
|
2020-07-18 09:55:35 +00:00
|
|
|
|
s32 count = 600;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
u32 pressedBtn;
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
|
while (true) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_Sleep(1000 / 60);
|
2020-07-18 09:55:35 +00:00
|
|
|
|
Fault_UpdatePadImpl();
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
pressedBtn = input->press.button;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == BTN_L) {
|
|
|
|
|
sFaultInstance->autoScroll = !sFaultInstance->autoScroll;
|
2020-07-18 09:55:35 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (sFaultInstance->autoScroll) {
|
2020-03-23 23:11:21 +00:00
|
|
|
|
if (count-- < 1) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
return false;
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
2020-07-18 09:55:35 +00:00
|
|
|
|
} else {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == BTN_A || pressedBtn == BTN_DRIGHT) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == BTN_DLEFT) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == BTN_DUP) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
FaultDrawer_SetOsSyncPrintfEnabled(true);
|
|
|
|
|
}
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == BTN_DDOWN) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
FaultDrawer_SetOsSyncPrintfEnabled(false);
|
|
|
|
|
}
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void Fault_WaitForInput(void) {
|
|
|
|
|
sFaultAwaitingInput = true;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_WaitForInputImpl();
|
2022-02-02 21:43:34 +00:00
|
|
|
|
sFaultAwaitingInput = false;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
|
void Fault_DrawRec(s32 x, s32 y, s32 w, s32 h, u16 color) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_DrawRecImpl(x, y, x + w - 1, y + h - 1, color);
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void Fault_FillScreenBlack(void) {
|
|
|
|
|
FaultDrawer_SetForeColor(GPACK_RGBA5551(255, 255, 255, 1));
|
|
|
|
|
FaultDrawer_SetBackColor(GPACK_RGBA5551(0, 0, 0, 1));
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_FillScreen();
|
2022-02-02 21:43:34 +00:00
|
|
|
|
FaultDrawer_SetBackColor(GPACK_RGBA5551(0, 0, 0, 0));
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void Fault_FillScreenRed(void) {
|
|
|
|
|
FaultDrawer_SetForeColor(GPACK_RGBA5551(255, 255, 255, 1));
|
|
|
|
|
FaultDrawer_SetBackColor(GPACK_RGBA5551(240, 0, 0, 1));
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_FillScreen();
|
2022-02-02 21:43:34 +00:00
|
|
|
|
FaultDrawer_SetBackColor(GPACK_RGBA5551(0, 0, 0, 0));
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
|
void Fault_DrawCornerRec(u16 color) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_DrawRec(22, 16, 8, 1, color);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
|
void Fault_PrintFReg(s32 idx, f32* value) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
u32 raw = *(u32*)value;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
s32 exp = ((raw & 0x7F800000) >> 0x17) - 0x7F;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if ((exp >= -0x7E && exp < 0x80) || raw == 0) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_Printf("F%02d:%14.7e ", idx, *value);
|
2020-03-22 21:19:43 +00:00
|
|
|
|
} else {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Print subnormal floats as their ieee-754 hex representation
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_Printf("F%02d: %08x(16) ", idx, raw);
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
|
void Fault_LogFReg(s32 idx, f32* value) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
u32 raw = *(u32*)value;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
s32 exp = ((raw & 0x7F800000) >> 0x17) - 0x7F;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if ((exp >= -0x7E && exp < 0x80) || raw == 0) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf("F%02d:%14.7e ", idx, *value);
|
2020-03-22 21:19:43 +00:00
|
|
|
|
} else {
|
2020-03-18 00:09:21 +00:00
|
|
|
|
osSyncPrintf("F%02d: %08x(16) ", idx, *(u32*)value);
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void Fault_PrintFPCSR(u32 value) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
s32 i;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
u32 flag = FPCSR_CE;
|
2021-10-03 03:17:09 +00:00
|
|
|
|
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_Printf("FPCSR:%08xH ", value);
|
2022-02-02 21:43:34 +00:00
|
|
|
|
|
|
|
|
|
// Go through each of the six causes and print the name of
|
|
|
|
|
// the first cause that is set
|
|
|
|
|
for (i = 0; i < ARRAY_COUNT(sFpExceptionNames); i++) {
|
2020-03-22 21:19:43 +00:00
|
|
|
|
if (value & flag) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
FaultDrawer_Printf("(%s)", sFpExceptionNames[i]);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
flag >>= 1;
|
|
|
|
|
}
|
|
|
|
|
FaultDrawer_Printf("\n");
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void Fault_LogFPCSR(u32 value) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
s32 i;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
u32 flag = FPCSR_CE;
|
2021-10-03 03:17:09 +00:00
|
|
|
|
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf("FPCSR:%08xH ", value);
|
2022-02-02 21:43:34 +00:00
|
|
|
|
for (i = 0; i < ARRAY_COUNT(sFpExceptionNames); i++) {
|
2020-03-22 21:19:43 +00:00
|
|
|
|
if (value & flag) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
osSyncPrintf("(%s)\n", sFpExceptionNames[i]);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
flag >>= 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void Fault_PrintThreadContext(OSThread* thread) {
|
2020-03-22 21:19:43 +00:00
|
|
|
|
__OSThreadContext* ctx;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
s16 causeStrIdx = _SHIFTR((u32)thread->context.cause, 2, 5);
|
2021-10-03 03:17:09 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (causeStrIdx == 23) { // Watchpoint
|
|
|
|
|
causeStrIdx = 16;
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (causeStrIdx == 31) { // Virtual coherency on data
|
|
|
|
|
causeStrIdx = 17;
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
|
|
|
|
FaultDrawer_FillScreen();
|
|
|
|
|
FaultDrawer_SetCharPad(-2, 4);
|
2022-02-02 21:43:34 +00:00
|
|
|
|
FaultDrawer_SetCursor(22, 20);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
ctx = &thread->context;
|
|
|
|
|
FaultDrawer_Printf("THREAD:%d (%d:%s)\n", thread->id, causeStrIdx, sExceptionNames[causeStrIdx]);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_SetCharPad(-1, 0);
|
|
|
|
|
|
|
|
|
|
FaultDrawer_Printf("PC:%08xH SR:%08xH VA:%08xH\n", (u32)ctx->pc, (u32)ctx->sr, (u32)ctx->badvaddr);
|
|
|
|
|
FaultDrawer_Printf("AT:%08xH V0:%08xH V1:%08xH\n", (u32)ctx->at, (u32)ctx->v0, (u32)ctx->v1);
|
|
|
|
|
FaultDrawer_Printf("A0:%08xH A1:%08xH A2:%08xH\n", (u32)ctx->a0, (u32)ctx->a1, (u32)ctx->a2);
|
|
|
|
|
FaultDrawer_Printf("A3:%08xH T0:%08xH T1:%08xH\n", (u32)ctx->a3, (u32)ctx->t0, (u32)ctx->t1);
|
|
|
|
|
FaultDrawer_Printf("T2:%08xH T3:%08xH T4:%08xH\n", (u32)ctx->t2, (u32)ctx->t3, (u32)ctx->t4);
|
|
|
|
|
FaultDrawer_Printf("T5:%08xH T6:%08xH T7:%08xH\n", (u32)ctx->t5, (u32)ctx->t6, (u32)ctx->t7);
|
|
|
|
|
FaultDrawer_Printf("S0:%08xH S1:%08xH S2:%08xH\n", (u32)ctx->s0, (u32)ctx->s1, (u32)ctx->s2);
|
|
|
|
|
FaultDrawer_Printf("S3:%08xH S4:%08xH S5:%08xH\n", (u32)ctx->s3, (u32)ctx->s4, (u32)ctx->s5);
|
|
|
|
|
FaultDrawer_Printf("S6:%08xH S7:%08xH T8:%08xH\n", (u32)ctx->s6, (u32)ctx->s7, (u32)ctx->t8);
|
|
|
|
|
FaultDrawer_Printf("T9:%08xH GP:%08xH SP:%08xH\n", (u32)ctx->t9, (u32)ctx->gp, (u32)ctx->sp);
|
|
|
|
|
FaultDrawer_Printf("S8:%08xH RA:%08xH LO:%08xH\n\n", (u32)ctx->s8, (u32)ctx->ra, (u32)ctx->lo);
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_PrintFPCSR(ctx->fpcsr);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_Printf("\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_PrintFReg(0, &ctx->fp0.f.f_even);
|
|
|
|
|
Fault_PrintFReg(2, &ctx->fp2.f.f_even);
|
|
|
|
|
FaultDrawer_Printf("\n");
|
|
|
|
|
Fault_PrintFReg(4, &ctx->fp4.f.f_even);
|
|
|
|
|
Fault_PrintFReg(6, &ctx->fp6.f.f_even);
|
|
|
|
|
FaultDrawer_Printf("\n");
|
|
|
|
|
Fault_PrintFReg(8, &ctx->fp8.f.f_even);
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_PrintFReg(10, &ctx->fp10.f.f_even);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_Printf("\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_PrintFReg(12, &ctx->fp12.f.f_even);
|
|
|
|
|
Fault_PrintFReg(14, &ctx->fp14.f.f_even);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_Printf("\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_PrintFReg(16, &ctx->fp16.f.f_even);
|
|
|
|
|
Fault_PrintFReg(18, &ctx->fp18.f.f_even);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_Printf("\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_PrintFReg(20, &ctx->fp20.f.f_even);
|
|
|
|
|
Fault_PrintFReg(22, &ctx->fp22.f.f_even);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_Printf("\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_PrintFReg(24, &ctx->fp24.f.f_even);
|
|
|
|
|
Fault_PrintFReg(26, &ctx->fp26.f.f_even);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_Printf("\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_PrintFReg(28, &ctx->fp28.f.f_even);
|
|
|
|
|
Fault_PrintFReg(30, &ctx->fp30.f.f_even);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_Printf("\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_SetCharPad(0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void Fault_LogThreadContext(OSThread* thread) {
|
2020-03-22 21:19:43 +00:00
|
|
|
|
__OSThreadContext* ctx;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
s16 causeStrIdx = _SHIFTR((u32)thread->context.cause, 2, 5);
|
2021-10-03 03:17:09 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (causeStrIdx == 23) { // Watchpoint
|
|
|
|
|
causeStrIdx = 16;
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (causeStrIdx == 31) { // Virtual coherency on data
|
|
|
|
|
causeStrIdx = 17;
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
ctx = &thread->context;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf("\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
osSyncPrintf("THREAD ID:%d (%d:%s)\n", thread->id, causeStrIdx, sExceptionNames[causeStrIdx]);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
|
|
|
|
osSyncPrintf("PC:%08xH SR:%08xH VA:%08xH\n", (u32)ctx->pc, (u32)ctx->sr, (u32)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");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
|
|
|
|
|
Fault_LogFPCSR(ctx->fpcsr);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf("\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
|
2020-03-17 04:31:30 +00:00
|
|
|
|
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);
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_LogFReg(10, &ctx->fp10.f.f_even);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf("\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_LogFReg(12, &ctx->fp12.f.f_even);
|
|
|
|
|
Fault_LogFReg(14, &ctx->fp14.f.f_even);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf("\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_LogFReg(16, &ctx->fp16.f.f_even);
|
|
|
|
|
Fault_LogFReg(18, &ctx->fp18.f.f_even);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf("\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_LogFReg(20, &ctx->fp20.f.f_even);
|
|
|
|
|
Fault_LogFReg(22, &ctx->fp22.f.f_even);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf("\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_LogFReg(24, &ctx->fp24.f.f_even);
|
|
|
|
|
Fault_LogFReg(26, &ctx->fp26.f.f_even);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf("\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_LogFReg(28, &ctx->fp28.f.f_even);
|
|
|
|
|
Fault_LogFReg(30, &ctx->fp30.f.f_even);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osSyncPrintf("\n");
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
/**
|
|
|
|
|
* Iterates through the active thread queue for a user thread with either
|
|
|
|
|
* the CPU break or Fault flag set.
|
|
|
|
|
*/
|
|
|
|
|
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;
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2022-02-02 21:43:34 +00:00
|
|
|
|
thread = thread->tlnext;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
|
void Fault_Wait5Seconds(void) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
s32 pad;
|
|
|
|
|
OSTime start = osGetTime();
|
2021-10-03 03:17:09 +00:00
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
|
do {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_Sleep(1000 / 60);
|
|
|
|
|
} while ((osGetTime() - start) < OS_SEC_TO_CYCLES(5) + 1);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
sFaultInstance->autoScroll = true;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
/**
|
|
|
|
|
* Waits for the following button combination to be entered before returning:
|
|
|
|
|
*
|
|
|
|
|
* (L & R & Z) + DPad-Up + C-Down + C-Up + DPad-Down + DPad-Left + C-Left + C-Right + DPad-Right + (B & A & START)
|
|
|
|
|
*/
|
|
|
|
|
void Fault_WaitForButtonCombo(void) {
|
2022-09-03 00:52:13 +00:00
|
|
|
|
Input* input = &sFaultInstance->inputs[0];
|
2020-07-18 09:55:35 +00:00
|
|
|
|
s32 state;
|
|
|
|
|
u32 s1;
|
|
|
|
|
u32 s2;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
u32 pressedBtn;
|
|
|
|
|
u32 curBtn;
|
2020-07-18 09:55:35 +00:00
|
|
|
|
|
2020-08-23 21:50:30 +00:00
|
|
|
|
if (1) {}
|
|
|
|
|
if (1) {}
|
|
|
|
|
|
2020-07-18 09:55:35 +00:00
|
|
|
|
osSyncPrintf(
|
|
|
|
|
VT_FGCOL(WHITE) "KeyWaitB (LRZ " VT_FGCOL(WHITE) "上" VT_FGCOL(YELLOW) "下 " VT_FGCOL(YELLOW) "上" VT_FGCOL(WHITE) "下 " VT_FGCOL(WHITE) "左" VT_FGCOL(
|
2020-08-23 21:50:30 +00:00
|
|
|
|
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");
|
2020-07-18 09:55:35 +00:00
|
|
|
|
osSyncPrintf(VT_FGCOL(WHITE) "KeyWaitB'(LR左" VT_FGCOL(YELLOW) "右 +" VT_FGCOL(RED) "START" VT_FGCOL(
|
|
|
|
|
WHITE) ")" VT_RST "\n");
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
FaultDrawer_SetForeColor(GPACK_RGBA5551(255, 255, 255, 1));
|
|
|
|
|
FaultDrawer_SetBackColor(GPACK_RGBA5551(0, 0, 0, 1));
|
2020-07-18 09:55:35 +00:00
|
|
|
|
|
|
|
|
|
state = 0;
|
|
|
|
|
s1 = 0;
|
|
|
|
|
s2 = 1;
|
|
|
|
|
|
|
|
|
|
while (state != 11) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_Sleep(1000 / 60);
|
2020-07-18 09:55:35 +00:00
|
|
|
|
Fault_UpdatePadImpl();
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
pressedBtn = input->press.button;
|
|
|
|
|
curBtn = input->cur.button;
|
2020-07-18 09:55:35 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (curBtn == 0 && s1 == s2) {
|
2020-08-23 21:50:30 +00:00
|
|
|
|
s1 = 0;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
} else if (pressedBtn != 0) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
if (s1 == s2) {
|
|
|
|
|
state = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (state) {
|
|
|
|
|
case 0:
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (curBtn == (BTN_Z | BTN_L | BTN_R) && pressedBtn == BTN_Z) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
state = s2;
|
|
|
|
|
s1 = s2;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == BTN_DUP) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
state = 2;
|
|
|
|
|
} else {
|
|
|
|
|
state = 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == BTN_CDOWN) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
state = 3;
|
|
|
|
|
s1 = s2;
|
|
|
|
|
} else {
|
|
|
|
|
state = 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == BTN_CUP) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
state = 4;
|
|
|
|
|
} else {
|
|
|
|
|
state = 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == BTN_DDOWN) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
state = 5;
|
|
|
|
|
s1 = s2;
|
|
|
|
|
} else {
|
|
|
|
|
state = 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == BTN_DLEFT) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
state = 6;
|
|
|
|
|
} else {
|
|
|
|
|
state = 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 6:
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == BTN_CLEFT) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
state = 7;
|
|
|
|
|
s1 = s2;
|
|
|
|
|
} else {
|
|
|
|
|
state = 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 7:
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == BTN_CRIGHT) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
state = 8;
|
|
|
|
|
} else {
|
|
|
|
|
state = 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 8:
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == BTN_DRIGHT) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
state = 9;
|
|
|
|
|
s1 = s2;
|
|
|
|
|
} else {
|
|
|
|
|
state = 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 9:
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == (BTN_A | BTN_B)) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
state = 10;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
} else if (pressedBtn == BTN_A) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
state = 0x5B;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
} else if (pressedBtn == BTN_B) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
state = 0x5C;
|
|
|
|
|
} else {
|
|
|
|
|
state = 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 0x5B:
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == BTN_B) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
state = 10;
|
|
|
|
|
} else {
|
|
|
|
|
state = 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 0x5C:
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == BTN_A) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
state = 10;
|
|
|
|
|
} else {
|
|
|
|
|
state = 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 10:
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (pressedBtn == BTN_START) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
state = 11;
|
|
|
|
|
} else {
|
|
|
|
|
state = 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
osWritebackDCacheAll();
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void Fault_DrawMemDumpContents(const char* title, uintptr_t addr, u32 arg2) {
|
|
|
|
|
uintptr_t alignedAddr = addr;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
u32* writeAddr;
|
|
|
|
|
s32 y;
|
|
|
|
|
s32 x;
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Ensure address is within the bounds of RDRAM (Fault_DrawMemDump has already done this)
|
|
|
|
|
if (alignedAddr < K0BASE) {
|
|
|
|
|
alignedAddr = K0BASE;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// 8MB RAM, leave room to display 0x100 bytes on the final page
|
|
|
|
|
//! @bug The loop below draws 22 * 4 * 4 = 0x160 bytes per page. Due to this, by scrolling further than
|
|
|
|
|
//! 0x807FFEA0 some invalid bytes are read from outside of 8MB RDRAM space. This does not cause a crash,
|
|
|
|
|
//! however the values it displays are meaningless. On N64 hardware these invalid addresses are read as 0.
|
|
|
|
|
if (alignedAddr > K0BASE + 0x800000 - 0x100) {
|
|
|
|
|
alignedAddr = K0BASE + 0x800000 - 0x100;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Ensure address is word-aligned
|
|
|
|
|
alignedAddr &= ~3;
|
|
|
|
|
writeAddr = (u32*)alignedAddr;
|
|
|
|
|
|
|
|
|
|
// Reset screen
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_FillScreenBlack();
|
|
|
|
|
FaultDrawer_SetCharPad(-2, 0);
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
FaultDrawer_DrawText(36, 18, "%s %08x", title != NULL ? title : "PrintDump", alignedAddr);
|
|
|
|
|
|
|
|
|
|
// Draw memory page contents
|
|
|
|
|
if (alignedAddr >= K0BASE && alignedAddr < K2BASE) {
|
|
|
|
|
for (y = 0; y < 22; y++) {
|
|
|
|
|
FaultDrawer_DrawText(24, 28 + y * 9, "%06x", writeAddr);
|
|
|
|
|
for (x = 0; x < 4; x++) {
|
|
|
|
|
FaultDrawer_DrawText(82 + x * 52, 28 + y * 9, "%08x", *writeAddr++);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FaultDrawer_SetCharPad(0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
/**
|
|
|
|
|
* Draws the memory dump page.
|
|
|
|
|
*
|
|
|
|
|
* DPad-Up scrolls up.
|
|
|
|
|
* DPad-Down scrolls down.
|
|
|
|
|
* Holding Z while scrolling speeds up scrolling by a factor of 0x10.
|
|
|
|
|
* Holding B while scrolling speeds up scrolling by a factor of 0x100.
|
|
|
|
|
*
|
|
|
|
|
* L toggles auto-scrolling pages.
|
|
|
|
|
* START and A move on to the next page.
|
|
|
|
|
*
|
|
|
|
|
* @param pc Program counter, pressing C-Up jumps to this address
|
|
|
|
|
* @param sp Stack pointer, pressing C-Down jumps to this address
|
|
|
|
|
* @param cLeftJump Unused parameter, pressing C-Left jumps to this address
|
|
|
|
|
* @param cRightJump Unused parameter, pressing C-Right jumps to this address
|
|
|
|
|
*/
|
|
|
|
|
void Fault_DrawMemDump(uintptr_t pc, uintptr_t sp, uintptr_t cLeftJump, uintptr_t cRightJump) {
|
2022-09-03 00:52:13 +00:00
|
|
|
|
Input* input = &sFaultInstance->inputs[0];
|
2022-02-02 21:43:34 +00:00
|
|
|
|
uintptr_t addr = pc;
|
|
|
|
|
s32 scrollCountdown;
|
2020-07-18 09:55:35 +00:00
|
|
|
|
u32 off;
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2020-07-18 09:55:35 +00:00
|
|
|
|
do {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
scrollCountdown = 0;
|
|
|
|
|
// Ensure address is within the bounds of RDRAM
|
|
|
|
|
if (addr < K0BASE) {
|
|
|
|
|
addr = K0BASE;
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// 8MB RAM, leave room to display 0x100 bytes on the final page
|
|
|
|
|
if (addr > K0BASE + 0x800000 - 0x100) {
|
|
|
|
|
addr = K0BASE + 0x800000 - 0x100;
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Align the address to 0x10 bytes and draw the page contents
|
2020-03-17 04:31:30 +00:00
|
|
|
|
addr &= ~0xF;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_DrawMemDumpContents("Dump", addr, 0);
|
|
|
|
|
scrollCountdown = 600;
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
while (sFaultInstance->autoScroll) {
|
|
|
|
|
// Count down until it's time to move on to the next page
|
|
|
|
|
if (scrollCountdown == 0) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
return;
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
scrollCountdown--;
|
|
|
|
|
Fault_Sleep(1000 / 60);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_UpdatePadImpl();
|
z_message_PAL, message_data_static and surrounding doc (#996)
* Initial progress on z_message_PAL, very messy
* Fix merge
* Some more progress
* Fix merge
* More z_message_PAL
* Small progress
* More small progress
* message_data_static files OK
* Prepare z_message_tables
* Matched another function, small updates
* Attempt to use asm-processor static-symbols branch
* Refactor text id declarations
* Begin large text codes parser function
* Fix merge
* Refactor done
* Build OK, add color and highscore names
* Remove encoded text headers and automatically encode during build
* Fix kanfont
* Various cleanups
* DISP macros
* Another match aside data
* Further progress
* Small improvements
* Deduplicate magic values for text control codes, small improvements
* Tiny progress
* Minor cleanups
* Clean up z_message_PAL comment
* Progress on large functions
* Further progress on large functions
* Changes to mkldscript to link .data in the .rodata section
* data OK
* Few improvements
* Use gDPLoadTextureBlock macros where appropriate
* rm z_message_tables, progress on large functions
* 2 more matches
* Improvements
* Small progress
* More progress on big function
* progress
* match func_80107980
* match Message_Update
* match func_8010BED8
* done
* Progress on remaining large functions
* Small progress on largest function
* Another match, extract text and move to assets, improve text build system
* Small nonmatchings improvements
* docs wip
* Largest function maybe equivalent
* Fix merge
* Document do_action values, largest function is almost instruction-matching
* Rename NAVI do_action to NONE, as that appears to be how that value is used in practice
* Fix merge
* one match
* Last function is instruction-matching
* Fix
* Improvements thanks to engineer124
* Stack matched thanks to petrie911, now just a/v/low t regalloc issues, some cleanup
* More variables labeled, use text state enum everywhere
* More labels and names
* Fix
* Actor_IsTalking -> Actor_TalkRequested
* Match func_8010C39C and remove unused asm
* More docs
* Mostly ocarina related docs
* All msgModes named
* Fix assetclean
* Cleanup
* Extraction fixes and headers
* Suggestions
* Review suggestions
* Change text extraction again, only extract if the headers do not already exist
* Fix
* Use ast for charmap, fix assetclean for real this time
* Review suggestions
* BGM ids and ran formatter
* Review comments
* rename include_readonly to include_data_with_rodata
* Remove leading 0s in number directives
* Review suggestions for message_data_static
* textbox pos enum comments, rename several enum names from Message to TextBox
Co-authored-by: Thar0 <maximilianc64@gmail.com>
Co-authored-by: Zelllll <56516451+Zelllll@users.noreply.github.com>
Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain>
Co-authored-by: Roman971 <romanlasnier@hotmail.com>
2021-11-23 01:20:30 +00:00
|
|
|
|
if (CHECK_BTN_ALL(input->press.button, BTN_L)) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Disable auto-scrolling
|
|
|
|
|
sFaultInstance->autoScroll = false;
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Wait for input
|
2020-03-22 21:19:43 +00:00
|
|
|
|
do {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_Sleep(1000 / 60);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_UpdatePadImpl();
|
z_message_PAL, message_data_static and surrounding doc (#996)
* Initial progress on z_message_PAL, very messy
* Fix merge
* Some more progress
* Fix merge
* More z_message_PAL
* Small progress
* More small progress
* message_data_static files OK
* Prepare z_message_tables
* Matched another function, small updates
* Attempt to use asm-processor static-symbols branch
* Refactor text id declarations
* Begin large text codes parser function
* Fix merge
* Refactor done
* Build OK, add color and highscore names
* Remove encoded text headers and automatically encode during build
* Fix kanfont
* Various cleanups
* DISP macros
* Another match aside data
* Further progress
* Small improvements
* Deduplicate magic values for text control codes, small improvements
* Tiny progress
* Minor cleanups
* Clean up z_message_PAL comment
* Progress on large functions
* Further progress on large functions
* Changes to mkldscript to link .data in the .rodata section
* data OK
* Few improvements
* Use gDPLoadTextureBlock macros where appropriate
* rm z_message_tables, progress on large functions
* 2 more matches
* Improvements
* Small progress
* More progress on big function
* progress
* match func_80107980
* match Message_Update
* match func_8010BED8
* done
* Progress on remaining large functions
* Small progress on largest function
* Another match, extract text and move to assets, improve text build system
* Small nonmatchings improvements
* docs wip
* Largest function maybe equivalent
* Fix merge
* Document do_action values, largest function is almost instruction-matching
* Rename NAVI do_action to NONE, as that appears to be how that value is used in practice
* Fix merge
* one match
* Last function is instruction-matching
* Fix
* Improvements thanks to engineer124
* Stack matched thanks to petrie911, now just a/v/low t regalloc issues, some cleanup
* More variables labeled, use text state enum everywhere
* More labels and names
* Fix
* Actor_IsTalking -> Actor_TalkRequested
* Match func_8010C39C and remove unused asm
* More docs
* Mostly ocarina related docs
* All msgModes named
* Fix assetclean
* Cleanup
* Extraction fixes and headers
* Suggestions
* Review suggestions
* Change text extraction again, only extract if the headers do not already exist
* Fix
* Use ast for charmap, fix assetclean for real this time
* Review suggestions
* BGM ids and ran formatter
* Review comments
* rename include_readonly to include_data_with_rodata
* Remove leading 0s in number directives
* Review suggestions for message_data_static
* textbox pos enum comments, rename several enum names from Message to TextBox
Co-authored-by: Thar0 <maximilianc64@gmail.com>
Co-authored-by: Zelllll <56516451+Zelllll@users.noreply.github.com>
Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain>
Co-authored-by: Roman971 <romanlasnier@hotmail.com>
2021-11-23 01:20:30 +00:00
|
|
|
|
} while (input->press.button == 0);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Move to next page
|
z_message_PAL, message_data_static and surrounding doc (#996)
* Initial progress on z_message_PAL, very messy
* Fix merge
* Some more progress
* Fix merge
* More z_message_PAL
* Small progress
* More small progress
* message_data_static files OK
* Prepare z_message_tables
* Matched another function, small updates
* Attempt to use asm-processor static-symbols branch
* Refactor text id declarations
* Begin large text codes parser function
* Fix merge
* Refactor done
* Build OK, add color and highscore names
* Remove encoded text headers and automatically encode during build
* Fix kanfont
* Various cleanups
* DISP macros
* Another match aside data
* Further progress
* Small improvements
* Deduplicate magic values for text control codes, small improvements
* Tiny progress
* Minor cleanups
* Clean up z_message_PAL comment
* Progress on large functions
* Further progress on large functions
* Changes to mkldscript to link .data in the .rodata section
* data OK
* Few improvements
* Use gDPLoadTextureBlock macros where appropriate
* rm z_message_tables, progress on large functions
* 2 more matches
* Improvements
* Small progress
* More progress on big function
* progress
* match func_80107980
* match Message_Update
* match func_8010BED8
* done
* Progress on remaining large functions
* Small progress on largest function
* Another match, extract text and move to assets, improve text build system
* Small nonmatchings improvements
* docs wip
* Largest function maybe equivalent
* Fix merge
* Document do_action values, largest function is almost instruction-matching
* Rename NAVI do_action to NONE, as that appears to be how that value is used in practice
* Fix merge
* one match
* Last function is instruction-matching
* Fix
* Improvements thanks to engineer124
* Stack matched thanks to petrie911, now just a/v/low t regalloc issues, some cleanup
* More variables labeled, use text state enum everywhere
* More labels and names
* Fix
* Actor_IsTalking -> Actor_TalkRequested
* Match func_8010C39C and remove unused asm
* More docs
* Mostly ocarina related docs
* All msgModes named
* Fix assetclean
* Cleanup
* Extraction fixes and headers
* Suggestions
* Review suggestions
* Change text extraction again, only extract if the headers do not already exist
* Fix
* Use ast for charmap, fix assetclean for real this time
* Review suggestions
* BGM ids and ran formatter
* Review comments
* rename include_readonly to include_data_with_rodata
* Remove leading 0s in number directives
* Review suggestions for message_data_static
* textbox pos enum comments, rename several enum names from Message to TextBox
Co-authored-by: Thar0 <maximilianc64@gmail.com>
Co-authored-by: Zelllll <56516451+Zelllll@users.noreply.github.com>
Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain>
Co-authored-by: Roman971 <romanlasnier@hotmail.com>
2021-11-23 01:20:30 +00:00
|
|
|
|
if (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->cur.button, BTN_A)) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
return;
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Memory dump controls
|
|
|
|
|
|
2020-03-17 04:31:30 +00:00
|
|
|
|
off = 0x10;
|
z_message_PAL, message_data_static and surrounding doc (#996)
* Initial progress on z_message_PAL, very messy
* Fix merge
* Some more progress
* Fix merge
* More z_message_PAL
* Small progress
* More small progress
* message_data_static files OK
* Prepare z_message_tables
* Matched another function, small updates
* Attempt to use asm-processor static-symbols branch
* Refactor text id declarations
* Begin large text codes parser function
* Fix merge
* Refactor done
* Build OK, add color and highscore names
* Remove encoded text headers and automatically encode during build
* Fix kanfont
* Various cleanups
* DISP macros
* Another match aside data
* Further progress
* Small improvements
* Deduplicate magic values for text control codes, small improvements
* Tiny progress
* Minor cleanups
* Clean up z_message_PAL comment
* Progress on large functions
* Further progress on large functions
* Changes to mkldscript to link .data in the .rodata section
* data OK
* Few improvements
* Use gDPLoadTextureBlock macros where appropriate
* rm z_message_tables, progress on large functions
* 2 more matches
* Improvements
* Small progress
* More progress on big function
* progress
* match func_80107980
* match Message_Update
* match func_8010BED8
* done
* Progress on remaining large functions
* Small progress on largest function
* Another match, extract text and move to assets, improve text build system
* Small nonmatchings improvements
* docs wip
* Largest function maybe equivalent
* Fix merge
* Document do_action values, largest function is almost instruction-matching
* Rename NAVI do_action to NONE, as that appears to be how that value is used in practice
* Fix merge
* one match
* Last function is instruction-matching
* Fix
* Improvements thanks to engineer124
* Stack matched thanks to petrie911, now just a/v/low t regalloc issues, some cleanup
* More variables labeled, use text state enum everywhere
* More labels and names
* Fix
* Actor_IsTalking -> Actor_TalkRequested
* Match func_8010C39C and remove unused asm
* More docs
* Mostly ocarina related docs
* All msgModes named
* Fix assetclean
* Cleanup
* Extraction fixes and headers
* Suggestions
* Review suggestions
* Change text extraction again, only extract if the headers do not already exist
* Fix
* Use ast for charmap, fix assetclean for real this time
* Review suggestions
* BGM ids and ran formatter
* Review comments
* rename include_readonly to include_data_with_rodata
* Remove leading 0s in number directives
* Review suggestions for message_data_static
* textbox pos enum comments, rename several enum names from Message to TextBox
Co-authored-by: Thar0 <maximilianc64@gmail.com>
Co-authored-by: Zelllll <56516451+Zelllll@users.noreply.github.com>
Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain>
Co-authored-by: Roman971 <romanlasnier@hotmail.com>
2021-11-23 01:20:30 +00:00
|
|
|
|
if (CHECK_BTN_ALL(input->cur.button, BTN_Z)) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
off *= 0x10;
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
2020-08-15 17:23:29 +00:00
|
|
|
|
|
z_message_PAL, message_data_static and surrounding doc (#996)
* Initial progress on z_message_PAL, very messy
* Fix merge
* Some more progress
* Fix merge
* More z_message_PAL
* Small progress
* More small progress
* message_data_static files OK
* Prepare z_message_tables
* Matched another function, small updates
* Attempt to use asm-processor static-symbols branch
* Refactor text id declarations
* Begin large text codes parser function
* Fix merge
* Refactor done
* Build OK, add color and highscore names
* Remove encoded text headers and automatically encode during build
* Fix kanfont
* Various cleanups
* DISP macros
* Another match aside data
* Further progress
* Small improvements
* Deduplicate magic values for text control codes, small improvements
* Tiny progress
* Minor cleanups
* Clean up z_message_PAL comment
* Progress on large functions
* Further progress on large functions
* Changes to mkldscript to link .data in the .rodata section
* data OK
* Few improvements
* Use gDPLoadTextureBlock macros where appropriate
* rm z_message_tables, progress on large functions
* 2 more matches
* Improvements
* Small progress
* More progress on big function
* progress
* match func_80107980
* match Message_Update
* match func_8010BED8
* done
* Progress on remaining large functions
* Small progress on largest function
* Another match, extract text and move to assets, improve text build system
* Small nonmatchings improvements
* docs wip
* Largest function maybe equivalent
* Fix merge
* Document do_action values, largest function is almost instruction-matching
* Rename NAVI do_action to NONE, as that appears to be how that value is used in practice
* Fix merge
* one match
* Last function is instruction-matching
* Fix
* Improvements thanks to engineer124
* Stack matched thanks to petrie911, now just a/v/low t regalloc issues, some cleanup
* More variables labeled, use text state enum everywhere
* More labels and names
* Fix
* Actor_IsTalking -> Actor_TalkRequested
* Match func_8010C39C and remove unused asm
* More docs
* Mostly ocarina related docs
* All msgModes named
* Fix assetclean
* Cleanup
* Extraction fixes and headers
* Suggestions
* Review suggestions
* Change text extraction again, only extract if the headers do not already exist
* Fix
* Use ast for charmap, fix assetclean for real this time
* Review suggestions
* BGM ids and ran formatter
* Review comments
* rename include_readonly to include_data_with_rodata
* Remove leading 0s in number directives
* Review suggestions for message_data_static
* textbox pos enum comments, rename several enum names from Message to TextBox
Co-authored-by: Thar0 <maximilianc64@gmail.com>
Co-authored-by: Zelllll <56516451+Zelllll@users.noreply.github.com>
Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain>
Co-authored-by: Roman971 <romanlasnier@hotmail.com>
2021-11-23 01:20:30 +00:00
|
|
|
|
if (CHECK_BTN_ALL(input->cur.button, BTN_B)) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
off *= 0x100;
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
2020-08-15 17:23:29 +00:00
|
|
|
|
|
z_message_PAL, message_data_static and surrounding doc (#996)
* Initial progress on z_message_PAL, very messy
* Fix merge
* Some more progress
* Fix merge
* More z_message_PAL
* Small progress
* More small progress
* message_data_static files OK
* Prepare z_message_tables
* Matched another function, small updates
* Attempt to use asm-processor static-symbols branch
* Refactor text id declarations
* Begin large text codes parser function
* Fix merge
* Refactor done
* Build OK, add color and highscore names
* Remove encoded text headers and automatically encode during build
* Fix kanfont
* Various cleanups
* DISP macros
* Another match aside data
* Further progress
* Small improvements
* Deduplicate magic values for text control codes, small improvements
* Tiny progress
* Minor cleanups
* Clean up z_message_PAL comment
* Progress on large functions
* Further progress on large functions
* Changes to mkldscript to link .data in the .rodata section
* data OK
* Few improvements
* Use gDPLoadTextureBlock macros where appropriate
* rm z_message_tables, progress on large functions
* 2 more matches
* Improvements
* Small progress
* More progress on big function
* progress
* match func_80107980
* match Message_Update
* match func_8010BED8
* done
* Progress on remaining large functions
* Small progress on largest function
* Another match, extract text and move to assets, improve text build system
* Small nonmatchings improvements
* docs wip
* Largest function maybe equivalent
* Fix merge
* Document do_action values, largest function is almost instruction-matching
* Rename NAVI do_action to NONE, as that appears to be how that value is used in practice
* Fix merge
* one match
* Last function is instruction-matching
* Fix
* Improvements thanks to engineer124
* Stack matched thanks to petrie911, now just a/v/low t regalloc issues, some cleanup
* More variables labeled, use text state enum everywhere
* More labels and names
* Fix
* Actor_IsTalking -> Actor_TalkRequested
* Match func_8010C39C and remove unused asm
* More docs
* Mostly ocarina related docs
* All msgModes named
* Fix assetclean
* Cleanup
* Extraction fixes and headers
* Suggestions
* Review suggestions
* Change text extraction again, only extract if the headers do not already exist
* Fix
* Use ast for charmap, fix assetclean for real this time
* Review suggestions
* BGM ids and ran formatter
* Review comments
* rename include_readonly to include_data_with_rodata
* Remove leading 0s in number directives
* Review suggestions for message_data_static
* textbox pos enum comments, rename several enum names from Message to TextBox
Co-authored-by: Thar0 <maximilianc64@gmail.com>
Co-authored-by: Zelllll <56516451+Zelllll@users.noreply.github.com>
Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain>
Co-authored-by: Roman971 <romanlasnier@hotmail.com>
2021-11-23 01:20:30 +00:00
|
|
|
|
if (CHECK_BTN_ALL(input->press.button, BTN_DUP)) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
addr -= off;
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
z_message_PAL, message_data_static and surrounding doc (#996)
* Initial progress on z_message_PAL, very messy
* Fix merge
* Some more progress
* Fix merge
* More z_message_PAL
* Small progress
* More small progress
* message_data_static files OK
* Prepare z_message_tables
* Matched another function, small updates
* Attempt to use asm-processor static-symbols branch
* Refactor text id declarations
* Begin large text codes parser function
* Fix merge
* Refactor done
* Build OK, add color and highscore names
* Remove encoded text headers and automatically encode during build
* Fix kanfont
* Various cleanups
* DISP macros
* Another match aside data
* Further progress
* Small improvements
* Deduplicate magic values for text control codes, small improvements
* Tiny progress
* Minor cleanups
* Clean up z_message_PAL comment
* Progress on large functions
* Further progress on large functions
* Changes to mkldscript to link .data in the .rodata section
* data OK
* Few improvements
* Use gDPLoadTextureBlock macros where appropriate
* rm z_message_tables, progress on large functions
* 2 more matches
* Improvements
* Small progress
* More progress on big function
* progress
* match func_80107980
* match Message_Update
* match func_8010BED8
* done
* Progress on remaining large functions
* Small progress on largest function
* Another match, extract text and move to assets, improve text build system
* Small nonmatchings improvements
* docs wip
* Largest function maybe equivalent
* Fix merge
* Document do_action values, largest function is almost instruction-matching
* Rename NAVI do_action to NONE, as that appears to be how that value is used in practice
* Fix merge
* one match
* Last function is instruction-matching
* Fix
* Improvements thanks to engineer124
* Stack matched thanks to petrie911, now just a/v/low t regalloc issues, some cleanup
* More variables labeled, use text state enum everywhere
* More labels and names
* Fix
* Actor_IsTalking -> Actor_TalkRequested
* Match func_8010C39C and remove unused asm
* More docs
* Mostly ocarina related docs
* All msgModes named
* Fix assetclean
* Cleanup
* Extraction fixes and headers
* Suggestions
* Review suggestions
* Change text extraction again, only extract if the headers do not already exist
* Fix
* Use ast for charmap, fix assetclean for real this time
* Review suggestions
* BGM ids and ran formatter
* Review comments
* rename include_readonly to include_data_with_rodata
* Remove leading 0s in number directives
* Review suggestions for message_data_static
* textbox pos enum comments, rename several enum names from Message to TextBox
Co-authored-by: Thar0 <maximilianc64@gmail.com>
Co-authored-by: Zelllll <56516451+Zelllll@users.noreply.github.com>
Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain>
Co-authored-by: Roman971 <romanlasnier@hotmail.com>
2021-11-23 01:20:30 +00:00
|
|
|
|
if (CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) {
|
2020-03-18 00:09:21 +00:00
|
|
|
|
addr += off;
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
z_message_PAL, message_data_static and surrounding doc (#996)
* Initial progress on z_message_PAL, very messy
* Fix merge
* Some more progress
* Fix merge
* More z_message_PAL
* Small progress
* More small progress
* message_data_static files OK
* Prepare z_message_tables
* Matched another function, small updates
* Attempt to use asm-processor static-symbols branch
* Refactor text id declarations
* Begin large text codes parser function
* Fix merge
* Refactor done
* Build OK, add color and highscore names
* Remove encoded text headers and automatically encode during build
* Fix kanfont
* Various cleanups
* DISP macros
* Another match aside data
* Further progress
* Small improvements
* Deduplicate magic values for text control codes, small improvements
* Tiny progress
* Minor cleanups
* Clean up z_message_PAL comment
* Progress on large functions
* Further progress on large functions
* Changes to mkldscript to link .data in the .rodata section
* data OK
* Few improvements
* Use gDPLoadTextureBlock macros where appropriate
* rm z_message_tables, progress on large functions
* 2 more matches
* Improvements
* Small progress
* More progress on big function
* progress
* match func_80107980
* match Message_Update
* match func_8010BED8
* done
* Progress on remaining large functions
* Small progress on largest function
* Another match, extract text and move to assets, improve text build system
* Small nonmatchings improvements
* docs wip
* Largest function maybe equivalent
* Fix merge
* Document do_action values, largest function is almost instruction-matching
* Rename NAVI do_action to NONE, as that appears to be how that value is used in practice
* Fix merge
* one match
* Last function is instruction-matching
* Fix
* Improvements thanks to engineer124
* Stack matched thanks to petrie911, now just a/v/low t regalloc issues, some cleanup
* More variables labeled, use text state enum everywhere
* More labels and names
* Fix
* Actor_IsTalking -> Actor_TalkRequested
* Match func_8010C39C and remove unused asm
* More docs
* Mostly ocarina related docs
* All msgModes named
* Fix assetclean
* Cleanup
* Extraction fixes and headers
* Suggestions
* Review suggestions
* Change text extraction again, only extract if the headers do not already exist
* Fix
* Use ast for charmap, fix assetclean for real this time
* Review suggestions
* BGM ids and ran formatter
* Review comments
* rename include_readonly to include_data_with_rodata
* Remove leading 0s in number directives
* Review suggestions for message_data_static
* textbox pos enum comments, rename several enum names from Message to TextBox
Co-authored-by: Thar0 <maximilianc64@gmail.com>
Co-authored-by: Zelllll <56516451+Zelllll@users.noreply.github.com>
Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain>
Co-authored-by: Roman971 <romanlasnier@hotmail.com>
2021-11-23 01:20:30 +00:00
|
|
|
|
if (CHECK_BTN_ALL(input->press.button, BTN_CUP)) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
addr = pc;
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
z_message_PAL, message_data_static and surrounding doc (#996)
* Initial progress on z_message_PAL, very messy
* Fix merge
* Some more progress
* Fix merge
* More z_message_PAL
* Small progress
* More small progress
* message_data_static files OK
* Prepare z_message_tables
* Matched another function, small updates
* Attempt to use asm-processor static-symbols branch
* Refactor text id declarations
* Begin large text codes parser function
* Fix merge
* Refactor done
* Build OK, add color and highscore names
* Remove encoded text headers and automatically encode during build
* Fix kanfont
* Various cleanups
* DISP macros
* Another match aside data
* Further progress
* Small improvements
* Deduplicate magic values for text control codes, small improvements
* Tiny progress
* Minor cleanups
* Clean up z_message_PAL comment
* Progress on large functions
* Further progress on large functions
* Changes to mkldscript to link .data in the .rodata section
* data OK
* Few improvements
* Use gDPLoadTextureBlock macros where appropriate
* rm z_message_tables, progress on large functions
* 2 more matches
* Improvements
* Small progress
* More progress on big function
* progress
* match func_80107980
* match Message_Update
* match func_8010BED8
* done
* Progress on remaining large functions
* Small progress on largest function
* Another match, extract text and move to assets, improve text build system
* Small nonmatchings improvements
* docs wip
* Largest function maybe equivalent
* Fix merge
* Document do_action values, largest function is almost instruction-matching
* Rename NAVI do_action to NONE, as that appears to be how that value is used in practice
* Fix merge
* one match
* Last function is instruction-matching
* Fix
* Improvements thanks to engineer124
* Stack matched thanks to petrie911, now just a/v/low t regalloc issues, some cleanup
* More variables labeled, use text state enum everywhere
* More labels and names
* Fix
* Actor_IsTalking -> Actor_TalkRequested
* Match func_8010C39C and remove unused asm
* More docs
* Mostly ocarina related docs
* All msgModes named
* Fix assetclean
* Cleanup
* Extraction fixes and headers
* Suggestions
* Review suggestions
* Change text extraction again, only extract if the headers do not already exist
* Fix
* Use ast for charmap, fix assetclean for real this time
* Review suggestions
* BGM ids and ran formatter
* Review comments
* rename include_readonly to include_data_with_rodata
* Remove leading 0s in number directives
* Review suggestions for message_data_static
* textbox pos enum comments, rename several enum names from Message to TextBox
Co-authored-by: Thar0 <maximilianc64@gmail.com>
Co-authored-by: Zelllll <56516451+Zelllll@users.noreply.github.com>
Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain>
Co-authored-by: Roman971 <romanlasnier@hotmail.com>
2021-11-23 01:20:30 +00:00
|
|
|
|
if (CHECK_BTN_ALL(input->press.button, BTN_CDOWN)) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
addr = sp;
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
z_message_PAL, message_data_static and surrounding doc (#996)
* Initial progress on z_message_PAL, very messy
* Fix merge
* Some more progress
* Fix merge
* More z_message_PAL
* Small progress
* More small progress
* message_data_static files OK
* Prepare z_message_tables
* Matched another function, small updates
* Attempt to use asm-processor static-symbols branch
* Refactor text id declarations
* Begin large text codes parser function
* Fix merge
* Refactor done
* Build OK, add color and highscore names
* Remove encoded text headers and automatically encode during build
* Fix kanfont
* Various cleanups
* DISP macros
* Another match aside data
* Further progress
* Small improvements
* Deduplicate magic values for text control codes, small improvements
* Tiny progress
* Minor cleanups
* Clean up z_message_PAL comment
* Progress on large functions
* Further progress on large functions
* Changes to mkldscript to link .data in the .rodata section
* data OK
* Few improvements
* Use gDPLoadTextureBlock macros where appropriate
* rm z_message_tables, progress on large functions
* 2 more matches
* Improvements
* Small progress
* More progress on big function
* progress
* match func_80107980
* match Message_Update
* match func_8010BED8
* done
* Progress on remaining large functions
* Small progress on largest function
* Another match, extract text and move to assets, improve text build system
* Small nonmatchings improvements
* docs wip
* Largest function maybe equivalent
* Fix merge
* Document do_action values, largest function is almost instruction-matching
* Rename NAVI do_action to NONE, as that appears to be how that value is used in practice
* Fix merge
* one match
* Last function is instruction-matching
* Fix
* Improvements thanks to engineer124
* Stack matched thanks to petrie911, now just a/v/low t regalloc issues, some cleanup
* More variables labeled, use text state enum everywhere
* More labels and names
* Fix
* Actor_IsTalking -> Actor_TalkRequested
* Match func_8010C39C and remove unused asm
* More docs
* Mostly ocarina related docs
* All msgModes named
* Fix assetclean
* Cleanup
* Extraction fixes and headers
* Suggestions
* Review suggestions
* Change text extraction again, only extract if the headers do not already exist
* Fix
* Use ast for charmap, fix assetclean for real this time
* Review suggestions
* BGM ids and ran formatter
* Review comments
* rename include_readonly to include_data_with_rodata
* Remove leading 0s in number directives
* Review suggestions for message_data_static
* textbox pos enum comments, rename several enum names from Message to TextBox
Co-authored-by: Thar0 <maximilianc64@gmail.com>
Co-authored-by: Zelllll <56516451+Zelllll@users.noreply.github.com>
Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain>
Co-authored-by: Roman971 <romanlasnier@hotmail.com>
2021-11-23 01:20:30 +00:00
|
|
|
|
if (CHECK_BTN_ALL(input->press.button, BTN_CLEFT)) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
addr = cLeftJump;
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
z_message_PAL, message_data_static and surrounding doc (#996)
* Initial progress on z_message_PAL, very messy
* Fix merge
* Some more progress
* Fix merge
* More z_message_PAL
* Small progress
* More small progress
* message_data_static files OK
* Prepare z_message_tables
* Matched another function, small updates
* Attempt to use asm-processor static-symbols branch
* Refactor text id declarations
* Begin large text codes parser function
* Fix merge
* Refactor done
* Build OK, add color and highscore names
* Remove encoded text headers and automatically encode during build
* Fix kanfont
* Various cleanups
* DISP macros
* Another match aside data
* Further progress
* Small improvements
* Deduplicate magic values for text control codes, small improvements
* Tiny progress
* Minor cleanups
* Clean up z_message_PAL comment
* Progress on large functions
* Further progress on large functions
* Changes to mkldscript to link .data in the .rodata section
* data OK
* Few improvements
* Use gDPLoadTextureBlock macros where appropriate
* rm z_message_tables, progress on large functions
* 2 more matches
* Improvements
* Small progress
* More progress on big function
* progress
* match func_80107980
* match Message_Update
* match func_8010BED8
* done
* Progress on remaining large functions
* Small progress on largest function
* Another match, extract text and move to assets, improve text build system
* Small nonmatchings improvements
* docs wip
* Largest function maybe equivalent
* Fix merge
* Document do_action values, largest function is almost instruction-matching
* Rename NAVI do_action to NONE, as that appears to be how that value is used in practice
* Fix merge
* one match
* Last function is instruction-matching
* Fix
* Improvements thanks to engineer124
* Stack matched thanks to petrie911, now just a/v/low t regalloc issues, some cleanup
* More variables labeled, use text state enum everywhere
* More labels and names
* Fix
* Actor_IsTalking -> Actor_TalkRequested
* Match func_8010C39C and remove unused asm
* More docs
* Mostly ocarina related docs
* All msgModes named
* Fix assetclean
* Cleanup
* Extraction fixes and headers
* Suggestions
* Review suggestions
* Change text extraction again, only extract if the headers do not already exist
* Fix
* Use ast for charmap, fix assetclean for real this time
* Review suggestions
* BGM ids and ran formatter
* Review comments
* rename include_readonly to include_data_with_rodata
* Remove leading 0s in number directives
* Review suggestions for message_data_static
* textbox pos enum comments, rename several enum names from Message to TextBox
Co-authored-by: Thar0 <maximilianc64@gmail.com>
Co-authored-by: Zelllll <56516451+Zelllll@users.noreply.github.com>
Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain>
Co-authored-by: Roman971 <romanlasnier@hotmail.com>
2021-11-23 01:20:30 +00:00
|
|
|
|
if (CHECK_BTN_ALL(input->press.button, BTN_CRIGHT)) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
addr = cRightJump;
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
z_message_PAL, message_data_static and surrounding doc (#996)
* Initial progress on z_message_PAL, very messy
* Fix merge
* Some more progress
* Fix merge
* More z_message_PAL
* Small progress
* More small progress
* message_data_static files OK
* Prepare z_message_tables
* Matched another function, small updates
* Attempt to use asm-processor static-symbols branch
* Refactor text id declarations
* Begin large text codes parser function
* Fix merge
* Refactor done
* Build OK, add color and highscore names
* Remove encoded text headers and automatically encode during build
* Fix kanfont
* Various cleanups
* DISP macros
* Another match aside data
* Further progress
* Small improvements
* Deduplicate magic values for text control codes, small improvements
* Tiny progress
* Minor cleanups
* Clean up z_message_PAL comment
* Progress on large functions
* Further progress on large functions
* Changes to mkldscript to link .data in the .rodata section
* data OK
* Few improvements
* Use gDPLoadTextureBlock macros where appropriate
* rm z_message_tables, progress on large functions
* 2 more matches
* Improvements
* Small progress
* More progress on big function
* progress
* match func_80107980
* match Message_Update
* match func_8010BED8
* done
* Progress on remaining large functions
* Small progress on largest function
* Another match, extract text and move to assets, improve text build system
* Small nonmatchings improvements
* docs wip
* Largest function maybe equivalent
* Fix merge
* Document do_action values, largest function is almost instruction-matching
* Rename NAVI do_action to NONE, as that appears to be how that value is used in practice
* Fix merge
* one match
* Last function is instruction-matching
* Fix
* Improvements thanks to engineer124
* Stack matched thanks to petrie911, now just a/v/low t regalloc issues, some cleanup
* More variables labeled, use text state enum everywhere
* More labels and names
* Fix
* Actor_IsTalking -> Actor_TalkRequested
* Match func_8010C39C and remove unused asm
* More docs
* Mostly ocarina related docs
* All msgModes named
* Fix assetclean
* Cleanup
* Extraction fixes and headers
* Suggestions
* Review suggestions
* Change text extraction again, only extract if the headers do not already exist
* Fix
* Use ast for charmap, fix assetclean for real this time
* Review suggestions
* BGM ids and ran formatter
* Review comments
* rename include_readonly to include_data_with_rodata
* Remove leading 0s in number directives
* Review suggestions for message_data_static
* textbox pos enum comments, rename several enum names from Message to TextBox
Co-authored-by: Thar0 <maximilianc64@gmail.com>
Co-authored-by: Zelllll <56516451+Zelllll@users.noreply.github.com>
Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain>
Co-authored-by: Roman971 <romanlasnier@hotmail.com>
2021-11-23 01:20:30 +00:00
|
|
|
|
} while (!CHECK_BTN_ALL(input->press.button, BTN_L));
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Resume auto-scroll and move to next page
|
|
|
|
|
sFaultInstance->autoScroll = true;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
/**
|
|
|
|
|
* Searches a single function's stack frame for the function it was called from.
|
|
|
|
|
* There are two cases that must be covered: Leaf and non-leaf functions.
|
|
|
|
|
*
|
|
|
|
|
* A leaf function is one that does not call any other function, in this case the
|
|
|
|
|
* return address need not be saved to the stack. Since a leaf function does not
|
|
|
|
|
* call other functions, only the function the stack trace begins in could possibly
|
|
|
|
|
* be a leaf function, in which case the return address is in the thread context's
|
|
|
|
|
* $ra already, as it never left.
|
|
|
|
|
*
|
|
|
|
|
* The procedure is therefore
|
|
|
|
|
* - Iterate instructions
|
|
|
|
|
* - Once jr $ra is found, set pc to $ra
|
|
|
|
|
* - Done after delay slot
|
|
|
|
|
*
|
|
|
|
|
* A non-leaf function calls other functions, it is necessary for the return address
|
|
|
|
|
* to be saved to the stack. In these functions, it is important to keep track of the
|
|
|
|
|
* stack frame size of each function.
|
|
|
|
|
*
|
|
|
|
|
* The procedure is therefore
|
|
|
|
|
* - Iterate instructions
|
|
|
|
|
* - If lw $ra <imm>($sp) is found, fetch the saved $ra from stack memory
|
|
|
|
|
* - If addiu $sp, $sp, <imm> is found, modify $sp by the immediate value
|
|
|
|
|
* - If jr $ra is found, set pc to $ra
|
|
|
|
|
* - Done after delay slot
|
|
|
|
|
*
|
|
|
|
|
* Note that searching for one jr $ra is sufficient, as only leaf functions can have
|
|
|
|
|
* multiple jr $ra in the same function.
|
|
|
|
|
*
|
|
|
|
|
* There is also additional handling for eret and j. Neither of these instructions
|
|
|
|
|
* appear in IDO compiled C, however do show up in the exception handler. It is not
|
|
|
|
|
* possible to backtrace through an eret as an interrupt can occur at any time, so
|
|
|
|
|
* there is no choice but to give up here. For j instructions, they can be followed
|
|
|
|
|
* and the backtrace may continue as normal.
|
|
|
|
|
*/
|
|
|
|
|
void Fault_WalkStack(uintptr_t* spPtr, uintptr_t* pcPtr, uintptr_t* raPtr) {
|
|
|
|
|
uintptr_t sp = *spPtr;
|
|
|
|
|
uintptr_t pc = *pcPtr;
|
|
|
|
|
uintptr_t ra = *raPtr;
|
|
|
|
|
s32 count = 0x10000; // maximum number of instructions to search through
|
|
|
|
|
u32 lastInsn;
|
|
|
|
|
u32 insn;
|
|
|
|
|
u16 insnHi;
|
|
|
|
|
s16 insnLo;
|
2020-07-18 09:55:35 +00:00
|
|
|
|
u32 imm;
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// ensure $sp and $ra are aligned and valid pointers, if they aren't a stack
|
|
|
|
|
// trace cannot be generated
|
|
|
|
|
if (sp % 4 != 0 || !IS_KSEG0(sp) || ra % 4 != 0 || !IS_KSEG0(ra)) {
|
|
|
|
|
*raPtr = *pcPtr = *spPtr = 0;
|
2020-07-18 09:55:35 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// ensure pc is aligned and a valid pointer, if not a stack trace cannot
|
|
|
|
|
// be generated
|
|
|
|
|
if (pc % 4 != 0 || !IS_KSEG0(pc)) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
*pcPtr = ra;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
lastInsn = 0;
|
2020-07-18 09:55:35 +00:00
|
|
|
|
while (true) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
insn = *(u32*)K0_TO_K1(pc);
|
|
|
|
|
insnHi = insn >> 16;
|
|
|
|
|
insnLo = insn & 0xFFFF;
|
|
|
|
|
imm = insnLo;
|
|
|
|
|
|
|
|
|
|
if (insnHi == 0x8FBF) {
|
|
|
|
|
// lw $ra, <imm>($sp)
|
|
|
|
|
// read return address saved on the stack
|
|
|
|
|
ra = *(uintptr_t*)K0_TO_K1(sp + imm);
|
|
|
|
|
} else if (insnHi == 0x27BD) {
|
|
|
|
|
// addiu $sp, $sp, <imm>
|
|
|
|
|
// stack pointer increment or decrement
|
2020-07-18 09:55:35 +00:00
|
|
|
|
sp += imm;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
} else if (insn == 0x42000018) {
|
|
|
|
|
// eret
|
|
|
|
|
// cannot backtrace through an eret, give up
|
|
|
|
|
ra = pc = sp = 0;
|
|
|
|
|
goto done;
|
2020-07-18 09:55:35 +00:00
|
|
|
|
}
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (lastInsn == 0x03E00008) {
|
|
|
|
|
// jr $ra
|
|
|
|
|
// return to previous function
|
2020-07-18 09:55:35 +00:00
|
|
|
|
pc = ra;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
goto done;
|
|
|
|
|
} else if (lastInsn >> 26 == 2) {
|
|
|
|
|
// j <target>
|
|
|
|
|
// extract jump target
|
|
|
|
|
pc = pc >> 28 << 28 | lastInsn << 6 >> 4;
|
|
|
|
|
goto done;
|
2020-07-18 09:55:35 +00:00
|
|
|
|
}
|
2022-02-02 21:43:34 +00:00
|
|
|
|
|
|
|
|
|
lastInsn = insn;
|
|
|
|
|
pc += sizeof(u32);
|
2020-07-18 09:55:35 +00:00
|
|
|
|
if (count == 0) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
count--;
|
|
|
|
|
}
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Hit the maximum number of instructions to search, give up
|
|
|
|
|
ra = pc = sp = 0;
|
2020-07-18 09:55:35 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
done:
|
2020-07-18 09:55:35 +00:00
|
|
|
|
*spPtr = sp;
|
|
|
|
|
*pcPtr = pc;
|
|
|
|
|
*raPtr = ra;
|
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
/**
|
|
|
|
|
* Draws the stack trace page contents for the specified thread
|
|
|
|
|
*/
|
2020-07-18 09:55:35 +00:00
|
|
|
|
void Fault_DrawStackTrace(OSThread* thread, s32 x, s32 y, s32 height) {
|
|
|
|
|
s32 line;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
uintptr_t sp = thread->context.sp;
|
|
|
|
|
uintptr_t ra = thread->context.ra;
|
|
|
|
|
uintptr_t pc = thread->context.pc;
|
|
|
|
|
uintptr_t addr;
|
2020-07-18 09:55:35 +00:00
|
|
|
|
|
|
|
|
|
FaultDrawer_DrawText(x, y, "SP PC (VPC)");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
|
|
|
|
|
// Backtrace from the current function to the start of the thread
|
|
|
|
|
for (line = 1; line < height && (ra != 0 || sp != 0) && pc != (uintptr_t)__osCleanupThread; line++) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
FaultDrawer_DrawText(x, y + line * 8, "%08x %08x", sp, pc);
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Convert relocated address to virtual address if applicable
|
2020-07-18 09:55:35 +00:00
|
|
|
|
addr = Fault_ConvertAddress(pc);
|
|
|
|
|
if (addr != 0) {
|
|
|
|
|
FaultDrawer_Printf(" -> %08x", addr);
|
|
|
|
|
}
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Search one function for the previous function
|
2020-07-18 09:55:35 +00:00
|
|
|
|
Fault_WalkStack(&sp, &pc, &ra);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2020-07-18 09:55:35 +00:00
|
|
|
|
void Fault_LogStackTrace(OSThread* thread, s32 height) {
|
|
|
|
|
s32 line;
|
2022-02-02 21:43:34 +00:00
|
|
|
|
uintptr_t sp = thread->context.sp;
|
|
|
|
|
uintptr_t ra = thread->context.ra;
|
|
|
|
|
uintptr_t pc = thread->context.pc;
|
|
|
|
|
uintptr_t addr;
|
2020-07-30 19:50:18 +00:00
|
|
|
|
s32 pad;
|
2020-07-18 09:55:35 +00:00
|
|
|
|
|
|
|
|
|
osSyncPrintf("STACK TRACE\nSP PC (VPC)\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
for (line = 1; line < height && (ra != 0 || sp != 0) && pc != (uintptr_t)__osCleanupThread; line++) {
|
2020-07-18 09:55:35 +00:00
|
|
|
|
osSyncPrintf("%08x %08x", sp, pc);
|
|
|
|
|
addr = Fault_ConvertAddress(pc);
|
|
|
|
|
if (addr != 0) {
|
|
|
|
|
osSyncPrintf(" -> %08x", addr);
|
|
|
|
|
}
|
|
|
|
|
osSyncPrintf("\n");
|
|
|
|
|
Fault_WalkStack(&sp, &pc, &ra);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void Fault_ResumeThread(OSThread* thread) {
|
|
|
|
|
thread->context.cause = 0;
|
|
|
|
|
thread->context.fpcsr = 0;
|
|
|
|
|
thread->context.pc += sizeof(u32);
|
2022-06-16 00:15:44 +00:00
|
|
|
|
*((u32*)thread->context.pc) = 0x0000000D; // write in a break instruction
|
|
|
|
|
osWritebackDCache((void*)thread->context.pc, 4);
|
|
|
|
|
osInvalICache((void*)thread->context.pc, 4);
|
2022-02-02 21:43:34 +00:00
|
|
|
|
osStartThread(thread);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void Fault_DisplayFrameBuffer(void) {
|
|
|
|
|
void* fb;
|
2021-10-03 03:17:09 +00:00
|
|
|
|
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osViSetYScale(1.0f);
|
|
|
|
|
osViSetMode(&osViModeNtscLan1);
|
2021-10-03 03:17:09 +00:00
|
|
|
|
osViSetSpecialFeatures(OS_VI_GAMMA_OFF | OS_VI_DITHER_FILTER_ON);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
osViBlack(false);
|
|
|
|
|
|
2022-04-30 12:33:28 +00:00
|
|
|
|
if (sFaultInstance->fb != NULL) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
fb = sFaultInstance->fb;
|
2020-03-22 21:19:43 +00:00
|
|
|
|
} else {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
fb = osViGetNextFramebuffer();
|
|
|
|
|
if ((uintptr_t)fb == K0BASE) {
|
2022-06-16 00:15:44 +00:00
|
|
|
|
fb = (void*)(PHYS_TO_K0(osMemSize) - sizeof(u16[SCREEN_HEIGHT][SCREEN_WIDTH]));
|
2020-03-22 21:19:43 +00:00
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
osViSwapBuffer(fb);
|
2020-09-15 19:10:19 +00:00
|
|
|
|
FaultDrawer_SetDrawerFB(fb, SCREEN_WIDTH, SCREEN_HEIGHT);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
/**
|
|
|
|
|
* Runs all registered fault clients. Each fault client displays a page
|
|
|
|
|
* on the crash screen.
|
|
|
|
|
*/
|
2020-03-22 21:19:43 +00:00
|
|
|
|
void Fault_ProcessClients(void) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
FaultClient* client = sFaultInstance->clients;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
s32 idx = 0;
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
while (client != NULL) {
|
|
|
|
|
if (client->callback != NULL) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_FillScreenBlack();
|
|
|
|
|
FaultDrawer_SetCharPad(-2, 0);
|
2022-02-02 21:43:34 +00:00
|
|
|
|
FaultDrawer_Printf(FAULT_COLOR(DARK_GRAY) "CallBack (%d) %08x %08x %08x\n" FAULT_COLOR(WHITE), idx++,
|
|
|
|
|
client, client->arg0, client->arg1);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_SetCharPad(0, 0);
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_ProcessClient(client->callback, client->arg0, client->arg1);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_WaitForInput();
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_DisplayFrameBuffer();
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
2022-02-02 21:43:34 +00:00
|
|
|
|
client = client->next;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void Fault_UpdatePad(void) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_UpdatePadImpl();
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
#define FAULT_MSG_CPU_BREAK ((OSMesg)1)
|
|
|
|
|
#define FAULT_MSG_FAULT ((OSMesg)2)
|
|
|
|
|
#define FAULT_MSG_UNK ((OSMesg)3)
|
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
|
void Fault_ThreadEntry(void* arg) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
OSMesg msg;
|
2020-07-18 09:55:35 +00:00
|
|
|
|
OSThread* faultedThread;
|
2020-07-30 19:50:18 +00:00
|
|
|
|
s32 pad;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Direct OS event messages to the fault event queue
|
|
|
|
|
osSetEventMesg(OS_EVENT_CPU_BREAK, &sFaultInstance->queue, FAULT_MSG_CPU_BREAK);
|
|
|
|
|
osSetEventMesg(OS_EVENT_FAULT, &sFaultInstance->queue, FAULT_MSG_FAULT);
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
|
while (true) {
|
|
|
|
|
do {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Wait for a thread to hit a fault
|
|
|
|
|
osRecvMesg(&sFaultInstance->queue, &msg, OS_MESG_BLOCK);
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (msg == FAULT_MSG_CPU_BREAK) {
|
|
|
|
|
sFaultInstance->msgId = (u32)FAULT_MSG_CPU_BREAK;
|
2020-03-18 00:09:21 +00:00
|
|
|
|
osSyncPrintf("フォルトマネージャ:OS_EVENT_CPU_BREAKを受信しました\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
} else if (msg == FAULT_MSG_FAULT) {
|
|
|
|
|
sFaultInstance->msgId = (u32)FAULT_MSG_FAULT;
|
2020-03-18 00:09:21 +00:00
|
|
|
|
osSyncPrintf("フォルトマネージャ:OS_EVENT_FAULTを受信しました\n");
|
2022-02-02 21:43:34 +00:00
|
|
|
|
} else if (msg == FAULT_MSG_UNK) {
|
2020-03-18 00:09:21 +00:00
|
|
|
|
Fault_UpdatePad();
|
|
|
|
|
faultedThread = NULL;
|
|
|
|
|
continue;
|
2020-03-22 21:19:43 +00:00
|
|
|
|
} else {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
sFaultInstance->msgId = (u32)FAULT_MSG_UNK;
|
2020-03-18 00:09:21 +00:00
|
|
|
|
osSyncPrintf("フォルトマネージャ:不明なメッセージを受信しました\n");
|
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
|
|
|
|
faultedThread = __osGetCurrFaultedThread();
|
|
|
|
|
osSyncPrintf("__osGetCurrFaultedThread()=%08x\n", faultedThread);
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2020-03-22 21:19:43 +00:00
|
|
|
|
if (faultedThread == NULL) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
faultedThread = Fault_FindFaultedThread();
|
|
|
|
|
osSyncPrintf("FindFaultedThread()=%08x\n", faultedThread);
|
|
|
|
|
}
|
2020-03-18 00:09:21 +00:00
|
|
|
|
} while (faultedThread == NULL);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Disable floating-point related exceptions
|
|
|
|
|
__osSetFpcCsr(__osGetFpcCsr() & ~(FPCSR_EV | FPCSR_EZ | FPCSR_EO | FPCSR_EU | FPCSR_EI));
|
|
|
|
|
sFaultInstance->faultedThread = faultedThread;
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
while (!sFaultInstance->faultHandlerEnabled) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_Sleep(1000);
|
2020-03-23 23:11:21 +00:00
|
|
|
|
}
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_Sleep(1000 / 2);
|
2020-03-18 00:09:21 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Show fault framebuffer
|
|
|
|
|
Fault_DisplayFrameBuffer();
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
if (sFaultInstance->autoScroll) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_Wait5Seconds();
|
2020-03-23 23:11:21 +00:00
|
|
|
|
} else {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Draw error bar signifying the crash screen is available
|
|
|
|
|
Fault_DrawCornerRec(GPACK_RGBA5551(255, 0, 0, 1));
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_WaitForButtonCombo();
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Set auto-scrolling and default colors
|
|
|
|
|
sFaultInstance->autoScroll = true;
|
|
|
|
|
FaultDrawer_SetForeColor(GPACK_RGBA5551(255, 255, 255, 1));
|
|
|
|
|
FaultDrawer_SetBackColor(GPACK_RGBA5551(0, 0, 0, 0));
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Draw pages
|
2020-03-22 21:19:43 +00:00
|
|
|
|
do {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Thread context page
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_PrintThreadContext(faultedThread);
|
|
|
|
|
Fault_LogThreadContext(faultedThread);
|
|
|
|
|
Fault_WaitForInput();
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Stack trace page
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_FillScreenBlack();
|
2022-02-02 21:43:34 +00:00
|
|
|
|
FaultDrawer_DrawText(120, 16, "STACK TRACE");
|
|
|
|
|
Fault_DrawStackTrace(faultedThread, 36, 24, 22);
|
|
|
|
|
Fault_LogStackTrace(faultedThread, 50);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_WaitForInput();
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Client pages
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_ProcessClients();
|
2022-02-02 21:43:34 +00:00
|
|
|
|
// Memory dump page
|
|
|
|
|
Fault_DrawMemDump(faultedThread->context.pc - 0x100, (uintptr_t)faultedThread->context.sp, 0, 0);
|
|
|
|
|
// End page
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_FillScreenRed();
|
2022-02-02 21:43:34 +00:00
|
|
|
|
FaultDrawer_DrawText(64, 80, " CONGRATURATIONS! ");
|
|
|
|
|
FaultDrawer_DrawText(64, 90, "All Pages are displayed.");
|
|
|
|
|
FaultDrawer_DrawText(64, 100, " THANK YOU! ");
|
|
|
|
|
FaultDrawer_DrawText(64, 110, " You are great debugger!");
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_WaitForInput();
|
2022-02-02 21:43:34 +00:00
|
|
|
|
} while (!sFaultInstance->exit);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
while (!sFaultInstance->exit) {}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
|
|
|
|
|
Fault_ResumeThread(faultedThread);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
void Fault_SetFrameBuffer(void* fb, u16 w, u16 h) {
|
|
|
|
|
sFaultInstance->fb = fb;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultDrawer_SetDrawerFB(fb, w, h);
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-03 15:22:44 +00:00
|
|
|
|
void Fault_Init(void) {
|
2022-02-02 21:43:34 +00:00
|
|
|
|
sFaultInstance = &gFaultMgr;
|
|
|
|
|
bzero(sFaultInstance, sizeof(FaultMgr));
|
|
|
|
|
FaultDrawer_Init();
|
2021-11-28 10:47:55 +00:00
|
|
|
|
FaultDrawer_SetInputCallback(Fault_WaitForInput);
|
2022-02-02 21:43:34 +00:00
|
|
|
|
sFaultInstance->exit = false;
|
|
|
|
|
sFaultInstance->msgId = 0;
|
|
|
|
|
sFaultInstance->faultHandlerEnabled = false;
|
|
|
|
|
sFaultInstance->faultedThread = NULL;
|
|
|
|
|
sFaultInstance->padCallback = Fault_PadCallback;
|
|
|
|
|
sFaultInstance->clients = NULL;
|
|
|
|
|
sFaultInstance->autoScroll = false;
|
|
|
|
|
gFaultMgr.faultHandlerEnabled = true;
|
|
|
|
|
osCreateMesgQueue(&sFaultInstance->queue, &sFaultInstance->msg, 1);
|
2022-10-02 21:40:09 +00:00
|
|
|
|
StackCheck_Init(&sFaultThreadInfo, sFaultStack, STACK_TOP(sFaultStack), 0, 0x100, "fault");
|
2022-10-04 05:18:50 +00:00
|
|
|
|
osCreateThread(&sFaultInstance->thread, THREAD_ID_FAULT, Fault_ThreadEntry, NULL, STACK_TOP(sFaultStack),
|
2022-04-09 00:20:23 +00:00
|
|
|
|
THREAD_PRI_FAULT);
|
2022-02-02 21:43:34 +00:00
|
|
|
|
osStartThread(&sFaultInstance->thread);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
/**
|
|
|
|
|
* Fault page for Hungup crashes. Displays the thread id and two messages
|
|
|
|
|
* specified in arguments to `Fault_AddHungupAndCrashImpl`.
|
|
|
|
|
*/
|
|
|
|
|
void Fault_HungupFaultClient(const char* exp1, const char* exp2) {
|
|
|
|
|
osSyncPrintf("HungUp on Thread %d\n", osGetThreadId(NULL));
|
|
|
|
|
osSyncPrintf("%s\n", exp1 != NULL ? exp1 : "(NULL)");
|
|
|
|
|
osSyncPrintf("%s\n", exp2 != NULL ? exp2 : "(NULL)");
|
|
|
|
|
FaultDrawer_Printf("HungUp on Thread %d\n", osGetThreadId(NULL));
|
|
|
|
|
FaultDrawer_Printf("%s\n", exp1 != NULL ? exp1 : "(NULL)");
|
|
|
|
|
FaultDrawer_Printf("%s\n", exp2 != NULL ? exp2 : "(NULL)");
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
/**
|
|
|
|
|
* Immediately crashes the current thread, for cases where an irrecoverable
|
|
|
|
|
* error occurs. The parameters specify two messages detailing the error, one
|
|
|
|
|
* or both may be NULL.
|
|
|
|
|
*/
|
|
|
|
|
void Fault_AddHungupAndCrashImpl(const char* exp1, const char* exp2) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
FaultClient client;
|
2021-02-14 00:49:40 +00:00
|
|
|
|
s32 pad;
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
Fault_AddClient(&client, Fault_HungupFaultClient, (void*)exp1, (void*)exp2);
|
|
|
|
|
*(u32*)0x11111111 = 0; // trigger an exception via unaligned memory access
|
2020-03-17 04:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
/**
|
|
|
|
|
* Like `Fault_AddHungupAndCrashImpl`, however provides a fixed message containing
|
|
|
|
|
* filename and line number
|
|
|
|
|
*/
|
|
|
|
|
void Fault_AddHungupAndCrash(const char* file, s32 line) {
|
2020-03-17 04:31:30 +00:00
|
|
|
|
char msg[256];
|
2021-02-14 00:49:40 +00:00
|
|
|
|
|
2022-02-02 21:43:34 +00:00
|
|
|
|
sprintf(msg, "HungUp %s:%d", file, line);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
Fault_AddHungupAndCrashImpl(msg, NULL);
|
|
|
|
|
}
|