Add audio FIFOs to savestates

This commit is contained in:
Jeffrey Pfau 2014-07-08 00:02:39 -07:00
parent 6bf0e704d2
commit 8c9790bb3b
4 changed files with 52 additions and 8 deletions

View File

@ -692,6 +692,10 @@ void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState*
state->audio.ch4.endTime = audio->ch4.control.endTime; state->audio.ch4.endTime = audio->ch4.control.endTime;
state->audio.ch4.nextEvent = audio->nextCh4; 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.nextEvent = audio->nextEvent;
state->audio.eventDiff = audio->eventDiff; state->audio.eventDiff = audio->eventDiff;
state->audio.nextSample = audio->nextSample; state->audio.nextSample = audio->nextSample;
@ -726,6 +730,14 @@ void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState
audio->ch4.control.endTime = state->audio.ch4.endTime; audio->ch4.control.endTime = state->audio.ch4.endTime;
audio->nextCh4 = state->audio.ch4.nextEvent; 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->nextEvent = state->audio.nextEvent;
audio->eventDiff = state->audio.eventDiff; audio->eventDiff = state->audio.eventDiff;
audio->nextSample = state->audio.nextSample; audio->nextSample = state->audio.nextSample;

View File

@ -61,9 +61,9 @@ static const int _isSpecialRegister[REG_MAX >> 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, 1, 1, 1, 1, 0, 0, 0, 0,
// DMA // DMA
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
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 // Timers
@ -466,12 +466,19 @@ void GBAIODeserialize(struct GBA* gba, struct GBASerializedState* state) {
} }
} }
gba->timersEnabled = 0;
memcpy(gba->timers, state->timers, sizeof(gba->timers));
for (i = 0; i < 4; ++i) { for (i = 0; i < 4; ++i) {
gba->memory.dma[i].nextSource = state->dma[i].nextSource; gba->memory.dma[i].nextSource = state->dma[i].nextSource;
gba->memory.dma[i].nextDest = state->dma[i].nextDest; gba->memory.dma[i].nextDest = state->dma[i].nextDest;
gba->memory.dma[i].nextCount = state->dma[i].nextCount; gba->memory.dma[i].nextCount = state->dma[i].nextCount;
gba->memory.dma[i].nextEvent = state->dma[i].nextEvent; 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]);
}
memcpy(state->timers, gba->timers, sizeof(gba->timers)); if (gba->timers[i].enable) {
gba->timersEnabled |= 1 << i;
}
}
} }

View File

@ -18,9 +18,7 @@ static int _checkIntegrity(struct CircleBuffer* buffer) {
void CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity) { void CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity) {
buffer->data = malloc(capacity); buffer->data = malloc(capacity);
buffer->capacity = capacity; buffer->capacity = capacity;
buffer->size = 0; CircleBufferClear(buffer);
buffer->readPtr = buffer->data;
buffer->writePtr = buffer->data;
} }
void CircleBufferDeinit(struct CircleBuffer* buffer) { void CircleBufferDeinit(struct CircleBuffer* buffer) {
@ -32,6 +30,12 @@ unsigned CircleBufferSize(const struct CircleBuffer* buffer) {
return buffer->size; 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) { int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value) {
int8_t* data = buffer->writePtr; int8_t* data = buffer->writePtr;
if (buffer->size + sizeof(int8_t) > buffer->capacity) { if (buffer->size + sizeof(int8_t) > buffer->capacity) {
@ -166,3 +170,22 @@ int CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length) {
#endif #endif
return length; 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;
}

View File

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