/** * m_Do_machine.cpp * Exception Management */ #include "m_Do/m_Do_machine.h" #include "JSystem/JFramework/JFWSystem.h" #include "JSystem/JKernel/JKRHeap.h" #include "JSystem/JUtility/JUTConsole.h" #include "JSystem/JUtility/JUTDbPrint.h" #include "JSystem/JUtility/JUTException.h" #include "JSystem/JUtility/JUTVideo.h" #include "JSystem/JKernel/JKRAramStream.h" #include "JSystem/JKernel/JKRDvdAramRipper.h" #include "JSystem/JKernel/JKRAram.h" #include "SSystem/SComponent/c_malloc.h" #include "SSystem/SComponent/c_math.h" #include "SSystem/SComponent/c_API_controller_pad.h" #include "base/PPCArch.h" #include "m_Do/m_Do_DVDError.h" #include "m_Do/m_Do_MemCard.h" #include "m_Do/m_Do_Reset.h" #include "m_Do/m_Do_dvd_thread.h" #include "m_Do/m_Do_ext.h" #include "m_Do/m_Do_machine_exception.h" #include "m_Do/m_Do_main.h" /* 80450BF0-80450BF4 0000F0 0004+00 1/1 0/0 0/0 .sbss None */ static u8 mDebugFill; #ifdef DEBUG static u8 mDebugFillNotuse; static u8 mDebugFillNew; static u8 mDebugFillDelete; #endif /* 80450BF4-80450BF8 0000F4 0004+00 1/1 0/0 0/0 .sbss solidHeapErrors */ static int solidHeapErrors; /* 80450BF8-80450BFC 0000F8 0004+00 1/1 0/0 0/0 .sbss gameHeapErrors */ static int gameHeapErrors; /* 80450BFC-80450C00 0000FC 0004+00 1/1 0/0 0/0 .sbss zeldaHeapErrors */ static int zeldaHeapErrors; /* 80450C00-80450C04 000100 0004+00 1/1 0/0 0/0 .sbss commandHeapErrors */ static int commandHeapErrors; /* 80450C04-80450C08 000104 0004+00 1/1 0/0 0/0 .sbss archiveHeapErrors */ static int archiveHeapErrors; /* 80450C08-80450C0C 000108 0004+00 1/1 0/0 0/0 .sbss unknownHeapErrors */ static int unknownHeapErrors; /* 80450C0C-80450C10 00010C 0004+00 1/1 0/0 0/0 .sbss heapErrors */ static u32 heapErrors; /* 8000B1EC-8000B3EC 005B2C 0200+00 2/2 0/0 0/0 .text myGetHeapTypeByString__FP7JKRHeap */ static const char* myGetHeapTypeByString(JKRHeap* p_heap) { static char tmpString[5]; if (p_heap == JKRHeap::getSystemHeap()) { return "SystemHeap"; } if (p_heap == mDoExt_getZeldaHeap()) { return "ZeldaHeap"; } if (p_heap == mDoExt_getGameHeap()) { return "GameHeap"; } if (p_heap == mDoExt_getArchiveHeap()) { return "ArchiveHeap"; } if (p_heap == mDoExt_getCommandHeap()) { return "CommandHeap"; } if (p_heap == mDoExt_getDbPrintHeap()) { return "DbPrintHeap"; } if (p_heap == mDoExt_getJ2dHeap()) { return "J2dHeap"; } u32 heapType = p_heap->getHeapType(); switch (heapType) { case 'ASTH': return "ASTH"; case 'EXPH': return "EXPH"; case 'SLID': return "SLID"; case 'STDH': return "STDH"; case 'UNIT': return "UNIT"; case 0: return "(Null)"; default: u32 tmpType = heapType; char* typeStr = (char*)&tmpType; tmpString[0] = typeStr[0]; tmpString[1] = typeStr[1]; tmpString[2] = typeStr[2]; tmpString[3] = typeStr[3]; tmpString[4] = 0; return tmpString; } } /* 8000B3EC-8000B5C8 005D2C 01DC+00 1/1 0/0 0/0 .text myMemoryErrorRoutine__FPvUli */ static void myMemoryErrorRoutine(void* p_heap, u32 size, int alignment) { JKRHeap* heap = (JKRHeap*)p_heap; BOOL notSolidHeap = true; if (heap->getHeapType() == 'SLID') { notSolidHeap = false; } if (notSolidHeap) { // "Error: Can't allocate memory %d(0x%x)Bytes, %d Byte Alignment from %08x\n" OSReport_Error( "エラー: メモリを確保できません %d(0x%x)バイト、 %d バイトアライメント from %08x\n", size, size, alignment, p_heap); } u32 heapType = heap->getHeapType(); u8* tmpString = (u8*)&heapType; if (notSolidHeap) { OSReport_Error( "FreeSize=%08x TotalFreeSize=%08x HeapType=%08x(%c%c%c%c) HeapSize=%08x %s\n", heap->getFreeSize(), heap->getTotalFreeSize(), heapType, tmpString[0], tmpString[1], tmpString[2], tmpString[3], heap->getHeapSize(), myGetHeapTypeByString(heap)); } if (heapErrors == 0) { heap->dump_sort(); } heapErrors++; if (p_heap == zeldaHeap) { zeldaHeapErrors++; } else if (p_heap == gameHeap) { gameHeapErrors++; } else if (p_heap == commandHeap) { commandHeapErrors++; } else if (p_heap == archiveHeap) { archiveHeapErrors++; } else if (heap->getHeapType() == 'SLID') { solidHeapErrors++; } else { unknownHeapErrors++; } } /* 8000B5C8-8000B668 005F08 00A0+00 1/1 0/0 0/0 .text myHeapCheckRecursive__FP7JKRHeap */ void myHeapCheckRecursive(JKRHeap* p_heap) { if (!p_heap->check()) { const char* type = myGetHeapTypeByString(p_heap); OSReport_Error("error in %08x(%s)\n", p_heap, type); } JSUTree* heapTree = &p_heap->getHeapTree(); for (JSUTree* i = heapTree->getFirstChild(); i != NULL; i = i->getNextChild()) { myHeapCheckRecursive(i->getObject()); } } /* 8000B668-8000B68C 005FA8 0024+00 0/0 2/2 0/0 .text mDoMch_HeapCheckAll__Fv */ void mDoMch_HeapCheckAll() { myHeapCheckRecursive(JKRHeap::sRootHeap); } /* 8000B68C-8000B73C 005FCC 00B0+00 1/1 0/0 0/0 .text developKeyCheck__FUlUl */ static int developKeyCheck(u32 btnTrig, u32 btnHold) { static u8 key_link; static u8 key_ganon; static u8 key_zelda; if (btnHold == (PAD_TRIGGER_L | PAD_TRIGGER_R | PAD_TRIGGER_Z | PAD_BUTTON_DOWN) && btnTrig == PAD_BUTTON_DOWN) { if (key_link == 3 && key_ganon == 6 && key_zelda == 5) { mDoMain::developmentMode = 1; } else { key_link = 0; key_ganon = 0; key_zelda = 0; } } if (btnHold == (PAD_TRIGGER_L | PAD_BUTTON_RIGHT) && btnTrig == PAD_TRIGGER_L) { key_link++; } if (btnHold == (PAD_TRIGGER_R | PAD_BUTTON_UP) && btnTrig == PAD_TRIGGER_R) { key_ganon++; } if (btnHold == (PAD_TRIGGER_Z | PAD_BUTTON_LEFT) && btnTrig == PAD_TRIGGER_Z) { key_zelda++; } return mDoMain::developmentMode; } /* 8000B73C-8000B768 00607C 002C+00 1/1 0/0 0/0 .text mDoMch_IsProgressiveMode__Fv */ BOOL mDoMch_IsProgressiveMode() { return OSGetProgressiveMode() == true; } /* 8000B768-8000B798 0060A8 0030+00 2/2 0/0 0/0 .text exceptionReadPad__FPUlPUl */ bool exceptionReadPad(u32* p_btnTrig, u32* p_btnHold) { return JUTException::getManager()->readPad(p_btnTrig, p_btnHold); } /* 8000B798-8000B7C8 0060D8 0030+00 1/1 0/0 0/0 .text exceptionRestart__Fv */ void exceptionRestart() { mDoRst_reset(0, 0, 0); OSResetSystem(0, 0, 0); do { } while (true); } /* 8000B7C8-8000B95C 006108 0194+00 1/1 0/0 0/0 .text myExceptionCallback__FUsP9OSContextUlUl */ void myExceptionCallback(u16, OSContext*, u32, u32) { u32 btnHold; u32 btnTrig; mDoMain::sHungUpTime = OSGetTime(); OSReportEnable(); cAPICPad_recalibrate(); // "Vibration stopping & resetting to default\n" OSReport("振動停止&原点復帰\n"); JUTException* manager = JUTException::getManager(); if (manager == NULL) { // "Exception Manager doesn't exist\n" OSReport("例外マネージャがありません\n"); PPCHalt(); } else { manager->setTraceSuppress(0x80); if (mDoMain::developmentMode == 0) { JUTGamePad pad(JUTGamePad::EPort1); manager->setGamePad(&pad); if (manager != NULL) { OSEnableInterrupts(); // "Accepting Key input\n" OSReport("キー入力を受け付けています\n"); while (mDoMain::developmentMode == 0) { exceptionReadPad(&btnTrig, &btnHold); developKeyCheck(btnTrig, btnHold); JUTException::waitTime(30); if (JUTGamePad::C3ButtonReset::sResetOccurred) { exceptionRestart(); } } // "JUTAssertion is visible\n" OSReport("JUTAssertionを可視化しました\n"); JUTAssertion::setVisible(true); JUTDbPrint::getManager()->setVisible(true); JFWSystem::getSystemConsole()->setOutput(JUTConsole::OUTPUT_OSREPORT | JUTConsole::OUTPUT_CONSOLE); } else { PPCHalt(); } } else { // "Wait for 3 seconds\n" OSReport("3秒間停止\n"); JUTException::waitTime(3000); } } DVDChangeDir("/map/Final/Release"); JUTVideo::destroyManager(); GXSetDrawDoneCallback(NULL); VISetBlack(0); VIFlush(); } /* 8000B95C-8000BCF4 00629C 0398+00 1/1 0/0 0/0 .text fault_callback_scroll__FUsP9OSContextUlUl */ static void fault_callback_scroll(u16, OSContext* p_context, u32, u32) { JUTException* manager = JUTException::getManager(); JUTConsole* exConsole = manager->getConsole(); u32 srr0 = p_context->srr0 & -4; if (srr0 >= 0x8000000C && srr0 < 0x82FFFFFF) { exConsole->print_f("(SRR0-3):%08X %08X %08X %08X\n", *(u32*)(srr0 - 0xC), *(u32*)(srr0 - 0x8), *(u32*)(srr0 - 0x4), *(u32*)srr0); } JUTGamePad pad(JUTGamePad::EPort1); manager->setGamePad(&pad); BOOL padDisabled = manager->isEnablePad() == false; if (!padDisabled) { exConsole->print("PUSH START BUTTON TO ADDITIONAL INFOMATION\n"); exConsole->print("--------------------------------------\n"); JUTConsoleManager::getManager()->drawDirect(true); OSEnableInterrupts(); int holdUpCount = 0; int holdDownCount = 0; while (true) { u32 btnHold, btnTrig; exceptionReadPad(&btnTrig, &btnHold); if (JUTGamePad::C3ButtonReset::sResetOccurred) { OSResetSystem(1, 0, 0); } bool waitRetrace = false; if (btnTrig == PAD_BUTTON_START) { exception_addition(exConsole); waitRetrace = true; } if (btnTrig == PAD_TRIGGER_Z) { JUTConsole* sysConsole = JFWSystem::getSystemConsole(); if (JUTConsoleManager::getManager()->getDirectConsole() != sysConsole) { exConsole = sysConsole; exConsole->setFontSize(8.0f, 6.0f); exConsole->setPosition(8, 32); exConsole->setHeight(23); exConsole->setVisible(true); exConsole->setOutput(JUTConsole::OUTPUT_CONSOLE | JUTConsole::OUTPUT_OSREPORT); } else { exConsole = JUTException::getConsole(); } JUTConsoleManager::getManager()->setDirectConsole(exConsole); waitRetrace = true; } if (btnTrig == PAD_BUTTON_A) { exConsole->scrollToLastLine(); waitRetrace = true; } if (btnTrig == PAD_BUTTON_B) { exConsole->scrollToFirstLine(); waitRetrace = true; } if (btnHold == PAD_BUTTON_UP) { exConsole->scroll(holdUpCount < 3 ? -1 : (holdUpCount < 5 ? -2 : (holdUpCount < 7 ? -4 : -8))); waitRetrace = true; holdDownCount = 0; holdUpCount++; } else if (btnHold == PAD_BUTTON_DOWN) { exConsole->scroll(holdDownCount < 3 ? 1 : (holdDownCount < 5 ? 2 : (holdDownCount < 7 ? 4 : 8))); waitRetrace = true; holdUpCount = 0; holdDownCount++; } else { holdUpCount = 0; holdDownCount = 0; } if (waitRetrace == true) { u32 count = VIGetRetraceCount(); do { } while (count == VIGetRetraceCount()); JUTConsoleManager::getManager()->drawDirect(true); } JUTException::waitTime(30); } } exception_addition(exConsole); JUTConsoleManager::getManager()->drawDirect(true); do { exConsole->scrollToFirstLine(); JUTConsoleManager::getManager()->drawDirect(true); JUTException::waitTime(2000); do { for (u32 i = exConsole->getHeight(); i != 0; i--) { exConsole->scroll(1); JUTConsoleManager::getManager()->drawDirect(true); if ((exConsole->getUsedLine() - exConsole->getHeight()) + 1 <= exConsole->getLineOffset()) { break; } JUTException::waitTime(20); } JUTException::waitTime(3000); if ((exConsole->getUsedLine() - exConsole->getHeight()) + 1 <= exConsole->getLineOffset()) { break; } } while (true); } while (true); } static void dummy_string() { DEAD_STRING("\x1B[32m%-24s = size=%d KB\n\x1B[m"); } /* 8000BCF4-8000BCF8 006634 0004+00 1/1 0/0 0/0 .text my_PrintHeap__FPCcUl */ static void my_PrintHeap(char const* heapName, u32 heapSize) { /* empty function */ } /* 8000BCF8-8000BD44 006638 004C+00 1/1 0/0 0/0 .text my_SysPrintHeap__FPCcPvUl */ void my_SysPrintHeap(char const* message, void* start, u32 size) { OSReport_System("\x1b[32m%-24s = %08x-%08x size=%d KB\n\x1b[m", message, start, (u32)start + size, size / 1024); } /* 803A2F60-803A2F9C 000080 003C+00 1/0 0/0 0/0 .data g_ntscZeldaIntDf */ extern GXRenderModeObj g_ntscZeldaIntDf = { VI_TVMODE_NTSC_INT, 608, 448, 448, 27, 16, 666, 448, VI_XFBMODE_DF, 0, 0, {{6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}}, {8, 8, 10, 12, 10, 8, 8}, }; /* 803A2F9C-803A2FD8 0000BC 003C+00 1/1 1/1 0/0 .data g_ntscZeldaProg */ extern GXRenderModeObj g_ntscZeldaProg = { VI_TVMODE_NTSC_PROG, 608, 448, 448, 27, 16, 666, 448, VI_XFBMODE_SF, 0, 0, {{6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}}, {0, 0, 21, 22, 21, 0, 0}, }; /* 804505A0-804505A8 -00001 0004+04 1/1 3/3 0/0 .sdata mRenderModeObj__15mDoMch_render_c */ GXRenderModeObj* mDoMch_render_c::mRenderModeObj = &g_ntscZeldaIntDf; /* 8000BD44-8000C0CC 006684 0388+00 0/0 2/1 0/0 .text mDoMch_Create__Fv */ // NONMATCHING - small regalloc int mDoMch_Create() { if (mDoMain::developmentMode == 0 || !(OSGetConsoleType() & 0x10000000)) { OSReportDisable(); } JKRHeap::setDefaultDebugFill(mDebugFill); #ifdef DEBUG JKRSetDebugFillNotuse(mDebugFillNotuse); JKRSetDebugFillNew(mDebugFillNew); JKRSetDebugFillDelete(mDebugFillDelete); #endif JFWSystem::setMaxStdHeap(1); #ifndef DEBUG u32 arenaHi = (u32)OSGetArenaHi(); u32 arenaLo =(u32)OSGetArenaLo(); if (arenaHi > 0x81800000 && arenaHi - 0x1800000 > arenaLo) { OSSetArenaHi((void*)(arenaHi - 0x1800000)); } #endif u32 arenaSize = ((u32)OSGetArenaHi() - (u32)OSGetArenaLo()) - 0xF0; my_PrintHeap("アリーナ", arenaSize); if (mDoMain::memMargin != -1) { arenaSize += mDoMain::memMargin; } #ifdef DEBUG u32 uVar14 = 0xf20c00; u32 local_1c = 0x74e000; if (mDoMain::archiveHeapSize == -1) { mDoMain::archiveHeapSize = 0x106ec00; } else { OSReport_Error("アーカイブヒープサイズ指定!\n"); uVar14 = mDoMain::archiveHeapSize; } if (mDoMain::gameHeapSize == -1) { mDoMain::gameHeapSize = 0x74e000; } else { OSReport_Error("ゲームヒープサイズ指定!\n"); local_1c = mDoMain::gameHeapSize; } #endif JFWSystem::setSysHeapSize(arenaSize - 0xDACD30); my_PrintHeap("システムヒープ", arenaSize - 0xDACD30); JFWSystem::setFifoBufSize(0xA0000); JFWSystem::setAramAudioBufSize(0xA00000); JFWSystem::setAramGraphBufSize(-1); if (!(OSGetResetCode() >> 0x1F)) { if (VIGetDTVStatus() == 0) { OSSetProgressiveMode(0); } } else if (mDoRst::getProgSeqFlag() != 0) { if (VIGetDTVStatus() != 0 && mDoMch_IsProgressiveMode()) { mDoMch_render_c::setProgressiveMode(); } } JFWSystem::setRenderMode(mDoMch_render_c::getRenderModeObj()); JFWSystem::firstInit(); JUTDbPrint::start(NULL, mDoExt_createDbPrintHeap(0x1800, JKRHeap::getRootHeap())); mDoExt_createAssertHeap(JKRHeap::getRootHeap()); JFWSystem::init(); if (mDoMain::developmentMode == 0) { JUTAssertion::setVisible(false); JUTDbPrint::getManager()->setVisible(false); } JKRHeap::setErrorHandler(myMemoryErrorRoutine); JKRHeap::getRootHeap()->setErrorFlag(true); JFWSystem::getSystemHeap()->setErrorFlag(true); JKRHeap* rootHeap = JKRGetRootHeap(); // Command Heap size: 4 KB my_SysPrintHeap("コマンドヒープ", mDoExt_createCommandHeap(0x1000, rootHeap), 0x1000); // Archive Heap size: 9085 KB my_SysPrintHeap("アーカイブヒープ", mDoExt_createArchiveHeap(0x8DF400, rootHeap), 0x8DF400); // J2D Heap size: 500 KB my_SysPrintHeap("J2D用ヒープ", mDoExt_createJ2dHeap(0x7D000, rootHeap), 0x7D000); // Game Heap size: 4408 KB my_SysPrintHeap("ゲームヒープ", mDoExt_createGameHeap(0x44E000, rootHeap), 0x44E000); JKRHeap* sysHeap = JKRGetSystemHeap(); u32 zeldaHeapSize = sysHeap->getFreeSize() - 0x10000; JKRHeap* zeldaHeap = mDoExt_createZeldaHeap(zeldaHeapSize, sysHeap); my_SysPrintHeap("ゼルダヒープ", zeldaHeap, zeldaHeapSize); zeldaHeap->becomeCurrentHeap(); JKRAramStream::setTransBuffer(NULL, 0x2000, JKRGetSystemHeap()); JKRThreadSwitch::createManager(NULL); JKRThread* thread = new JKRThread(OSGetCurrentThread(), 0); JUTConsole* sysConsole = JFWSystem::getSystemConsole(); sysConsole->setOutput(JUTConsole::OUTPUT_CONSOLE | JUTConsole::OUTPUT_OSREPORT); sysConsole->setPosition(16, 42); JUTException::appendMapFile("/map/Final/Release/frameworkF.map"); JUTException::setPreUserCallback(myExceptionCallback); JUTException::setPostUserCallback(fault_callback_scroll); cMl::init(mDoExt_getZeldaHeap()); cM_initRnd(100, 100, 100); JKRDvdRipper::setSZSBufferSize(0x4000); JKRDvdAramRipper::setSZSBufferSize(0x4000); JKRAram::setSZSBufferSize(0x2000); mDoDvdThd::create(OSGetThreadPriority(OSGetCurrentThread()) - 2); mDoDvdErr_ThdInit(); mDoMemCd_ThdInit(); return 1; }