Use new bitfields for DMAs
Jeffrey Pfau jeffrey@endrift.com
Wed, 01 Oct 2014 00:17:51 -0700
5 files changed,
34 insertions(+),
32 deletions(-)
M
src/arm/common.h
→
src/arm/common.h
@@ -64,6 +64,7 @@
#define MAKE_MASK(START, END) (((1 << ((END) - (START))) - 1) << (START)) #define CHECK_BITS(SRC, START, END) ((SRC) & MAKE_MASK(START, END)) #define EXT_BITS(SRC, START, END) (((SRC) >> (START)) & ((1 << ((END) - (START))) - 1)) +#define INS_BITS(SRC, START, END, BITS) (CLEAR_BITS(SRC, START, END) | (((BITS) << (START)) & MAKE_MASK(START, END))) #define CLEAR_BITS(SRC, START, END) ((SRC) & ~MAKE_MASK(START, END)) #define FILL_BITS(SRC, START, END) ((SRC) | MAKE_MASK(START, END))@@ -81,6 +82,9 @@ return CLEAR_BITS(src, (START), (START) + (SIZE)); \
} \ static inline TYPE TYPE ## Fill ## FIELD (TYPE src) { \ return FILL_BITS(src, (START), (START) + (SIZE)); \ + } \ + static inline TYPE TYPE ## Set ## FIELD (TYPE src, TYPE bits) { \ + return INS_BITS(src, (START), (START) + (SIZE), bits); \ } #define DECL_BIT(TYPE, FIELD, BIT) DECL_BITS(TYPE, FIELD, BIT, 1)
M
src/gba/gba-audio.c
→
src/gba/gba-audio.c
@@ -253,7 +253,7 @@ default:
GBALog(audio->p, GBA_LOG_GAME_ERROR, "Invalid FIFO destination: 0x%08X", info->dest); return; } - info->dstControl = DMA_FIXED; + info->reg = GBADMARegisterSetDestControl(info->reg, DMA_FIXED); } void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value) {
M
src/gba/gba-io.c
→
src/gba/gba-io.c
@@ -482,7 +482,7 @@ gba->memory.dma[i].nextSource = state->dma[i].nextSource;
gba->memory.dma[i].nextDest = state->dma[i].nextDest; gba->memory.dma[i].nextCount = state->dma[i].nextCount; gba->memory.dma[i].nextEvent = state->dma[i].nextEvent; - if (gba->memory.dma[i].timing != DMA_TIMING_NOW) { + if (GBADMARegisterGetTiming(gba->memory.dma[i].reg) != DMA_TIMING_NOW) { GBAMemoryScheduleDMA(gba, i, &gba->memory.dma[i]); }
M
src/gba/gba-memory.c
→
src/gba/gba-memory.c
@@ -651,26 +651,26 @@
uint16_t GBAMemoryWriteDMACNT_HI(struct GBA* gba, int dma, uint16_t control) { struct GBAMemory* memory = &gba->memory; struct GBADMA* currentDma = &memory->dma[dma]; - int wasEnabled = currentDma->enable; - currentDma->packed = control; + int wasEnabled = GBADMARegisterIsEnable(currentDma->reg); + currentDma->reg = control; - if (currentDma->drq) { + if (GBADMARegisterIsDRQ(currentDma->reg)) { GBALog(gba, GBA_LOG_STUB, "DRQ not implemented"); } - if (!wasEnabled && currentDma->enable) { + if (!wasEnabled && GBADMARegisterIsEnable(currentDma->reg)) { currentDma->nextSource = currentDma->source; currentDma->nextDest = currentDma->dest; currentDma->nextCount = currentDma->count; GBAMemoryScheduleDMA(gba, dma, currentDma); } // If the DMA has already occurred, this value might have changed since the function started - return currentDma->packed; + return currentDma->reg; }; void GBAMemoryScheduleDMA(struct GBA* gba, int number, struct GBADMA* info) { struct ARMCore* cpu = gba->cpu; - switch (info->timing) { + switch (GBADMARegisterGetTiming(info->reg)) { case DMA_TIMING_NOW: info->nextEvent = cpu->cycles; GBAMemoryUpdateDMAs(gba, 0);@@ -706,7 +706,7 @@ struct GBADMA* dma;
int i; for (i = 0; i < 4; ++i) { dma = &memory->dma[i]; - if (dma->enable && dma->timing == DMA_TIMING_HBLANK) { + if (GBADMARegisterIsEnable(dma->reg) && GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_HBLANK) { dma->nextEvent = cycles; } }@@ -719,7 +719,7 @@ struct GBADMA* dma;
int i; for (i = 0; i < 4; ++i) { dma = &memory->dma[i]; - if (dma->enable && dma->timing == DMA_TIMING_VBLANK) { + if (GBADMARegisterIsEnable(dma->reg) && GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_VBLANK) { dma->nextEvent = cycles; } }@@ -752,7 +752,7 @@ for (i = 3; i >= 0; --i) {
struct GBADMA* dma = &memory->dma[i]; if (dma->nextEvent != INT_MAX) { dma->nextEvent -= cycles; - if (dma->enable) { + if (GBADMARegisterIsEnable(dma->reg)) { memory->activeDMA = i; memory->nextDMA = dma->nextEvent; }@@ -766,9 +766,9 @@
void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info) { struct GBAMemory* memory = &gba->memory; struct ARMCore* cpu = gba->cpu; - uint32_t width = info->width ? 4 : 2; - int sourceOffset = DMA_OFFSET[info->srcControl] * width; - int destOffset = DMA_OFFSET[info->dstControl] * width; + uint32_t width = GBADMARegisterGetWidth(info->reg) ? 4 : 2; + int sourceOffset = DMA_OFFSET[GBADMARegisterGetSrcControl(info->reg)] * width; + int destOffset = DMA_OFFSET[GBADMARegisterGetDestControl(info->reg)] * width; int32_t wordsRemaining = info->nextCount; uint32_t source = info->nextSource; uint32_t dest = info->nextDest;@@ -828,20 +828,20 @@ }
} if (!wordsRemaining) { - if (!info->repeat) { - info->enable = 0; + if (!GBADMARegisterIsRepeat(info->reg)) { + info->reg = GBADMARegisterClearEnable(info->reg); info->nextEvent = INT_MAX; // Clear the enable bit in memory memory->io[(REG_DMA0CNT_HI + number * (REG_DMA1CNT_HI - REG_DMA0CNT_HI)) >> 1] &= 0x7FE0; } else { info->nextCount = info->count; - if (info->dstControl == DMA_INCREMENT_RELOAD) { + if (GBADMARegisterGetDestControl(info->reg) == DMA_INCREMENT_RELOAD) { info->nextDest = info->dest; } GBAMemoryScheduleDMA(gba, number, info); } - if (info->doIrq) { + if (GBADMARegisterIsDoIRQ(info->reg)) { GBARaiseIRQ(gba, IRQ_DMA0 + number); } } else {
M
src/gba/gba-memory.h
→
src/gba/gba-memory.h
@@ -80,21 +80,19 @@ DMA_TIMING_HBLANK = 2,
DMA_TIMING_CUSTOM = 3 }; + +DECL_BITFIELD(GBADMARegister, uint16_t); +DECL_BITS(GBADMARegister, DestControl, 5, 2); +DECL_BITS(GBADMARegister, SrcControl, 7, 2); +DECL_BIT(GBADMARegister, Repeat, 9); +DECL_BIT(GBADMARegister, Width, 10); +DECL_BIT(GBADMARegister, DRQ, 11); +DECL_BITS(GBADMARegister, Timing, 12, 2); +DECL_BIT(GBADMARegister, DoIRQ, 14); +DECL_BIT(GBADMARegister, Enable, 15); + struct GBADMA { - union { - struct { - int : 5; - enum DMAControl dstControl : 2; - enum DMAControl srcControl : 2; - unsigned repeat : 1; - unsigned width : 1; - unsigned drq : 1; - enum DMATiming timing : 2; - unsigned doIrq : 1; - unsigned enable : 1; - }; - uint16_t packed; - }; + GBADMARegister reg; uint32_t source; uint32_t dest;