all repos — mgba @ 0ff5f43eb0f14409614282fb27d540eec1fb516f

mGBA Game Boy Advance Emulator

DS GX: Implement GX DMAs
Vicki Pfau vi@endrift.com
Sat, 04 Mar 2017 10:59:44 -0800
commit

0ff5f43eb0f14409614282fb27d540eec1fb516f

parent

6103d49697c8015264ab18cf2a8d3c07dd893289

3 files changed, 30 insertions(+), 0 deletions(-)

jump to
M include/mgba/internal/ds/gx.hinclude/mgba/internal/ds/gx.h

@@ -157,6 +157,7 @@ struct CircleBuffer fifo;

struct CircleBuffer pipe; struct mTimingEvent fifoEvent; + int dmaSource; int outstandingParams[4]; uint8_t outstandingCommand[4];

@@ -213,6 +214,10 @@ uint32_t DSGXWriteRegister32(struct DSGX*, uint32_t address, uint32_t value);

void DSGXFlush(struct DSGX*); void DSGXUpdateGXSTAT(struct DSGX*); + +struct GBADMA; +struct DSCommon; +void DSGXScheduleDMA(struct DSCommon* dscore, int number, struct GBADMA* info); CXX_GUARD_END
M src/ds/dma.csrc/ds/dma.c

@@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <mgba/internal/ds/dma.h> #include <mgba/internal/ds/ds.h> +#include <mgba/internal/ds/gx.h> #include <mgba/internal/ds/io.h> #include <mgba/internal/ds/memory.h>

@@ -97,6 +98,9 @@ // Handled implicitly

return; case DS9_DMA_TIMING_SLOT1: DSSlot1ScheduleDMA(dscore, number, info); + return; + case DS_DMA_TIMING_GEOM_FIFO: + DSGXScheduleDMA(dscore, number, info); return; case DS_DMA_TIMING_HBLANK: // DS7_DMA_TIMING_SLOT1 default:
M src/ds/gx.csrc/ds/gx.c

@@ -1021,6 +1021,7 @@ gx->activeParams = 0;

memset(&gx->currentVertex, 0, sizeof(gx->currentVertex)); memset(&gx->nextPoly, 0, sizeof(gx-> nextPoly)); gx->currentVertex.color = 0x7FFF; + gx->dmaSource = -1; } void DSGXAssociateRenderer(struct DSGX* gx, struct DSGXRenderer* renderer) {

@@ -1052,6 +1053,21 @@

value = DSRegGXSTATSetBusy(value, mTimingIsScheduled(&gx->p->ds9.timing, &gx->fifoEvent) || gx->swapBuffers); gx->p->memory.io9[DS9_REG_GXSTAT_HI >> 1] = value >> 16; + + struct GBADMA* dma = NULL; + if (gx->dmaSource >= 0) { + dma = &gx->p->ds9.memory.dma[gx->dmaSource]; + if (GBADMARegisterGetTiming9(dma->reg) != DS_DMA_TIMING_GEOM_FIFO) { + gx->dmaSource = -1; + } else if (GBADMARegisterIsEnable(dma->reg) && entries < (DS_GX_FIFO_SIZE / 2) && !dma->nextCount) { + dma->nextCount = dma->count; + if (dma->count > 112) { + dma->nextCount = 112; + } + dma->when = mTimingCurrentTime(&gx->p->ds9.timing); + DSDMAUpdate(&gx->p->ds9); + } + } } static void DSGXUnpackCommand(struct DSGX* gx, uint32_t command) {

@@ -1244,6 +1260,11 @@ }

} DSGXUpdateGXSTAT(gx); +} + +void DSGXScheduleDMA(struct DSCommon* dscore, int number, struct GBADMA* info) { + UNUSED(info); + dscore->p->gx.dmaSource = number; } static void DSGXDummyRendererInit(struct DSGXRenderer* renderer) {