summaryrefslogtreecommitdiff
path: root/src/JSystem/JUtility/JUTException.cpp
diff options
context:
space:
mode:
authorJcw87 <Jcw87@users.noreply.github.com>2023-09-20 21:07:19 -0700
committerGitHub <noreply@github.com>2023-09-20 21:07:19 -0700
commit12ddfa5d0023df3a72c640370aa626ddf1ceafe6 (patch)
treeec936bc26a7da9119c74262ec3ca39de19cadb5e /src/JSystem/JUtility/JUTException.cpp
parentb2fc1d2683958a772da702d74bbbfd8e4a1d514c (diff)
JUTAssert, JUTConsole, JUTException (#63)
* JUTAssert * JUTConsole * JUTException
Diffstat (limited to 'src/JSystem/JUtility/JUTException.cpp')
-rw-r--r--src/JSystem/JUtility/JUTException.cpp979
1 files changed, 916 insertions, 63 deletions
diff --git a/src/JSystem/JUtility/JUTException.cpp b/src/JSystem/JUtility/JUTException.cpp
index 7e113e68..b32a961b 100644
--- a/src/JSystem/JUtility/JUTException.cpp
+++ b/src/JSystem/JUtility/JUTException.cpp
@@ -4,154 +4,1007 @@
//
#include "JSystem/JUtility/JUTException.h"
-#include "dolphin/types.h"
+#include "JSystem/JUtility/JUTConsole.h"
+#include "JSystem/JUtility/JUTDirectFile.h"
+#include "JSystem/JUtility/JUTDirectPrint.h"
+#include "MSL_C/math.h"
+#include "MSL_C/stdio.h"
+#include "MSL_C/stdlib.h"
+#include "dolphin/base/PPCArch.h"
+#include "dolphin/gx/GX.h"
+#include "dolphin/os/OS.h"
+#include "dolphin/vi/vi.h"
+
+struct CallbackObject {
+ /* 0x00 */ OSErrorHandler callback;
+ /* 0x04 */ u16 error;
+ /* 0x06 */ u16 pad_0x06;
+ /* 0x08 */ OSContext* context;
+ /* 0x0C */ int param_3;
+ /* 0x10 */ int param_4;
+};
+
+void search_name_part(u8*, u8*, int);
+
+OSMessageQueue JUTException::sMessageQueue = {};
+static OSTime c3bcnt[4] = {0, 0, 0, 0};
+const char* JUTException::sCpuExpName[] = {
+ "SYSTEM RESET",
+ "MACHINE CHECK",
+ "DSI",
+ "ISI",
+ "EXTERNAL INTERRUPT",
+ "ALIGNMENT",
+ "PROGRAM",
+ "FLOATING POINT",
+ "DECREMENTER",
+ "SYSTEM CALL",
+ "TRACE",
+ "PERFORMACE MONITOR",
+ "BREAK POINT",
+ "SYSTEM INTERRUPT",
+ "THERMAL INTERRUPT",
+ "PROTECTION",
+ "FLOATING POINT",
+};
+JUTException* JUTException::sErrorManager;
+OSErrorHandler JUTException::sPreUserCallback;
+OSErrorHandler JUTException::sPostUserCallback;
/* 802C4AC8-802C4BAC .text __ct__12JUTExceptionFP14JUTDirectPrint */
-JUTException::JUTException(JUTDirectPrint*) {
- /* Nonmatching */
+JUTException::JUTException(JUTDirectPrint* directPrint) : JKRThread(0x4000, 0x10, 0) {
+ mDirectPrint = directPrint;
+ OSSetErrorHandler(EXCEPTION_DSI, errorHandler);
+ OSSetErrorHandler(EXCEPTION_ISI, errorHandler);
+ OSSetErrorHandler(EXCEPTION_PROGRAM, errorHandler);
+ OSSetErrorHandler(EXCEPTION_ALIGNMENT, errorHandler);
+ OSSetErrorHandler(EXCEPTION_MEMORY_PROTECTION, errorHandler);
+ setFPException(0);
+
+ sPreUserCallback = NULL;
+ sPostUserCallback = NULL;
+
+ setGamePad(NULL);
+
+ this->mPrintWaitTime0 = 10;
+ this->mPrintWaitTime1 = 10;
+ this->mTraceSuppress = -1;
+ this->field_0x98 = 0;
+ this->mPrintFlags =
+ JUT_PRINT_GPR | JUT_PRINT_GPR_MAP | JUT_PRINT_SRR0_MAP | JUT_PRINT_FLOAT | JUT_PRINT_STACK;
}
/* 802C4BAC-802C4C14 .text create__12JUTExceptionFP14JUTDirectPrint */
-void JUTException::create(JUTDirectPrint*) {
- /* Nonmatching */
+JUTException* JUTException::create(JUTDirectPrint* directPrint) {
+ if (!sErrorManager) {
+ JKRHeap* systemHeap = JKRGetSystemHeap();
+ sErrorManager = new (systemHeap, 0) JUTException(directPrint);
+ sErrorManager->resume();
+ }
+
+ return sErrorManager;
}
+OSMessage JUTException::sMessageBuffer[1] = {0};
+
/* 802C4C14-802C4CEC .text run__12JUTExceptionFv */
-void JUTException::run() {
- /* Nonmatching */
+void* JUTException::run() {
+ PPCMtmsr(PPCMfmsr() & ~0x0900);
+ OSInitMessageQueue(&sMessageQueue, sMessageBuffer, 1);
+ OSMessage message;
+ while (true) {
+ OSReceiveMessage(&sMessageQueue, &message, OS_MESSAGE_BLOCK);
+ CallbackObject* cb = (CallbackObject*)message;
+ OSErrorHandler callback = cb->callback;
+ u16 error = cb->error;
+ OSContext* context = cb->context;
+ int r24 = cb->param_3;
+ int r23 = cb->param_4;
+ mFrameMemory = (JUTExternalFB*)sErrorManager->mDirectPrint->getFrameBuffer();
+ if (!sErrorManager->mDirectPrint->getFrameBuffer()) {
+ sErrorManager->createFB();
+ }
+ if (callback) {
+ callback(error, context, r24, r23);
+ }
+ OSDisableInterrupts();
+ sErrorManager->printContext(error, context, r24, r23);
+ }
}
+static CallbackObject exCallbackObject;
+void* JUTException::sConsoleBuffer;
+u32 JUTException::sConsoleBufferSize;
+JUTConsole* JUTException::sConsole;
+u32 JUTException::msr;
+u32 JUTException::fpscr;
+
/* 802C4CEC-802C5084 .text errorHandler__12JUTExceptionFUsP9OSContextUlUl */
-void JUTException::errorHandler(unsigned short, OSContext*, unsigned long, unsigned long) {
+void JUTException::errorHandler(OSError error, OSContext* context, u32 param_3, u32 param_4) {
/* Nonmatching */
+ if (error == 0x10) {
+ OSReport("\x1b[41;37m");
+ OSReport(" FPE: 浮動小数点例外が発生しました。アドレスは %08x fpscr=%08x\n", context->srr0, context->fpscr);
+ u8 stack_38[0x20];
+ u32 stack_3c;
+ u32 stack_40;
+ u32 stack_44;
+ u32 stack_48;
+ if (searchPartialModule(context->srr0, &stack_40, &stack_44, &stack_48, &stack_3c) == 1) {
+ search_name_part((u8*)stack_3c, stack_38, 0x20);
+ OSReport("%s:%x section:%d\n", stack_38, stack_48, stack_44);
+ }
+ u32 r31 = context->fpscr;
+ r31 &= ((context->fpscr & 0xf8) << 22) | 0x01f80700;
+ if (r31 & 0x20000000) {
+ context->fpscr &= ~0x80;
+ OSReport(" FPE: Invalid operation(無効な演算)\n");
+ if (fpscr & 0x01000000) {
+ OSReport(" SNaN\n");
+ }
+ if (fpscr & 0x00800000) {
+ OSReport(" Infinity - Infinity\n");
+ }
+ if (fpscr & 0x00400000) {
+ OSReport(" Infinity / Infinity\n");
+ }
+ if (fpscr & 0x00200000) {
+ OSReport(" 0 / 0\n");
+ }
+ if (fpscr & 0x00100000) {
+ OSReport(" Infinity * 0\n");
+ }
+ if (fpscr & 0x00080000) {
+ OSReport(" Invalid compare\n");
+ }
+ if (fpscr & 0x0400) {
+ OSReport(" Software request\n");
+ }
+ if (fpscr & 0x0200) {
+ OSReport(" Invalid square root\n");
+ }
+ if (fpscr & 0x0100) {
+ OSReport(" Invalid integer convert\n");
+ }
+ }
+ if (r31 & 0x10000000) {
+ context->fpscr &= ~0x40;
+ OSReport(" FPE: Overflow(オーバーフロー)\n");
+ }
+ if (r31 & 0x08000000) {
+ context->fpscr &= ~0x20;
+ OSReport(" FPE: Underflow(アンダーフロー)\n");
+ }
+ if (r31 & 0x04000000) {
+ context->fpscr &= ~0x10;
+ OSReport(" FPE: Zero division(0による割り算)\n");
+ }
+ if (r31 & 0x02000000) {
+ context->fpscr &= ~0x08;
+ OSReport(" FPE: Inexact result(不正確な結果)\n");
+ }
+ OSReport("\x1b[m");
+ return;
+ }
+
+ msr = PPCMfmsr();
+ fpscr = context->fpscr;
+ OSFillFPUContext(context);
+ OSSetErrorHandler(error, NULL);
+ if (error == OS_ERROR_MEMORY_PROTECTION) {
+ OSProtectRange(0, NULL, 0, 3);
+ OSProtectRange(1, NULL, 0, 3);
+ OSProtectRange(2, NULL, 0, 3);
+ OSProtectRange(3, NULL, 0, 3);
+ }
+
+ exCallbackObject.callback = sPreUserCallback;
+ exCallbackObject.error = error;
+ exCallbackObject.context = context;
+ exCallbackObject.param_3 = param_3;
+ exCallbackObject.param_4 = param_4;
+
+ OSSendMessage(&sMessageQueue, &exCallbackObject, OS_MESSAGE_BLOCK);
+ OSEnableScheduler();
+ OSYieldThread();
}
/* 802C5084-802C50CC .text setFPException__12JUTExceptionFUl */
-void JUTException::setFPException(unsigned long) {
- /* Nonmatching */
+void JUTException::setFPException(u32 fpscr_enable_bits) {
+ __OSFpscrEnableBits = fpscr_enable_bits;
+ if (fpscr_enable_bits) {
+ OSSetErrorHandler(EXCEPTION_FLOATING_POINT_EXCEPTION, errorHandler);
+ } else {
+ OSSetErrorHandler(EXCEPTION_FLOATING_POINT_EXCEPTION, NULL);
+ }
}
/* 802C50CC-802C525C .text showFloatSub__12JUTExceptionFif */
-void JUTException::showFloatSub(int, float) {
- /* Nonmatching */
+void JUTException::showFloatSub(int index, f32 value) {
+ if (fpclassify(value) == FP_NAN) {
+ sConsole->print_f("F%02d: Nan ", index);
+ } else if (fpclassify(value) == FP_INFINITE) {
+ if (signbit(value)) {
+ sConsole->print_f("F%02d:+Inf ", index);
+ } else {
+ sConsole->print_f("F%02d:-Inf ", index);
+ }
+ } else if (value == 0.0f) {
+ sConsole->print_f("F%02d: 0.0 ", index);
+ } else {
+ sConsole->print_f("F%02d:%+.3E", index, value);
+ }
}
/* 802C525C-802C5380 .text showFloat__12JUTExceptionFP9OSContext */
-void JUTException::showFloat(OSContext*) {
- /* Nonmatching */
+void JUTException::showFloat(OSContext* context) {
+ if (!sConsole) {
+ return;
+ }
+
+ sConsole->print("-------------------------------- FPR\n");
+ for (int i = 0; i < 10; i++) {
+ showFloatSub(i, context->fpr[i]);
+ sConsole->print(" ");
+ showFloatSub(i + 11, context->fpr[i + 11]);
+ sConsole->print(" ");
+ showFloatSub(i + 22, context->fpr[i + 22]);
+ sConsole->print("\n");
+ }
+ showFloatSub(10, context->fpr[10]);
+ sConsole->print(" ");
+ showFloatSub(21, context->fpr[21]);
+ sConsole->print("\n");
}
/* 802C5380-802C5440 .text searchPartialModule__12JUTExceptionFUlPUlPUlPUlPUl */
-void JUTException::searchPartialModule(unsigned long, unsigned long*, unsigned long*, unsigned long*, unsigned long*) {
- /* Nonmatching */
+bool JUTException::searchPartialModule(u32 address, u32* module_id, u32* section_id, u32* section_offset, u32* name_offset) {
+ if (!address) {
+ return false;
+ }
+
+ OSModuleInfo* module = *(OSModuleInfo**)0x800030C8;
+ while (module) {
+ OSSectionInfo* section = (OSSectionInfo*)module->info.sectionInfoOffset;
+ for (u32 i = 0; i < module->mNumSections; section = section + 1, i++) {
+ if (section->mSize) {
+ u32 addr = ALIGN_PREV(section->mOffset, 2);
+ if ((addr <= address) && (address < addr + section->mSize)) {
+ if (module_id)
+ *module_id = module->mId;
+ if (section_id)
+ *section_id = i;
+ if (section_offset)
+ *section_offset = address - addr;
+ if (name_offset)
+ *name_offset = module->mModuleNameOffset;
+ return true;
+ }
+ }
+ }
+
+ module = (OSModuleInfo*)module->mNext;
+ }
+
+ return false;
}
/* 802C5440-802C54B8 .text search_name_part__FPUcPUci */
-void search_name_part(unsigned char*, unsigned char*, int) {
- /* Nonmatching */
+void search_name_part(u8* src, u8* dst, int dst_length) {
+ for (u8* p = src; *p; p++) {
+ if (*p == '\\') {
+ src = p;
+ }
+ }
+
+ if (*src == '\\') {
+ src++;
+ }
+
+ for (int i = 0; (*src != 0) && (i < dst_length);) {
+ if (*src == '.')
+ break;
+ *dst++ = *src++;
+ i++;
+ }
+
+ *dst = '\0';
}
/* 802C54B8-802C55BC .text showStack__12JUTExceptionFP9OSContext */
-void JUTException::showStack(OSContext*) {
- /* Nonmatching */
+void JUTException::showStack(OSContext* context) {
+ if (!sConsole) {
+ return;
+ }
+
+ u32 i;
+ u32* stackPointer;
+ sConsole->print("-------------------------------- TRACE\n");
+ sConsole->print_f("Address: BackChain LR save\n");
+
+ for (i = 0, stackPointer = (u32*)context->gpr[1]; (stackPointer != NULL) && (stackPointer != (u32*)0xFFFFFFFF) && (i++ < 0x10);) {
+ if (i > mTraceSuppress) {
+ sConsole->print("Suppress trace.\n");
+ return;
+ }
+
+ sConsole->print_f("%08X: %08X %08X\n", stackPointer, stackPointer[0], stackPointer[1]);
+ showMapInfo_subroutine(stackPointer[1], false);
+ JUTConsoleManager* manager = JUTConsoleManager::sManager;
+ manager->drawDirect(true);
+ waitTime(mPrintWaitTime1);
+ stackPointer = (u32*)stackPointer[0];
+ }
}
/* 802C55BC-802C586C .text showMainInfo__12JUTExceptionFUsP9OSContextUlUl */
-void JUTException::showMainInfo(unsigned short, OSContext*, unsigned long, unsigned long) {
- /* Nonmatching */
+void JUTException::showMainInfo(u16 error, OSContext* context, u32 dsisr, u32 dar) {
+ if (!sConsole) {
+ return;
+ }
+
+ sConsole->print_f("CONTEXT:%08XH (%s EXCEPTION)\n", context, sCpuExpName[error]);
+
+ if (error == OS_ERROR_FLOATING_POINT_EXCEPTION) {
+ u32 flags = fpscr & (((fpscr & 0xf8) << 0x16) | 0x1f80700);
+ if ((flags & 0x20000000) != 0) {
+ sConsole->print_f(" FPE: Invalid operation\n");
+ if ((fpscr & 0x1000000) != 0) {
+ sConsole->print_f(" SNaN\n");
+ }
+ if ((fpscr & 0x800000) != 0) {
+ sConsole->print_f(" Infinity - Infinity\n");
+ }
+ if ((fpscr & 0x400000) != 0) {
+ sConsole->print_f(" Infinity / Infinity\n");
+ }
+ if ((fpscr & 0x200000) != 0) {
+ sConsole->print_f(" 0 / 0\n");
+ }
+ if ((fpscr & 0x100000) != 0) {
+ sConsole->print_f(" Infinity * 0\n");
+ }
+ if ((fpscr & 0x80000) != 0) {
+ sConsole->print_f(" Invalid compare\n");
+ }
+ if ((fpscr & 0x400) != 0) {
+ sConsole->print_f(" Software request\n");
+ }
+ if ((fpscr & 0x200) != 0) {
+ sConsole->print_f(" Invalid square root\n");
+ }
+ if ((fpscr & 0x100) != 0) {
+ sConsole->print_f(" Invalid integer convert\n");
+ }
+ }
+ if ((flags & 0x10000000) != 0) {
+ sConsole->print_f(" FPE: Overflow\n");
+ }
+ if ((flags & 0x8000000) != 0) {
+ sConsole->print_f(" FPE: Underflow\n");
+ }
+ if ((flags & 0x4000000) != 0) {
+ sConsole->print_f(" FPE: Zero division\n");
+ }
+ if ((flags & 0x2000000) != 0) {
+ sConsole->print_f(" FPE: Inexact result\n");
+ }
+ }
+ sConsole->print_f("SRR0: %08XH SRR1:%08XH\n", context->srr0, context->srr1);
+ sConsole->print_f("DSISR: %08XH DAR: %08XH\n", dsisr, dar);
}
/* 802C586C-802C592C .text showGPR__12JUTExceptionFP9OSContext */
-void JUTException::showGPR(OSContext*) {
- /* Nonmatching */
+void JUTException::showGPR(OSContext* context) {
+ if (!sConsole) {
+ return;
+ }
+
+ sConsole->print("-------------------------------- GPR\n");
+ for (int i = 0; i < 10; i++) {
+ sConsole->print_f("R%02d:%08XH R%02d:%08XH R%02d:%08XH\n", i, context->gpr[i], i + 11,
+ context->gpr[i + 11], i + 22, context->gpr[i + 22]);
+ }
+ sConsole->print_f("R%02d:%08XH R%02d:%08XH\n", 10, context->gpr[10], 21, context->gpr[21]);
}
+JSUList<JUTException::JUTExMapFile> JUTException::sMapFileList(false);
+
/* 802C592C-802C5A88 .text showMapInfo_subroutine__12JUTExceptionFUlb */
-void JUTException::showMapInfo_subroutine(unsigned long, bool) {
- /* Nonmatching */
+bool JUTException::showMapInfo_subroutine(u32 address, bool begin_with_newline) {
+ if ((address < 0x80000000) || (0x82ffffff < address)) {
+ return false;
+ }
+
+ u32 name_offset;
+ u32 module_id;
+ u32 section_id;
+ u32 section_offset;
+ u8 name_part[36];
+
+ const char* new_line = "\n";
+ if (begin_with_newline == false) {
+ new_line = "";
+ }
+
+ bool result =
+ searchPartialModule(address, &module_id, &section_id, &section_offset, &name_offset);
+ if (result == true) {
+ search_name_part((u8*)name_offset, name_part, 32);
+ sConsole->print_f("%s %s:%x section:%d\n", new_line, name_part, section_offset, section_id);
+ begin_with_newline = false;
+ }
+
+ JSUListIterator<JUTException::JUTExMapFile> last = sMapFileList.getEnd();
+ JSUListIterator<JUTException::JUTExMapFile> first = sMapFileList.getFirst();
+ if (first != last) {
+ u32 out_addr;
+ u32 out_size;
+ char out_line[256];
+
+ if (result == true) {
+ result =
+ queryMapAddress((char*)name_part, section_offset, section_id, &out_addr, &out_size,
+ out_line, ARRAY_SIZE(out_line), true, begin_with_newline);
+ } else {
+ result = queryMapAddress(NULL, address, -1, &out_addr, &out_size, out_line,
+ ARRAY_SIZE(out_line), true, begin_with_newline);
+ }
+
+ if (result == true) {
+ return true;
+ }
+ }
+
+ return false;
}
/* 802C5A88-802C5B94 .text showGPRMap__12JUTExceptionFP9OSContext */
-void JUTException::showGPRMap(OSContext*) {
- /* Nonmatching */
+void JUTException::showGPRMap(OSContext* context) {
+ if (!sConsole) {
+ return;
+ }
+
+ bool found_address_register = false;
+ sConsole->print("-------------------------------- GPRMAP\n");
+
+ for (int i = 0; i < 31; i++) {
+ u32 address = context->gpr[i];
+
+ if (address >= 0x80000000 && 0x83000000 - 1 >= address) {
+ found_address_register = true;
+
+ sConsole->print_f("R%02d: %08XH", i, address);
+ if (!showMapInfo_subroutine(address, true)) {
+ sConsole->print(" no information\n");
+ }
+ JUTConsoleManager::sManager->drawDirect(true);
+ waitTime(mPrintWaitTime1);
+ }
+ }
+
+ if (!found_address_register) {
+ sConsole->print(" no register which seem to address.\n");
+ }
}
/* 802C5B94-802C5C58 .text showSRR0Map__12JUTExceptionFP9OSContext */
-void JUTException::showSRR0Map(OSContext*) {
- /* Nonmatching */
+void JUTException::showSRR0Map(OSContext* context) {
+ if (!sConsole) {
+ return;
+ }
+
+ sConsole->print("-------------------------------- SRR0MAP\n");
+ u32 address = context->srr0;
+ if (address >= 0x80000000 && 0x83000000 - 1 >= address) {
+ sConsole->print_f("SRR0: %08XH", address);
+ if (showMapInfo_subroutine(address, true) == false) {
+ sConsole->print(" no information\n");
+ }
+ JUTConsoleManager::getManager()->drawDirect(true);
+ }
}
/* 802C5C58-802C5D00 .text printDebugInfo__12JUTExceptionFQ212JUTException9EInfoPageUsP9OSContextUlUl */
-void JUTException::printDebugInfo(JUTException::EInfoPage, unsigned short, OSContext*, unsigned long, unsigned long) {
- /* Nonmatching */
+void JUTException::printDebugInfo(JUTException::EInfoPage page, OSError error, OSContext* context, u32 param_3, u32 param_4) {
+ switch (page) {
+ case EINFO_PAGE_GPR:
+ return showGPR(context);
+ case EINFO_PAGE_FLOAT:
+ showFloat(context);
+ if (sConsole) {
+ sConsole->print_f(" MSR:%08XH\t FPSCR:%08XH\n", msr, fpscr);
+ }
+ break;
+ case EINFO_PAGE_STACK:
+ return showStack(context);
+ case EINFO_PAGE_GPR_MAP:
+ return showGPRMap(context);
+ case EINFO_PAGE_SSR0_MAP:
+ return showSRR0Map(context);
+ }
}
/* 802C5D00-802C5D3C .text isEnablePad__12JUTExceptionCFv */
-void JUTException::isEnablePad() const {
- /* Nonmatching */
+bool JUTException::isEnablePad() const {
+ if (mGamePad == (JUTGamePad*)0xFFFFFFFF)
+ return true;
+
+ if (mGamePadPort >= 0)
+ return true;
+
+ return mGamePad;
}
/* 802C5D3C-802C62A8 .text readPad__12JUTExceptionFPUlPUl */
-void JUTException::readPad(unsigned long*, unsigned long*) {
- /* Nonmatching */
+bool JUTException::readPad(u32* out_trigger, u32* out_button) {
+ bool result = false;
+ OSTime start_time = OSGetTime();
+ OSTime ms;
+ do {
+ OSTime end_time = OSGetTime();
+ OSTime ticks = end_time - start_time;
+ ms = ticks / (OS_TIMER_CLOCK / 1000);
+ } while (ms < 0x32);
+
+ if (mGamePad == (JUTGamePad*)0xffffffff) {
+ JUTGamePad gamePad0(JUTGamePad::Port_1);
+ JUTGamePad gamePad1(JUTGamePad::Port_2);
+ JUTGamePad gamePad2(JUTGamePad::Port_3);
+ JUTGamePad gamePad3(JUTGamePad::Port_4);
+ JUTGamePad::read();
+
+ c3bcnt[0] =
+ (gamePad0.isPushing3ButtonReset() ? (c3bcnt[0] != 0 ? c3bcnt[0] : OSGetTime()) : 0);
+ c3bcnt[1] =
+ (gamePad1.isPushing3ButtonReset() ? (c3bcnt[1] != 0 ? c3bcnt[1] : OSGetTime()) : 0);
+ c3bcnt[2] =
+ (gamePad2.isPushing3ButtonReset() ? (c3bcnt[2] != 0 ? c3bcnt[2] : OSGetTime()) : 0);
+ c3bcnt[3] =
+ (gamePad3.isPushing3ButtonReset() ? (c3bcnt[3] != 0 ? c3bcnt[3] : OSGetTime()) : 0);
+
+ OSTime resetTime0 = (c3bcnt[0] != 0) ? (OSGetTime() - c3bcnt[0]) : 0;
+ OSTime resetTime1 = (c3bcnt[1] != 0) ? (OSGetTime() - c3bcnt[1]) : 0;
+ OSTime resetTime2 = (c3bcnt[2] != 0) ? (OSGetTime() - c3bcnt[2]) : 0;
+ OSTime resetTime3 = (c3bcnt[3] != 0) ? (OSGetTime() - c3bcnt[3]) : 0;
+
+ gamePad0.checkResetCallback(resetTime0);
+ gamePad1.checkResetCallback(resetTime1);
+ gamePad2.checkResetCallback(resetTime2);
+ gamePad3.checkResetCallback(resetTime3);
+
+ if (out_trigger) {
+ *out_trigger = gamePad0.getTrigger() | gamePad1.getTrigger() | gamePad2.getTrigger() |
+ gamePad3.getTrigger();
+ }
+ if (out_button) {
+ *out_button = gamePad0.getButton() | gamePad1.getButton() | gamePad2.getButton() |
+ gamePad3.getButton();
+ }
+
+ result = true;
+ } else if (mGamePadPort >= 0) {
+ JUTGamePad gamePad(mGamePadPort);
+ OSTime& gamePadTime = c3bcnt[0];
+ gamePadTime =
+ (gamePad.isPushing3ButtonReset() ? (gamePadTime != 0 ? gamePadTime : OSGetTime()) : 0);
+
+ OSTime resetTime = (gamePadTime != 0) ? (OSGetTime() - gamePadTime) : 0;
+ gamePad.checkResetCallback(resetTime);
+
+ JUTGamePad::read();
+ if (out_trigger) {
+ *out_trigger = gamePad.getTrigger();
+ }
+ if (out_button) {
+ *out_button = gamePad.getButton();
+ }
+
+ result = true;
+ } else if (mGamePad) {
+ JUTGamePad::read();
+ if (out_trigger) {
+ *out_trigger = mGamePad->getTrigger();
+ }
+ if (out_button) {
+ *out_button = mGamePad->getButton();
+ }
+
+ result = true;
+ }
+
+ return result;
}
/* 802C62A8-802C6724 .text printContext__12JUTExceptionFUsP9OSContextUlUl */
-void JUTException::printContext(unsigned short, OSContext*, unsigned long, unsigned long) {
- /* Nonmatching */
+void JUTException::printContext(OSError error, OSContext* context, u32 dsisr, u32 dar) {
+ bool is_pad_enabled = isEnablePad() == 0;
+ if (!sErrorManager->mDirectPrint->isActive()) {
+ return;
+ }
+
+ if (!sConsole) {
+ return;
+ }
+
+ sConsole->print_f("******** EXCEPTION OCCURRED! ********\nFrameMemory:%XH\n", getFrameMemory());
+
+ int post_callback_executed = false;
+ while (true) {
+ showMainInfo(error, context, dsisr, dar);
+
+ JUTConsoleManager::sManager->drawDirect(true);
+ waitTime(mPrintWaitTime0);
+
+ if ((mPrintFlags & JUT_PRINT_GPR) != 0) {
+ printDebugInfo(EINFO_PAGE_GPR, error, context, dsisr, dar);
+ JUTConsoleManager::sManager->drawDirect(true);
+ waitTime(mPrintWaitTime0);
+ }
+ if ((mPrintFlags & JUT_PRINT_SRR0_MAP) != 0) {
+ printDebugInfo(EINFO_PAGE_SSR0_MAP, error, context, dsisr, dar);
+ JUTConsoleManager::sManager->drawDirect(true);
+ waitTime(mPrintWaitTime0);
+ }
+ if ((mPrintFlags & JUT_PRINT_GPR_MAP) != 0) {
+ printDebugInfo(EINFO_PAGE_GPR_MAP, error, context, dsisr, dar);
+ JUTConsoleManager::sManager->drawDirect(true);
+ waitTime(mPrintWaitTime0);
+ }
+ if ((mPrintFlags & JUT_PRINT_FLOAT) != 0) {
+ printDebugInfo(EINFO_PAGE_FLOAT, error, context, dsisr, dar);
+ JUTConsoleManager::sManager->drawDirect(true);
+ waitTime(mPrintWaitTime0);
+ }
+ if ((mPrintFlags & JUT_PRINT_STACK) != 0) {
+ printDebugInfo(EINFO_PAGE_STACK, error, context, dsisr, dar);
+ JUTConsoleManager::sManager->drawDirect(true);
+ waitTime(mPrintWaitTime1);
+ }
+
+ sConsole->print("--------------------------------\n");
+ JUTConsoleManager::sManager->drawDirect(true);
+
+ if (post_callback_executed == 0 && sPostUserCallback) {
+ BOOL enable = OSEnableInterrupts();
+ post_callback_executed = true;
+ (*sPostUserCallback)(error, context, dsisr, dar);
+ OSRestoreInterrupts(enable);
+ }
+
+ if (this->field_0x98 == 0 || !is_pad_enabled) {
+ break;
+ }
+
+ sConsole->setOutput(sConsole->getOutput() & 1);
+ }
+
+ if (!is_pad_enabled) {
+ OSEnableInterrupts();
+
+ u32 button;
+ u32 trigger;
+
+ int down = 0;
+ int up = 0;
+ do {
+ readPad(&trigger, &button);
+
+ bool draw = false;
+ if (trigger == 0x100) {
+ sConsole->scrollToLastLine();
+ draw = true;
+ }
+
+ if (trigger == 0x200) {
+ sConsole->scrollToFirstLine();
+ draw = true;
+ }
+
+ if (button == 8) {
+ JUTConsole* console = sConsole;
+ up = (down < 3) ? -1 : ((down < 5) ? -2 : ((down < 7) ? -4 : -8));
+
+ console->scroll(up);
+ draw = true;
+ up = 0;
+ down++;
+ } else if (button == 4) {
+ JUTConsole* console = sConsole;
+ down = (up < 3) ? 1 : ((up < 5) ? 2 : ((up < 7) ? 4 : 8));
+
+ console->scroll(down);
+ draw = true;
+ down = 0;
+ up++;
+ } else {
+ down = 0;
+ up = 0;
+ }
+
+ if (draw == true) {
+ u32 start = VIGetRetraceCount();
+ while (start == VIGetRetraceCount())
+ ;
+ JUTConsoleManager::sManager->drawDirect(true);
+ }
+
+ waitTime(30);
+ } while (true);
+ }
+
+ while (true) {
+ sConsole->scrollToFirstLine();
+ JUTConsoleManager::sManager->drawDirect(true);
+ waitTime(2000);
+
+ int line_offset;
+ int used_line;
+ u32 height;
+ next:
+ for (u32 i = sConsole->getHeight(); i > 0; i--) {
+ sConsole->scroll(1);
+ JUTConsoleManager::sManager->drawDirect(true);
+
+ height = sConsole->getHeight();
+ JUTConsole* console = sConsole;
+ line_offset = console->getLineOffset();
+ used_line = console->getUsedLine();
+ if ((used_line - height) + 1U <= line_offset)
+ break;
+ waitTime(20);
+ }
+
+ waitTime(3000);
+ height = sConsole->getHeight();
+ JUTConsole* console = sConsole;
+ line_offset = console->getLineOffset();
+ used_line = console->getUsedLine();
+ if ((used_line - height) + 1U <= line_offset) {
+ continue;
+ }
+ goto next;
+ }
}
/* 802C6724-802C67AC .text waitTime__12JUTExceptionFl */
-void JUTException::waitTime(long) {
- /* Nonmatching */
+void JUTException::waitTime(s32 timeout_ms) {
+ if (timeout_ms) {
+ OSTime start_time = OSGetTime();
+ OSTime ms;
+ do {
+ OSTime end_time = OSGetTime();
+ OSTime ticks = end_time - start_time;
+ ms = ticks / (OS_TIMER_CLOCK / 1000);
+ } while (ms < timeout_ms);
+ }
}
/* 802C67AC-802C6868 .text createFB__12JUTExceptionFv */
void JUTException::createFB() {
- /* Nonmatching */
+ GXRenderModeObj* renderMode = &GXNtsc480Int;
+ void* end = (void*)OSGetArenaHi();
+ u16 width = ALIGN_NEXT(renderMode->fb_width, 16);
+ u16 height = renderMode->xfb_height;
+ u32 pixel_count = width * height;
+ u32 size = pixel_count * 2;
+
+ void* begin = (void*)ALIGN_PREV((u32)end - size, 32);
+ void* object = (void*)ALIGN_PREV((s32)begin - sizeof(JUTExternalFB), 32);
+ new (object) JUTExternalFB(renderMode, GX_GM_1_7, begin, size);
+
+ mDirectPrint->changeFrameBuffer(object);
+ VIConfigure(renderMode);
+ VISetNextFrameBuffer(begin);
+ VISetBlack(FALSE);
+ VIFlush();
+
+ mFrameMemory = (JUTExternalFB*)object;
}
/* 802C6868-802C6878 .text setPreUserCallback__12JUTExceptionFPFUsP9OSContextUlUl_v */
-void JUTException::setPreUserCallback(void (*)(unsigned short, OSContext*, unsigned long, unsigned long)) {
- /* Nonmatching */
+OSErrorHandler JUTException::setPreUserCallback(OSErrorHandler callback) {
+ OSErrorHandler previous = sPreUserCallback;
+ sPreUserCallback = callback;
+ return previous;
}
/* 802C6878-802C6888 .text setPostUserCallback__12JUTExceptionFPFUsP9OSContextUlUl_v */
-void JUTException::setPostUserCallback(void (*)(unsigned short, OSContext*, unsigned long, unsigned long)) {
- /* Nonmatching */
+OSErrorHandler JUTException::setPostUserCallback(OSErrorHandler callback) {
+ OSErrorHandler previous = sPostUserCallback;
+ sPostUserCallback = callback;
+ return previous;
}
/* 802C6888-802C691C .text appendMapFile__12JUTExceptionFPCc */
-void JUTException::appendMapFile(const char*) {
- /* Nonmatching */
+void JUTException::appendMapFile(const char* path) {
+ if (!path) {
+ return;
+ }
+
+ JSUListIterator<JUTExMapFile> iterator;
+ for (iterator = sMapFileList.getFirst(); iterator != sMapFileList.getEnd(); ++iterator) {
+ if (strcmp(path, iterator->mPath) == 0) {
+ return;
+ }
+ }
+
+ JUTExMapFile* mapFile = new JUTExMapFile((char*)path);
+ sMapFileList.append(&mapFile->mLink);
}
/* 802C691C-802C6A0C .text queryMapAddress__12JUTExceptionFPcUllPUlPUlPcUlbb */
-void JUTException::queryMapAddress(char*, unsigned long, long, unsigned long*, unsigned long*, char*, unsigned long, bool, bool) {
- /* Nonmatching */
+bool JUTException::queryMapAddress(char* mapPath, u32 address, s32 section_id, u32* out_addr, u32* out_size, char* out_line, u32 line_length, bool print, bool begin_with_newline) {
+ if (mapPath) {
+ char buffer[80];
+ snprintf(buffer, sizeof(buffer), "/maps/%s.map", mapPath);
+ if (queryMapAddress_single(buffer, address, section_id, out_addr, out_size, out_line,
+ line_length, print, begin_with_newline) == true)
+ {
+ return true;
+ }
+ } else if (sMapFileList.getFirst() != sMapFileList.getEnd()) {
+ if (queryMapAddress_single(sMapFileList.getFirst()->getObject()->mPath, address, -1,
+ out_addr, out_size, out_line, line_length, print,
+ begin_with_newline) == true)
+ {
+ return true;
+ }
+ }
+
+ return false;
}
/* 802C6A0C-802C6D60 .text queryMapAddress_single__12JUTExceptionFPcUllPUlPUlPcUlbb */
-void JUTException::queryMapAddress_single(char*, unsigned long, long, unsigned long*, unsigned long*, char*, unsigned long, bool, bool) {
+bool JUTException::queryMapAddress_single(char* mapPath, u32 address, s32 section_id, u32* out_addr, u32* out_size, char* out_line, u32 line_length, bool print, bool begin_with_newline) {
/* Nonmatching */
+ if (!mapPath) {
+ return false;
+ }
+
+ char section_name[16];
+ char buffer[0x200];
+ JUTDirectFile file;
+ int i = 0;
+ if (!file.fopen(mapPath)) {
+ return false;
+ }
+
+ int result = 0;
+ do {
+ char* src = buffer;
+ int found_section = 0;
+ do {
+ i++;
+ while (true) {
+ while (true) {
+ int length = file.fgets(buffer, ARRAY_SIZE(buffer));
+ if (length < 0)
+ goto next_section;
+ if (buffer[0] == '.')
+ break;
+ }
+
+ char* dst = section_name;
+ int i = 0;
+ char* src = buffer + 1;
+ for (; *src != '\0'; i++, dst++, src++) {
+ *dst = *src;
+ if (*src == ' ' || i == 0xf)
+ break;
+ }
+
+ section_name[i] = 0;
+ if (*src == 0)
+ break;
+
+ if (src[1] == 's' && src[2] == 'e' && src[3] == 'c' && src[4] == 't') {
+ found_section = true;
+ break;
+ }
+ }
+ if ((found_section & 0xFF) == 0)
+ goto end;
+ } while (section_id >= 0 && section_id != i);
+ next_section:;
+
+ u32 addr;
+ int size;
+ do {
+ int length;
+ do {
+ length = file.fgets(buffer, ARRAY_SIZE(buffer));
+ if (length <= 4)
+ goto next_symbol;
+ } while ((length < 28) || (buffer[28] != '4'));
+
+ addr = strtol(buffer + 19, NULL, 16);
+ addr = ((buffer[18] - '0') << 28) | addr;
+ size = strtol(buffer + 11, NULL, 16);
+ } while (addr > address || address >= addr + size);
+
+ if (out_addr)
+ *out_addr = addr;
+
+ if (out_size)
+ *out_size = size;
+
+ if (out_line) {
+ src = buffer + 0x1e;
+ char* dst = out_line;
+ u32 length = 0;
+ for (; length < line_length - 1; src++) {
+ u32 ch = *(u8*)src;
+ if (ch < ' ' && ch != '\t')
+ break;
+ if (((int)ch == ' ' || ch == '\t') && (length != 0)) {
+ if (dst[-1] != ' ') {
+ *dst = ' ';
+ dst++;
+ length++;
+ }
+ } else {
+ *dst = ch;
+ dst++;
+ length++;
+ }
+ }
+ if (length != 0 && dst[-1] == ' ') {
+ dst--;
+ }
+ *dst = 0;
+ if (print) {
+ if (begin_with_newline) {
+ sConsole->print("\n");
+ }
+ sConsole->print_f(" [%08X]: .%s [%08X: %XH]\n %s\n", address, section_name, addr, size, out_line);
+ begin_with_newline = false;
+ }
+ }
+
+ result = true;
+
+ next_symbol:;
+ } while (section_id >= 0 && section_id != i);
+
+ if (print && begin_with_newline) {
+ sConsole->print("\n");
+ }
+
+end:
+ file.fclose();
+ bool bresult = (result & 0xff) != 0;
+ return bresult;
}
/* 802C6D60-802C6E40 .text createConsole__12JUTExceptionFPvUl */
-void JUTException::createConsole(void*, unsigned long) {
- /* Nonmatching */
-}
+void JUTException::createConsole(void* console_buffer, u32 console_buffer_size) {
+ if (!console_buffer || !console_buffer_size) {
+ return;
+ }
-/* 802C6E40-802C6E60 .text __ct__13JUTExternalFBFP16_GXRenderModeObj8_GXGammaPvUl */
-JUTExternalFB::JUTExternalFB(_GXRenderModeObj*, _GXGamma, void*, unsigned long) {
- /* Nonmatching */
-}
+ u32 lines = JUTConsole::getLineFromObjectSize(console_buffer_size, 0x32);
+ if (lines != 0) {
+ sConsoleBuffer = console_buffer;
+ sConsoleBufferSize = console_buffer_size;
+ sConsole = JUTConsole::create(0x32, console_buffer, console_buffer_size);
-/* 802C6E60-802C6EC0 .text __dt__12JUTExceptionFv */
-JUTException::~JUTException() {
- /* Nonmatching */
+ JUTConsoleManager* manager = JUTConsoleManager::sManager;
+ manager->setDirectConsole(sConsole);
+
+ sConsole->setFontSize(10.0, 6.0);
+ sConsole->setPosition(12, 40);
+ sConsole->setHeight(23);
+ sConsole->setVisible(true);
+ sConsole->setOutput(JUTConsole::OUTPUT_OSREPORT | JUTConsole::OUTPUT_CONSOLE);
+ }
}
-/* 802C6F08-802C6F5C .text __dt__39JSUList<Q212JUTException12JUTExMapFile>Fv */
-JSUList<JUTException::JUTExMapFile>::~JSUList() {
- /* Nonmatching */
+/* 802C6E40-802C6E60 .text __ct__13JUTExternalFBFP16_GXRenderModeObj8_GXGammaPvUl */
+JUTExternalFB::JUTExternalFB(GXRenderModeObj* renderMode, GXGamma gamma, void* buffer, u32 size) {
+ mRenderMode = renderMode;
+ mSize = size;
+ field_0x0C = 1;
+ mGamma = gamma;
+ field_0x10 = false;
}