mirror of https://github.com/zeldaret/tp.git
320 lines
9.6 KiB
C++
320 lines
9.6 KiB
C++
#include "JSystem/JKernel/JKRAram/JKRAram.h"
|
|
#include "JSystem/JKernel/JKRAramBlock/JKRAramBlock.h"
|
|
#include "JSystem/JKernel/JKRAramHeap/JKRAramHeap.h"
|
|
#include "JSystem/JKernel/JKRAramPiece/JKRAramPiece.h"
|
|
#include "JSystem/JKernel/JKRAramStream/JKRAramStream.h"
|
|
#include "JSystem/JKernel/JKRExpHeap/JKRExpHeap.h"
|
|
#include "msl_c/string.h"
|
|
extern "C" {
|
|
void __dl__FPv(void);
|
|
void __RAS_OSDisableInterrupts_begin(void);
|
|
void alloc__11JKRAramHeapFUlQ211JKRAramHeap10EAllocMode(void);
|
|
void alloc__7JKRHeapFUli(void);
|
|
void alloc__7JKRHeapFUliP7JKRHeap(void);
|
|
void changeGroupIdIfNeed__7JKRAramFPUci(void);
|
|
void checkCompressed__9JKRDecompFPUc(void);
|
|
void checkOkAddress__7JKRAramFPUcUlP12JKRAramBlockUl(void);
|
|
void DCStoreRangeNoSync(void);
|
|
void decompSZS_subroutine__FPUcPUc(void);
|
|
void firstSrcData__Fv(void);
|
|
void free__7JKRHeapFPvP7JKRHeap(void);
|
|
void JKRDecompressFromAramToMainRam__FUlPvUlUlUlPUl(void);
|
|
void panic_f__12JUTExceptionFPCciPCce(const char* filename, int line, const char* format, ...);
|
|
void nextSrcData__FPUc(void);
|
|
void orderSync__12JKRAramPieceFiUlUlUlP12JKRAramBlock(void);
|
|
void orderSync__9JKRDecompFPUcPUcUlUl(void);
|
|
void startDMA__12JKRAramPieceFP12JKRAMCommand(void);
|
|
}
|
|
|
|
extern u8 lbl_803CC158; // JKRAram::__vt
|
|
extern OSMessageQueue sMessageQueue__7JKRAram; // JKRAram::sMessageQueue
|
|
extern bool lbl_804513FC; // DAT_804513fc (init global mutex)
|
|
extern OSMutex lbl_804342E8; // JKernel::decompMutex (static?)
|
|
extern u8 lbl_804342D0; // JKernel::@492 (global destructor chain)
|
|
extern u8 sAramCommandList__7JKRAram; // JKRAram::sAramCommandList
|
|
extern u8 sSZSBufferSize__7JKRAram; // JKRAram::sSZSBufferSize
|
|
extern u8 sMessageBuffer__7JKRAram; // JKRAram::sMessageBuffer
|
|
|
|
// Uncomment when static initialization is working
|
|
// JKRAram* JKRAram::sAramObject = NULL;
|
|
// u32 JKRAram::sSZSBufferSize = 0x400;
|
|
|
|
static void decompSZS_subroutine(u8*, u8*);
|
|
static u8* firstSrcData(void);
|
|
static u8* nextSrcData(u8*);
|
|
|
|
// The prefix JKRAram__ is for now used to skip name collision in 'sbss.s'. All of these variables
|
|
// are probably defined as static and only visible in this translation unit.
|
|
extern u8* JKRAram__szpBuf;
|
|
extern u8* JKRAram__szpEnd;
|
|
extern u8* JKRAram__refBuf;
|
|
extern u8* JKRAram__refEnd;
|
|
extern u8* JKRAram__refCurrent;
|
|
extern u32 JKRAram__srcOffset;
|
|
extern u32 JKRAram__transLeft;
|
|
extern u32 JKRAram__srcLimit;
|
|
extern u32 JKRAram__srcAddress;
|
|
extern u32 JKRAram__fileOffset;
|
|
extern u32 JKRAram__readCount;
|
|
extern u32 JKRAram__maxDest;
|
|
extern u32* JKRAram__tsPtr;
|
|
extern u32 JKRAram__tsArea;
|
|
extern JKRExpHeap* sSystemHeap__7JKRHeap;
|
|
|
|
JKRAram* JKRAram::create(u32 aram_audio_buffer_size, u32 aram_audio_graph_size,
|
|
long stream_priority, long decomp_priority, long piece_priority) {
|
|
if (!sAramObject) {
|
|
sAramObject = new (JKRHeap::getSystemHeap(), 0)
|
|
JKRAram(aram_audio_buffer_size, aram_audio_graph_size, piece_priority);
|
|
}
|
|
|
|
JKRCreateAramStreamManager(stream_priority);
|
|
JKRCreateDecompManager(decomp_priority);
|
|
sAramObject->resume();
|
|
return sAramObject;
|
|
}
|
|
|
|
JKRAram::JKRAram(u32 audio_buffer_size, u32 audio_graph_size, long priority)
|
|
: JKRThread(0xC00, 0x10, priority) {
|
|
u32 aramBase = ARInit(mStackArray, ARRAY_SIZE(mStackArray));
|
|
ARQInit();
|
|
|
|
u32 aramSize = ARGetSize();
|
|
|
|
mAudioMemorySize = audio_buffer_size;
|
|
if (audio_graph_size == 0xffffffff) {
|
|
mGraphMemorySize = (aramSize - audio_buffer_size) - aramBase;
|
|
mAramMemorySize = 0;
|
|
} else {
|
|
mGraphMemorySize = audio_graph_size;
|
|
mAramMemorySize = (aramSize - (audio_buffer_size + audio_graph_size)) - aramBase;
|
|
}
|
|
|
|
mAudioMemoryPtr = ARAlloc(mAudioMemorySize);
|
|
mGraphMemoryPtr = ARAlloc(mGraphMemorySize);
|
|
|
|
if (mAramMemorySize) {
|
|
mAramMemoryPtr = ARAlloc(mAramMemorySize);
|
|
} else {
|
|
mAramMemoryPtr = NULL;
|
|
}
|
|
|
|
mAramHeap = new (JKRHeap::getSystemHeap(), 0) JKRAramHeap(mGraphMemoryPtr, mGraphMemorySize);
|
|
}
|
|
|
|
JKRAram::~JKRAram() {
|
|
sAramObject = NULL;
|
|
if (mAramHeap)
|
|
delete mAramHeap;
|
|
}
|
|
|
|
// almost full match
|
|
#ifdef NONMATCHING
|
|
void* JKRAram::run(void) {
|
|
int result;
|
|
JKRAMCommand* command;
|
|
JKRAMCommand::Message* message;
|
|
OSInitMessageQueue(&sMessageQueue, sMessageBuffer, 4);
|
|
do {
|
|
OSReceiveMessage(&sMessageQueue, &message, OS_MESSAGE_BLOCKING);
|
|
result = message->field_0x0;
|
|
command = message->command;
|
|
delete message;
|
|
|
|
if (result == 1) {
|
|
JKRAramPiece::startDMA(command);
|
|
}
|
|
} while (true);
|
|
}
|
|
#else
|
|
asm void* JKRAram::run(void) {
|
|
nofralloc
|
|
#include "JSystem/JKernel/JKRAram/asm/func_802D21DC.s"
|
|
}
|
|
#endif
|
|
|
|
void JKRAram::checkOkAddress(u8* addr, u32 size, JKRAramBlock* block, u32 param_4) {
|
|
if (!IS_ALIGNED((u32)addr, 0x20) && !IS_ALIGNED(size, 0x20)) {
|
|
panic_f__12JUTExceptionFPCciPCce("JKRAram.cpp", 0xdb, "%s",
|
|
":::address not 32Byte aligned.");
|
|
}
|
|
|
|
if (block && !IS_ALIGNED((u32)block->getAddress() + param_4, 0x20)) {
|
|
panic_f__12JUTExceptionFPCciPCce("JKRAram.cpp", 0xe3, "%s",
|
|
":::address not 32Byte aligned.");
|
|
}
|
|
}
|
|
|
|
void JKRAram::changeGroupIdIfNeed(u8* data, int groupId) {
|
|
JKRHeap* currentHeap = JKRHeap::getCurrentHeap();
|
|
if (currentHeap->getHeapType() == 'EXPH' && groupId >= 0) {
|
|
JKRExpHeap::CMemBlock* block = JKRExpHeap::CMemBlock::getBlock(data);
|
|
block->newGroupId(groupId);
|
|
}
|
|
}
|
|
|
|
asm void JKRAram::mainRamToAram(u8*, u32, u32, JKRExpandSwitch, u32, JKRHeap*, int, u32*) {
|
|
nofralloc
|
|
#include "JSystem/JKernel/JKRAram/asm/func_802D233C.s"
|
|
}
|
|
|
|
asm void JKRAram::aramToMainRam(u32, u8*, u32, JKRExpandSwitch, u32, JKRHeap*, int, u32*) {
|
|
nofralloc
|
|
#include "JSystem/JKernel/JKRAram/asm/func_802D25B4.s"
|
|
}
|
|
|
|
#ifdef NONMATCHING
|
|
// full match, except:
|
|
// tsPtr = &tsArea;
|
|
// doesn't use r13
|
|
void JKRDecompressFromAramToMainRam(u32 src, void* dst, u32 srcLength, u32 dstLength, u32 offset,
|
|
u32* resourceSize) {
|
|
#define s_is_decompress_mutex_initialized lbl_804513FC
|
|
#define decompMutex lbl_804343C0
|
|
|
|
// STATIC BEGIN
|
|
// This code is probably generated by the compiler for a static variable
|
|
BOOL enable = OSDisableInterrupts();
|
|
if (s_is_decompress_mutex_initialized == false) {
|
|
OSInitMutex(&decompMutex);
|
|
s_is_decompress_mutex_initialized = true;
|
|
}
|
|
OSRestoreInterrupts(enable);
|
|
// STATIC END
|
|
|
|
OSLockMutex(&decompMutex);
|
|
u32 szpSize = getSZSBufferSize();
|
|
szpBuf = (u8*)JKRAllocFromSysHeap(szpSize, 0x20);
|
|
ASSERT(szpBuf != 0);
|
|
szpEnd = szpBuf + szpSize;
|
|
|
|
if (offset != 0) {
|
|
refBuf = (u8*)JKRAllocFromSysHeap(0x1120, 0);
|
|
ASSERT(refBuf != 0);
|
|
refEnd = refBuf + 0x1120;
|
|
refCurrent = refBuf;
|
|
} else {
|
|
refBuf = NULL;
|
|
}
|
|
|
|
srcAddress = src;
|
|
srcOffset = 0;
|
|
if (srcLength == 0) {
|
|
transLeft = -1;
|
|
} else {
|
|
transLeft = srcLength;
|
|
}
|
|
|
|
fileOffset = offset;
|
|
readCount = 0;
|
|
maxDest = dstLength;
|
|
if (!resourceSize) {
|
|
tsPtr = &tsArea;
|
|
} else {
|
|
tsPtr = resourceSize;
|
|
}
|
|
|
|
*tsPtr = 0;
|
|
|
|
decompSZS_subroutine(firstSrcData(), (u8*)dst);
|
|
JKRFreeToSysHeap(szpBuf);
|
|
if (refBuf) {
|
|
JKRFreeToSysHeap(refBuf);
|
|
}
|
|
DCStoreRangeNoSync(dst, *tsPtr);
|
|
OSUnlockMutex(&decompMutex);
|
|
#undef s_is_decompress_mutex_initialized
|
|
#undef decompMutex
|
|
}
|
|
#else
|
|
asm void JKRDecompressFromAramToMainRam(u32 src, void* dst, u32 srcLength, u32 dstLength,
|
|
u32 offset, u32* resourceSize) {
|
|
nofralloc
|
|
#include "JSystem/JKernel/JKRAram/asm/func_802D2830.s"
|
|
}
|
|
#endif
|
|
|
|
asm void decompSZS_subroutine(u8*, u8*){nofralloc
|
|
#include "JSystem/JKernel/JKRAram/asm/func_802D29A0.s"
|
|
}
|
|
|
|
u8* firstSrcData(void) {
|
|
JKRAram__srcLimit = (u32)(JKRAram__szpEnd - 0x19);
|
|
u8* buffer = JKRAram__szpBuf;
|
|
|
|
u32 length;
|
|
u32 size = JKRAram__szpEnd - JKRAram__szpBuf;
|
|
if (JKRAram__transLeft < size) {
|
|
length = JKRAram__transLeft;
|
|
} else {
|
|
length = size;
|
|
}
|
|
|
|
u32 src = (u32)(JKRAram__srcAddress + JKRAram__srcOffset);
|
|
u32 dst = (u32)buffer;
|
|
u32 alignedLength = ALIGN_NEXT(length, 0x20);
|
|
JKRAramPcs(1, src, dst, alignedLength, NULL);
|
|
|
|
JKRAram__srcOffset += length;
|
|
JKRAram__transLeft -= length;
|
|
if (!JKRAram__transLeft) {
|
|
JKRAram__srcLimit = (u32)(buffer + length);
|
|
}
|
|
|
|
return buffer;
|
|
}
|
|
|
|
// missing one add instruction
|
|
#ifdef NONMATCHING
|
|
inline u32 nextSrcData_MIN(u32 A, u32 B) {
|
|
if (A > B)
|
|
return B;
|
|
return A;
|
|
}
|
|
|
|
static u8* nextSrcData(u8* current) {
|
|
u8* dest;
|
|
u32 left = (u32)(szpEnd - current);
|
|
if (!IS_NOT_ALIGNED(left, 0x20)) {
|
|
dest = szpBuf;
|
|
} else {
|
|
dest = szpBuf + 0x20 - (left & 0x1f);
|
|
}
|
|
|
|
memcpy(dest, current, left);
|
|
u32 transSize = nextSrcData_MIN(transLeft, szpEnd - (dest + left));
|
|
ASSERT(transSize > 0);
|
|
|
|
JKRAramPcs(1, (u32)(srcAddress + srcOffset), (u32)(dest + left), ALIGN_NEXT(transSize, 0x20),
|
|
NULL);
|
|
srcOffset += transSize;
|
|
transLeft -= transSize;
|
|
|
|
if (transLeft == 0) {
|
|
srcLimit = (u32)(dest + left) + transSize;
|
|
}
|
|
|
|
return dest;
|
|
}
|
|
#else
|
|
asm u8* nextSrcData(u8* current) {
|
|
nofralloc
|
|
#include "JSystem/JKernel/JKRAram/asm/func_802D2CE4.s"
|
|
}
|
|
#endif
|
|
|
|
#if 0
|
|
asm void __sinit_JKRAram_cpp {
|
|
nofralloc
|
|
#include "JSystem/JKernel/JKRAram/asm/func_802D2DAC.s"
|
|
}
|
|
|
|
asm JSUList<12JKRAMCommand>::~JSUList<12JKRAMCommand>(void) {
|
|
nofralloc
|
|
#include "JSystem/JKernel/JKRAram/asm/func_802D2DF0.s"
|
|
}
|
|
#endif
|
|
|
|
const char* lbl_8039D0A6 = "bad aramSync\n";
|
|
const char* lbl_8039D0B4 = "\x00\x00\x00"; /* padding */
|