You've already forked Microtransactions64
mirror of
https://github.com/Print-and-Panic/Microtransactions64.git
synced 2026-01-21 10:17:19 -08:00
idk what i changed but it should be ready now
This commit is contained in:
@@ -18,6 +18,7 @@ enum crashPages {
|
||||
PAGE_CONTEXT,
|
||||
PAGE_LOG,
|
||||
PAGE_STACKTRACE,
|
||||
PAGE_DISASM,
|
||||
PAGE_COUNT
|
||||
};
|
||||
|
||||
@@ -193,19 +194,16 @@ void draw_crash_context(OSThread *thread, s32 cause)
|
||||
{
|
||||
__OSThreadContext *tc = &thread->context;
|
||||
|
||||
crash_screen_draw_rect(25, 20, 270, 25);
|
||||
crash_screen_print(30, 25, "THREAD:%d (%s)", thread->id, gCauseDesc[cause]);
|
||||
crash_screen_print(30, 35, "PC:%08XH SR:%08XH VA:%08XH", tc->pc, tc->sr, tc->badvaddr);
|
||||
crash_screen_draw_rect(15, 20, 270, 210);
|
||||
crash_screen_print(30, 20, "THREAD:%d (%s)", thread->id, gCauseDesc[cause]);
|
||||
crash_screen_print(30, 30, "PC:%08XH SR:%08XH VA:%08XH", tc->pc, tc->sr, tc->badvaddr);
|
||||
osWritebackDCacheAll();
|
||||
crash_screen_draw_rect(25, 45, 270, 185);
|
||||
if ((u32)parse_map == 0x80345678) {
|
||||
crash_screen_print(30, 50, "AT:%08XH V0:%08XH V1:%08XH", (u32) tc->at, (u32) tc->v0,
|
||||
(u32) tc->v1);
|
||||
} else {
|
||||
crash_screen_draw_rect(15, 45, 270, 185);
|
||||
if ((u32)parse_map != 0x80345678) {
|
||||
char *fname = parse_map(tc->pc);
|
||||
crash_screen_print(30, 50, "CRASH AT: %s", fname == NULL ? "UNKNOWN" : fname);
|
||||
crash_screen_print(30, 40, "CRASH AT: %s", fname == NULL ? "UNKNOWN" : fname);
|
||||
}
|
||||
// crash_screen_print(30, 50, "AT:%08XH V0:%08XH V1:%08XH", (u32) tc->at, (u32) tc->v0, (u32) tc->v1);
|
||||
crash_screen_print(30, 50, "AT:%08XH V0:%08XH V1:%08XH", (u32) tc->at, (u32) tc->v0, (u32) tc->v1);
|
||||
crash_screen_print(30, 60, "A0:%08XH A1:%08XH A2:%08XH", (u32) tc->a0, (u32) tc->a1, (u32) tc->a2);
|
||||
crash_screen_print(30, 70, "A3:%08XH T0:%08XH T1:%08XH", (u32) tc->a3, (u32) tc->t0, (u32) tc->t1);
|
||||
crash_screen_print(30, 80, "T2:%08XH T3:%08XH T4:%08XH", (u32) tc->t2, (u32) tc->t3, (u32) tc->t4);
|
||||
@@ -263,7 +261,7 @@ void draw_stacktrace(OSThread *thread, UNUSED s32 cause) {
|
||||
__OSThreadContext *tc = &thread->context;
|
||||
u32 temp_sp = tc->sp + 0x14;
|
||||
|
||||
crash_screen_draw_rect(25, 20, 270, 25);
|
||||
crash_screen_draw_rect(25, 20, 270, 210);
|
||||
crash_screen_print(30, 25, "STACK TRACE FROM %08X:", temp_sp);
|
||||
if ((u32) parse_map == 0x80345678) {
|
||||
crash_screen_print(30, 35, "CURRFUNC: NONE");
|
||||
@@ -290,8 +288,31 @@ void draw_stacktrace(OSThread *thread, UNUSED s32 cause) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static u32 sProgramPosition = 0;
|
||||
void draw_disasm(OSThread *thread) {
|
||||
__OSThreadContext *tc = &thread->context;
|
||||
// u32 insn = *(u32*)tc->pc;
|
||||
|
||||
crash_screen_draw_rect(25, 20, 270, 210);
|
||||
if (sProgramPosition == 0) {
|
||||
sProgramPosition = tc->pc - 36;
|
||||
}
|
||||
crash_screen_print(30, 25, "DISASM %08X", sProgramPosition);
|
||||
osWritebackDCacheAll();
|
||||
|
||||
|
||||
for (int i = 0; i < 19; i++) {
|
||||
u32 addr = sProgramPosition + (i * 4);
|
||||
u32 toDisasm = *(u32*)(addr);
|
||||
|
||||
|
||||
|
||||
crash_screen_print(30, 35 + (i * 10), "%s", insn_disasm(toDisasm, addr == tc->pc));
|
||||
}
|
||||
|
||||
osWritebackDCacheAll();
|
||||
}
|
||||
|
||||
|
||||
@@ -321,6 +342,14 @@ void draw_crash_screen(OSThread *thread)
|
||||
crashPage--;
|
||||
updateBuffer = TRUE;
|
||||
}
|
||||
if (gPlayer1Controller->buttonDown & D_CBUTTONS) {
|
||||
sProgramPosition += 4;
|
||||
updateBuffer = TRUE;
|
||||
}
|
||||
if (gPlayer1Controller->buttonDown & U_CBUTTONS) {
|
||||
sProgramPosition -= 4;
|
||||
updateBuffer = TRUE;
|
||||
}
|
||||
|
||||
if (crashPage >= PAGE_COUNT && crashPage != 255)
|
||||
crashPage = 0;
|
||||
@@ -336,6 +365,7 @@ void draw_crash_screen(OSThread *thread)
|
||||
case PAGE_CONTEXT: draw_crash_context(thread, cause); break;
|
||||
case PAGE_LOG: draw_crash_log(); break;
|
||||
case PAGE_STACKTRACE: draw_stacktrace(thread, cause); break;
|
||||
case PAGE_DISASM: draw_disasm(thread); break;
|
||||
}
|
||||
|
||||
osWritebackDCacheAll();
|
||||
|
||||
168
src/game/insn_disasm.c
Normal file
168
src/game/insn_disasm.c
Normal file
@@ -0,0 +1,168 @@
|
||||
#include <PR/ultratypes.h>
|
||||
#include "macros.h"
|
||||
#include "farcall.h"
|
||||
|
||||
enum InsnTypes {
|
||||
R_TYPE,
|
||||
I_TYPE,
|
||||
J_TYPE,
|
||||
};
|
||||
|
||||
enum ParamTypes {
|
||||
PARAM_NONE,
|
||||
PARAM_SWAP_RS_IMM,
|
||||
PARAM_JAL,
|
||||
PARAM_JR,
|
||||
PARAM_LUI,
|
||||
};
|
||||
|
||||
extern far char *parse_map(u32);
|
||||
static char insn_as_string[100];
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
u8 rd : 5;
|
||||
u8 shift_amt : 5;
|
||||
u8 function : 6;
|
||||
} RTypeData;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
u8 opcode : 6;
|
||||
u8 rs : 5;
|
||||
u8 rt : 5;
|
||||
union {
|
||||
RTypeData rdata;
|
||||
u16 immediate;
|
||||
};
|
||||
} Insn;
|
||||
|
||||
typedef union {
|
||||
Insn i;
|
||||
u32 d;
|
||||
} InsnData;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
u32 type;
|
||||
u32 arbitraryParam;
|
||||
u8 opcode : 6;
|
||||
u8 function : 6;
|
||||
u8 name[10];
|
||||
} InsnTemplate;
|
||||
|
||||
|
||||
InsnTemplate insn_db[] = {
|
||||
{R_TYPE, PARAM_NONE, 0, 0b100000, "ADD"},
|
||||
{R_TYPE, PARAM_NONE, 0, 0b100001, "ADDU"},
|
||||
{I_TYPE, PARAM_SWAP_RS_IMM, 0b001001, 0, "ADDIU"},
|
||||
{R_TYPE, PARAM_NONE, 0, 0b100100, "AND"},
|
||||
{R_TYPE, PARAM_NONE, 0, 0b011010, "DIV"},
|
||||
{R_TYPE, PARAM_NONE, 0, 0b011011, "DIVU"},
|
||||
{R_TYPE, PARAM_NONE, 0, 0b001000, "JR"},
|
||||
|
||||
{I_TYPE, PARAM_NONE, 0b101000, 0, "SB"},
|
||||
{I_TYPE, PARAM_NONE, 0b100000, 0, "LB"},
|
||||
{I_TYPE, PARAM_NONE, 0b100100, 0, "LBU"},
|
||||
{I_TYPE, PARAM_NONE, 0b101001, 0, "SH"},
|
||||
{I_TYPE, PARAM_NONE, 0b100001, 0, "LH"},
|
||||
{I_TYPE, PARAM_NONE, 0b100101, 0, "LHU"},
|
||||
{I_TYPE, PARAM_NONE, 0b101011, 0, "SW"},
|
||||
{I_TYPE, PARAM_NONE, 0b100011, 0, "LW"},
|
||||
{I_TYPE, PARAM_LUI, 0b001111, 0, "LUI"},
|
||||
|
||||
// branches
|
||||
{I_TYPE, PARAM_SWAP_RS_IMM, 0b000100, 0, "BEQ"},
|
||||
{I_TYPE, PARAM_SWAP_RS_IMM, 0b000101, 0, "BNE"},
|
||||
{R_TYPE, PARAM_NONE, 0, 0b110100, "TEQ"},
|
||||
{R_TYPE, PARAM_NONE, 0, 0b001001, "JALR"},
|
||||
|
||||
// jal (special)
|
||||
{J_TYPE, PARAM_JAL, 0b000011, 0, "JAL"}
|
||||
};
|
||||
|
||||
|
||||
char registerMaps[][4] = {
|
||||
"$R0",
|
||||
"$AT",
|
||||
"$V0", "$V1",
|
||||
"$A0", "$A1", "$A2", "$A3",
|
||||
"$T0", "$T1", "$T2", "$T3", "$T4", "$T5", "$T6", "$T7",
|
||||
"$S0", "$S1", "$S2", "$S3", "$S4", "$S5", "$S6", "$S7",
|
||||
"$T8", "$T9",
|
||||
"$K0", "$K1",
|
||||
"$GP", "$SP", "$FP", "$RA",
|
||||
};
|
||||
|
||||
char *insn_disasm(InsnData insn, u32 isPC) {
|
||||
char *strp = &insn_as_string[0];
|
||||
int successful_print = 0;
|
||||
|
||||
if (insn.d == 0) { // trivial case
|
||||
if (isPC)
|
||||
return "NOP <-- CRASH";
|
||||
else
|
||||
return "NOP";
|
||||
}
|
||||
|
||||
for (int i = 0; i < ARRAY_COUNT(insn_as_string); i++) insn_as_string[i] = 0;
|
||||
|
||||
|
||||
for (int i = 0; i < ARRAY_COUNT(insn_db); i++) {
|
||||
if (insn.i.opcode != 0 && insn.i.opcode == insn_db[i].opcode) {
|
||||
switch (insn_db[i].arbitraryParam) {
|
||||
case PARAM_SWAP_RS_IMM:
|
||||
strp += sprintf(strp, "%-8s %s %s %04X", insn_db[i].name,
|
||||
registerMaps[insn.i.rt],
|
||||
registerMaps[insn.i.rs],
|
||||
insn.i.immediate
|
||||
); break;
|
||||
case PARAM_LUI:
|
||||
strp += sprintf(strp, "%-8s %s %04X", insn_db[i].name,
|
||||
registerMaps[insn.i.rt],
|
||||
insn.i.immediate
|
||||
); break;
|
||||
break;
|
||||
case PARAM_JAL:
|
||||
u32 target = 0x80000000 | ((insn.d & 0x1FFFFFF) * 4);
|
||||
if ((u32)parse_map != 0x80345678) {
|
||||
strp += sprintf(strp, "%-8s %s", insn_db[i].name,
|
||||
parse_map(target)
|
||||
);
|
||||
} else {
|
||||
strp += sprintf(strp, "%-8s %08X", insn_db[i].name,
|
||||
target
|
||||
);
|
||||
}
|
||||
break;
|
||||
case PARAM_NONE:
|
||||
strp += sprintf(strp, "%-8s %s %04X (%s)", insn_db[i].name,
|
||||
registerMaps[insn.i.rt],
|
||||
insn.i.immediate,
|
||||
registerMaps[insn.i.rs]
|
||||
); break;
|
||||
|
||||
}
|
||||
successful_print = 1;
|
||||
break;
|
||||
}
|
||||
else if (insn.i.rdata.function != 0 && insn.i.rdata.function == insn_db[i].function) {
|
||||
strp += sprintf(strp, "%-8s %s %s %s", insn_db[i].name,
|
||||
registerMaps[insn.i.rdata.rd],
|
||||
registerMaps[insn.i.rs],
|
||||
registerMaps[insn.i.rt]
|
||||
);
|
||||
successful_print = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (successful_print == 0) {
|
||||
strp += sprintf(strp, "unimpl %08X", insn.d);
|
||||
}
|
||||
|
||||
if (isPC) {
|
||||
sprintf(strp, " <-- CRASH");
|
||||
}
|
||||
|
||||
return insn_as_string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user