Skip to content

Commit

Permalink
completely label and document dma3_manager.c
Browse files Browse the repository at this point in the history
  • Loading branch information
camthesaxman committed Jan 8, 2018
1 parent 11cf295 commit 3b09726
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 79 deletions.
4 changes: 2 additions & 2 deletions include/dma3.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

void ClearDma3Requests(void);
void ProcessDma3Requests(void);
int RequestDma3Copy(const void *src, void *dest, u16 size, u8 mode);
int RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode);
s16 RequestDma3Copy(const void *src, void *dest, u16 size, u8 mode);
s16 RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode);
int CheckForSpaceForDma3Request(s16 index);

#endif // GUARD_DMA3_H
155 changes: 79 additions & 76 deletions src/dma3_manager.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
#include "global.h"
#include "dma3.h"

IWRAM_DATA struct {
/* 0x00 */ const u8 *src;
/* 0x04 */ u8 *dest;
/* 0x08 */ u16 size;
/* 0x0A */ u16 mode;
/* 0x0C */ u32 value;
} gDma3Requests[128];
// Maximum amount of data we will transfer in one operation
#define MAX_DMA_BLOCK_SIZE 0x1000

#define MAX_DMA_REQUESTS 128

#define DMA_REQUEST_COPY32 1
#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 u8 gDma3RequestCursor;
Expand All @@ -19,35 +30,32 @@ void ClearDma3Requests(void)
gDma3ManagerLocked = TRUE;
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].src = 0;
gDma3Requests[i].dest = 0;
gDma3Requests[i].src = NULL;
gDma3Requests[i].dest = NULL;
}

gDma3ManagerLocked = FALSE;
}

// Maximum amount of data will will transfer in one operation
#define DMA_MAX_BLOCK_SIZE 0x1000

#define Dma3CopyLarge_(src, dest, size, bit) \
{ \
const void *_src = src; \
void *_dest = dest; \
u32 _size = size; \
while (1) \
{ \
if (_size <= DMA_MAX_BLOCK_SIZE) \
if (_size <= MAX_DMA_BLOCK_SIZE) \
{ \
DmaCopy##bit(3, _src, _dest, _size); \
break; \
} \
DmaCopy##bit(3, _src, _dest, DMA_MAX_BLOCK_SIZE); \
_src += DMA_MAX_BLOCK_SIZE; \
_dest += DMA_MAX_BLOCK_SIZE; \
_size -= DMA_MAX_BLOCK_SIZE; \
DmaCopy##bit(3, _src, _dest, MAX_DMA_BLOCK_SIZE); \
_src += MAX_DMA_BLOCK_SIZE; \
_dest += MAX_DMA_BLOCK_SIZE; \
_size -= MAX_DMA_BLOCK_SIZE; \
} \
}

Expand All @@ -60,14 +68,14 @@ void ClearDma3Requests(void)
u32 _size = size; \
while (1) \
{ \
if (_size <= DMA_MAX_BLOCK_SIZE) \
if (_size <= MAX_DMA_BLOCK_SIZE) \
{ \
DmaFill##bit(3, value, _dest, _size); \
break; \
} \
DmaFill##bit(3, value, _dest, DMA_MAX_BLOCK_SIZE); \
_dest += DMA_MAX_BLOCK_SIZE; \
_size -= DMA_MAX_BLOCK_SIZE; \
DmaFill##bit(3, value, _dest, MAX_DMA_BLOCK_SIZE); \
_dest += MAX_DMA_BLOCK_SIZE; \
_size -= MAX_DMA_BLOCK_SIZE; \
} \
}

Expand All @@ -77,148 +85,143 @@ void ClearDma3Requests(void)

void ProcessDma3Requests(void)
{
u16 totalSize;
u16 bytesTransferred;

if (gDma3ManagerLocked)
return;

totalSize = 0;
bytesTransferred = 0;

// as long as there are DMA requests to process (unless size or vblank is an issue), do not exit
while (gDma3Requests[gDma3RequestCursor].size != 0)
{
totalSize += gDma3Requests[gDma3RequestCursor].size;
bytesTransferred += gDma3Requests[gDma3RequestCursor].size;

if (totalSize > 0xA000)
return; // don't do too much at once
if (bytesTransferred > 40 * 1024)
return; // don't transfer more than 40 KiB
if (*(u8 *)REG_ADDR_VCOUNT > 224)
return; // we're about to leave vblank, stop

switch (gDma3Requests[gDma3RequestCursor].mode)
{
case 1: // regular 32-bit copy
case DMA_REQUEST_COPY32: // regular 32-bit copy
Dma3CopyLarge32_(gDma3Requests[gDma3RequestCursor].src,
gDma3Requests[gDma3RequestCursor].dest,
gDma3Requests[gDma3RequestCursor].size);
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,
gDma3Requests[gDma3RequestCursor].dest,
gDma3Requests[gDma3RequestCursor].size);
break;
case 3: // regular 16-bit copy
case DMA_REQUEST_COPY16: // regular 16-bit copy
Dma3CopyLarge16_(gDma3Requests[gDma3RequestCursor].src,
gDma3Requests[gDma3RequestCursor].dest,
gDma3Requests[gDma3RequestCursor].size);
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,
gDma3Requests[gDma3RequestCursor].dest,
gDma3Requests[gDma3RequestCursor].size);
break;
}

// Free the request
gDma3Requests[gDma3RequestCursor].src = NULL;
gDma3Requests[gDma3RequestCursor].dest = NULL;
gDma3Requests[gDma3RequestCursor].size = 0;
gDma3Requests[gDma3RequestCursor].mode = 0;
gDma3Requests[gDma3RequestCursor].value = 0;
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;
}
}

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 var = 0;

gDma3ManagerLocked = 1;
int i = 0;

gDma3ManagerLocked = TRUE;
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].dest = dest;
gDma3Requests[cursor].size = size;

if(mode == 1)
gDma3Requests[cursor].mode = mode;
if (mode == 1)
gDma3Requests[cursor].mode = DMA_REQUEST_COPY32;
else
gDma3Requests[cursor].mode = 3;
gDma3Requests[cursor].mode = DMA_REQUEST_COPY16;

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;
}
if(++var >= 0x80) // max checks were made. all resulted in failure.
{
break;
}
i++;
}
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 var = 0;
int i = 0;

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].size = size;
gDma3Requests[cursor].mode = mode;
gDma3Requests[cursor].value = value;

if(mode == 1)
gDma3Requests[cursor].mode = 2;
gDma3Requests[cursor].mode = DMA_REQUEST_FILL32;
else
gDma3Requests[cursor].mode = 4;
gDma3Requests[cursor].mode = DMA_REQUEST_FILL16;

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;
}
if(++var >= 0x80) // max checks were made. all resulted in failure.
{
break;
}
i++;
}
gDma3ManagerLocked = FALSE;
return -1;
return -1; // no free DMA request was found
}

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 ++)
if (gDma3Requests[current].size)
while (i < MAX_DMA_REQUESTS)
{
if (gDma3Requests[i].size != 0)
return -1;

i++;
}
return 0;
}
else // check the specified request
{
if (gDma3Requests[index].size != 0)
return -1;
return 0;
}

if (gDma3Requests[index].size)
return -1;

return 0;
}
1 change: 0 additions & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,6 @@ void SetSerialCallback(IntrCallback callback)
}

extern void CopyBufferedValuesToGpuRegs(void);
extern void ProcessDma3Requests(void);

static void VBlankIntr(void)
{
Expand Down

0 comments on commit 3b09726

Please sign in to comment.