From 59a3d0020959bbb765e98c80e01eb13963fa74ec Mon Sep 17 00:00:00 2001 From: Jonathan Wase Date: Sun, 6 Dec 2020 06:40:34 +0100 Subject: [PATCH] OS.h and JKRDvdFile (#19) * OS header * JKRFile and JKRDvdFile --- .../JSystem/JKernel/JKRDvdFile/JKRDvdFile.h | 20 +-- include/JSystem/JKernel/JKRFile/JKRFile.h | 8 +- include/JSystem/JKernel/JKRHeap/JKRHeap.h | 6 +- include/JSystem/JKernel/JKRThread/JKRThread.h | 18 +- include/functions.h | 54 +----- include/global.h | 1 + include/os/OS.h | 59 +++++++ include/variables.h | 8 +- libs/JSystem/JKernel/JKRDvdFile.cpp | 161 +++++++++++++----- libs/JSystem/JKernel/JKRFile.cpp | 12 +- libs/JSystem/JKernel/JKRHeap.cpp | 2 +- libs/JSystem/JKernel/JKRThread.cpp | 6 +- 12 files changed, 223 insertions(+), 132 deletions(-) create mode 100644 include/os/OS.h diff --git a/include/JSystem/JKernel/JKRDvdFile/JKRDvdFile.h b/include/JSystem/JKernel/JKRDvdFile/JKRDvdFile.h index d0870c3033b..47eae122157 100644 --- a/include/JSystem/JKernel/JKRDvdFile/JKRDvdFile.h +++ b/include/JSystem/JKernel/JKRDvdFile/JKRDvdFile.h @@ -14,12 +14,12 @@ class JKRDvdFile : public JKRFile { ~JKRDvdFile(); void initiate(void); - void sync(void); + s32 sync(void); static void doneProcess(long, DVDFileInfo*); virtual bool open(char const*); virtual void close(void); - virtual void readData(void*, long, long); + virtual s32 readData(void*, long, long); virtual s32 writeData(void const*, long, long); virtual s32 getFileSize(void) const; virtual bool open(long); @@ -36,9 +36,9 @@ class JKRDvdFile : public JKRFile { return DVDGetCommandBlockStatus(&this->mDvdCommandBlock[0]); } - public: - u8 mMutex1[24]; - u8 mMutex2[24]; + protected: + OSMutex mMutex1; + OSMutex mMutex2; u32 field_0x4c; u32 field_0x50; u32 field_0x54; @@ -48,12 +48,12 @@ class JKRDvdFile : public JKRFile { s32 mFileSize; u32 field_0x94; JKRDvdFile* mDvdFile; - u8 mQueue1[32]; - void* mMessages1[1]; - u8 mQueue2[32]; - void* mMessages2[1]; + OSMessageQueue mQueue1; + OSMessage mMessages1[1]; + OSMessageQueue mQueue2; + OSMessage mMessages2[1]; JSULink mDvdLink; - void* mOSThread; + OSThread* mOSThread; }; #endif diff --git a/include/JSystem/JKernel/JKRFile/JKRFile.h b/include/JSystem/JKernel/JKRFile/JKRFile.h index 3594b481269..bc1e850481c 100644 --- a/include/JSystem/JKernel/JKRFile/JKRFile.h +++ b/include/JSystem/JKernel/JKRFile/JKRFile.h @@ -6,19 +6,19 @@ class JKRFile : public JKRDisposer { public: - JKRFile(); - virtual ~JKRFile(); + JKRFile() : mIsOpen(false) {} + virtual ~JKRFile() {} virtual bool open(const char*); virtual void close(); - virtual void readData(void*, long, long); + virtual s32 readData(void*, long, long); virtual s32 writeData(const void*, long, long); virtual s32 getFileSize(); virtual bool open(long); s32 read(void*, long, long); - private: + protected: bool mIsOpen; u8 field_0x19[3]; }; diff --git a/include/JSystem/JKernel/JKRHeap/JKRHeap.h b/include/JSystem/JKernel/JKRHeap/JKRHeap.h index 48364f52af2..1c1d0433283 100644 --- a/include/JSystem/JKernel/JKRHeap/JKRHeap.h +++ b/include/JSystem/JKernel/JKRHeap/JKRHeap.h @@ -127,11 +127,11 @@ class JKRHeap : public JKRDisposer { } void lock() { - OSLockMutex(this->mMutex); + OSLockMutex(&this->mMutex); } void unlock() { - OSUnlockMutex(this->mMutex); + OSUnlockMutex(&this->mMutex); } public: @@ -158,7 +158,7 @@ class JKRHeap : public JKRDisposer { virtual void state_dump(); public: - u8 mMutex[24]; + OSMutex mMutex; u32 mStart; u32 mEnd; u32 mSize; diff --git a/include/JSystem/JKernel/JKRThread/JKRThread.h b/include/JSystem/JKernel/JKRThread/JKRThread.h index f5b3d6cfa6f..9efba043c4c 100644 --- a/include/JSystem/JKernel/JKRThread/JKRThread.h +++ b/include/JSystem/JKernel/JKRThread/JKRThread.h @@ -3,19 +3,7 @@ #include "dolphin/types.h" #include "JSystem/JKernel/JKRDisposer/JKRDisposer.h" - -struct OSThread { - u8 unkn[0x318]; -}; - -struct OSMessageQueue { - u8 unkn[0x20]; -}; - -typedef void* OSMessage; - -class JKRThread; -extern JSUList lbl_8043428C; // JSUList JKRThread::sThreadList +#include "global.h" class JKRThreadName_; class JUTConsole; @@ -31,7 +19,7 @@ class JKRThread : JKRDisposer { void setCommon_heapSpecified(JKRHeap* heap, u32 stack_size, int param_3); OSThread* getThreadRecord() { - return this->mOsThread; + return this->mOSThread; } static void* start(void* param_1); @@ -45,7 +33,7 @@ class JKRThread : JKRDisposer { public: JSULink mThreadListLink; JKRHeap* mHeap; - OSThread* mOsThread; + OSThread* mOSThread; OSMessageQueue mQueue; OSMessage* mMessages; int mMessageCount; diff --git a/include/functions.h b/include/functions.h index c745b8e2dd2..4e91598ed2e 100644 --- a/include/functions.h +++ b/include/functions.h @@ -212,60 +212,16 @@ extern "C" { void func_80365470(void); } -// OS -struct OSThread; -struct OSMessageQueue; -typedef void* OSMessage; -extern "C" { - void OSInitMutex(u8[24]); - void OSLockMutex(u8[24]); - void OSUnlockMutex(u8[24]); - void OSEnableScheduler(void); - void OSDisableScheduler(void); - void OSCheckActiveThreads(void); - void OSReport_Error(char*,...); - u32 OSGetSoundMode(void); - void OSSuspendThread(void); - void OSSetThreadPriority(void); - void OSResumeThread(void); - void OSGetThreadPriority(void); - void OSGetConsoleType(void); - void OSGetResetCode(void); - void OSAllocFromArenaLo(void); - void OSReportInit(void); - void OSGetCurrentThread(void); - void OSTicksToCalendarTime(void); - - u32 OSGetArenaLo(); - u32 OSGetArenaHi(); - u32 OSInitAlloc(u32 low, u32 high, int param_3); - void OSSetArenaLo(u32 param_1); - void OSSetArenaHi(u32 param_1); - - void OSGetTick(void); - - - void OSCreateThread(OSThread* thread, void* (*func)(void*), void* param, - void* stack, u32 stackSize, int param_6, int param_7); - void OSCancelThread(OSThread* thread); - void OSDetachThread(OSThread* thread); - bool OSIsThreadSuspended(OSThread* thread); - bool OSIsThreadTerminated(OSThread* thread); - void OSInitMessageQueue(OSMessageQueue *queue, OSMessage* messages, int message_count); - void OSSetSwitchThreadCallback(void); - void OSReceiveMessage(void); - void OSSendMessage(void); -} - // DVD +class DVDFileInfo; extern "C" { - void DVDOpen(void); - void DVDClose(void); + s32 DVDOpen(const char*, u8[48]); + s32 DVDClose(u8[48]); void DVDReadPrio(void); void DVDGetCurrentDiskID(void); - void DVDFastOpen(void); + s32 DVDFastOpen(long, u8[48]); int DVDGetCommandBlockStatus(u8[48]); - void DVDReadAsyncPrio(void); + s32 DVDReadAsyncPrio(u8[48], void*, long, long, void(*)(long,DVDFileInfo*), long); void DVDConvertPathToEntrynum(void); void DVDChangeDir(void); diff --git a/include/global.h b/include/global.h index 10e453b8d9c..a3672634fed 100644 --- a/include/global.h +++ b/include/global.h @@ -5,6 +5,7 @@ #include "dolphin/types.h" +#include "os/OS.h" #include "functions.h" #include "variables.h" diff --git a/include/os/OS.h b/include/os/OS.h new file mode 100644 index 00000000000..709347d7a70 --- /dev/null +++ b/include/os/OS.h @@ -0,0 +1,59 @@ +#ifndef __OS_H_ +#define __OS_H_ + +struct OSThread { + u8 unkn[0x318]; +}; + +struct OSMessageQueue { + u8 unkn[0x20]; +}; + +struct OSMutex { + u8 unkn[24]; +}; + +typedef void* OSMessage; +extern "C" { + void OSInitMutex(OSMutex*); + void OSLockMutex(OSMutex*); + void OSUnlockMutex(OSMutex*); + void OSEnableScheduler(void); + void OSDisableScheduler(void); + void OSCheckActiveThreads(void); + void OSReport_Error(char*,...); + u32 OSGetSoundMode(void); + void OSSuspendThread(void); + void OSSetThreadPriority(void); + void OSResumeThread(void); + void OSGetThreadPriority(void); + void OSGetConsoleType(void); + void OSGetResetCode(void); + void OSAllocFromArenaLo(void); + void OSReportInit(void); + OSThread* OSGetCurrentThread(void); + void OSTicksToCalendarTime(void); + + u32 OSGetArenaLo(); + u32 OSGetArenaHi(); + u32 OSInitAlloc(u32 low, u32 high, int param_3); + void OSSetArenaLo(u32 param_1); + void OSSetArenaHi(u32 param_1); + + void OSGetTick(void); + + + void OSCreateThread(OSThread* thread, void* (*func)(void*), void* param, + void* stack, u32 stackSize, int param_6, int param_7); + void OSCancelThread(OSThread* thread); + void OSDetachThread(OSThread* thread); + bool OSIsThreadSuspended(OSThread* thread); + bool OSIsThreadTerminated(OSThread* thread); + void OSInitMessageQueue(OSMessageQueue *queue, OSMessage* messages, int message_count); + void OSSetSwitchThreadCallback(void); + void OSReceiveMessage(OSMessageQueue *queue, OSMessage message, int flags); + void OSSendMessage(OSMessageQueue *queue, OSMessage message, int flags); +} + + +#endif \ No newline at end of file diff --git a/include/variables.h b/include/variables.h index 4b7a0b08e16..43e9cfb5b8b 100644 --- a/include/variables.h +++ b/include/variables.h @@ -213,7 +213,7 @@ class JKRDvdFile; extern JSUList lbl_8043436C; // JKRDvdFile::sDvdList extern u8 lbl_803CC438; // JKRDvdFile::__vt extern u8 lbl_80434360; // JKernel::@657 (global destructor chain) -extern u8 lbl_8039D260; // "JKRDvdFile.cpp" +extern char lbl_8039D260[12]; // "JKRDvdFile.cpp" extern u8 lbl_803CC328; // JKRFile::__vt class JKRFileLoader; @@ -258,4 +258,8 @@ struct unkEvent{ //figure out what this is later u8 unk567[0x439]; }; extern unkEvent lbl_803A7288; -extern u8 lbl_8037B0D0[0x8]; \ No newline at end of file +extern u8 lbl_8037B0D0[0x8]; + +class JKRThread; +extern JSUList lbl_8043428C; // JSUList JKRThread::sThreadList + diff --git a/libs/JSystem/JKernel/JKRDvdFile.cpp b/libs/JSystem/JKernel/JKRDvdFile.cpp index 60826fe35e8..ec3d64c16c5 100644 --- a/libs/JSystem/JKernel/JKRDvdFile.cpp +++ b/libs/JSystem/JKernel/JKRDvdFile.cpp @@ -1,68 +1,145 @@ #include "JSystem/JKernel/JKRDvdFile/JKRDvdFile.h" #include "global.h" - -asm JKRDvdFile::JKRDvdFile(void) { - nofralloc - #include "JSystem/JKernel/JKRDvdFile/asm/func_802D9584.s" +// #include "JSystem/JKernel/JKRDvdFile/asm/func_802D9584.s" +JKRDvdFile::JKRDvdFile() : JKRFile(), mDvdLink(this) { + this->initiate(); } -asm JKRDvdFile::JKRDvdFile(char const *) { +#ifdef NONMATCHING +JKRDvdFile::JKRDvdFile(char const* param_1) : JKRFile(), mDvdLink(this) { + this->initiate(); + bool result = this->open(param_1); + this->mIsOpen = result; +} +#else +asm JKRDvdFile::JKRDvdFile(char const*) { nofralloc - #include "JSystem/JKernel/JKRDvdFile/asm/func_802D95F8.s" +#include "JSystem/JKernel/JKRDvdFile/asm/func_802D95F8.s" +} +#endif + +#ifdef NONMATHCING +JKRDvdFile::JKRDvdFile(long param_1) : JKRFile(), mDvdLink(this) { + this->initiate(); + bool result = this->open(param_1); + this->mIsOpen = result; +} +#else +asm JKRDvdFile::JKRDvdFile(long) { + nofralloc +#include "JSystem/JKernel/JKRDvdFile/asm/func_802D96A0.s" +} +#endif + +// #include "JSystem/JKernel/JKRDvdFile/asm/func_802D9748.s" +JKRDvdFile::~JKRDvdFile() { + this->close(); } -asm JKRDvdFile::JKRDvdFile(long) { - nofralloc - #include "JSystem/JKernel/JKRDvdFile/asm/func_802D96A0.s" +// #include "JSystem/JKernel/JKRDvdFile/asm/func_802D97E4.s" +void JKRDvdFile::initiate(void) { + this->mDvdFile = this; + OSInitMutex(&this->mMutex1); + OSInitMutex(&this->mMutex2); + OSInitMessageQueue(&this->mQueue2, this->mMessages2, 1); + OSInitMessageQueue(&this->mQueue1, this->mMessages1, 1); + this->mOSThread = NULL; + this->field_0x50 = 0; + this->field_0x58 = 0; } -asm JKRDvdFile::~JKRDvdFile() { - nofralloc - #include "JSystem/JKernel/JKRDvdFile/asm/func_802D9748.s" +// #include "JSystem/JKernel/JKRDvdFile/asm/func_802D9850.s" +bool JKRDvdFile::open(char const* param_1) { + if (!this->mIsOpen) { + this->mIsOpen = DVDOpen(param_1, this->mDvdCommandBlock); + if (this->mIsOpen) { + lbl_8043436C.append(&this->mDvdLink); + this->getStatus(); + } + } + return this->mIsOpen; } -asm void JKRDvdFile::initiate(void) { - nofralloc - #include "JSystem/JKernel/JKRDvdFile/asm/func_802D97E4.s" +// #include "JSystem/JKernel/JKRDvdFile/asm/func_802D98C4.s" +bool JKRDvdFile::open(long param_1) { + if (!this->mIsOpen) { + this->mIsOpen = DVDFastOpen(param_1, this->mDvdCommandBlock); + if (this->mIsOpen) { + lbl_8043436C.append(&this->mDvdLink); + this->getStatus(); + } + } + return this->mIsOpen; } -asm bool JKRDvdFile::open(char const *) { - nofralloc - #include "JSystem/JKernel/JKRDvdFile/asm/func_802D9850.s" +// #include "JSystem/JKernel/JKRDvdFile/asm/func_802D9938.s" +void JKRDvdFile::close() { + if (this->mIsOpen) { + s32 result = DVDClose(this->mDvdCommandBlock); + if (result != 0) { + this->mIsOpen = false; + lbl_8043436C.remove(&this->mDvdLink); + } else { + const char* filename = lbl_8039D260; // "JKRDvdFile.cpp" + const char* format = lbl_8039D260 + 0x0F; // "%s" + const char* arg1 = lbl_8039D260 + 0x12; // "cannot close DVD file\n" + JUTException_NS_panic_f(filename, 0xd5, format, arg1); + } + } } -asm bool JKRDvdFile::open(long) { - nofralloc - #include "JSystem/JKernel/JKRDvdFile/asm/func_802D98C4.s" +#define JUT_ASSERT(CONDITION) + +//#include "JSystem/JKernel/JKRDvdFile/asm/func_802D99B4.s" +s32 JKRDvdFile::readData(void* param_1, long length, long param_3) { + JUT_ASSERT((length & 0x1f) == 0); + + OSLockMutex(&this->mMutex1); + if (this->mOSThread) { + OSUnlockMutex(&this->mMutex1); + return -1; + } + + this->mOSThread = OSGetCurrentThread(); + + s32 result = -1; + s32 readAsyncResult = + DVDReadAsyncPrio(this->mDvdCommandBlock, param_1, length, param_3, JKRDvdFile::doneProcess, 2); + if (readAsyncResult) { + result = this->sync(); + } + + this->mOSThread = NULL; + OSUnlockMutex(&this->mMutex1); + + return result; } -asm void JKRDvdFile::close(void) { - nofralloc - #include "JSystem/JKernel/JKRDvdFile/asm/func_802D9938.s" +// #include "JSystem/JKernel/JKRDvdFile/asm/func_802D9A68.s" +s32 JKRDvdFile::writeData(void const*, long, long) { + return -1; } -asm void JKRDvdFile::readData(void *, long, long) { - nofralloc - #include "JSystem/JKernel/JKRDvdFile/asm/func_802D99B4.s" +// #include "JSystem/JKernel/JKRDvdFile/asm/func_802D9A70.s" +s32 JKRDvdFile::sync(void) { + OSMessage message; + OSLockMutex(&this->mMutex1); + OSReceiveMessage(&this->mQueue2, &message, 1); + this->mOSThread = NULL; + OSUnlockMutex(&this->mMutex1); + return (int)message; } -asm s32 JKRDvdFile::writeData(void const *, long, long) { - nofralloc - #include "JSystem/JKernel/JKRDvdFile/asm/func_802D9A68.s" +// #include "JSystem/JKernel/JKRDvdFile/asm/func_802D9AC4.s" +void JKRDvdFile::doneProcess(long id, DVDFileInfo* fileInfo) { + // fileInfo->field_0x3c looks like some kind of user pointer? + JKRDvdFile* dvdFile = *(JKRDvdFile**)((u8*)fileInfo + 0x3c); + OSSendMessage(&dvdFile->mQueue2, (OSMessage)id, 0); } -asm void JKRDvdFile::sync(void) { - nofralloc - #include "JSystem/JKernel/JKRDvdFile/asm/func_802D9A70.s" +// #include "JSystem/JKernel/JKRDvdFile/asm/func_802D9AF8.s" +s32 JKRDvdFile::getFileSize(void) const { + return this->mFileSize; } -asm void JKRDvdFile::doneProcess(long, DVDFileInfo *) { - nofralloc - #include "JSystem/JKernel/JKRDvdFile/asm/func_802D9AC4.s" -} - -asm s32 JKRDvdFile::getFileSize(void) const { - nofralloc - #include "JSystem/JKernel/JKRDvdFile/asm/func_802D9AF8.s" -} diff --git a/libs/JSystem/JKernel/JKRFile.cpp b/libs/JSystem/JKernel/JKRFile.cpp index 3741982af09..9565d7d5871 100644 --- a/libs/JSystem/JKernel/JKRFile.cpp +++ b/libs/JSystem/JKernel/JKRFile.cpp @@ -1,8 +1,14 @@ #include "JSystem/JKernel/JKRFile/JKRFile.h" #include "global.h" -asm s32 JKRFile::read(void *, long, long) { - nofralloc - #include "JSystem/JKernel/JKRFile/asm/func_802D9518.s" +// #include "JSystem/JKernel/JKRFile/asm/func_802D9518.s" +s32 JKRFile::read(void* data, s32 size, long param_3) { + while (true) { + s32 result = this->readData(data, size, param_3); + if (size != result) + VIWaitForRetrace(); + else + return result; + } } diff --git a/libs/JSystem/JKernel/JKRHeap.cpp b/libs/JSystem/JKernel/JKRHeap.cpp index e905f1f52ff..1b1d3d3c16b 100644 --- a/libs/JSystem/JKernel/JKRHeap.cpp +++ b/libs/JSystem/JKernel/JKRHeap.cpp @@ -4,7 +4,7 @@ // #include "JSystem/JKernel/JKRHeap/asm/func_802CE138.s" JKRHeap::JKRHeap(void* data, u32 size, JKRHeap* parent, bool error_flag) : JKRDisposer(), mChildTree(this), mDisposerList() { - OSInitMutex(this->mMutex); + OSInitMutex(&this->mMutex); this->mSize = size; this->mStart = (u32)data; this->mEnd = (u32)data + size; diff --git a/libs/JSystem/JKernel/JKRThread.cpp b/libs/JSystem/JKernel/JKRThread.cpp index 6ea9de3abb5..b7ce3ce7949 100644 --- a/libs/JSystem/JKernel/JKRThread.cpp +++ b/libs/JSystem/JKernel/JKRThread.cpp @@ -62,10 +62,10 @@ void JKRThread::setCommon_heapSpecified(JKRHeap* heap, u32 stack_size, int param this->mHeap = heap; this->mStackSize = stack_size & 0xffffffe0; this->mStackPtr = JKRHeap::alloc(this->mStackSize, 0x20, this->mHeap); - this->mOsThread = (OSThread*)JKRHeap::alloc(sizeof(OSThread), 0x20, this->mHeap); + this->mOSThread = (OSThread*)JKRHeap::alloc(sizeof(OSThread), 0x20, this->mHeap); void* stackBase = (void*)((int)this->mStackPtr + this->mStackSize); - OSCreateThread(this->mOsThread, start, this, stackBase, this->mStackSize, param_3, 1); + OSCreateThread(this->mOSThread, start, this, stackBase, this->mStackSize, param_3, 1); } // #include "JSystem/JKernel/JKRThread/asm/func_802D1934.s" @@ -81,7 +81,7 @@ JKRThread* JKRThread::searchThread(OSThread* thread) { JSUListIterator iterator; for (iterator = threadList; iterator != threadList->getEnd(); iterator++) { JKRThread* jkrThread = iterator.getObject(); - if (jkrThread->mOsThread == thread) { + if (jkrThread->mOSThread == thread) { return jkrThread; } }