mirror of
https://github.com/PrimeDecomp/prime.git
synced 2025-12-21 04:59:10 +00:00
170
src/Dolphin/ar/arq.c
Normal file
170
src/Dolphin/ar/arq.c
Normal file
@@ -0,0 +1,170 @@
|
||||
#include "dolphin/arq.h"
|
||||
#include "dolphin/os.h"
|
||||
|
||||
const char* __ARQVersion = "<< Dolphin SDK - ARQ\trelease build: Sep 5 2002 05:34:29 (0x2301) >>";
|
||||
static ARQRequest* __ARQRequestQueueHi;
|
||||
static ARQRequest* __ARQRequestTailHi;
|
||||
static ARQRequest* __ARQRequestQueueLo;
|
||||
static ARQRequest* __ARQRequestTailLo;
|
||||
static ARQRequest* __ARQRequestPendingHi;
|
||||
static ARQRequest* __ARQRequestPendingLo;
|
||||
static ARQCallback __ARQCallbackHi;
|
||||
static ARQCallback __ARQCallbackLo;
|
||||
static u32 __ARQChunkSize;
|
||||
|
||||
static volatile BOOL __ARQ_init_flag = FALSE;
|
||||
|
||||
void __ARQPopTaskQueueHi(void);
|
||||
void __ARQServiceQueueLo(void);
|
||||
void __ARQCallbackHack(void);
|
||||
void __ARQInterruptServiceRoutine(void);
|
||||
void __ARQInitTempQueue(void);
|
||||
void __ARQPushTempQueue(ARQRequest* task);
|
||||
|
||||
void __ARQPopTaskQueueHi(void) {
|
||||
|
||||
if (__ARQRequestQueueHi) {
|
||||
if (__ARQRequestQueueHi->type == ARQ_TYPE_MRAM_TO_ARAM) {
|
||||
ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->source, __ARQRequestQueueHi->dest,
|
||||
__ARQRequestQueueHi->length);
|
||||
} else {
|
||||
ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->dest, __ARQRequestQueueHi->source,
|
||||
__ARQRequestQueueHi->length);
|
||||
}
|
||||
|
||||
__ARQCallbackHi = __ARQRequestQueueHi->callback;
|
||||
|
||||
__ARQRequestPendingHi = __ARQRequestQueueHi;
|
||||
|
||||
__ARQRequestQueueHi = __ARQRequestQueueHi->next;
|
||||
}
|
||||
}
|
||||
|
||||
void __ARQServiceQueueLo(void) {
|
||||
|
||||
if ((__ARQRequestPendingLo == NULL) && (__ARQRequestQueueLo)) {
|
||||
__ARQRequestPendingLo = __ARQRequestQueueLo;
|
||||
|
||||
__ARQRequestQueueLo = __ARQRequestQueueLo->next;
|
||||
}
|
||||
|
||||
if (__ARQRequestPendingLo) {
|
||||
if (__ARQRequestPendingLo->length <= __ARQChunkSize) {
|
||||
if (__ARQRequestPendingLo->type == ARQ_TYPE_MRAM_TO_ARAM)
|
||||
ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source,
|
||||
__ARQRequestPendingLo->dest, __ARQRequestPendingLo->length);
|
||||
else
|
||||
ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest,
|
||||
__ARQRequestPendingLo->source, __ARQRequestPendingLo->length);
|
||||
|
||||
__ARQCallbackLo = __ARQRequestPendingLo->callback;
|
||||
} else {
|
||||
if (__ARQRequestPendingLo->type == ARQ_TYPE_MRAM_TO_ARAM)
|
||||
ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source,
|
||||
__ARQRequestPendingLo->dest, __ARQChunkSize);
|
||||
else
|
||||
ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest,
|
||||
__ARQRequestPendingLo->source, __ARQChunkSize);
|
||||
}
|
||||
|
||||
__ARQRequestPendingLo->length -= __ARQChunkSize;
|
||||
__ARQRequestPendingLo->source += __ARQChunkSize;
|
||||
__ARQRequestPendingLo->dest += __ARQChunkSize;
|
||||
}
|
||||
}
|
||||
void __ARQCallbackHack(void) { return; }
|
||||
|
||||
void __ARQInterruptServiceRoutine(void) {
|
||||
|
||||
if (__ARQCallbackHi) {
|
||||
(*__ARQCallbackHi)((u32)__ARQRequestPendingHi);
|
||||
__ARQRequestPendingHi = NULL;
|
||||
__ARQCallbackHi = NULL;
|
||||
}
|
||||
|
||||
else if (__ARQCallbackLo) {
|
||||
(*__ARQCallbackLo)((u32)__ARQRequestPendingLo);
|
||||
__ARQRequestPendingLo = NULL;
|
||||
__ARQCallbackLo = NULL;
|
||||
}
|
||||
|
||||
__ARQPopTaskQueueHi();
|
||||
|
||||
if (__ARQRequestPendingHi == NULL)
|
||||
__ARQServiceQueueLo();
|
||||
}
|
||||
|
||||
void ARQInit(void) {
|
||||
|
||||
if (TRUE == __ARQ_init_flag) {
|
||||
return;
|
||||
}
|
||||
|
||||
OSRegisterVersion(__ARQVersion);
|
||||
__ARQRequestQueueHi = __ARQRequestQueueLo = NULL;
|
||||
__ARQChunkSize = ARQ_CHUNK_SIZE_DEFAULT;
|
||||
ARRegisterDMACallback(&__ARQInterruptServiceRoutine);
|
||||
__ARQRequestPendingHi = NULL;
|
||||
__ARQRequestPendingLo = NULL;
|
||||
__ARQCallbackHi = NULL;
|
||||
__ARQCallbackLo = NULL;
|
||||
__ARQ_init_flag = TRUE;
|
||||
}
|
||||
|
||||
void ARQPostRequest(ARQRequest* request, u32 owner, u32 type, u32 priority, u32 source, u32 dest,
|
||||
u32 length, ARQCallback callback) {
|
||||
|
||||
BOOL enabled;
|
||||
|
||||
request->next = NULL;
|
||||
request->owner = owner;
|
||||
request->type = type;
|
||||
request->source = source;
|
||||
request->dest = dest;
|
||||
request->length = length;
|
||||
|
||||
if (callback) {
|
||||
request->callback = callback;
|
||||
} else {
|
||||
request->callback = (ARQCallback)&__ARQCallbackHack;
|
||||
}
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
switch (priority) {
|
||||
case ARQ_PRIORITY_LOW:
|
||||
|
||||
if (__ARQRequestQueueLo) {
|
||||
__ARQRequestTailLo->next = request;
|
||||
} else {
|
||||
__ARQRequestQueueLo = request;
|
||||
}
|
||||
__ARQRequestTailLo = request;
|
||||
|
||||
break;
|
||||
|
||||
case ARQ_PRIORITY_HIGH:
|
||||
|
||||
if (__ARQRequestQueueHi) {
|
||||
__ARQRequestTailHi->next = request;
|
||||
} else {
|
||||
__ARQRequestQueueHi = request;
|
||||
}
|
||||
|
||||
__ARQRequestTailHi = request;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ((__ARQRequestPendingHi == NULL) && (__ARQRequestPendingLo == NULL)) {
|
||||
__ARQPopTaskQueueHi();
|
||||
|
||||
if (__ARQRequestPendingHi == NULL) {
|
||||
__ARQServiceQueueLo();
|
||||
}
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
}
|
||||
|
||||
u32 ARQGetChunkSize(void) { return __ARQChunkSize; }
|
||||
Reference in New Issue
Block a user