idk what i changed but it should be ready now

This commit is contained in:
someone2639
2021-09-26 16:01:08 -04:00
parent f32f2d3997
commit 2d729ea42f
2 changed files with 209 additions and 11 deletions

View File

@@ -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
View 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;
}