diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index f87b3a4b..e8d15920 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -17861,7 +17861,7 @@ Set__7mQuat_cFRC7mVec3_cRC7mVec3_c = .text:0x802F2330; // type:function size:0x1 fn_802F2450__7mQuat_cFRC7mVec3_cRC7mVec3_cf = .text:0x802F2450; // type:function size:0x18C fn_802F25E0 = .text:0x802F25E0; // type:function size:0x19C fn_802F2780__7mQuat_cFRC7mQuat_c = .text:0x802F2780; // type:function size:0x198 -fn_802F2920 = .text:0x802F2920; // type:function size:0x48 +registerThread__7mThreadFP8OSThreadPv = .text:0x802F2920; // type:function size:0x48 createProjectionXZ__7mVec3_cFRC7mAng3_cf = .text:0x802F2970; // type:function size:0x110 mVec__fromXY = .text:0x802F2A80; // type:function size:0xF0 normalize__7mVec3_cFv = .text:0x802F2B70; // type:function size:0x78 @@ -26254,10 +26254,10 @@ switchThreadCallback__Q23EGG6ThreadFP8OSThreadP8OSThread = .text:0x80496C70; // setCommonMesgQueue__Q23EGG6ThreadFiPQ23EGG4Heap = .text:0x80496D60; // type:function size:0x5C start__Q23EGG6ThreadFPv = .text:0x80496DC0; // type:function size:0x10 run__Q23EGG6ThreadFv = .text:0x80496DD0; // type:function size:0x8 scope:weak -FUN_80496de0 = .text:0x80496DE0; // type:function size:0x44 -FUN_80496e30 = .text:0x80496E30; // type:function size:0xD8 -FUN_80496f10 = .text:0x80496F10; // type:function size:0x1CC -FUN_804970e0 = .text:0x804970E0; // type:function size:0x8C +getThreadIndex__Q23EGG13ThreadMonitorFP8OSThread = .text:0x80496DE0; // type:function size:0x44 +doRegisterThread__Q23EGG13ThreadMonitorFP8OSThread = .text:0x80496E30; // type:function size:0xD8 +sortByPriority__Q23EGG13ThreadMonitorFv = .text:0x80496F10; // type:function size:0x1CC +registerThread__Q23EGG13ThreadMonitorFP8OSThreadQ23EGG13UnknownStruct = .text:0x804970E0; // type:function size:0x8C initMemory__Q23EGG17ConfigurationDataFv = .text:0x80497170; // type:function size:0x174 run__Q23EGG17ConfigurationDataFv = .text:0x804972F0; // type:function size:0x23C PreRetraceCallback = .text:0x80497530; // type:function size:0x40 @@ -43334,7 +43334,7 @@ sFreeCallbackArg__Q23EGG4Heap = .sbss:0x80576760; // type:object size:0x4 data:4 sCreateCallback__Q23EGG4Heap = .sbss:0x80576764; // type:object size:0x4 data:4byte sDestroyCallback__Q23EGG4Heap = .sbss:0x80576768; // type:object size:0x4 data:4byte sOldSwitchThreadCallback__Q23EGG6Thread = .sbss:0x80576770; // type:object size:0x4 data:4byte -lbl_80576778 = .sbss:0x80576778; // type:object size:0x8 data:4byte +sInstance__Q23EGG13ThreadMonitor = .sbss:0x80576778; // type:object size:0x4 data:4byte mConfigData__Q23EGG10BaseSystem = .sbss:0x80576780; // type:object size:0x4 data:4byte sTickPeriod__Q23EGG7Display = .sbss:0x80576788; // type:object size:0x4 data:4byte spSelector = .sbss:0x80576790; // type:object size:0x4 scope:local data:4byte diff --git a/configure.py b/configure.py index 313daaba..504b169d 100644 --- a/configure.py +++ b/configure.py @@ -893,7 +893,7 @@ config.libs = [ Object(Matching, "m/m_pad.cpp"), # probably two files due to sdata2 float duplication and gap Object(NonMatching, "m/m_quat.cpp"), - Object(NonMatching, "m/m_thread.cpp"), + Object(Matching, "m/m_thread.cpp"), Object(NonMatching, "m/m_vec.cpp"), Object(NonMatching, "m/m_video.cpp"), ], @@ -1232,7 +1232,7 @@ config.libs = [ Object(Matching, "egg/core/eggAssertHeap.cpp"), Object(Matching, "egg/core/eggDisposer.cpp"), Object(Matching, "egg/core/eggThread.cpp"), - Object(NonMatching, "egg/core/eggUnk.cpp"), + Object(Matching, "egg/core/eggUnk.cpp"), Object(Matching, "egg/core/eggSystem.cpp"), Object(Matching, "egg/core/eggDisplay.cpp"), Object(Matching, "egg/core/eggColorFader.cpp"), diff --git a/include/egg/core/eggUnk.h b/include/egg/core/eggUnk.h index f1ec5c73..4d2eaaa4 100644 --- a/include/egg/core/eggUnk.h +++ b/include/egg/core/eggUnk.h @@ -12,14 +12,54 @@ // with part of that thread referencing tsome of these funcs namespace EGG { -class Unknown { -public: - u8 _[0xfC - 0x00]; // size unsure, but this is the limit seen - void fn_80496de0(OSThread *); - void fn_80496e30(OSThread *); - void fn_80496f10(); - void fn_804970e0(OSThread *, u8 *); + +// Color? Tag? +struct UnknownStruct { + u8 _00; + u8 _01; + u8 _02; + u8 _03; }; + +struct ThreadInfo { + OSThread *mThread; + UnknownStruct _04; + bool _08; + char _09[32]; // Buffer for name? + u32 _2C; +}; + +// This is a complete guess +class ThreadMonitor { +public: + void registerThread(OSThread *thread, UnknownStruct); + + static ThreadMonitor *getInstance() { + return sInstance; + } + +private: + s32 getThreadIndex(OSThread *thread); + s32 doRegisterThread(OSThread *thread); + void sortByPriority(); + +private: + u8 _placeholder_00[0x8]; + /* 0x08 */ s32 mMaxThreads; + u8 _placeholder_0C[0x3C - 0xC]; + /* 0x3C */ ThreadInfo *mThreadList; + u8 _placeholder_40[0x44 - 0x40]; + /* 0x44 */ s32 mThreadCount; + u8 _placeholder_48[0xEC - 0x48]; + /* 0xEC */ UnknownStruct _EC; // Default color/tag? + u8 _placeholder_F0[0xF4 - 0xF0]; + /* 0xF4 */ u32 _F4; + /* 0xF8 */ bool mSortEnabled; + // size unsure, but this is the limit seen + + static ThreadMonitor *sInstance; +}; + } // namespace EGG #endif diff --git a/include/m/m_thread.h b/include/m/m_thread.h index 104c7b69..11ca4fd3 100644 --- a/include/m/m_thread.h +++ b/include/m/m_thread.h @@ -3,4 +3,12 @@ // This file is a complete guess +struct OSThread; + +namespace mThread { + +void registerThread(OSThread *thread, void *threadArg); + +} // namespace mThread + #endif diff --git a/src/egg/core/eggUnk.cpp b/src/egg/core/eggUnk.cpp new file mode 100644 index 00000000..e49285ca --- /dev/null +++ b/src/egg/core/eggUnk.cpp @@ -0,0 +1,73 @@ +#include "egg/core/eggUnk.h" + +#include "rvl/OS.h" + +namespace EGG { + +ThreadMonitor *ThreadMonitor::sInstance; // Never initialized + +s32 ThreadMonitor::getThreadIndex(OSThread *thread) { + for (s32 i = 0; i < mThreadCount; i++) { + if (mThreadList[i].mThread == thread) { + return i; + } + } + return -1; +} + +s32 ThreadMonitor::doRegisterThread(OSThread *thread) { + if (mThreadCount != mMaxThreads) { + s32 i = mThreadCount; + + mThreadList[i].mThread = thread; + mThreadList[i]._04 = _EC; + mThreadList[i]._08 = true; + mThreadList[i]._09[0] = '\0'; + mThreadList[i]._2C = _F4; + + mThreadCount++; + + if (mSortEnabled) { + sortByPriority(); + } + + return getThreadIndex(thread); + } + + return -1; +} + +void ThreadMonitor::sortByPriority() { + // Selection sort on thread priority + for (s32 i = 0; i < mThreadCount - 1; i++) { + OSPriority minPrio = 31; + s32 minPrioIndex = -1; + + for (s32 j = i; j < mThreadCount; j++) { + OSPriority prio = OSGetThreadPriority(mThreadList[j].mThread); + if (prio <= minPrio) { + minPrio = prio; + minPrioIndex = j; + } + } + + if (i != minPrioIndex) { + ThreadInfo temp = mThreadList[i]; + mThreadList[i] = mThreadList[minPrioIndex]; + mThreadList[minPrioIndex] = temp; + } + } +} + +void ThreadMonitor::registerThread(OSThread *thread, UnknownStruct arg) { + s32 i = getThreadIndex(thread); + if (i == -1) { + i = doRegisterThread(thread); + } + + if (i != -1) { + mThreadList[i]._04 = arg; + } +} + +} // namespace EGG diff --git a/src/m/m_thread.cpp b/src/m/m_thread.cpp new file mode 100644 index 00000000..49fd62ba --- /dev/null +++ b/src/m/m_thread.cpp @@ -0,0 +1,10 @@ +#include "m/m_thread.h" + +#include "egg/core/eggUnk.h" +#include "rvl/OS/OSThread.h" + +void mThread::registerThread(OSThread *thread, void *threadArg) { + if (threadArg && EGG::ThreadMonitor::getInstance()) { + EGG::ThreadMonitor::getInstance()->registerThread(thread, *(EGG::UnknownStruct *)threadArg); + } +} diff --git a/src/toBeSorted/nand_request_thread.cpp b/src/toBeSorted/nand_request_thread.cpp index 286a522f..d288fb33 100644 --- a/src/toBeSorted/nand_request_thread.cpp +++ b/src/toBeSorted/nand_request_thread.cpp @@ -4,6 +4,7 @@ #include "egg/core/eggAssertHeap.h" // IWYU pragma: export #include "egg/core/eggThread.h" #include "m/m_heap.h" +#include "m/m_thread.h" #include "rvl/NAND/NANDCheck.h" #include "rvl/NAND/NANDCore.h" #include "rvl/NAND/nand.h" @@ -13,8 +14,6 @@ #include -extern "C" void fn_802F2920(OSThread *, size_t); - NandRequestThread::NandRequestThread( int priority, EGG::Heap *commandHeap, void *bufFromGameHeap, size_t bufSize, void *mThreadArg, EGG::Heap *heap ) @@ -27,7 +26,7 @@ NandRequestThread::NandRequestThread( mBufSize = bufSize; setThreadCurrentHeap(mHeap::g_assertHeap); - fn_802F2920(mOSThread, bufSize); + mThread::registerThread(mOSThread, mThreadArg); OSInitMessageQueue(&mMessageQueue, &mMessageBuffer, 1); OSInitMutex(&mMutex); OSResumeThread(mOSThread);