Match and link CARAMToken

This commit is contained in:
Phillip Stephens 2022-12-05 23:59:41 -08:00
parent f163fb3fd5
commit b096be696a
8 changed files with 263 additions and 51 deletions

View File

@ -31,8 +31,8 @@ lbl_80358374:
/* 80358380 003552E0 38 21 00 10 */ addi r1, r1, 0x10 /* 80358380 003552E0 38 21 00 10 */ addi r1, r1, 0x10
/* 80358384 003552E4 4E 80 00 20 */ blr /* 80358384 003552E4 4E 80 00 20 */ blr
.global sub_80358388 .global sub_80358388__10CARAMTokenFv
sub_80358388: sub_80358388__10CARAMTokenFv:
/* 80358388 003552E8 94 21 FF F0 */ stwu r1, -0x10(r1) /* 80358388 003552E8 94 21 FF F0 */ stwu r1, -0x10(r1)
/* 8035838C 003552EC 7C 08 02 A6 */ mflr r0 /* 8035838C 003552EC 7C 08 02 A6 */ mflr r0
/* 80358390 003552F0 90 01 00 14 */ stw r0, 0x14(r1) /* 80358390 003552F0 90 01 00 14 */ stw r0, 0x14(r1)
@ -54,8 +54,8 @@ lbl_803583C0:
/* 803583CC 0035532C 38 21 00 10 */ addi r1, r1, 0x10 /* 803583CC 0035532C 38 21 00 10 */ addi r1, r1, 0x10
/* 803583D0 00355330 4E 80 00 20 */ blr /* 803583D0 00355330 4E 80 00 20 */ blr
.global sub_803583d4 .global sub_803583d4__10CARAMTokenFv
sub_803583d4: sub_803583d4__10CARAMTokenFv:
/* 803583D4 00355334 94 21 FF F0 */ stwu r1, -0x10(r1) /* 803583D4 00355334 94 21 FF F0 */ stwu r1, -0x10(r1)
/* 803583D8 00355338 7C 08 02 A6 */ mflr r0 /* 803583D8 00355338 7C 08 02 A6 */ mflr r0
/* 803583DC 0035533C 90 01 00 14 */ stw r0, 0x14(r1) /* 803583DC 0035533C 90 01 00 14 */ stw r0, 0x14(r1)
@ -544,8 +544,8 @@ __ct__10CARAMTokenFRC10CARAMToken:
/* 80358A44 003559A4 38 21 00 10 */ addi r1, r1, 0x10 /* 80358A44 003559A4 38 21 00 10 */ addi r1, r1, 0x10
/* 80358A48 003559A8 4E 80 00 20 */ blr /* 80358A48 003559A8 4E 80 00 20 */ blr
.global __ct__10CARAMTokenFPvUi .global __ct__10CARAMTokenFPvUii
__ct__10CARAMTokenFPvUi: __ct__10CARAMTokenFPvUii:
/* 80358A4C 003559AC 94 21 FF F0 */ stwu r1, -0x10(r1) /* 80358A4C 003559AC 94 21 FF F0 */ stwu r1, -0x10(r1)
/* 80358A50 003559B0 7C 08 02 A6 */ mflr r0 /* 80358A50 003559B0 7C 08 02 A6 */ mflr r0
/* 80358A54 003559B4 80 E2 CB A8 */ lwz r7, kInvalidAlloc__12CARAMManager@sda21(r2) /* 80358A54 003559B4 80 E2 CB A8 */ lwz r7, kInvalidAlloc__12CARAMManager@sda21(r2)

View File

@ -63,7 +63,7 @@ sub_8030e10c__8CTextureFv:
/* 8030E11C 0030B07C 2C 00 00 06 */ cmpwi r0, 6 /* 8030E11C 0030B07C 2C 00 00 06 */ cmpwi r0, 6
/* 8030E120 0030B080 41 82 00 18 */ beq lbl_8030E138 /* 8030E120 0030B080 41 82 00 18 */ beq lbl_8030E138
/* 8030E124 0030B084 38 63 00 44 */ addi r3, r3, 0x44 /* 8030E124 0030B084 38 63 00 44 */ addi r3, r3, 0x44
/* 8030E128 0030B088 48 04 A2 AD */ bl sub_803583d4 /* 8030E128 0030B088 48 04 A2 AD */ bl sub_803583d4__10CARAMTokenFv
/* 8030E12C 0030B08C 7C 64 1B 78 */ mr r4, r3 /* 8030E12C 0030B08C 7C 64 1B 78 */ mr r4, r3
/* 8030E130 0030B090 38 60 00 01 */ li r3, 1 /* 8030E130 0030B090 38 60 00 01 */ li r3, 1
/* 8030E134 0030B094 48 05 EA E9 */ bl sub_8036cc1c__19CFrameDelayedKillerFbPv /* 8030E134 0030B094 48 05 EA E9 */ bl sub_8036cc1c__19CFrameDelayedKillerFbPv

