mirror of
https://github.com/PrimeDecomp/prime.git
synced 2025-12-09 21:47:57 +00:00
Match and link CARAMToken
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user