DS GX: Start work on multi-parameter FIFO entries
Vicki Pfau vi@endrift.com
Mon, 27 Feb 2017 18:16:26 -0800
2 files changed,
28 insertions(+),
10 deletions(-)
M
include/mgba/internal/ds/gx.h
→
include/mgba/internal/ds/gx.h
@@ -121,7 +121,7 @@ int outstandingParams[4];
uint8_t outstandingCommand[4]; int activeParams; - int activeEntries[32]; + struct DSGXEntry activeEntries[32]; bool swapBuffers; int bufferIndex;
M
src/ds/gx.c
→
src/ds/gx.c
@@ -140,8 +140,13 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate) {
struct DSGX* gx = context; uint32_t cycles; bool first = true; - while (true) { - if (gx->swapBuffers) { + while (!gx->swapBuffers) { + if (CircleBufferSize(&gx->pipe) <= 2 * sizeof(struct DSGXEntry)) { + _pullPipe(gx); + } + + if (!CircleBufferSize(&gx->pipe)) { + cycles = 0; break; }@@ -149,10 +154,6 @@ DSRegGXSTAT gxstat = gx->p->memory.io9[DS9_REG_GXSTAT_LO >> 1];
int pvMatrixPointer = DSRegGXSTATGetPVMatrixStackLevel(gxstat); int projMatrixPointer = DSRegGXSTATGetProjMatrixStackLevel(gxstat); - if (CircleBufferSize(&gx->pipe) <= 2 * sizeof(struct DSGXEntry)) { - _pullPipe(gx); - } - struct DSGXEntry entry = { 0 }; CircleBufferDump(&gx->pipe, (int8_t*) &entry.command, 1); cycles = _gxCommandCycleBase[entry.command];@@ -168,6 +169,24 @@ CircleBufferRead8(&gx->pipe, (int8_t*) &entry.params[1]);
CircleBufferRead8(&gx->pipe, (int8_t*) &entry.params[2]); CircleBufferRead8(&gx->pipe, (int8_t*) &entry.params[3]); + if (gx->activeParams) { + int index = _gxCommandParams[entry.command] - gx->activeParams; + gx->activeEntries[index] = entry; + --gx->activeParams; + } else { + gx->activeParams = _gxCommandParams[entry.command]; + if (gx->activeParams) { + --gx->activeParams; + } + if (gx->activeParams) { + gx->activeEntries[0] = entry; + } + } + + if (gx->activeParams) { + continue; + } + switch (entry.command) { case DS_GX_CMD_MTX_MODE: if (entry.params[0] < 4) {@@ -249,9 +268,7 @@ gx->p->memory.io9[DS9_REG_GXSTAT_LO >> 1] = gxstat;
if (cyclesLate >= cycles) { cyclesLate -= cycles; - } - if (!CircleBufferSize(&gx->pipe)) { - cycles = 0; + } else { break; } }@@ -298,6 +315,7 @@ gx->mtxMode = 0;
memset(gx->outstandingParams, 0, sizeof(gx->outstandingParams)); memset(gx->outstandingCommand, 0, sizeof(gx->outstandingCommand)); + gx->activeParams = 0; } void DSGXAssociateRenderer(struct DSGX* gx, struct DSGXRenderer* renderer) {