Created
December 24, 2023 21:08
-
-
Save luckytyphlosion/a6ce7b1ebba05e7f56f94e79a3b52121 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef GUARD_GBA_MACRO_H | |
#define GUARD_GBA_MACRO_H | |
#define CPU_FILL(value, dest, size, bit) \ | |
{ \ | |
vu##bit tmp = (vu##bit)(value); \ | |
CpuSet((void *)&tmp, \ | |
dest, \ | |
CPU_SET_##bit##BIT | CPU_SET_SRC_FIXED | ((size)/(bit/8) & 0x1FFFFF)); \ | |
} | |
#define CpuFill16(value, dest, size) CPU_FILL(value, dest, size, 16) | |
#define CpuFill32(value, dest, size) CPU_FILL(value, dest, size, 32) | |
#define CPU_COPY(src, dest, size, bit) CpuSet(src, dest, CPU_SET_##bit##BIT | ((size)/(bit/8) & 0x1FFFFF)) | |
#define CpuCopy16(src, dest, size) CPU_COPY(src, dest, size, 16) | |
#define CpuCopy32(src, dest, size) CPU_COPY(src, dest, size, 32) | |
#define CpuSmartCopy16(src, dest, size) \ | |
{ \ | |
if ((((size) & 0x1f) == 0) && ((((u32)(src)) & 3) == 0) && ((((u32)(dest)) & 3) == 0)) { \ | |
CpuFastCopy((src), (dest), (size)); \ | |
} else { \ | |
CpuCopy16((src), (dest), (size)); \ | |
} \ | |
} | |
#define CpuSmartCopy32(src, dest, size) \ | |
{ \ | |
if ((((size) & 0x1f) == 0) && ((((u32)(src)) & 3) == 0) && ((((u32)(dest)) & 3) == 0)) { \ | |
CpuFastCopy((src), (dest), (size)); \ | |
} else { \ | |
CpuCopy32((src), (dest), (size)); \ | |
} \ | |
} | |
#define CpuFastFill(value, dest, size) \ | |
{ \ | |
vu32 tmp = (vu32)(value); \ | |
CpuFastSet((void *)&tmp, \ | |
dest, \ | |
CPU_FAST_SET_SRC_FIXED | ((size)/(32/8) & 0x1FFFFF)); \ | |
} | |
#define CpuFastFill16(value, dest, size) CpuFastFill(((value) << 16) | (value), (dest), (size)) | |
#define CpuFastFill8(value, dest, size) CpuFastFill(((value) << 24) | ((value) << 16) | ((value) << 8) | (value), (dest), (size)) | |
#define CpuSmartFill(value, dest, size) \ | |
{ \ | |
if ((((size) & 0x1f) == 0) && ((((u32)(dest)) & 3) == 0)) { \ | |
CpuFastFill((value), (dest), (size)); \ | |
} else { \ | |
CpuFill32((value), (dest), (size)); \ | |
} \ | |
} | |
#define CpuSmartFill16(value, dest, size) \ | |
{ \ | |
if ((((size) & 0x1f) == 0) && ((((u32)(dest)) & 3) == 0)) { \ | |
CpuFastFill16((value), (dest), (size)); \ | |
} else { \ | |
CpuFill16((value), (dest), (size)); \ | |
} \ | |
} | |
#define CpuFastCopy(src, dest, size) CpuFastSet(src, dest, ((size)/(32/8) & 0x1FFFFF)) | |
#define DmaSet(dmaNum, src, dest, control) \ | |
{ \ | |
vu32 *dmaRegs = (vu32 *)REG_ADDR_DMA##dmaNum; \ | |
u32 eval_src = (u32)(src); \ | |
u32 eval_dst = (u32)(dest); \ | |
u32 eval_ctl = (u32)(control); \ | |
register u32 r_src asm("r0") = eval_src; \ | |
register u32 r_dst asm("r1") = eval_dst; \ | |
register u32 r_ctl asm("r2") = eval_ctl; \ | |
asm volatile("stmia %0!, {%1, %2, %3}" : "+l" (dmaRegs) : "l" (r_src), "l" (r_dst), "l" (r_ctl) : "memory"); \ | |
} | |
#define DMA_FILL(dmaNum, value, dest, size, bit) \ | |
{ \ | |
vu##bit tmp = (vu##bit)(value); \ | |
DmaSet(dmaNum, \ | |
&tmp, \ | |
dest, \ | |
(DMA_ENABLE | DMA_START_NOW | DMA_##bit##BIT | DMA_SRC_FIXED | DMA_DEST_INC) << 16 \ | |
| ((size)/(bit/8))); \ | |
} | |
#define DmaFill16(dmaNum, value, dest, size) DMA_FILL(dmaNum, value, dest, size, 16) | |
#define DmaFill32(dmaNum, value, dest, size) DMA_FILL(dmaNum, value, dest, size, 32) | |
// Note that the DMA clear macros cause the DMA control value to be calculated | |
// at runtime rather than compile time. The size is divided by the DMA transfer | |
// unit size (2 or 4 bytes) and then combined with the DMA control flags using a | |
// bitwise OR operation. | |
#define DMA_CLEAR(dmaNum, dest, size, bit) \ | |
{ \ | |
vu##bit *_dest = (vu##bit *)(dest); \ | |
u32 _size = size; \ | |
DmaFill##bit(dmaNum, 0, _dest, _size); \ | |
} | |
#define DmaClear16(dmaNum, dest, size) DMA_CLEAR(dmaNum, dest, size, 16) | |
#define DmaClear32(dmaNum, dest, size) DMA_CLEAR(dmaNum, dest, size, 32) | |
#define DMA_COPY(dmaNum, src, dest, size, bit) \ | |
DmaSet(dmaNum, \ | |
src, \ | |
dest, \ | |
(DMA_ENABLE | DMA_START_NOW | DMA_##bit##BIT | DMA_SRC_INC | DMA_DEST_INC) << 16 \ | |
| ((size)/(bit/8))) | |
#define DmaCopy16(dmaNum, src, dest, size) DMA_COPY(dmaNum, src, dest, size, 16) | |
#define DmaCopy32(dmaNum, src, dest, size) DMA_COPY(dmaNum, src, dest, size, 32) | |
#define DmaCopyLarge(dmaNum, src, dest, size, block, bit) \ | |
{ \ | |
const void *_src = src; \ | |
void *_dest = dest; \ | |
u32 _size = size; \ | |
while (1) \ | |
{ \ | |
DmaCopy##bit(dmaNum, _src, _dest, (block)); \ | |
_src += (block); \ | |
_dest += (block); \ | |
_size -= (block); \ | |
if (_size <= (block)) \ | |
{ \ | |
DmaCopy##bit(dmaNum, _src, _dest, _size); \ | |
break; \ | |
} \ | |
} \ | |
} | |
#define DmaCopyLarge16(dmaNum, src, dest, size, block) DmaCopyLarge(dmaNum, src, dest, size, block, 16) | |
#define DmaCopyLarge32(dmaNum, src, dest, size, block) DmaCopyLarge(dmaNum, src, dest, size, block, 32) | |
#define DmaFillLarge(dmaNum, value, dest, size, block, bit) \ | |
{ \ | |
void *_dest = dest; \ | |
u32 _size = size; \ | |
while (1) \ | |
{ \ | |
DmaFill##bit(dmaNum, value, _dest, (block)); \ | |
_dest += (block); \ | |
_size -= (block); \ | |
if (_size <= (block)) \ | |
{ \ | |
DmaFill##bit(dmaNum, value, _dest, _size); \ | |
break; \ | |
} \ | |
} \ | |
} | |
#define DmaFillLarge16(dmaNum, value, dest, size, block) DmaFillLarge(dmaNum, value, dest, size, block, 16) | |
#define DmaFillLarge32(dmaNum, value, dest, size, block) DmaFillLarge(dmaNum, value, dest, size, block, 32) | |
#define DmaClearLarge(dmaNum, dest, size, block, bit) \ | |
{ \ | |
void *_dest = dest; \ | |
u32 _size = size; \ | |
while (1) \ | |
{ \ | |
DmaFill##bit(dmaNum, 0, _dest, (block)); \ | |
_dest += (block); \ | |
_size -= (block); \ | |
if (_size <= (block)) \ | |
{ \ | |
DmaFill##bit(dmaNum, 0, _dest, _size); \ | |
break; \ | |
} \ | |
} \ | |
} | |
#define DmaClearLarge16(dmaNum, dest, size, block) DmaClearLarge(dmaNum, dest, size, block, 16) | |
#define DmaClearLarge32(dmaNum, dest, size, block) DmaClearLarge(dmaNum, dest, size, block, 32) | |
#define DmaCopyDefvars(dmaNum, src, dest, size, bit) \ | |
{ \ | |
const void *_src = src; \ | |
void *_dest = dest; \ | |
u32 _size = size; \ | |
DmaCopy##bit(dmaNum, _src, _dest, _size); \ | |
} | |
#define DmaCopy16Defvars(dmaNum, src, dest, size) DmaCopyDefvars(dmaNum, src, dest, size, 16) | |
#define DmaCopy32Defvars(dmaNum, src, dest, size) DmaCopyDefvars(dmaNum, src, dest, size, 32) | |
#define DmaFillDefvars(dmaNum, value, dest, size, bit) \ | |
{ \ | |
void *_dest = dest; \ | |
u32 _size = size; \ | |
DmaFill##bit(dmaNum, value, _dest, _size); \ | |
} | |
#define DmaFill16Defvars(dmaNum, value, dest, size) DmaFillDefvars(dmaNum, value, dest, size, 16) | |
#define DmaFill32Defvars(dmaNum, value, dest, size) DmaFillDefvars(dmaNum, value, dest, size, 32) | |
#define DmaClearDefvars(dmaNum, dest, size, bit) \ | |
{ \ | |
void *_dest = dest; \ | |
u32 _size = size; \ | |
DmaClear##bit(dmaNum, _dest, _size); \ | |
} | |
#define DmaClear16Defvars(dmaNum, dest, size) DmaClearDefvars(dmaNum, dest, size, 16) | |
#define DmaClear32Defvars(dmaNum, dest, size) DmaClearDefvars(dmaNum, dest, size, 32) | |
#define DmaStop(dmaNum) \ | |
{ \ | |
vu16 *dmaRegs = (vu16 *)REG_ADDR_DMA##dmaNum; \ | |
dmaRegs[5] &= ~(DMA_START_MASK | DMA_DREQ_ON | DMA_REPEAT); \ | |
dmaRegs[5] &= ~DMA_ENABLE; \ | |
dmaRegs[5]; \ | |
} | |
#define IntrEnable(flags) \ | |
{ \ | |
u16 imeTemp; \ | |
\ | |
imeTemp = REG_IME; \ | |
REG_IME = 0; \ | |
REG_IE |= flags; \ | |
REG_IME = imeTemp; \ | |
} \ | |
#endif // GUARD_GBA_MACRO_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment