mirror of
https://gitlab.com/ryandwyer/perfect-dark
synced 2026-09-02 01:42:31 -04:00
Optimise DMA functions
This commit is contained in:
@@ -73,7 +73,7 @@ ROM_SIZE := 32
|
||||
# When enabled, press C-up and C-down simultaneously to toggle the debug menu.
|
||||
# Note that some emulators have problems displaying the crash screen text.
|
||||
|
||||
DEBUG = 0
|
||||
DEBUG = 1
|
||||
|
||||
# ANTIALIAS
|
||||
#
|
||||
|
||||
+7
-73
@@ -5,97 +5,31 @@
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
|
||||
volatile u32 g_DmaNumSlotsBusy;
|
||||
OSIoMesg g_DmaIoMsgs[32];
|
||||
volatile u8 g_DmaSlotsBusy[32];
|
||||
OSMesg g_DmaMesgs[32];
|
||||
OSIoMesg g_DmaIoMsgs[1];
|
||||
OSMesg g_DmaMesgs[1];
|
||||
OSMesgQueue g_DmaMesgQueue;
|
||||
|
||||
static void dmaWait(void);
|
||||
|
||||
void dmaInit(void)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < ARRAYCOUNT(g_DmaSlotsBusy); i++) {
|
||||
g_DmaSlotsBusy[i] = 0;
|
||||
}
|
||||
|
||||
g_DmaNumSlotsBusy = 0;
|
||||
|
||||
osCreateMesgQueue(&g_DmaMesgQueue, g_DmaMesgs, ARRAYCOUNT(g_DmaMesgs));
|
||||
}
|
||||
|
||||
static void dmaStart(void *memaddr, u32 romaddr, u32 len, bool priority)
|
||||
{
|
||||
u32 numiterations;
|
||||
u32 remainder;
|
||||
s32 i;
|
||||
|
||||
if (g_DmaNumSlotsBusy) {
|
||||
dmaWait();
|
||||
}
|
||||
|
||||
if (len < 0x4000 * ARRAYCOUNT(g_DmaIoMsgs)) {
|
||||
numiterations = len / 0x4000;
|
||||
remainder = len % 0x4000;
|
||||
} else {
|
||||
// DMA size is 0x80000 or more. It won't fit in the queue, so do it
|
||||
// all in one call to osPiStartDma using the remainder variable.
|
||||
numiterations = 0;
|
||||
remainder = len;
|
||||
}
|
||||
|
||||
osInvalDCache(memaddr, len);
|
||||
|
||||
for (i = 0; i != numiterations; i++) {
|
||||
g_DmaSlotsBusy[i] = true;
|
||||
g_DmaNumSlotsBusy++;
|
||||
|
||||
osPiStartDma(&g_DmaIoMsgs[i], priority, 0, romaddr, memaddr, 0x4000, &g_DmaMesgQueue);
|
||||
|
||||
romaddr += 0x4000;
|
||||
memaddr = (void *)((u32)memaddr + 0x4000);
|
||||
}
|
||||
|
||||
if (remainder) {
|
||||
g_DmaSlotsBusy[i] = true;
|
||||
g_DmaNumSlotsBusy++;
|
||||
|
||||
osPiStartDma(&g_DmaIoMsgs[i], priority, 0, romaddr, memaddr, remainder, &g_DmaMesgQueue);
|
||||
}
|
||||
}
|
||||
|
||||
static void dmaWait(void)
|
||||
{
|
||||
u32 stack;
|
||||
OSIoMesg *msg;
|
||||
s32 i;
|
||||
|
||||
while (g_DmaNumSlotsBusy) {
|
||||
osRecvMesg(&g_DmaMesgQueue, (OSMesg) &msg, OS_MESG_BLOCK);
|
||||
|
||||
for (i = 0; i < ARRAYCOUNT(g_DmaIoMsgs); i++) {
|
||||
if (&g_DmaIoMsgs[i] == msg) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_DmaSlotsBusy[i] = false;
|
||||
g_DmaNumSlotsBusy--;
|
||||
}
|
||||
osInvalDCache(memaddr, len);
|
||||
osPiStartDma(&g_DmaIoMsgs[0], priority, 0, romaddr, memaddr, len, &g_DmaMesgQueue);
|
||||
osRecvMesg(&g_DmaMesgQueue, (OSMesg) &msg, OS_MESG_BLOCK);
|
||||
}
|
||||
|
||||
void dmaExec(void *memaddr, u32 romaddr, u32 len)
|
||||
{
|
||||
dmaStart(memaddr, romaddr, len, false);
|
||||
dmaWait();
|
||||
dmaStart(memaddr, romaddr, len, OS_MESG_PRI_NORMAL);
|
||||
}
|
||||
|
||||
void dmaExecHighPriority(void *memaddr, u32 romaddr, u32 len)
|
||||
{
|
||||
dmaStart(memaddr, romaddr, len, true);
|
||||
dmaWait();
|
||||
dmaStart(memaddr, romaddr, len, OS_MESG_PRI_HIGH);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user