View File

@ -4846,7 +4846,7 @@ lbl_80061C88:
/* 80061C9C 0005EBFC 38 C0 00 01 */ li r6, 1 /* 80061C9C 0005EBFC 38 C0 00 01 */ li r6, 1
/* 80061CA0 0005EC00 98 04 00 00 */ stb r0, 0(r4) /* 80061CA0 0005EC00 98 04 00 00 */ stb r0, 0(r4)
/* 80061CA4 0005EC04 80 84 00 04 */ lwz r4, 4(r4) /* 80061CA4 0005EC04 80 84 00 04 */ lwz r4, 4(r4)
/* 80061CA8 0005EC08 48 2F 6D A5 */ bl __ct__10CARAMTokenFPvUi /* 80061CA8 0005EC08 48 2F 6D A5 */ bl __ct__10CARAMTokenFPvUii
/* 80061CAC 0005EC0C 38 61 00 D8 */ addi r3, r1, 0xd8 /* 80061CAC 0005EC0C 38 61 00 D8 */ addi r3, r1, 0xd8
/* 80061CB0 0005EC10 38 81 00 B8 */ addi r4, r1, 0xb8 /* 80061CB0 0005EC10 38 81 00 B8 */ addi r4, r1, 0xb8
/* 80061CB4 0005EC14 48 2F 6D 19 */ bl __ct__10CARAMTokenFRC10CARAMToken /* 80061CB4 0005EC14 48 2F 6D 19 */ bl __ct__10CARAMTokenFRC10CARAMToken

View File

@ -276,11 +276,11 @@ lbl_802090DC:
/* 802090F4 00206054 80 81 00 4C */ lwz r4, 0x4c(r1) /* 802090F4 00206054 80 81 00 4C */ lwz r4, 0x4c(r1)
/* 802090F8 00206058 38 61 00 80 */ addi r3, r1, 0x80 /* 802090F8 00206058 38 61 00 80 */ addi r3, r1, 0x80
/* 802090FC 0020605C 38 C0 00 01 */ li r6, 1 /* 802090FC 0020605C 38 C0 00 01 */ li r6, 1
/* 80209100 00206060 48 14 F9 4D */ bl __ct__10CARAMTokenFPvUi /* 80209100 00206060 48 14 F9 4D */ bl __ct__10CARAMTokenFPvUii
/* 80209104 00206064 38 61 00 80 */ addi r3, r1, 0x80 /* 80209104 00206064 38 61 00 80 */ addi r3, r1, 0x80
/* 80209108 00206068 48 14 F5 71 */ bl LoadToARAM__10CARAMTokenFv /* 80209108 00206068 48 14 F5 71 */ bl LoadToARAM__10CARAMTokenFv
/* 8020910C 0020606C 38 61 00 80 */ addi r3, r1, 0x80 /* 8020910C 0020606C 38 61 00 80 */ addi r3, r1, 0x80
/* 80209110 00206070 48 14 F2 79 */ bl sub_80358388 /* 80209110 00206070 48 14 F2 79 */ bl sub_80358388__10CARAMTokenFv
/* 80209114 00206074 83 61 00 A8 */ lwz r27, 0xa8(r1) /* 80209114 00206074 83 61 00 A8 */ lwz r27, 0xa8(r1)
/* 80209118 00206078 3C 60 80 3D */ lis r3, lbl_803D2768@ha /* 80209118 00206078 3C 60 80 3D */ lis r3, lbl_803D2768@ha
/* 8020911C 0020607C 38 83 27 68 */ addi r4, r3, lbl_803D2768@l /* 8020911C 0020607C 38 83 27 68 */ addi r4, r3, lbl_803D2768@l
@ -322,7 +322,7 @@ lbl_80209160:
lbl_802091A0: lbl_802091A0:
/* 802091A0 00206100 80 61 00 A4 */ lwz r3, 0xa4(r1) /* 802091A0 00206100 80 61 00 A4 */ lwz r3, 0xa4(r1)
/* 802091A4 00206104 38 63 00 08 */ addi r3, r3, 8 /* 802091A4 00206104 38 63 00 08 */ addi r3, r3, 8
/* 802091A8 00206108 48 14 F2 2D */ bl sub_803583d4 /* 802091A8 00206108 48 14 F2 2D */ bl sub_803583d4__10CARAMTokenFv
/* 802091AC 0020610C 80 81 00 A4 */ lwz r4, 0xa4(r1) /* 802091AC 0020610C 80 81 00 A4 */ lwz r4, 0xa4(r1)
/* 802091B0 00206110 7C 7B 1B 78 */ mr r27, r3 /* 802091B0 00206110 7C 7B 1B 78 */ mr r27, r3
/* 802091B4 00206114 38 61 00 A0 */ addi r3, r1, 0xa0 /* 802091B4 00206114 38 61 00 A0 */ addi r3, r1, 0xa0

