completely label and document dma3_manager.c
This commit is contained in:
parent
11cf2950ae
commit
3b097262f5
3 changed files with 81 additions and 79 deletions
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
void ClearDma3Requests(void);
|
void ClearDma3Requests(void);
|
||||||
void ProcessDma3Requests(void);
|
void ProcessDma3Requests(void);
|
||||||
int RequestDma3Copy(const void *src, void *dest, u16 size, u8 mode);
|
s16 RequestDma3Copy(const void *src, void *dest, u16 size, u8 mode);
|
||||||
int RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode);
|
s16 RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode);
|
||||||
int CheckForSpaceForDma3Request(s16 index);
|
int CheckForSpaceForDma3Request(s16 index);
|
||||||
|
|
||||||
#endif // GUARD_DMA3_H
|
#endif // GUARD_DMA3_H
|
||||||
|
|
|
@ -1,13 +1,24 @@
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "dma3.h"
|
#include "dma3.h"
|
||||||
|
|
||||||
IWRAM_DATA struct {
|
// Maximum amount of data we will transfer in one operation
|
||||||
/* 0x00 */ const u8 *src;
|
#define MAX_DMA_BLOCK_SIZE 0x1000
|
||||||
/* 0x04 */ u8 *dest;
|
|
||||||
/* 0x08 */ u16 size;
|
#define MAX_DMA_REQUESTS 128
|
||||||
/* 0x0A */ u16 mode;
|
|
||||||
/* 0x0C */ u32 value;
|
#define DMA_REQUEST_COPY32 1
|
||||||
} gDma3Requests[128];
|
#define DMA_REQUEST_FILL32 2
|
||||||
|
#define DMA_REQUEST_COPY16 3
|
||||||
|
#define DMA_REQUEST_FILL16 4
|
||||||
|
|
||||||
|
IWRAM_DATA struct
|
||||||
|
{
|
||||||
|
const u8 *src;
|
||||||
|
u8 *dest;
|
||||||
|
u16 size;
|
||||||
|
u16 mode;
|
||||||
|
u32 value;
|
||||||
|
} gDma3Requests[MAX_DMA_REQUESTS];
|
||||||
|
|
||||||
static bool8 gDma3ManagerLocked;
|
static bool8 gDma3ManagerLocked;
|
||||||
static u8 gDma3RequestCursor;
|
static u8 gDma3RequestCursor;
|
||||||
|
@ -19,19 +30,16 @@ void ClearDma3Requests(void)
|
||||||
gDma3ManagerLocked = TRUE;
|
gDma3ManagerLocked = TRUE;
|
||||||
gDma3RequestCursor = 0;
|
gDma3RequestCursor = 0;
|
||||||
|
|
||||||
for(i = 0; i < (u8)ARRAY_COUNT(gDma3Requests); i++)
|
for (i = 0; i < MAX_DMA_REQUESTS; i++)
|
||||||
{
|
{
|
||||||
gDma3Requests[i].size = 0;
|
gDma3Requests[i].size = 0;
|
||||||
gDma3Requests[i].src = 0;
|
gDma3Requests[i].src = NULL;
|
||||||
gDma3Requests[i].dest = 0;
|
gDma3Requests[i].dest = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gDma3ManagerLocked = FALSE;
|
gDma3ManagerLocked = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maximum amount of data will will transfer in one operation
|
|
||||||
#define DMA_MAX_BLOCK_SIZE 0x1000
|
|
||||||
|
|
||||||
#define Dma3CopyLarge_(src, dest, size, bit) \
|
#define Dma3CopyLarge_(src, dest, size, bit) \
|
||||||
{ \
|
{ \
|
||||||
const void *_src = src; \
|
const void *_src = src; \
|
||||||
|
@ -39,15 +47,15 @@ void ClearDma3Requests(void)
|
||||||
u32 _size = size; \
|
u32 _size = size; \
|
||||||
while (1) \
|
while (1) \
|
||||||
{ \
|
{ \
|
||||||
if (_size <= DMA_MAX_BLOCK_SIZE) \
|
if (_size <= MAX_DMA_BLOCK_SIZE) \
|
||||||
{ \
|
{ \
|
||||||
DmaCopy##bit(3, _src, _dest, _size); \
|
DmaCopy##bit(3, _src, _dest, _size); \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
DmaCopy##bit(3, _src, _dest, DMA_MAX_BLOCK_SIZE); \
|
DmaCopy##bit(3, _src, _dest, MAX_DMA_BLOCK_SIZE); \
|
||||||
_src += DMA_MAX_BLOCK_SIZE; \
|
_src += MAX_DMA_BLOCK_SIZE; \
|
||||||
_dest += DMA_MAX_BLOCK_SIZE; \
|
_dest += MAX_DMA_BLOCK_SIZE; \
|
||||||
_size -= DMA_MAX_BLOCK_SIZE; \
|
_size -= MAX_DMA_BLOCK_SIZE; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,14 +68,14 @@ void ClearDma3Requests(void)
|
||||||
u32 _size = size; \
|
u32 _size = size; \
|
||||||
while (1) \
|
while (1) \
|
||||||
{ \
|
{ \
|
||||||
if (_size <= DMA_MAX_BLOCK_SIZE) \
|
if (_size <= MAX_DMA_BLOCK_SIZE) \
|
||||||
{ \
|
{ \
|
||||||
DmaFill##bit(3, value, _dest, _size); \
|
DmaFill##bit(3, value, _dest, _size); \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
DmaFill##bit(3, value, _dest, DMA_MAX_BLOCK_SIZE); \
|
DmaFill##bit(3, value, _dest, MAX_DMA_BLOCK_SIZE); \
|
||||||
_dest += DMA_MAX_BLOCK_SIZE; \
|
_dest += MAX_DMA_BLOCK_SIZE; \
|
||||||
_size -= DMA_MAX_BLOCK_SIZE; \
|
_size -= MAX_DMA_BLOCK_SIZE; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,46 +85,48 @@ void ClearDma3Requests(void)
|
||||||
|
|
||||||
void ProcessDma3Requests(void)
|
void ProcessDma3Requests(void)
|
||||||
{
|
{
|
||||||
u16 totalSize;
|
u16 bytesTransferred;
|
||||||
|
|
||||||
if (gDma3ManagerLocked)
|
if (gDma3ManagerLocked)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
totalSize = 0;
|
bytesTransferred = 0;
|
||||||
|
|
||||||
// as long as there are DMA requests to process (unless size or vblank is an issue), do not exit
|
// as long as there are DMA requests to process (unless size or vblank is an issue), do not exit
|
||||||
while (gDma3Requests[gDma3RequestCursor].size != 0)
|
while (gDma3Requests[gDma3RequestCursor].size != 0)
|
||||||
{
|
{
|
||||||
totalSize += gDma3Requests[gDma3RequestCursor].size;
|
bytesTransferred += gDma3Requests[gDma3RequestCursor].size;
|
||||||
|
|
||||||
if (totalSize > 0xA000)
|
if (bytesTransferred > 40 * 1024)
|
||||||
return; // don't do too much at once
|
return; // don't transfer more than 40 KiB
|
||||||
if (*(u8 *)REG_ADDR_VCOUNT > 224)
|
if (*(u8 *)REG_ADDR_VCOUNT > 224)
|
||||||
return; // we're about to leave vblank, stop
|
return; // we're about to leave vblank, stop
|
||||||
|
|
||||||
switch (gDma3Requests[gDma3RequestCursor].mode)
|
switch (gDma3Requests[gDma3RequestCursor].mode)
|
||||||
{
|
{
|
||||||
case 1: // regular 32-bit copy
|
case DMA_REQUEST_COPY32: // regular 32-bit copy
|
||||||
Dma3CopyLarge32_(gDma3Requests[gDma3RequestCursor].src,
|
Dma3CopyLarge32_(gDma3Requests[gDma3RequestCursor].src,
|
||||||
gDma3Requests[gDma3RequestCursor].dest,
|
gDma3Requests[gDma3RequestCursor].dest,
|
||||||
gDma3Requests[gDma3RequestCursor].size);
|
gDma3Requests[gDma3RequestCursor].size);
|
||||||
break;
|
break;
|
||||||
case 2: // repeat a single 32-bit value across RAM
|
case DMA_REQUEST_FILL32: // repeat a single 32-bit value across RAM
|
||||||
Dma3FillLarge32_(gDma3Requests[gDma3RequestCursor].value,
|
Dma3FillLarge32_(gDma3Requests[gDma3RequestCursor].value,
|
||||||
gDma3Requests[gDma3RequestCursor].dest,
|
gDma3Requests[gDma3RequestCursor].dest,
|
||||||
gDma3Requests[gDma3RequestCursor].size);
|
gDma3Requests[gDma3RequestCursor].size);
|
||||||
break;
|
break;
|
||||||
case 3: // regular 16-bit copy
|
case DMA_REQUEST_COPY16: // regular 16-bit copy
|
||||||
Dma3CopyLarge16_(gDma3Requests[gDma3RequestCursor].src,
|
Dma3CopyLarge16_(gDma3Requests[gDma3RequestCursor].src,
|
||||||
gDma3Requests[gDma3RequestCursor].dest,
|
gDma3Requests[gDma3RequestCursor].dest,
|
||||||
gDma3Requests[gDma3RequestCursor].size);
|
gDma3Requests[gDma3RequestCursor].size);
|
||||||
break;
|
break;
|
||||||
case 4: // repeat a single 16-bit value across RAM
|
case DMA_REQUEST_FILL16: // repeat a single 16-bit value across RAM
|
||||||
Dma3FillLarge16_(gDma3Requests[gDma3RequestCursor].value,
|
Dma3FillLarge16_(gDma3Requests[gDma3RequestCursor].value,
|
||||||
gDma3Requests[gDma3RequestCursor].dest,
|
gDma3Requests[gDma3RequestCursor].dest,
|
||||||
gDma3Requests[gDma3RequestCursor].size);
|
gDma3Requests[gDma3RequestCursor].size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free the request
|
||||||
gDma3Requests[gDma3RequestCursor].src = NULL;
|
gDma3Requests[gDma3RequestCursor].src = NULL;
|
||||||
gDma3Requests[gDma3RequestCursor].dest = NULL;
|
gDma3Requests[gDma3RequestCursor].dest = NULL;
|
||||||
gDma3Requests[gDma3RequestCursor].size = 0;
|
gDma3Requests[gDma3RequestCursor].size = 0;
|
||||||
|
@ -124,59 +134,54 @@ void ProcessDma3Requests(void)
|
||||||
gDma3Requests[gDma3RequestCursor].value = 0;
|
gDma3Requests[gDma3RequestCursor].value = 0;
|
||||||
gDma3RequestCursor++;
|
gDma3RequestCursor++;
|
||||||
|
|
||||||
if (gDma3RequestCursor >= 128) // loop back to the first DMA request
|
if (gDma3RequestCursor >= MAX_DMA_REQUESTS) // loop back to the first DMA request
|
||||||
gDma3RequestCursor = 0;
|
gDma3RequestCursor = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int RequestDma3Copy(const void *src, void *dest, u16 size, u8 mode)
|
s16 RequestDma3Copy(const void *src, void *dest, u16 size, u8 mode)
|
||||||
{
|
{
|
||||||
int cursor;
|
int cursor;
|
||||||
int var = 0;
|
int i = 0;
|
||||||
|
|
||||||
gDma3ManagerLocked = 1;
|
|
||||||
|
|
||||||
|
gDma3ManagerLocked = TRUE;
|
||||||
cursor = gDma3RequestCursor;
|
cursor = gDma3RequestCursor;
|
||||||
while(1)
|
|
||||||
|
while (i < MAX_DMA_REQUESTS)
|
||||||
{
|
{
|
||||||
if(!gDma3Requests[cursor].size) // an empty copy was found and the current cursor will be returned.
|
if (gDma3Requests[cursor].size == 0) // an empty request was found.
|
||||||
{
|
{
|
||||||
gDma3Requests[cursor].src = src;
|
gDma3Requests[cursor].src = src;
|
||||||
gDma3Requests[cursor].dest = dest;
|
gDma3Requests[cursor].dest = dest;
|
||||||
gDma3Requests[cursor].size = size;
|
gDma3Requests[cursor].size = size;
|
||||||
|
|
||||||
if(mode == 1)
|
if (mode == 1)
|
||||||
gDma3Requests[cursor].mode = mode;
|
gDma3Requests[cursor].mode = DMA_REQUEST_COPY32;
|
||||||
else
|
else
|
||||||
gDma3Requests[cursor].mode = 3;
|
gDma3Requests[cursor].mode = DMA_REQUEST_COPY16;
|
||||||
|
|
||||||
gDma3ManagerLocked = FALSE;
|
gDma3ManagerLocked = FALSE;
|
||||||
return (s16)cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
if(++cursor >= 0x80) // loop back to start.
|
if (++cursor >= MAX_DMA_REQUESTS) // loop back to start.
|
||||||
{
|
|
||||||
cursor = 0;
|
cursor = 0;
|
||||||
}
|
i++;
|
||||||
if(++var >= 0x80) // max checks were made. all resulted in failure.
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
gDma3ManagerLocked = FALSE;
|
gDma3ManagerLocked = FALSE;
|
||||||
return -1;
|
return -1; // no free DMA request was found
|
||||||
}
|
}
|
||||||
|
|
||||||
int RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode)
|
s16 RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode)
|
||||||
{
|
{
|
||||||
int cursor;
|
int cursor;
|
||||||
int var = 0;
|
int i = 0;
|
||||||
|
|
||||||
cursor = gDma3RequestCursor;
|
cursor = gDma3RequestCursor;
|
||||||
gDma3ManagerLocked = 1;
|
gDma3ManagerLocked = TRUE;
|
||||||
|
|
||||||
while(1)
|
while (i < MAX_DMA_REQUESTS)
|
||||||
{
|
{
|
||||||
if(!gDma3Requests[cursor].size)
|
if (gDma3Requests[cursor].size == 0) // an empty request was found.
|
||||||
{
|
{
|
||||||
gDma3Requests[cursor].dest = dest;
|
gDma3Requests[cursor].dest = dest;
|
||||||
gDma3Requests[cursor].size = size;
|
gDma3Requests[cursor].size = size;
|
||||||
|
@ -184,41 +189,39 @@ int RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode)
|
||||||
gDma3Requests[cursor].value = value;
|
gDma3Requests[cursor].value = value;
|
||||||
|
|
||||||
if(mode == 1)
|
if(mode == 1)
|
||||||
gDma3Requests[cursor].mode = 2;
|
gDma3Requests[cursor].mode = DMA_REQUEST_FILL32;
|
||||||
else
|
else
|
||||||
gDma3Requests[cursor].mode = 4;
|
gDma3Requests[cursor].mode = DMA_REQUEST_FILL16;
|
||||||
|
|
||||||
gDma3ManagerLocked = FALSE;
|
gDma3ManagerLocked = FALSE;
|
||||||
return (s16)cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
if(++cursor >= 0x80) // loop back to start.
|
if (++cursor >= MAX_DMA_REQUESTS) // loop back to start.
|
||||||
{
|
|
||||||
cursor = 0;
|
cursor = 0;
|
||||||
}
|
i++;
|
||||||
if(++var >= 0x80) // max checks were made. all resulted in failure.
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
gDma3ManagerLocked = FALSE;
|
gDma3ManagerLocked = FALSE;
|
||||||
return -1;
|
return -1; // no free DMA request was found
|
||||||
}
|
}
|
||||||
|
|
||||||
int CheckForSpaceForDma3Request(s16 index)
|
int CheckForSpaceForDma3Request(s16 index)
|
||||||
{
|
{
|
||||||
int current = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (index == -1)
|
if (index == -1) // check if all requests are free
|
||||||
{
|
{
|
||||||
for (; current < 0x80; current ++)
|
while (i < MAX_DMA_REQUESTS)
|
||||||
if (gDma3Requests[current].size)
|
{
|
||||||
|
if (gDma3Requests[i].size != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else // check the specified request
|
||||||
|
{
|
||||||
|
if (gDma3Requests[index].size != 0)
|
||||||
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gDma3Requests[index].size)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -332,7 +332,6 @@ void SetSerialCallback(IntrCallback callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void CopyBufferedValuesToGpuRegs(void);
|
extern void CopyBufferedValuesToGpuRegs(void);
|
||||||
extern void ProcessDma3Requests(void);
|
|
||||||
|
|
||||||
static void VBlankIntr(void)
|
static void VBlankIntr(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue