all repos — mgba @ 8c9790bb3bd8ac8c388c11d131333236796af194

mGBA Game Boy Advance Emulator

Add audio FIFOs to savestates
Jeffrey Pfau jeffrey@endrift.com
Tue, 08 Jul 2014 00:02:39 -0700
commit

8c9790bb3bd8ac8c388c11d131333236796af194

parent

6bf0e704d2233518aaade380d86d3143530a75fc

4 files changed, 52 insertions(+), 8 deletions(-)

jump to
M src/gba/gba-audio.csrc/gba/gba-audio.c

@@ -692,6 +692,10 @@ state->audio.ch4.lfsr = audio->ch4.lfsr;

state->audio.ch4.endTime = audio->ch4.control.endTime; state->audio.ch4.nextEvent = audio->nextCh4; + CircleBufferDump(&audio->chA.fifo, state->audio.fifoA, sizeof(state->audio.fifoA)); + CircleBufferDump(&audio->chB.fifo, state->audio.fifoB, sizeof(state->audio.fifoB)); + state->audio.fifoSize = CircleBufferSize(&audio->chA.fifo); + state->audio.nextEvent = audio->nextEvent; state->audio.eventDiff = audio->eventDiff; state->audio.nextSample = audio->nextSample;

@@ -725,6 +729,14 @@ audio->ch4.envelope.nextStep = state->audio.ch4.envelopeNextStep;

audio->ch4.lfsr = state->audio.ch4.lfsr; audio->ch4.control.endTime = state->audio.ch4.endTime; audio->nextCh4 = state->audio.ch4.nextEvent; + + CircleBufferClear(&audio->chA.fifo); + CircleBufferClear(&audio->chB.fifo); + unsigned i; + for (i = 0; i < state->audio.fifoSize / sizeof(uint32_t); ++i) { + CircleBufferWrite32(&audio->chA.fifo, state->audio.fifoA[i]); + CircleBufferWrite32(&audio->chB.fifo, state->audio.fifoB[i]); + } audio->nextEvent = state->audio.nextEvent; audio->eventDiff = state->audio.eventDiff;
M src/gba/gba-io.csrc/gba/gba-io.c

@@ -61,9 +61,9 @@ 0, 0, 0, 0, 0, 0, 0, 0,

1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, // DMA - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Timers

@@ -466,12 +466,19 @@ GBAIOWrite(gba, i, state->io[i >> 1]);

} } + gba->timersEnabled = 0; + memcpy(gba->timers, state->timers, sizeof(gba->timers)); for (i = 0; i < 4; ++i) { 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) { + GBAMemoryScheduleDMA(gba, i, &gba->memory.dma[i]); + } + + if (gba->timers[i].enable) { + gba->timersEnabled |= 1 << i; + } } - - memcpy(state->timers, gba->timers, sizeof(gba->timers)); }
M src/util/circle-buffer.csrc/util/circle-buffer.c

@@ -18,9 +18,7 @@

void CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity) { buffer->data = malloc(capacity); buffer->capacity = capacity; - buffer->size = 0; - buffer->readPtr = buffer->data; - buffer->writePtr = buffer->data; + CircleBufferClear(buffer); } void CircleBufferDeinit(struct CircleBuffer* buffer) {

@@ -30,6 +28,12 @@ }

unsigned CircleBufferSize(const struct CircleBuffer* buffer) { return buffer->size; +} + +void CircleBufferClear(struct CircleBuffer* buffer) { + buffer->size = 0; + buffer->readPtr = buffer->data; + buffer->writePtr = buffer->data; } int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value) {

@@ -166,3 +170,22 @@ }

#endif return length; } + +int CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length) { + int8_t* data = buffer->readPtr; + if (buffer->size == 0) { + return 0; + } + if (length > buffer->size) { + length = buffer->size; + } + size_t remaining = buffer->capacity - ((int8_t*) data - (int8_t*) buffer->data); + if (length <= remaining) { + memcpy(output, data, length); + } else { + memcpy(output, data, remaining); + memcpy((int8_t*) output + remaining, buffer->data, length - remaining); + } + + return length; +}
M src/util/circle-buffer.hsrc/util/circle-buffer.h

@@ -14,10 +14,12 @@

void CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity); void CircleBufferDeinit(struct CircleBuffer* buffer); unsigned CircleBufferSize(const struct CircleBuffer* buffer); +void CircleBufferClear(struct CircleBuffer* buffer); int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value); int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value); int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value); int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value); int CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length); +int CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length); #endif