View File

@ -669,7 +669,7 @@ LIBS = [
"Kyoto/Animation/CVertexMorphEffect", "Kyoto/Animation/CVertexMorphEffect",
"Kyoto/Animation/CSkinnedModelWithAvgNormals", "Kyoto/Animation/CSkinnedModelWithAvgNormals",
["Kyoto/CTimeProvider", True], ["Kyoto/CTimeProvider", True],
["Kyoto/CARAMToken", False], ["Kyoto/CARAMToken", True],
"Kyoto/Audio/CMidiManager", "Kyoto/Audio/CMidiManager",
["Kyoto/Text/CFontImageDef", True], ["Kyoto/Text/CFontImageDef", True],
"Kyoto/Text/CImageInstruction", "Kyoto/Text/CImageInstruction",

View File

@ -5,21 +5,36 @@
class CARAMManager { class CARAMManager {
public: public:
enum EDMAPriority {
kDMAPrio_Zero,
kDMAPrio_One,
kDMAPrio_Two,
kDMAPrio_Three,
kDMAPrio_Four,
kDMAPrio_Five,
kDMAPrio_Six,
};
static void Shutdown(); static void Shutdown();
static void CollectGarbage(); static void CollectGarbage();
static void PreInitializeAlloc(uint size) { mPreInitializeAlloc += size; } static void PreInitializeAlloc(uint size) { mPreInitializeAlloc += size; }
static void Initialize(uint); static void Initialize(uint);
static void WaitForAllDMAsToComplete(); static void WaitForAllDMAsToComplete();
static void* GetInvalidAlloc() { return kInvalidAlloc; } static const void* GetInvalidAlloc() { return (const void*)kInvalidAlloc; }
static uint GetInvalidDMAHandle() { return kInvalidHandle; } static const uint GetInvalidDMAHandle() { return kInvalidHandle; }
static bool CancelDMA(uint); static bool CancelDMA(uint);
static void WaitForDMACompletion(uint); static void WaitForDMACompletion(uint);
static bool IsDMACompleted(uint handle);
static void* Alloc(uint len);
static void Free(const void* ptr); static void Free(const void* ptr);
static int DMAToARAM(void*, void*, uint, EDMAPriority);
static int DMAToMRAM(void*, void*, uint, EDMAPriority);
private: private:
static uint mPreInitializeAlloc; static uint mPreInitializeAlloc;
static void* kInvalidAlloc; static const int kInvalidAlloc;
static int kInvalidHandle; static const int kInvalidHandle;
}; };
#endif // _CARAMMANAGER #endif // _CARAMMANAGER

View File

@ -4,39 +4,46 @@
#include "types.h" #include "types.h"
class CARAMToken { class CARAMToken {
static CARAMToken* sLists[7];
public: public:
enum EStatus { enum EStatus {
kS_Zero, kS_Zero,
kS_One, kS_One,
kS_Two,
kS_Three,
kS_Four,
kS_Five,
kS_Six,
}; };
CARAMToken(); CARAMToken();
CARAMToken(void* ptr, uint len); CARAMToken(void* ptr, uint len, int unk);
CARAMToken(const CARAMToken& other); CARAMToken(const CARAMToken& other);
~CARAMToken(); ~CARAMToken();
void PostConstruct(void* ptr, uint len, int unk); void PostConstruct(void* ptr, uint len, int unk);
CARAMToken& operator=(const CARAMToken& other); CARAMToken& operator=(const CARAMToken& other);
void LoadToMRAM(); bool LoadToMRAM();
void LoadToARAM(); bool LoadToARAM();
void RefreshStatus(); bool RefreshStatus();
static void UpdateAllDMAs(); static void UpdateAllDMAs();
void InitiallyMoveToList(); void InitiallyMoveToList();
void MoveToList(EStatus status); void MoveToList(EStatus status);
void RemoveFromList(); void RemoveFromList();
void MakeInvalid(); void MakeInvalid();
void sub_803583d4(); void* sub_803583d4();
void sub_80358388(); void sub_80358388();
void* GetMRAMSafe(); void* GetMRAMSafe();
private: private:
int x0_; EStatus x0_status;
void* x4_; void* x4_mramPtr;
void* x8_; const void* x8_aramPtr;
int xc_; int xc_dataLen;
uint x10_; uint x10_dmaHandle;
int x14_; CARAMToken* x14_prev;
int x18_; CARAMToken* x18_next;
bool x1c_24_ : 1; bool x1c_24_ : 1;
}; };

View File

@ -5,47 +5,69 @@
#include "rstl/construct.hpp" #include "rstl/construct.hpp"
#include "dolphin/OS/OSCache.h"
CARAMToken* CARAMToken::sLists[7];
CARAMToken::CARAMToken() { CARAMToken::CARAMToken() {
x0_ = 6; x0_status = kS_Six;
x4_ = NULL; x4_mramPtr = nullptr;
x8_ = CARAMManager::GetInvalidAlloc(); x8_aramPtr = CARAMManager::GetInvalidAlloc();
xc_ = 0; xc_dataLen = 0;
x10_ = CARAMManager::GetInvalidDMAHandle(); x10_dmaHandle = CARAMManager::GetInvalidDMAHandle();
x14_ = 0; x14_prev = nullptr;
x18_ = 0; x18_next = nullptr;
x1c_24_ = false; x1c_24_ = false;
InitiallyMoveToList(); InitiallyMoveToList();
} }
CARAMToken::CARAMToken(void* ptr, uint len) {} CARAMToken::CARAMToken(void* ptr, uint len, int unk) {
x0_status = kS_One;
x4_mramPtr = ptr;
x8_aramPtr = CARAMManager::GetInvalidAlloc();
xc_dataLen = len;
x10_dmaHandle = CARAMManager::GetInvalidDMAHandle();
x14_prev = nullptr;
x18_next = nullptr;
x1c_24_ = !unk;
InitiallyMoveToList();
if (x1c_24_) {
x8_aramPtr = CARAMManager::Alloc(xc_dataLen);
x10_dmaHandle = CARAMManager::DMAToARAM(x4_mramPtr, (void*)x8_aramPtr, xc_dataLen,
CARAMManager::kDMAPrio_One);
CARAMManager::WaitForDMACompletion(x10_dmaHandle);
x10_dmaHandle = CARAMManager::GetInvalidDMAHandle();
}
}
CARAMToken::CARAMToken(const CARAMToken& other) CARAMToken::CARAMToken(const CARAMToken& other)
: x0_(other.x0_) : x0_status(other.x0_status)
, x4_(other.x4_) , x4_mramPtr(other.x4_mramPtr)
, x8_(other.x8_) , x8_aramPtr(other.x8_aramPtr)
, xc_(other.xc_) , xc_dataLen(other.xc_dataLen)
, x10_(other.x10_) , x10_dmaHandle(other.x10_dmaHandle)
, x14_(0) , x14_prev(nullptr)
, x18_(0) , x18_next(nullptr)
, x1c_24_(other.x1c_24_) { , x1c_24_(other.x1c_24_) {
const_cast< CARAMToken& >(other).MakeInvalid(); const_cast< CARAMToken& >(other).MakeInvalid();
InitiallyMoveToList(); InitiallyMoveToList();
} }
CARAMToken::~CARAMToken() { CARAMToken::~CARAMToken() {
if (x10_ != CARAMManager::GetInvalidDMAHandle() && !CARAMManager::CancelDMA(x10_)) { if (x10_dmaHandle != CARAMManager::GetInvalidDMAHandle() &&
CARAMManager::WaitForDMACompletion(x10_); !CARAMManager::CancelDMA(x10_dmaHandle)) {
CARAMManager::WaitForDMACompletion(x10_dmaHandle);
} }
RemoveFromList(); RemoveFromList();
CMemory::Free(x4_); CMemory::Free(x4_mramPtr);
CARAMManager::Free(x8_); CARAMManager::Free(x8_aramPtr);
} }
void CARAMToken::PostConstruct(void* ptr, uint len, int unk) { void CARAMToken::PostConstruct(void* ptr, uint len, int unk) {
MoveToList(kS_One); MoveToList(kS_One);
x4_ = ptr; x4_mramPtr = ptr;
xc_ = len; xc_dataLen = len;
x1c_24_ = unk == 0; x1c_24_ = unk == 0;
} }
@ -59,7 +81,175 @@ CARAMToken& CARAMToken::operator=(const CARAMToken& other) {
return *this; return *this;
} }
bool CARAMToken::LoadToMRAM() {
void CARAMToken::LoadToMRAM() { switch (x0_status) {
case kS_Three: {
break;
}
case kS_Four:
case kS_One: {
return true;
}
case kS_Two: {
MoveToList(kS_Four);
if (CARAMManager::CancelDMA(x10_dmaHandle)) {
RefreshStatus();
}
return true;
}
case kS_Five: {
MoveToList(kS_Three);
break;
}
case kS_Zero: {
x4_mramPtr = CMemory::Alloc(xc_dataLen, IAllocator::kHI_RoundUpLen);
DCInvalidateRange(x4_mramPtr, xc_dataLen);
x10_dmaHandle = CARAMManager::DMAToMRAM((void*)x8_aramPtr, x4_mramPtr, xc_dataLen,
CARAMManager::kDMAPrio_One);
MoveToList(kS_Three);
break;
}
}
return RefreshStatus();
}
bool CARAMToken::LoadToARAM() {
switch (x0_status) {
case kS_Zero:
case kS_Five:
return true;
case kS_Three: {
MoveToList(kS_Five);
if (CARAMManager::CancelDMA(x10_dmaHandle)) {
RefreshStatus();
}
return true;
}
case kS_Four: {
MoveToList(kS_Two);
break;
}
case kS_One: {
if (!x1c_24_) {
x8_aramPtr = CARAMManager::Alloc(xc_dataLen);
if (CARAMManager::GetInvalidAlloc() == x8_aramPtr) {
return false;
}
x10_dmaHandle = CARAMManager::DMAToARAM(x4_mramPtr, (void*)x8_aramPtr, xc_dataLen,
CARAMManager::kDMAPrio_One);
}
MoveToList(kS_Two);
break;
}
}
return RefreshStatus();
}
bool CARAMToken::RefreshStatus() {
if (x0_status == kS_One || x0_status == kS_Zero) {
return true;
}
if (!CARAMManager::IsDMACompleted(x10_dmaHandle)) {
return false;
}
x10_dmaHandle = CARAMManager::GetInvalidDMAHandle();
switch (x0_status) {
case kS_Three:
case kS_Four: {
if (!x1c_24_) {
CARAMManager::Free(x8_aramPtr);
x8_aramPtr = CARAMManager::GetInvalidAlloc();
}
MoveToList(kS_One);
break;
}
case kS_Two:
case kS_Five: {
delete[] x4_mramPtr;
x4_mramPtr = nullptr;
MoveToList(kS_Zero);
break;
}
}
return true;
}
void CARAMToken::UpdateAllDMAs() {
for (int i = kS_Two; i <= kS_Five; ++i) {
CARAMToken* ptr = sLists[i];
while (ptr != nullptr) {
CARAMToken* tmp = ptr->x18_next;
ptr->RefreshStatus();
ptr = tmp;
}
}
}
void CARAMToken::InitiallyMoveToList() {
x14_prev = nullptr;
x18_next = sLists[x0_status];
sLists[x0_status] = this;
if (x18_next != nullptr) {
x18_next->x14_prev = this;
}
}
void CARAMToken::MoveToList(EStatus status) {
if (x0_status == status) {
return;
}
RemoveFromList();
x0_status = status;
InitiallyMoveToList();
}
void CARAMToken::RemoveFromList() {
if (x14_prev == nullptr) {
sLists[x0_status] = x18_next;
} else {
x14_prev->x18_next = x18_next;
}
if (x18_next != nullptr) {
x18_next->x14_prev = x14_prev;
}
}
void CARAMToken::MakeInvalid() {
MoveToList(kS_Six);
x4_mramPtr = nullptr;
x8_aramPtr = CARAMManager::GetInvalidAlloc();
xc_dataLen = 0;
x10_dmaHandle = CARAMManager::GetInvalidDMAHandle();
}
void* CARAMToken::sub_803583d4() {
void* ptr = GetMRAMSafe();
MakeInvalid();
return ptr;
}
void CARAMToken::sub_80358388() {
if (x0_status >= kS_Two && x0_status <= kS_Five) {
CARAMManager::WaitForDMACompletion(x10_dmaHandle);
RefreshStatus();
}
}
void* CARAMToken::GetMRAMSafe() {
if (x0_status == kS_One) {
return x4_mramPtr;
}
LoadToMRAM();
while (!RefreshStatus())
;
return x4_mramPtr;
} }