From 9fa0a7f1da1b70bee995f53c6c96c43189018772 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Wed, 1 Feb 2023 18:45:02 -0400 Subject: global: Import Dolphin SDK This version comes from the Metroid Prime decompilation project. https://github.com/PrimeDecomp/prime --- src/Dolphin/ar/arq.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 src/Dolphin/ar/arq.c (limited to 'src/Dolphin/ar/arq.c') diff --git a/src/Dolphin/ar/arq.c b/src/Dolphin/ar/arq.c new file mode 100644 index 0000000..d157463 --- /dev/null +++ b/src/Dolphin/ar/arq.c @@ -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; } -- cgit v1.2.3-13-gbd6f