Files
perfect_dark/src/lib/lib_0c000.c
T
2021-03-14 18:25:17 +10:00

852 lines
29 KiB
C

#include <ultra64.h>
#include "constants.h"
#include "gvars/gvars.h"
#include "lib/entry.h"
#include "lib/lib_09660.h"
#include "lib/lib_0c000.h"
#include "lib/lib_2fa00.h"
#include "data.h"
#include "types.h"
u32 var8005d5b0 = 0x00000000;
u32 var8005d5b4 = 0x00000000;
u32 var8005d5b8 = 0x00000000;
struct crashdescription {
u32 mask;
u32 value;
const char *text;
};
struct var8005d994 {
u8 unk00[30][71];
};
struct crashdescription g_CrashCauseDescriptions[] = {
{ 0x80000000, 0x80000000, "BD" },
{ 0x00008000, 0x00008000, "IP8" },
{ 0x00004000, 0x00004000, "IP7" },
{ 0x00002000, 0x00002000, "IP6" },
{ 0x00001000, 0x00001000, "IP5" },
{ 0x00000800, 0x00000800, "IP4" },
{ 0x00000400, 0x00000400, "IP3" },
{ 0x00000200, 0x00000200, "IP2" },
{ 0x00000100, 0x00000100, "IP1" },
{ 0x0000007c, 0x00000000, "Int" },
{ 0x0000007c, 0x00000004, "TLBmod" },
{ 0x0000007c, 0x00000008, "TLBload" },
{ 0x0000007c, 0x0000000c, "TLBstore" },
{ 0x0000007c, 0x00000010, "Address error on load or instruction fetch" },
{ 0x0000007c, 0x00000014, "Address error on store" },
{ 0x0000007c, 0x00000018, "Bus error exception on instruction fetch" },
{ 0x0000007c, 0x0000001c, "Bus error exception on data reference" },
{ 0x0000007c, 0x00000020, "Syscall" },
{ 0x0000007c, 0x00000024, "Brk" },
{ 0x0000007c, 0x00000028, "Reserved instruction" },
{ 0x0000007c, 0x0000002c, "Cop unusable" },
{ 0x0000007c, 0x00000030, "Overflow" },
{ 0x0000007c, 0x00000034, "Trap" },
{ 0x0000007c, 0x00000038, "Virtual coherency exception on intruction fetch" },
{ 0x0000007c, 0x0000003c, "Fp exception" },
{ 0x0000007c, 0x0000005c, "Watchpoint" },
{ 0x0000007c, 0x0000007c, "Virtual coherency exception on data reference" },
{ 0x00000000, 0x00000000, "" },
{ 0x80000000, 0x80000000, "CU3" },
{ 0x40000000, 0x40000000, "CU2" },
{ 0x20000000, 0x20000000, "CU1" },
{ 0x10000000, 0x10000000, "CU0" },
{ 0x08000000, 0x08000000, "RP" },
{ 0x04000000, 0x04000000, "FR" },
{ 0x02000000, 0x02000000, "RE" },
{ 0x00400000, 0x00400000, "BEV" },
{ 0x00200000, 0x00200000, "TS" },
{ 0x00100000, 0x00100000, "SR" },
{ 0x00040000, 0x00040000, "CH" },
{ 0x00020000, 0x00020000, "CE" },
{ 0x00010000, 0x00010000, "DE" },
{ 0x00008000, 0x00008000, "IM8" },
{ 0x00004000, 0x00004000, "IM7" },
{ 0x00002000, 0x00002000, "IM6" },
{ 0x00001000, 0x00001000, "IM5" },
{ 0x00000800, 0x00000800, "IM4" },
{ 0x00000400, 0x00000400, "IM3" },
{ 0x00000200, 0x00000200, "IM2" },
{ 0x00000100, 0x00000100, "IM1" },
{ 0x00000080, 0x00000080, "KX" },
{ 0x00000040, 0x00000040, "SX" },
{ 0x00000020, 0x00000020, "UX" },
{ 0x00000018, 0x00000010, "USR" },
{ 0x00000018, 0x00000008, "SUP" },
{ 0x00000018, 0x00000000, "KER" },
{ 0x00000004, 0x00000004, "ERL" },
{ 0x00000002, 0x00000002, "EXL" },
{ 0x00000001, 0x00000001, "IE" },
{ 0x00000000, 0x00000000, "" },
};
struct crashdescription g_CrashFpcsrDescriptions[] = {
{ 0x01000000, 0x01000000, "FS" },
{ 0x00800000, 0x00800000, "C" },
{ 0x00020000, 0x00020000, "Unimplemented" },
{ 0x00010000, 0x00010000, "Invalid op" },
{ 0x00008000, 0x00008000, "/ by 0.0" },
{ 0x00004000, 0x00004000, "Overflow" },
{ 0x00002000, 0x00002000, "Underflow" },
{ 0x00001000, 0x00001000, "Inexact op" },
{ 0x00000800, 0x00000800, "EV" },
{ 0x00000400, 0x00000400, "EZ" },
{ 0x00000200, 0x00000200, "EO" },
{ 0x00000100, 0x00000100, "EU" },
{ 0x00000080, 0x00000080, "EI" },
{ 0x00000040, 0x00000040, "FV" },
{ 0x00000020, 0x00000020, "FZ" },
{ 0x00000010, 0x00000010, "FO" },
{ 0x00000008, 0x00000008, "FU" },
{ 0x00000004, 0x00000004, "FI" },
{ 0x00000003, 0x00000000, "RN" },
{ 0x00000003, 0x00000001, "RZ" },
{ 0x00000003, 0x00000002, "RP" },
{ 0x00000003, 0x00000003, "RM" },
{ 0x00000000, 0x00000000, "" },
};
struct var8005d994 *var8005d994 = NULL;
u32 var8005d998 = 0;
extern u32 _libSegmentStart;
void faultproc(void *arg0);
void crashPrintDescription(u32 mask, char *label, struct crashdescription *descriptions);
void faultCreateThread2(void)
{
osCreateMesgQueue(&g_FaultMesgQueue, &g_FaultMesg, 1);
osCreateThread(&g_FaultThread, THREAD_FAULT, faultproc, NULL, &g_FaultSp, THREADPRI_FAULT);
osStartThread(&g_FaultThread);
}
GLOBAL_ASM(
glabel faultproc
/* c06c: 27bdffa0 */ addiu $sp,$sp,-96
/* c070: afb1001c */ sw $s1,0x1c($sp)
/* c074: 3c118009 */ lui $s1,%hi(g_FaultMesgQueue)
/* c078: 26314ab0 */ addiu $s1,$s1,%lo(g_FaultMesgQueue)
/* c07c: afbf0024 */ sw $ra,0x24($sp)
/* c080: afa40060 */ sw $a0,0x60($sp)
/* c084: afb20020 */ sw $s2,0x20($sp)
/* c088: afb00018 */ sw $s0,0x18($sp)
/* c08c: afa0005c */ sw $zero,0x5c($sp)
/* c090: 2404000c */ addiu $a0,$zero,0xc
/* c094: 02202825 */ or $a1,$s1,$zero
/* c098: 0c012148 */ jal osSetEventMesg
/* c09c: 24060010 */ addiu $a2,$zero,0x10
/* c0a0: 3c018009 */ lui $at,%hi(var80094ad0)
/* c0a4: ac204ad0 */ sw $zero,%lo(var80094ad0)($at)
/* c0a8: 27b2005c */ addiu $s2,$sp,0x5c
.L0000c0ac:
/* c0ac: 02202025 */ or $a0,$s1,$zero
.L0000c0b0:
/* c0b0: 02402825 */ or $a1,$s2,$zero
/* c0b4: 0c0121bc */ jal osRecvMesg
/* c0b8: 24060001 */ addiu $a2,$zero,0x1
/* c0bc: 0c012194 */ jal osSetIntMask
/* c0c0: 24040001 */ addiu $a0,$zero,0x1
/* c0c4: 0c013990 */ jal __osGetCurrFaultedThread
/* c0c8: 00408025 */ or $s0,$v0,$zero
/* c0cc: 3c018009 */ lui $at,%hi(var80094acc)
/* c0d0: 1040fff6 */ beqz $v0,.L0000c0ac
/* c0d4: ac224acc */ sw $v0,%lo(var80094acc)($at)
/* c0d8: 0c012194 */ jal osSetIntMask
/* c0dc: 02002025 */ or $a0,$s0,$zero
/* c0e0: 1000fff3 */ b .L0000c0b0
/* c0e4: 02202025 */ or $a0,$s1,$zero
/* c0e8: 00000000 */ nop
/* c0ec: 00000000 */ nop
/* c0f0: 00000000 */ nop
/* c0f4: 00000000 */ nop
/* c0f8: 00000000 */ nop
/* c0fc: 00000000 */ nop
/* c100: 8fbf0024 */ lw $ra,0x24($sp)
/* c104: 8fb00018 */ lw $s0,0x18($sp)
/* c108: 8fb1001c */ lw $s1,0x1c($sp)
/* c10c: 8fb20020 */ lw $s2,0x20($sp)
/* c110: 03e00008 */ jr $ra
/* c114: 27bd0060 */ addiu $sp,$sp,0x60
);
// Mismatch because bss needs to be sprinkled around various files first
//void faultproc(void *arg0)
//{
// OSMesg msg = 0;
// OSIntMask mask;
// u8 stack2[4];
// u8 stack1[44];
// static u32 result; // var80094acc
//
// osSetEventMesg(OS_EVENT_FAULT, &g_FaultMesgQueue, (OSMesg) 16);
// var80094ad0 = 0;
//
// while (true) {
// do {
// osRecvMesg(&g_FaultMesgQueue, &msg, 1);
// mask = osSetIntMask(1);
// result = __osGetCurrFaultedThread();
// } while (!result);
//
// osSetIntMask(mask);
//
// // Beta versions have something like this here:
// //crashRender(result, stack1, stack2);
// //func00001b1c(true);
// }
//}
GLOBAL_ASM(
glabel func0000c118
/* c118: 27bdfff0 */ addiu $sp,$sp,-16
/* c11c: afa40010 */ sw $a0,0x10($sp)
/* c120: afb1000c */ sw $s1,0xc($sp)
/* c124: afb00008 */ sw $s0,0x8($sp)
/* c128: 00c01825 */ or $v1,$a2,$zero
/* c12c: 00001025 */ or $v0,$zero,$zero
/* c130: 00004025 */ or $t0,$zero,$zero
/* c134: 24040020 */ addiu $a0,$zero,0x20
/* c138: 00004825 */ or $t1,$zero,$zero
/* c13c: 00e05025 */ or $t2,$a3,$zero
.L0000c140:
/* c140: 25290001 */ addiu $t1,$t1,0x1
/* c144: ad400000 */ sw $zero,0x0($t2)
/* c148: 1524fffd */ bne $t1,$a0,.L0000c140
/* c14c: 254a0004 */ addiu $t2,$t2,0x4
/* c150: 8fa40010 */ lw $a0,0x10($sp)
/* c154: 3c1103e0 */ lui $s1,0x3e0
/* c158: 36310008 */ ori $s1,$s1,0x8
/* c15c: 0085082b */ sltu $at,$a0,$a1
/* c160: 1420002d */ bnez $at,.L0000c218
/* c164: 2410001f */ addiu $s0,$zero,0x1f
/* c168: 3c0dffe0 */ lui $t5,0xffe0
/* c16c: 3c0cafa0 */ lui $t4,0xafa0
/* c170: 3c0bffff */ lui $t3,0xffff
/* c174: 3c0a27bd */ lui $t2,0x27bd
/* c178: 8c890000 */ lw $t1,0x0($a0)
.L0000c17c:
/* c17c: 2484fffc */ addiu $a0,$a0,-4
/* c180: 0085082b */ sltu $at,$a0,$a1
/* c184: 012b7824 */ and $t7,$t1,$t3
/* c188: 154f000b */ bne $t2,$t7,.L0000c1b8
/* c18c: 012dc024 */ and $t8,$t1,$t5
/* c190: 0009c400 */ sll $t8,$t1,0x10
/* c194: 0018cc03 */ sra $t9,$t8,0x10
/* c198: 1f20001f */ bgtz $t9,.L0000c218
/* c19c: 24020001 */ addiu $v0,$zero,0x1
/* c1a0: 00197083 */ sra $t6,$t9,0x2
/* c1a4: 000e7880 */ sll $t7,$t6,0x2
/* c1a8: 11000019 */ beqz $t0,.L0000c210
/* c1ac: 006f1823 */ subu $v1,$v1,$t7
/* c1b0: 10000019 */ b .L0000c218
/* c1b4: 00000000 */ nop
.L0000c1b8:
/* c1b8: 15980013 */ bne $t4,$t8,.L0000c208
/* c1bc: 00093402 */ srl $a2,$t1,0x10
/* c1c0: 30d9001f */ andi $t9,$a2,0x1f
/* c1c4: 00097c00 */ sll $t7,$t1,0x10
/* c1c8: 000fc403 */ sra $t8,$t7,0x10
/* c1cc: 03203025 */ or $a2,$t9,$zero
/* c1d0: 0018c883 */ sra $t9,$t8,0x2
/* c1d4: 00197080 */ sll $t6,$t9,0x2
/* c1d8: 0006c080 */ sll $t8,$a2,0x2
/* c1dc: 00f8c821 */ addu $t9,$a3,$t8
/* c1e0: 01c37821 */ addu $t7,$t6,$v1
/* c1e4: 16060002 */ bne $s0,$a2,.L0000c1f0
/* c1e8: af2f0000 */ sw $t7,0x0($t9)
/* c1ec: 24080001 */ addiu $t0,$zero,0x1
.L0000c1f0:
/* c1f0: 10400007 */ beqz $v0,.L0000c210
/* c1f4: 00000000 */ nop
/* c1f8: 11000005 */ beqz $t0,.L0000c210
/* c1fc: 00000000 */ nop
/* c200: 10000005 */ b .L0000c218
/* c204: 00000000 */ nop
.L0000c208:
/* c208: 11310003 */ beq $t1,$s1,.L0000c218
/* c20c: 00000000 */ nop
.L0000c210:
/* c210: 5020ffda */ beqzl $at,.L0000c17c
/* c214: 8c890000 */ lw $t1,0x0($a0)
.L0000c218:
/* c218: 10400005 */ beqz $v0,.L0000c230
/* c21c: 8fb00008 */ lw $s0,0x8($sp)
/* c220: 51000004 */ beqzl $t0,.L0000c234
/* c224: 00001025 */ or $v0,$zero,$zero
/* c228: 10000002 */ b .L0000c234
/* c22c: 00601025 */ or $v0,$v1,$zero
.L0000c230:
/* c230: 00001025 */ or $v0,$zero,$zero
.L0000c234:
/* c234: 8fb1000c */ lw $s1,0xc($sp)
/* c238: 03e00008 */ jr $ra
/* c23c: 27bd0010 */ addiu $sp,$sp,0x10
);
extern u32 _libSegmentEnd;
bool crashIsReturnAddress(u32 *instruction)
{
if (((u32)instruction % 4) == 0
&& (u32)instruction >= (u32)boot
&& (u32)instruction <= (u32)&_libSegmentEnd) {
// This condition can never pass because 9 is masked out
if ((instruction[-2] & 0xfc00003c) == 9) {
return true;
}
// If 2 instructions earlier was a jal
if ((instruction[-2] & 0xfc000000) == 0x0c000000) {
return true;
}
}
return false;
}
u32 crashGetStackEnd(u32 sp, s32 tid)
{
u32 start;
u32 end;
if (tid <= 0 || tid > 6U) {
crashPrint("Bad tid\n");
return 0;
}
start = (u32)g_StackStartAddrs[tid];
end = (u32)g_StackEndAddrs[tid];
if (sp >= 0x80000000) {
return end;
}
return (sp & 0xf0000000) | (end - start);
}
u32 crashGetStackStart(u32 sp, s32 tid)
{
u32 start;
if (tid <= 0 || tid > 6U) {
crashPrint("Bad tid\n");
return 0;
}
start = (u32)g_StackStartAddrs[tid];
if (sp >= 0x80000000) {
return start;
}
return sp & 0xf0000000;
}
GLOBAL_ASM(
glabel crashIsDouble
/* c398: e7ac0000 */ swc1 $f12,0x0($sp)
/* c39c: 8fa40000 */ lw $a0,0x0($sp)
/* c3a0: 3c01007f */ lui $at,0x7f
/* c3a4: 3421ffff */ ori $at,$at,0xffff
/* c3a8: 00811024 */ and $v0,$a0,$at
/* c3ac: 2c4e0001 */ sltiu $t6,$v0,0x1
/* c3b0: 15c00008 */ bnez $t6,.L0000c3d4
/* c3b4: 01c01025 */ or $v0,$t6,$zero
/* c3b8: 00041dc2 */ srl $v1,$a0,0x17
/* c3bc: 306f00ff */ andi $t7,$v1,0xff
/* c3c0: 000f102b */ sltu $v0,$zero,$t7
/* c3c4: 10400003 */ beqz $v0,.L0000c3d4
/* c3c8: 00000000 */ nop
/* c3cc: 39e200ff */ xori $v0,$t7,0xff
/* c3d0: 0002102b */ sltu $v0,$zero,$v0
.L0000c3d4:
/* c3d4: 03e00008 */ jr $ra
/* c3d8: 00000000 */ nop
);
//bool crashIsDouble(f32 value)
//{
// u32 bits = *(u32 *)&value;
//
// return (bits & 0x7fffff) != 0
// && ((bits >> 23) & 0xff) != 0
// && ((bits >> 23) & 0xff) != 0xff;
//}
void crashPrintFloat(s32 index, f32 value)
{
if (crashIsDouble(value)) {
crashPrint("%s%s%02d: % .7e ", "", "", index, (f64)value);
} else {
u32 bits = *(u32 *)&value;
crashPrint("%02d: I%d.%03d.%07d ", index, (bits & 0x80000000) >> 31, (bits & 0x7f800000) >> 23, bits & 0x7fffff);
}
}
void crashPrint2Floats(s32 index, f32 value1, f32 value2)
{
crashPrintFloat(index, value1);
crashPrint(" ");
crashPrintFloat(index + 1, value2);
crashPrint("\n");
}
void crashPrint3Floats(s32 index, f32 value1, f32 value2, f32 value3)
{
crashPrintFloat(index, value1);
crashPrint(" ");
crashPrintFloat(index + 1, value2);
crashPrint(" ");
crashPrintFloat(index + 2, value3);
crashPrint("\n");
}
u32 crashRender(OSThread *thread, u32 *callstack, s32 *tracelen)
{
s32 i;
u32 ptr;
u32 *sp;
u32 sp64[32];
u32 *stackend;
u32 *stackstart;
__OSThreadContext *ctx = &thread->context;
bool done;
crashPrint("\n\nFAULT-\n");
if (g_Vars.unk0004e0 == 0) {
// Print a stack trace in a dodgy way.
// It works by iterating through the stack allocation, looking for any
// values which could potentially be a return address, and prints them.
u32 *stackend = (u32 *) crashGetStackEnd(ctx->sp, thread->id);
u32 *sp;
crashPrint("DodgyStackTrace: %08llx ", ctx->ra & 0xffffffff);
sp = (u32 *) ctx->sp;
while (sp < stackend) {
if (crashIsReturnAddress((u32 *)*sp)) {
crashPrint("%08x ", *sp);
}
sp++;
}
crashPrint(".\n");
}
crashPrint("%H#@! Another Perfect Crash (tm)\n");
if (g_Vars.unk0004e0 == 0) {
// Print floating point registers
crashPrint2Floats(0, ctx->fp0.f.f_odd, ctx->fp0.f.f_even);
crashPrint3Floats(2, ctx->fp2.f.f_odd, ctx->fp2.f.f_even, ctx->fp4.f.f_odd);
crashPrint3Floats(5, ctx->fp4.f.f_even, ctx->fp6.f.f_odd, ctx->fp6.f.f_even);
crashPrint3Floats(8, ctx->fp8.f.f_odd, ctx->fp8.f.f_even, ctx->fp10.f.f_odd);
crashPrint3Floats(11, ctx->fp10.f.f_even, ctx->fp12.f.f_odd, ctx->fp12.f.f_even);
crashPrint3Floats(14, ctx->fp14.f.f_odd, ctx->fp14.f.f_even, ctx->fp16.f.f_odd);
crashPrint3Floats(17, ctx->fp16.f.f_even, ctx->fp18.f.f_odd, ctx->fp18.f.f_even);
crashPrint3Floats(20, ctx->fp20.f.f_odd, ctx->fp20.f.f_even, ctx->fp22.f.f_odd);
crashPrint3Floats(23, ctx->fp22.f.f_even, ctx->fp24.f.f_odd, ctx->fp24.f.f_even);
crashPrint3Floats(26, ctx->fp26.f.f_odd, ctx->fp26.f.f_even, ctx->fp28.f.f_odd);
crashPrint3Floats(29, ctx->fp28.f.f_even, ctx->fp30.f.f_odd, ctx->fp30.f.f_even);
}
// Print integer registers
crashPrint("at 0x%016llx v0 0x%016llx v1 0x%016llx\n", ctx->at, ctx->v0, ctx->v1);
crashPrint("a0 0x%016llx a1 0x%016llx a2 0x%016llx\n", ctx->a0, ctx->a1, ctx->a2);
crashPrint("a3 0x%016llx t0 0x%016llx t1 0x%016llx\n", ctx->a3, ctx->t0, ctx->t1);
crashPrint("t2 0x%016llx t3 0x%016llx t4 0x%016llx\n", ctx->t2, ctx->t3, ctx->t4);
crashPrint("t5 0x%016llx t6 0x%016llx t7 0x%016llx\n", ctx->t5, ctx->t6, ctx->t7);
crashPrint("s0 0x%016llx s1 0x%016llx s2 0x%016llx\n", ctx->s0, ctx->s1, ctx->s2);
crashPrint("s3 0x%016llx s4 0x%016llx s5 0x%016llx\n", ctx->s3, ctx->s4, ctx->s5);
crashPrint("s6 0x%016llx s7 0x%016llx t8 0x%016llx\n", ctx->s6, ctx->s7, ctx->t8);
crashPrint("t9 0x%016llx gp 0x%016llx sp 0x%016llx\n", ctx->t9, ctx->gp, ctx->sp);
crashPrint("s8 0x%016llx ra 0x%016llx\n", ctx->s8, ctx->ra);
crashPrint("TID %d epc %08x caus %08x fp %08x badv %08x sr %08x\n",
thread->id, ctx->pc, ctx->cause, ctx->fpcsr, ctx->badvaddr, ctx->sr);
// Print the address of the faulted instruction, along with the instruction
// itself and the next three - presumably to help the developer locate it.
crashPrint("dshex -a %08x %08x %08x %08x %08x\n", ctx->pc,
((u32 *)ctx->pc)[0],
((u32 *)ctx->pc)[1],
((u32 *)ctx->pc)[2],
((u32 *)ctx->pc)[3]);
crashPrintDescription(ctx->cause, "cause", g_CrashCauseDescriptions);
crashPrint(" : ");
crashPrintDescription(ctx->fpcsr, "fpcsr", g_CrashFpcsrDescriptions);
crashPrint("\n");
// Print a proper stack trace
i = 0;
done = false;
sp = (u32 *)ctx->sp;
stackend = (u32 *) crashGetStackEnd((u32)sp, thread->id);
stackstart = (u32 *) crashGetStackStart((u32)sp, thread->id);
ptr = ctx->pc;
*tracelen = 0;
crashPrint("nearl: ");
while (!done) {
sp = (u32 *) func0000c118(ptr, &_libSegmentStart, (u32)sp, sp64);
crashPrint(" %08x ", ptr);
callstack[*tracelen] = ptr;
*tracelen = *tracelen + 1;
if (i == 4) {
crashPrint("\n ");
}
if (sp == NULL) {
sp = (u32 *)ctx->sp;
}
if (sp64[31] == 0) {
ptr = ctx->ra;
} else {
ptr = *(u32 *)(sp64[31]);
}
if (sp < stackstart || sp >= stackend || stackend == &sp[4] || ptr == 0) {
break;
}
done = i >= 9;
i++;
}
crashPrint("\n");
crashPrint("\n");
return 0;
}
void crashPrintDescription(u32 mask, char *label, struct crashdescription *description)
{
bool first = true;
s32 i;
crashPrint("%s <", label);
while (description->mask != 0) {
if ((description->mask & mask) == description->value) {
if (first) {
first = false;
} else {
crashPrint(",");
}
crashPrint("%s", description->text);
}
description++;
}
crashPrint(">");
}
GLOBAL_ASM(
glabel func0000cba0
/* cba0: 30ce00ff */ andi $t6,$a2,0xff
/* cba4: afa60008 */ sw $a2,0x8($sp)
/* cba8: 24010009 */ addiu $at,$zero,0x9
/* cbac: 01c03025 */ or $a2,$t6,$zero
/* cbb0: 11c10004 */ beq $t6,$at,.L0000cbc4
/* cbb4: 01c01025 */ or $v0,$t6,$zero
/* cbb8: 2401000a */ addiu $at,$zero,0xa
/* cbbc: 15c10003 */ bne $t6,$at,.L0000cbcc
/* cbc0: 00000000 */ nop
.L0000cbc4:
/* cbc4: 00003025 */ or $a2,$zero,$zero
/* cbc8: 00001025 */ or $v0,$zero,$zero
.L0000cbcc:
/* cbcc: 18400002 */ blez $v0,.L0000cbd8
/* cbd0: 28410020 */ slti $at,$v0,0x20
/* cbd4: 14200003 */ bnez $at,.L0000cbe4
.L0000cbd8:
/* cbd8: 2841007f */ slti $at,$v0,0x7f
/* cbdc: 14200002 */ bnez $at,.L0000cbe8
/* cbe0: 00000000 */ nop
.L0000cbe4:
/* cbe4: 2406003f */ addiu $a2,$zero,0x3f
.L0000cbe8:
/* cbe8: 04800010 */ bltz $a0,.L0000cc2c
/* cbec: 28810048 */ slti $at,$a0,0x48
/* cbf0: 1020000e */ beqz $at,.L0000cc2c
/* cbf4: 00000000 */ nop
/* cbf8: 04a0000c */ bltz $a1,.L0000cc2c
/* cbfc: 28a1001e */ slti $at,$a1,0x1e
/* cc00: 1020000a */ beqz $at,.L0000cc2c
/* cc04: 3c028006 */ lui $v0,%hi(var8005d994)
/* cc08: 8c42d994 */ lw $v0,%lo(var8005d994)($v0)
/* cc0c: 000578c0 */ sll $t7,$a1,0x3
/* cc10: 01e57821 */ addu $t7,$t7,$a1
/* cc14: 10400005 */ beqz $v0,.L0000cc2c
/* cc18: 000f78c0 */ sll $t7,$t7,0x3
/* cc1c: 01e57823 */ subu $t7,$t7,$a1
/* cc20: 004fc021 */ addu $t8,$v0,$t7
/* cc24: 0304c821 */ addu $t9,$t8,$a0
/* cc28: a3260000 */ sb $a2,0x0($t9)
.L0000cc2c:
/* cc2c: 03e00008 */ jr $ra
/* cc30: 00000000 */ nop
);
GLOBAL_ASM(
glabel func0000cc34
/* cc34: 27bdffd8 */ addiu $sp,$sp,-40
/* cc38: 308600ff */ andi $a2,$a0,0xff
/* cc3c: afbf001c */ sw $ra,0x1c($sp)
/* cc40: afb00018 */ sw $s0,0x18($sp)
/* cc44: afa40028 */ sw $a0,0x28($sp)
/* cc48: 10c0003b */ beqz $a2,.L0000cd38
/* cc4c: 00c01025 */ or $v0,$a2,$zero
/* cc50: 24010009 */ addiu $at,$zero,0x9
/* cc54: 14c1000a */ bne $a2,$at,.L0000cc80
/* cc58: 3c108006 */ lui $s0,%hi(var8005d5b4)
/* cc5c: 2610d5b4 */ addiu $s0,$s0,%lo(var8005d5b4)
.L0000cc60:
/* cc60: 0c00330d */ jal func0000cc34
/* cc64: 24040020 */ addiu $a0,$zero,0x20
/* cc68: 860e0000 */ lh $t6,0x0($s0)
/* cc6c: 31cf0007 */ andi $t7,$t6,0x7
/* cc70: 15e0fffb */ bnez $t7,.L0000cc60
/* cc74: 00000000 */ nop
/* cc78: 10000030 */ b .L0000cd3c
/* cc7c: 8fbf001c */ lw $ra,0x1c($sp)
.L0000cc80:
/* cc80: 2401000a */ addiu $at,$zero,0xa
/* cc84: 14410008 */ bne $v0,$at,.L0000cca8
/* cc88: 3c038006 */ lui $v1,%hi(var8005d5b8)
/* cc8c: 2463d5b8 */ addiu $v1,$v1,%lo(var8005d5b8)
/* cc90: 84780000 */ lh $t8,0x0($v1)
/* cc94: 3c108006 */ lui $s0,%hi(var8005d5b4)
/* cc98: 2610d5b4 */ addiu $s0,$s0,%lo(var8005d5b4)
/* cc9c: 27190001 */ addiu $t9,$t8,0x1
/* cca0: a4790000 */ sh $t9,0x0($v1)
/* cca4: a6000000 */ sh $zero,0x0($s0)
.L0000cca8:
/* cca8: 3c038006 */ lui $v1,%hi(var8005d5b8)
/* ccac: 2463d5b8 */ addiu $v1,$v1,%lo(var8005d5b8)
/* ccb0: 84650000 */ lh $a1,0x0($v1)
/* ccb4: 3c108006 */ lui $s0,%hi(var8005d5b4)
/* ccb8: 2610d5b4 */ addiu $s0,$s0,%lo(var8005d5b4)
/* ccbc: 28a1001d */ slti $at,$a1,0x1d
/* ccc0: 1420000a */ bnez $at,.L0000ccec
/* ccc4: 24a4ffe4 */ addiu $a0,$a1,-28
/* ccc8: afa20024 */ sw $v0,0x24($sp)
/* cccc: 0c003353 */ jal func0000cd4c
/* ccd0: a3a6002b */ sb $a2,0x2b($sp)
/* ccd4: 3c038006 */ lui $v1,%hi(var8005d5b8)
/* ccd8: 2463d5b8 */ addiu $v1,$v1,%lo(var8005d5b8)
/* ccdc: 2408001c */ addiu $t0,$zero,0x1c
/* cce0: 8fa20024 */ lw $v0,0x24($sp)
/* cce4: 93a6002b */ lbu $a2,0x2b($sp)
/* cce8: a4680000 */ sh $t0,0x0($v1)
.L0000ccec:
/* ccec: 2401000a */ addiu $at,$zero,0xa
/* ccf0: 50410012 */ beql $v0,$at,.L0000cd3c
/* ccf4: 8fbf001c */ lw $ra,0x1c($sp)
/* ccf8: 86040000 */ lh $a0,0x0($s0)
/* ccfc: 0c0032e8 */ jal func0000cba0
/* cd00: 84650000 */ lh $a1,0x0($v1)
/* cd04: 86090000 */ lh $t1,0x0($s0)
/* cd08: 3c038006 */ lui $v1,%hi(var8005d5b8)
/* cd0c: 2463d5b8 */ addiu $v1,$v1,%lo(var8005d5b8)
/* cd10: 252a0001 */ addiu $t2,$t1,0x1
/* cd14: a60a0000 */ sh $t2,0x0($s0)
/* cd18: 860b0000 */ lh $t3,0x0($s0)
/* cd1c: 29610047 */ slti $at,$t3,0x47
/* cd20: 54200006 */ bnezl $at,.L0000cd3c
/* cd24: 8fbf001c */ lw $ra,0x1c($sp)
/* cd28: 846c0000 */ lh $t4,0x0($v1)
/* cd2c: a6000000 */ sh $zero,0x0($s0)
/* cd30: 258d0001 */ addiu $t5,$t4,0x1
/* cd34: a46d0000 */ sh $t5,0x0($v1)
.L0000cd38:
/* cd38: 8fbf001c */ lw $ra,0x1c($sp)
.L0000cd3c:
/* cd3c: 8fb00018 */ lw $s0,0x18($sp)
/* cd40: 27bd0028 */ addiu $sp,$sp,0x28
/* cd44: 03e00008 */ jr $ra
/* cd48: 00000000 */ nop
);
GLOBAL_ASM(
glabel func0000cd4c
/* cd4c: 3c068006 */ lui $a2,%hi(var8005d994)
/* cd50: 24c6d994 */ addiu $a2,$a2,%lo(var8005d994)
/* cd54: 8cce0000 */ lw $t6,0x0($a2)
/* cd58: 0004102a */ slt $v0,$zero,$a0
/* cd5c: 11c00018 */ beqz $t6,.L0000cdc0
/* cd60: 00000000 */ nop
/* cd64: 10400016 */ beqz $v0,.L0000cdc0
/* cd68: 2484ffff */ addiu $a0,$a0,-1
/* cd6c: 2408001d */ addiu $t0,$zero,0x1d
/* cd70: 24070047 */ addiu $a3,$zero,0x47
.L0000cd74:
/* cd74: 00001025 */ or $v0,$zero,$zero
/* cd78: 00001825 */ or $v1,$zero,$zero
.L0000cd7c:
/* cd7c: 0002c0c0 */ sll $t8,$v0,0x3
/* cd80: 8ccf0000 */ lw $t7,0x0($a2)
/* cd84: 0302c021 */ addu $t8,$t8,$v0
/* cd88: 0018c0c0 */ sll $t8,$t8,0x3
/* cd8c: 0302c023 */ subu $t8,$t8,$v0
/* cd90: 01f8c821 */ addu $t9,$t7,$t8
/* cd94: 03232821 */ addu $a1,$t9,$v1
/* cd98: 90a90047 */ lbu $t1,0x47($a1)
/* cd9c: 24630001 */ addiu $v1,$v1,0x1
/* cda0: 1467fff6 */ bne $v1,$a3,.L0000cd7c
/* cda4: a0a90000 */ sb $t1,0x0($a1)
/* cda8: 24420001 */ addiu $v0,$v0,0x1
/* cdac: 5448fff3 */ bnel $v0,$t0,.L0000cd7c
/* cdb0: 00001825 */ or $v1,$zero,$zero
/* cdb4: 0004102a */ slt $v0,$zero,$a0
/* cdb8: 1440ffee */ bnez $v0,.L0000cd74
/* cdbc: 2484ffff */ addiu $a0,$a0,-1
.L0000cdc0:
/* cdc0: 03e00008 */ jr $ra
/* cdc4: 00000000 */ nop
);
GLOBAL_ASM(
glabel func0000cdc8
/* cdc8: 27bdffe8 */ addiu $sp,$sp,-24
/* cdcc: afbf0014 */ sw $ra,0x14($sp)
/* cdd0: afa40018 */ sw $a0,0x18($sp)
/* cdd4: afa5001c */ sw $a1,0x1c($sp)
/* cdd8: 0c002f02 */ jal viGetWidth
/* cddc: afa60020 */ sw $a2,0x20($sp)
/* cde0: 93a30023 */ lbu $v1,0x23($sp)
/* cde4: 8fa50018 */ lw $a1,0x18($sp)
/* cde8: 8fa6001c */ lw $a2,0x1c($sp)
/* cdec: 54600003 */ bnezl $v1,.L0000cdfc
/* cdf0: 28610020 */ slti $at,$v1,0x20
/* cdf4: 24030020 */ addiu $v1,$zero,0x20
/* cdf8: 28610020 */ slti $at,$v1,0x20
.L0000cdfc:
/* cdfc: 1420003a */ bnez $at,.L0000cee8
/* ce00: 2861007f */ slti $at,$v1,0x7f
/* ce04: 10200038 */ beqz $at,.L0000cee8
/* ce08: 38490280 */ xori $t1,$v0,0x280
/* ce0c: 2d290001 */ sltiu $t1,$t1,0x1
/* ce10: 1120000a */ beqz $t1,.L0000ce3c
/* ce14: 00006025 */ or $t4,$zero,$zero
/* ce18: 00c20019 */ multu $a2,$v0
/* ce1c: 3c188006 */ lui $t8,%hi(var8005d998)
/* ce20: 8f18d998 */ lw $t8,%lo(var8005d998)($t8)
/* ce24: 00057880 */ sll $t7,$a1,0x2
/* ce28: 01f8c821 */ addu $t9,$t7,$t8
/* ce2c: 00007012 */ mflo $t6
/* ce30: 000e7840 */ sll $t7,$t6,0x1
/* ce34: 10000009 */ b .L0000ce5c
/* ce38: 032f2021 */ addu $a0,$t9,$t7
.L0000ce3c:
/* ce3c: 00c20019 */ multu $a2,$v0
/* ce40: 3c0e8006 */ lui $t6,%hi(var8005d998)
/* ce44: 8dced998 */ lw $t6,%lo(var8005d998)($t6)
/* ce48: 0005c040 */ sll $t8,$a1,0x1
/* ce4c: 030ec821 */ addu $t9,$t8,$t6
/* ce50: 00007812 */ mflo $t7
/* ce54: 000fc040 */ sll $t8,$t7,0x1
/* ce58: 03382021 */ addu $a0,$t9,$t8
.L0000ce5c:
/* ce5c: 00003025 */ or $a2,$zero,$zero
/* ce60: 00026840 */ sll $t5,$v0,0x1
/* ce64: 241f0007 */ addiu $ra,$zero,0x7
/* ce68: 240b0004 */ addiu $t3,$zero,0x4
/* ce6c: 3c0a8000 */ lui $t2,0x8000
/* ce70: 24080001 */ addiu $t0,$zero,0x1
/* ce74: 24077bdf */ addiu $a3,$zero,0x7bdf
/* ce78: 00002825 */ or $a1,$zero,$zero
.L0000ce7c:
/* ce7c: 00ca1824 */ and $v1,$a2,$t2
/* ce80: 10600003 */ beqz $v1,.L0000ce90
/* ce84: 00067040 */ sll $t6,$a2,0x1
/* ce88: 10000002 */ b .L0000ce94
/* ce8c: a4870000 */ sh $a3,0x0($a0)
.L0000ce90:
/* ce90: a4880000 */ sh $t0,0x0($a0)
.L0000ce94:
/* ce94: 11200006 */ beqz $t1,.L0000ceb0
/* ce98: 24a50001 */ addiu $a1,$a1,0x1
/* ce9c: 50600004 */ beqzl $v1,.L0000ceb0
/* cea0: a4880002 */ sh $t0,0x2($a0)
/* cea4: 10000002 */ b .L0000ceb0
/* cea8: a4870002 */ sh $a3,0x2($a0)
/* ceac: a4880002 */ sh $t0,0x2($a0)
.L0000ceb0:
/* ceb0: 11200002 */ beqz $t1,.L0000cebc
/* ceb4: 24840002 */ addiu $a0,$a0,0x2
/* ceb8: 24840002 */ addiu $a0,$a0,0x2
.L0000cebc:
/* cebc: 14abffef */ bne $a1,$t3,.L0000ce7c
/* cec0: 01c03025 */ or $a2,$t6,$zero
/* cec4: 11200004 */ beqz $t1,.L0000ced8
/* cec8: 258c0001 */ addiu $t4,$t4,0x1
/* cecc: 008d2021 */ addu $a0,$a0,$t5
/* ced0: 10000003 */ b .L0000cee0
/* ced4: 2484fff0 */ addiu $a0,$a0,-16
.L0000ced8:
/* ced8: 008d2021 */ addu $a0,$a0,$t5
/* cedc: 2484fff8 */ addiu $a0,$a0,-8
.L0000cee0:
/* cee0: 559fffe6 */ bnel $t4,$ra,.L0000ce7c
/* cee4: 00002825 */ or $a1,$zero,$zero
.L0000cee8:
/* cee8: 8fbf0014 */ lw $ra,0x14($sp)
/* ceec: 27bd0018 */ addiu $sp,$sp,0x18
/* cef0: 03e00008 */ jr $ra
/* cef4: 00000000 */ nop
);
void func0000cef8(void)
{
var8005d994 = NULL;
if (var8005d994) {
// Unreachable
s32 i;
s32 j;
for (i = 0; i < 30; i++) {
for (j = 0; j < 71; j++) {
var8005d994->unk00[i][j] = 0;
}
}
}
}
void func0000cf54(u16 *fb)
{
s32 width;
s32 height;
s32 x;
s32 y;
var8005d998 = (u32)fb | 0xa0000000;
width = (viGetWidth() - 13) / 4;
height = (viGetHeight() - 10) / 7 - 1;
if (var8005d994 != NULL) {
for (y = 0; y < height && y < 29; y++) {
for (x = 0; x < width - 5 && x < 71; x++) {
func0000cdc8(20 + x * 4, 7 + y * 7, var8005d994->unk00[y][x]);
}
}
}
}