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
/* 80358384 003552E4 4E 80 00 20 */ blr
.global sub_80358388
sub_80358388:
.global sub_80358388__10CARAMTokenFv
sub_80358388__10CARAMTokenFv:
/* 80358388 003552E8 94 21 FF F0 */ stwu r1, -0x10(r1)
/* 8035838C 003552EC 7C 08 02 A6 */ mflr r0
/* 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
/* 803583D0 00355330 4E 80 00 20 */ blr
.global sub_803583d4
sub_803583d4:
.global sub_803583d4__10CARAMTokenFv
sub_803583d4__10CARAMTokenFv:
/* 803583D4 00355334 94 21 FF F0 */ stwu r1, -0x10(r1)
/* 803583D8 00355338 7C 08 02 A6 */ mflr r0
/* 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
/* 80358A48 003559A8 4E 80 00 20 */ blr
.global __ct__10CARAMTokenFPvUi
__ct__10CARAMTokenFPvUi:
.global __ct__10CARAMTokenFPvUii
__ct__10CARAMTokenFPvUii:
/* 80358A4C 003559AC 94 21 FF F0 */ stwu r1, -0x10(r1)
/* 80358A50 003559B0 7C 08 02 A6 */ mflr r0
/* 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
/* 8030E120 0030B080 41 82 00 18 */ beq lbl_8030E138
/* 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
/* 8030E130 0030B090 38 60 00 01 */ li r3, 1
/* 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
/* 80061CA0 0005EC00 98 04 00 00 */ stb r0, 0(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
/* 80061CB0 0005EC10 38 81 00 B8 */ addi r4, r1, 0xb8
/* 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)
/* 802090F8 00206058 38 61 00 80 */ addi r3, r1, 0x80
/* 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
/* 80209108 00206068 48 14 F5 71 */ bl LoadToARAM__10CARAMTokenFv
/* 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)
/* 80209118 00206078 3C 60 80 3D */ lis r3, lbl_803D2768@ha
/* 8020911C 0020607C 38 83 27 68 */ addi r4, r3, lbl_803D2768@l
@ -322,7 +322,7 @@ lbl_80209160:
lbl_802091A0:
/* 802091A0 00206100 80 61 00 A4 */ lwz r3, 0xa4(r1)
/* 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)
/* 802091B0 00206110 7C 7B 1B 78 */ mr r27, r3
/* 802091B4 00206114 38 61 00 A0 */ addi r3, r1, 0xa0

View File

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

View File

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

View File

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

View File

@ -5,47 +5,69 @@
#include "rstl/construct.hpp"
#include "dolphin/OS/OSCache.h"
CARAMToken* CARAMToken::sLists[7];
CARAMToken::CARAMToken() {
x0_ = 6;
x4_ = NULL;
x8_ = CARAMManager::GetInvalidAlloc();
xc_ = 0;
x10_ = CARAMManager::GetInvalidDMAHandle();
x14_ = 0;
x18_ = 0;
x0_status = kS_Six;
x4_mramPtr = nullptr;
x8_aramPtr = CARAMManager::GetInvalidAlloc();
xc_dataLen = 0;
x10_dmaHandle = CARAMManager::GetInvalidDMAHandle();
x14_prev = nullptr;
x18_next = nullptr;
x1c_24_ = false;
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)
: x0_(other.x0_)
, x4_(other.x4_)
, x8_(other.x8_)
, xc_(other.xc_)
, x10_(other.x10_)
, x14_(0)
, x18_(0)
: x0_status(other.x0_status)
, x4_mramPtr(other.x4_mramPtr)
, x8_aramPtr(other.x8_aramPtr)
, xc_dataLen(other.xc_dataLen)
, x10_dmaHandle(other.x10_dmaHandle)
, x14_prev(nullptr)
, x18_next(nullptr)
, x1c_24_(other.x1c_24_) {
const_cast< CARAMToken& >(other).MakeInvalid();
InitiallyMoveToList();
}
CARAMToken::~CARAMToken() {
if (x10_ != CARAMManager::GetInvalidDMAHandle() && !CARAMManager::CancelDMA(x10_)) {
CARAMManager::WaitForDMACompletion(x10_);
if (x10_dmaHandle != CARAMManager::GetInvalidDMAHandle() &&
!CARAMManager::CancelDMA(x10_dmaHandle)) {
CARAMManager::WaitForDMACompletion(x10_dmaHandle);
}
RemoveFromList();
CMemory::Free(x4_);
CARAMManager::Free(x8_);
CMemory::Free(x4_mramPtr);
CARAMManager::Free(x8_aramPtr);
}
void CARAMToken::PostConstruct(void* ptr, uint len, int unk) {
MoveToList(kS_One);
x4_ = ptr;
xc_ = len;
x4_mramPtr = ptr;
xc_dataLen = len;
x1c_24_ = unk == 0;
}
@ -59,7 +81,175 @@ CARAMToken& CARAMToken::operator=(const CARAMToken& other) {
return *this;
}
bool 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;
}
}
void CARAMToken::LoadToMRAM() {
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;
}