DS GX: Implement GX DMAs

This commit is contained in:
Vicki Pfau 2017-03-04 10:59:44 -08:00
parent 6103d49697
commit 0ff5f43eb0
3 changed files with 30 additions and 0 deletions

View File

@ -157,6 +157,7 @@ struct DSGX {
struct CircleBuffer pipe; struct CircleBuffer pipe;
struct mTimingEvent fifoEvent; struct mTimingEvent fifoEvent;
int dmaSource;
int outstandingParams[4]; int outstandingParams[4];
uint8_t outstandingCommand[4]; uint8_t outstandingCommand[4];
@ -214,6 +215,10 @@ uint32_t DSGXWriteRegister32(struct DSGX*, uint32_t address, uint32_t value);
void DSGXFlush(struct DSGX*); void DSGXFlush(struct DSGX*);
void DSGXUpdateGXSTAT(struct DSGX*); void DSGXUpdateGXSTAT(struct DSGX*);
struct GBADMA;
struct DSCommon;
void DSGXScheduleDMA(struct DSCommon* dscore, int number, struct GBADMA* info);
CXX_GUARD_END CXX_GUARD_END
#endif #endif

View File

@ -6,6 +6,7 @@
#include <mgba/internal/ds/dma.h> #include <mgba/internal/ds/dma.h>
#include <mgba/internal/ds/ds.h> #include <mgba/internal/ds/ds.h>
#include <mgba/internal/ds/gx.h>
#include <mgba/internal/ds/io.h> #include <mgba/internal/ds/io.h>
#include <mgba/internal/ds/memory.h> #include <mgba/internal/ds/memory.h>
@ -98,6 +99,9 @@ void DSDMASchedule(struct DSCommon* dscore, int number, struct GBADMA* info) {
case DS9_DMA_TIMING_SLOT1: case DS9_DMA_TIMING_SLOT1:
DSSlot1ScheduleDMA(dscore, number, info); DSSlot1ScheduleDMA(dscore, number, info);
return; return;
case DS_DMA_TIMING_GEOM_FIFO:
DSGXScheduleDMA(dscore, number, info);
return;
case DS_DMA_TIMING_HBLANK: // DS7_DMA_TIMING_SLOT1 case DS_DMA_TIMING_HBLANK: // DS7_DMA_TIMING_SLOT1
default: default:
mLOG(DS_MEM, STUB, "Unimplemented DMA"); mLOG(DS_MEM, STUB, "Unimplemented DMA");

View File

@ -1021,6 +1021,7 @@ void DSGXReset(struct DSGX* gx) {
memset(&gx->currentVertex, 0, sizeof(gx->currentVertex)); memset(&gx->currentVertex, 0, sizeof(gx->currentVertex));
memset(&gx->nextPoly, 0, sizeof(gx-> nextPoly)); memset(&gx->nextPoly, 0, sizeof(gx-> nextPoly));
gx->currentVertex.color = 0x7FFF; gx->currentVertex.color = 0x7FFF;
gx->dmaSource = -1;
} }
void DSGXAssociateRenderer(struct DSGX* gx, struct DSGXRenderer* renderer) { void DSGXAssociateRenderer(struct DSGX* gx, struct DSGXRenderer* renderer) {
@ -1052,6 +1053,21 @@ void DSGXUpdateGXSTAT(struct DSGX* gx) {
value = DSRegGXSTATSetBusy(value, mTimingIsScheduled(&gx->p->ds9.timing, &gx->fifoEvent) || gx->swapBuffers); value = DSRegGXSTATSetBusy(value, mTimingIsScheduled(&gx->p->ds9.timing, &gx->fifoEvent) || gx->swapBuffers);
gx->p->memory.io9[DS9_REG_GXSTAT_HI >> 1] = value >> 16; 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) { static void DSGXUnpackCommand(struct DSGX* gx, uint32_t command) {
@ -1246,6 +1262,11 @@ void DSGXFlush(struct DSGX* gx) {
DSGXUpdateGXSTAT(gx); 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) { static void DSGXDummyRendererInit(struct DSGXRenderer* renderer) {
UNUSED(renderer); UNUSED(renderer);
// Nothing to do // Nothing to do