diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 7fefadea..30a5435f 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -261,7 +261,8 @@ egg/core/eggAllocator.cpp: egg/core/eggHeap.cpp: .text start:0x804953F0 end:0x80495AB0 .data start:0x8056E8E8 end:0x8056E980 - .sbss start:0x80576740 end:0x80576770 + .sdata start:0x80574ED8 end:0x80574EE8 + .sbss start:0x80576740 end:0x8057676C .bss start:0x80673AE8 end:0x80673B10 egg/core/eggExpHeap.cpp: diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 669414f7..b04afa94 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -2212,7 +2212,7 @@ fn_80054550 = .text:0x80054550; // type:function size:0x31C fn_80054870 = .text:0x80054870; // type:function size:0x25C fn_80054AD0 = .text:0x80054AD0; // type:function size:0x10 fn_80054AE0 = .text:0x80054AE0; // type:function size:0x14 -fn_80054B00 = .text:0x80054B00; // type:function size:0x40 +__dt__5dHeapFv = .text:0x80054B00; // type:function size:0x40 fn_80054B40 = .text:0x80054B40; // type:function size:0x20 init__5dHeapFPCcUlPQ23EGG4Heap = .text:0x80054B60; // type:function size:0x64 createWork1Heap__5dHeapFUlPQ23EGG4Heap = .text:0x80054BD0; // type:function size:0x18 @@ -21996,9 +21996,9 @@ fn_803AA830 = .text:0x803AA830; // type:function size:0x18 BATConfig = .text:0x803AA850; // type:function size:0x120 scope:local fn_803AA970 = .text:0x803AA970; // type:function size:0x44 __OSInitMemoryProtection = .text:0x803AA9C0; // type:function size:0xCC scope:global -fn_803AAA90 = .text:0x803AAA90; // type:function size:0x38 -fn_803AAAD0 = .text:0x803AAAD0; // type:function size:0xDC -fn_803AABB0 = .text:0x803AABB0; // type:function size:0xC8 +OSInitMutex = .text:0x803AAA90; // type:function size:0x38 +OSLockMutex = .text:0x803AAAD0; // type:function size:0xDC +OSUnlockMutex = .text:0x803AABB0; // type:function size:0xC8 fn_803AAC80 = .text:0x803AAC80; // type:function size:0x6C fn_803AACF0 = .text:0x803AACF0; // type:function size:0xBC fn_803AADB0 = .text:0x803AADB0; // type:function size:0x6C @@ -22033,7 +22033,7 @@ fn_803AC380 = .text:0x803AC380; // type:function size:0x4 fn_803AC390 = .text:0x803AC390; // type:function size:0x70 __OSThreadInit = .text:0x803AC400; // type:function size:0x284 scope:global OSInitThreadQueue = .text:0x803AC690; // type:function size:0x10 scope:global -fn_803AC6A0 = .text:0x803AC6A0; // type:function size:0xC +OSGetCurrentThread = .text:0x803AC6A0; // type:function size:0xC fn_803AC6B0 = .text:0x803AC6B0; // type:function size:0x2C OSDisableScheduler = .text:0x803AC6E0; // type:function size:0x3C scope:global OSEnableScheduler = .text:0x803AC720; // type:function size:0x3C scope:global @@ -22562,7 +22562,7 @@ fn_803CC1F0 = .text:0x803CC1F0; // type:function size:0x14C fn_803CC340 = .text:0x803CC340; // type:function size:0x1C0 fn_803CC500 = .text:0x803CC500; // type:function size:0x16C fn_803CC670 = .text:0x803CC670; // type:function size:0x140 -fn_803CC7B0 = .text:0x803CC7B0; // type:function size:0x18C +MEMFindContainHeap = .text:0x803CC7B0; // type:function size:0x18C fn_803CC940 = .text:0x803CC940; // type:function size:0x22C fn_803CCB70 = .text:0x803CCB70; // type:function size:0xDC fn_803CCC50 = .text:0x803CCC50; // type:function size:0xC8 @@ -22588,7 +22588,7 @@ fn_803CDA40 = .text:0x803CDA40; // type:function size:0x84 fn_803CDAD0 = .text:0x803CDAD0; // type:function size:0xD0 fn_803CDBA0 = .text:0x803CDBA0; // type:function size:0x10 fn_803CDBB0 = .text:0x803CDBB0; // type:function size:0x8 -fn_803CDBC0 = .text:0x803CDBC0; // type:function size:0x10 +MEMAllocFromAllocator = .text:0x803CDBC0; // type:function size:0x10 fn_803CDBD0 = .text:0x803CDBD0; // type:function size:0x10 fn_803CDBE0 = .text:0x803CDBE0; // type:function size:0x1C fn_803CDC00 = .text:0x803CDC00; // type:function size:0x18 @@ -26204,11 +26204,11 @@ dump__Q23EGG4HeapFv = .text:0x804958A0; // type:function size:0x4 dumpAll__Q23EGG4HeapFv = .text:0x804958B0; // type:function size:0xEC becomeCurrentHeap__Q23EGG4HeapFv = .text:0x804959A0; // type:function size:0x58 _becomeCurrentHeapWithoutLock__Q23EGG4HeapFv = .text:0x80495A00; // type:function size:0x3C -initAllocator__Q23EGG4HeapFPQ23EGG9Allocatorl = .text:0x80495A40; // type:function size:0x14 +initAllocator__Q23EGG4HeapFPQ23EGG9Allocatori = .text:0x80495A40; // type:function size:0x14 __nw__FUlPv = .text:0x80495A60; // type:function size:0x8 -__nw__FUlPQ23EGG4Heapi = .text:0x80495A70; // type:function size:0x10 -__nwa__FUl = .text:0x80495A80; // type:function size:0x10 -__nwa__FUli = .text:0x80495A90; // type:function size:0x8 +__nw__FUlPQ23EGG4HeapUi = .text:0x80495A70; // type:function size:0x10 +__nw__FUlPQ23EGG9Allocator = .text:0x80495A80; // type:function size:0x10 +__nwa__FUlUi = .text:0x80495A90; // type:function size:0x8 __nwa__FUlPQ23EGG4Heapi = .text:0x80495AA0; // type:function size:0x10 __ct__Q23EGG7ExpHeapFP12MEMiHeapHead = .text:0x80495AB0; // type:function size:0x3C __dt__Q23EGG7ExpHeapFv = .text:0x80495AF0; // type:function size:0x74 @@ -37096,7 +37096,7 @@ lbl_8056E8A0 = .data:0x8056E8A0; // type:object size:0x18 lbl_8056E8B8 = .data:0x8056E8B8; // type:object size:0x18 lbl_8056E8D0 = .data:0x8056E8D0; // type:object size:0x18 lbl_8056E8E8 = .data:0x8056E8E8; // type:object size:0x68 -lbl_8056E950 = .data:0x8056E950; // type:object size:0x30 +__vt__Q23EGG4Heap = .data:0x8056E950; // type:object size:0x30 lbl_8056E980 = .data:0x8056E980; // type:object size:0x10 lbl_8056E990 = .data:0x8056E990; // type:object size:0x10 lbl_8056E9A0 = .data:0x8056E9A0; // type:object size:0x30 @@ -39735,7 +39735,7 @@ layoutExHeap__5dHeap = .sbss:0x805751B8; // type:object size:0x4 data:4byte layoutEx2Heap__5dHeap = .sbss:0x805751BC; // type:object size:0x4 data:4byte layoutResHeap__5dHeap = .sbss:0x805751C0; // type:object size:0x4 data:4byte fontHeap__5dHeap = .sbss:0x805751C4; // type:object size:0x4 data:4byte -HBMHeap__5dHeap = .sbss:0x805751C8; // type:object size:0x8 data:4byte +HBMHeap__5dHeap = .sbss:0x805751C8; // type:object size:0x4 data:4byte lbl_805751D0 = .sbss:0x805751D0; // type:object size:0x8 data:4byte lbl_805751D8 = .sbss:0x805751D8; // type:object size:0x4 data:4byte lbl_805751DC = .sbss:0x805751DC; // type:object size:0x4 data:4byte @@ -40880,16 +40880,16 @@ lbl_80576728 = .sbss:0x80576728; // type:object size:0x8 data:byte lbl_80576730 = .sbss:0x80576730; // type:object size:0x8 data:byte lbl_80576738 = .sbss:0x80576738; // type:object size:0x8 data:4byte sCurrentHeap__Q23EGG4Heap = .sbss:0x80576740; // type:object size:0x4 data:4byte -lbl_80576744 = .sbss:0x80576744; // type:object size:0x4 data:4byte -lbl_80576748 = .sbss:0x80576748; // type:object size:0x4 data:4byte -lbl_8057674C = .sbss:0x8057674C; // type:object size:0x4 data:4byte -lbl_80576750 = .sbss:0x80576750; // type:object size:0x4 data:4byte -lbl_80576754 = .sbss:0x80576754; // type:object size:0x4 data:4byte -lbl_80576758 = .sbss:0x80576758; // type:object size:0x4 data:4byte -lbl_8057675C = .sbss:0x8057675C; // type:object size:0x4 data:4byte -lbl_80576760 = .sbss:0x80576760; // type:object size:0x4 data:4byte -lbl_80576764 = .sbss:0x80576764; // type:object size:0x4 data:4byte -lbl_80576768 = .sbss:0x80576768; // type:object size:0x8 data:4byte +sIsHeapListInitialized__Q23EGG4Heap = .sbss:0x80576744; // type:object size:0x4 data:4byte +sAllocatableHeap__Q23EGG4Heap = .sbss:0x80576748; // type:object size:0x4 data:4byte +sErrorCallback__Q23EGG4Heap = .sbss:0x8057674C; // type:object size:0x4 data:4byte +sAllocCallback__Q23EGG4Heap = .sbss:0x80576750; // type:object size:0x4 data:4byte +sFreeCallback__Q23EGG4Heap = .sbss:0x80576754; // type:object size:0x4 data:4byte +sErrorCallbackArg__Q23EGG4Heap = .sbss:0x80576758; // type:object size:0x4 data:4byte +sAllocCallbackArg__Q23EGG4Heap = .sbss:0x8057675C; // type:object size:0x4 data:4byte +sFreeCallbackArg__Q23EGG4Heap = .sbss:0x80576760; // type:object size:0x4 data:4byte +sCreateCallback__Q23EGG4Heap = .sbss:0x80576764; // type:object size:0x4 data:4byte +sDestroyCallback__Q23EGG4Heap = .sbss:0x80576768; // type:object size:0x4 data:4byte lbl_80576770 = .sbss:0x80576770; // type:object size:0x8 data:4byte lbl_80576778 = .sbss:0x80576778; // type:object size:0x8 data:4byte mConfigData__Q23EGG10BaseSystem = .sbss:0x80576780; // type:object size:0x4 data:4byte @@ -49345,8 +49345,8 @@ lbl_80673A8C = .bss:0x80673A8C; // type:object size:0x1C data:byte lbl_80673AA8 = .bss:0x80673AA8; // type:object size:0x20 data:float lbl_80673AC8 = .bss:0x80673AC8; // type:object size:0x10 lbl_80673AD8 = .bss:0x80673AD8; // type:object size:0x10 -lbl_80673AE8 = .bss:0x80673AE8; // type:object size:0x10 -lbl_80673AF8 = .bss:0x80673AF8; // type:object size:0x18 +sHeapList__Q23EGG4Heap = .bss:0x80673AE8; // type:object size:0xC +sRootMutex__Q23EGG4Heap = .bss:0x80673AF8; // type:object size:0x18 lbl_80673B10 = .bss:0x80673B10; // type:object size:0x10 clear_z_tobj__29@unnamed@eggAsyncDisplay_cpp@ = .bss:0x80673B20; // type:object size:0x20 scope:local lbl_80673B40 = .bss:0x80673B40; // type:object size:0x10C0 data:4byte diff --git a/include/egg/core/eggHeap.h b/include/egg/core/eggHeap.h index 10b114e9..4d61a44a 100644 --- a/include/egg/core/eggHeap.h +++ b/include/egg/core/eggHeap.h @@ -101,7 +101,7 @@ public: /* 804957c0 */ static void free(void *memBlock, Heap *heap); /* 80495830 */ void dispose(); /* 804958a0 */ void dump(); - /* 804958b0 */ void dumpAll(); + /* 804958b0 */ static void dumpAll(); /* 804959a0 */ Heap *becomeCurrentHeap(); /* 80495a00 */ Heap *_becomeCurrentHeapWithoutLock(); @@ -138,6 +138,11 @@ public: inline int getArenaEnd() { return (int)mHeapHandle->end; } + + inline const char *getName() { + return mName; + } + /* 80673ae8 */ static nw4r::ut::List sHeapList; /* 80673af8 */ static OSMutex sRootMutex; /* 80576740 */ static Heap *sCurrentHeap; diff --git a/include/egg/prim/eggBitFlag.h b/include/egg/prim/eggBitFlag.h index 13e6c5f9..f9a9a4ae 100644 --- a/include/egg/prim/eggBitFlag.h +++ b/include/egg/prim/eggBitFlag.h @@ -14,9 +14,8 @@ public: inline void makeAllZero() { value = T(); } - inline TBitFlag() { - makeAllZero(); - } + inline TBitFlag() {} + inline TBitFlag(T value): value(value) {} inline T makeMask(u8 bit) const { return 1 << bit; } diff --git a/src/egg/core/eggColorFader.cpp b/src/egg/core/eggColorFader.cpp index f4207cf5..a0f9863b 100644 --- a/src/egg/core/eggColorFader.cpp +++ b/src/egg/core/eggColorFader.cpp @@ -6,7 +6,7 @@ /* 80497930 */ EGG::ColorFader::ColorFader(float startX, float startY, float lengthX, float lengthY, nw4r::ut::Color color, Fader::EStatus initialStatus) - : mStartX(startX), mStartY(startY), mEndX(startX + lengthX), mEndY(startY + lengthY), mFrame(0x14), mFadeTimer(0) { + : mStartX(startX), mStartY(startY), mEndX(startX + lengthX), mEndY(startY + lengthY), mFrame(0x14), mFadeTimer(0), mFlags(0) { setColor(color); setStatus(initialStatus); mFlags.setBit(1); diff --git a/src/egg/core/eggDisplay.cpp b/src/egg/core/eggDisplay.cpp index 16031605..6fb5b0f5 100644 --- a/src/egg/core/eggDisplay.cpp +++ b/src/egg/core/eggDisplay.cpp @@ -16,13 +16,13 @@ u32 Display::sTickPeriod = ((OS_BUS_CLOCK_SPEED >> 2)/125000)*300 >> 3; /* 80497570 */ Display::Display(u8 maxRetrace) : mMaxRetraces(maxRetrace), - mScreenStateFlag(), + mScreenStateFlag(0), mRetraceCount(0), mFrameCount(0), mClearColor(0x808080ff), mClearZ(0xFFFFFF), mBeginTick(0), - mFlag() + mFlag(0) { mFlag.setBit(mFlag_SetClear); mFlag.setBit(mFlag_WaitForRetrace); @@ -99,4 +99,4 @@ void Display::calcFrequency() { mBeginTick = endTick; } -} // namespace EGG \ No newline at end of file +} // namespace EGG diff --git a/src/egg/core/eggHeap.cpp b/src/egg/core/eggHeap.cpp new file mode 100644 index 00000000..620b9e95 --- /dev/null +++ b/src/egg/core/eggHeap.cpp @@ -0,0 +1,207 @@ +#include +#include +#include + +namespace EGG { + +/* 80673ae8 */ nw4r::ut::List Heap::sHeapList; +/* 80673af8 */ OSMutex Heap::sRootMutex; +/* 80576740 */ Heap *Heap::sCurrentHeap; +/* 80576744 */ int Heap::sIsHeapListInitialized; +/* 80576748 */ Heap *Heap::sAllocatableHeap; +/* 8057674c */ ErrorCallback Heap::sErrorCallback; +/* 80576750 */ HeapAllocCallback Heap::sAllocCallback; +/* 80576754 */ HeapFreeCallback Heap::sFreeCallback; +/* 80576758 */ void *Heap::sErrorCallbackArg; +/* 8057675c */ void *Heap::sAllocCallbackArg; +/* 80576760 */ void *Heap::sFreeCallbackArg; +/* 80576764 */ HeapCreateCallback Heap::sCreateCallback; +/* 80576764 */ HeapDestroyCallback Heap::sDestroyCallback; + +/* 804953f0 */ void Heap::initialize() { + nw4r::ut::List_Init(&sHeapList, 0x1c /* todo offsetof() */); + OSInitMutex(&sRootMutex); + sIsHeapListInitialized = true; +} + +/* 80495430 */ Heap::Heap(MEMiHeapHead *head) : mHeapHandle(head), mParentBlock(nullptr), mName("NoName"), mFlag() { + mFlag.value = 0; + nw4r::ut::List_Init(&mChildren, 0x8 /* todo offsetof() */); + OSLockMutex(&sRootMutex); + nw4r::ut::List_Append(&sHeapList, this); + OSUnlockMutex(&sRootMutex); +} + +/* 804954c0 */ Heap::~Heap() { + OSLockMutex(&sRootMutex); + nw4r::ut::List_Remove(&sHeapList, this); + OSUnlockMutex(&sRootMutex); +} + +/* 80495560 */ void *Heap::alloc(size_t size, s32 align, Heap *heap) { + Heap *currentHeap = sCurrentHeap; + Thread *thread = Thread::findThread(OSGetCurrentThread()); + Heap *threadHeap = nullptr; + + if (thread != nullptr && (threadHeap = thread->mAllocatableHeap, threadHeap != nullptr)) { + heap = threadHeap; + } + if (sAllocatableHeap != nullptr) { + if (heap == nullptr) { + heap = currentHeap; + } + if (heap != sAllocatableHeap) { + // TODO small instshuffle here, related to regshuffle problems + OSReport("cannot allocate from heap %x(%s) : allocatable heap is %x(%s)\n", heap, heap->getName(), + sAllocatableHeap, sAllocatableHeap->getName()); + OSReport("\tthread heap=%x(%s)\n", threadHeap, + threadHeap != nullptr ? threadHeap->getName() : "none"); + if (sErrorCallback != nullptr) { + HeapErrorArg arg; + arg.msg = "disable_but"; + arg.userdata = sErrorCallbackArg; + sErrorCallback(&arg); + } + dumpAll(); + return nullptr; + } + } + + if (heap == nullptr) { + heap = currentHeap; + } + void *ptr = nullptr; + if (heap) { + ptr = heap->alloc(size, align); + } + return ptr; +} + +/* 80495690 */ Heap *Heap::findHeap(MEMiHeapHead *head) { + Heap *heap = nullptr; + OSLockMutex(&sRootMutex); + if (sIsHeapListInitialized) { + Heap *heap2 = nullptr; + while ((heap2 = (Heap *)nw4r::ut::List_GetNext(&sHeapList, heap2))) { + if (heap2->mHeapHandle == head) { + heap = heap2; + break; + } + } + } + OSUnlockMutex(&sRootMutex); + return heap; +} + +/* 80495730 */ Heap *Heap::findParentHeap() { + Heap *retHeap = nullptr; + MEMiHeapHead *heap = MEMFindContainHeap(mHeapHandle); + if (heap) { + retHeap = findHeap(heap); + } + + return retHeap; +} + +extern "C" MEMiHeapHead *fn_803CC670(const void *memBlock); + +/* 80495780 */ Heap *Heap::findContainHeap(const void *memBlock) { + Heap *retHeap = nullptr; + MEMiHeapHead *heap = fn_803CC670(memBlock); + if (heap) { + retHeap = findHeap(heap); + } + + return retHeap; +} + +/* 804957c0 */ void Heap::free(void *ptr, Heap *heap) { + if (heap == nullptr) { + MEMiHeapHead *iheap = fn_803CC670(ptr); + if (iheap == nullptr) { + return; + } + heap = findHeap(iheap); + if (heap == nullptr) { + return; + } + } + + heap->free(ptr); +} + +/* 80495830 */ void Heap::dispose() { + mFlag.setBit(1); + Heap *heap; + while ((heap = (Heap *)nw4r::ut::List_GetFirst(&mChildren)) != nullptr) { + heap->~Heap(); + } + mFlag.resetBit(1); +} + +/* 804958a0 */ void Heap::dump() {} + +// TODO: This debugging function with stripped out error reports doesn't match yet +/* 804958b0 */ void Heap::dumpAll() { + u32 mem[2] = {0, 0}; + + OSLockMutex(&sRootMutex); + for (Heap *heap = nullptr; heap != nullptr; heap = (Heap *)nw4r::ut::List_GetNext(&sHeapList, &heap)) { + Heap *childHeap = nullptr; + Heap *parentHeap = heap->findParentHeap(); + if ((u32)heap < 0x90000000) { + mem[0] += heap->getAllocatableSize(4); + } else { + mem[1] += heap->getAllocatableSize(4); + } + + while ((childHeap = (Heap *)nw4r::ut::List_GetNext(&sHeapList, childHeap)) != nullptr) { + if (parentHeap == childHeap) { + break; + } + } + } + OSUnlockMutex(&sRootMutex); +} + +/* 804959a0 */ Heap *Heap::becomeCurrentHeap() { + OSLockMutex(&sRootMutex); + Heap *h = sCurrentHeap; + sCurrentHeap = this; + OSUnlockMutex(&sRootMutex); + return h; +} + +/* 80495a00 */ Heap *Heap::_becomeCurrentHeapWithoutLock() { + Heap *h = sCurrentHeap; + sCurrentHeap = this; + DCStoreRange(&sCurrentHeap, sizeof(sCurrentHeap)); + return h; +} + +// TODO +extern "C" void MEMInitAllocatorForHeap(Allocator *alloc, s32 align, Heap *heap); + +// TODO this could be an inline virtual function +/* 80495a40 */ void Heap::initAllocator(Allocator *alloc, s32 align) { + MEMInitAllocatorForHeap(alloc, align, this); +} + +} // namespace EGG + +/* 80495a60 */ void *operator new(size_t, void *p) { + return p; +} +/* 80495a70 */ void *operator new(size_t size, EGG::Heap *heap, u32 align) { + return EGG::Heap::alloc(size, align, heap); +} + +/* 80495a80 */ void *operator new(size_t size, EGG::Allocator *alloc) { + return MEMAllocFromAllocator(alloc->getHandle(), size); +} +/* 80495a90 */ void *operator new[](size_t size, u32 align) { + return EGG::Heap::alloc(size, align, nullptr); +} +/* 80495aa0 */ void *operator new[](size_t size, EGG::Heap *heap, int align) { + return EGG::Heap::alloc(size, align, heap); +}