GBA: Savestates now take into account savedata state machines (fixes #109)

This commit is contained in:
Jeffrey Pfau 2015-03-21 01:12:39 -07:00
parent d36c0ec7df
commit c1d02a1369
5 changed files with 79 additions and 12 deletions

View File

@ -75,6 +75,7 @@ Misc:
- All: Enable link-time optimization - All: Enable link-time optimization
- GBA Thread: Make GBASyncWaitFrameStart time out - GBA Thread: Make GBASyncWaitFrameStart time out
- GBA: Move A/V stream interface into core - GBA: Move A/V stream interface into core
- GBA: Savestates now take into account savedata state machines (fixes #109)
0.1.1: (2015-01-24) 0.1.1: (2015-01-24)
Bugfixes: Bugfixes:

View File

@ -6,6 +6,7 @@
#include "savedata.h" #include "savedata.h"
#include "gba/gba.h" #include "gba/gba.h"
#include "gba/serialize.h"
#include "util/memory.h" #include "util/memory.h"
#include "util/vfs.h" #include "util/vfs.h"
@ -375,6 +376,37 @@ uint16_t GBASavedataReadEEPROM(struct GBASavedata* savedata) {
return 0; return 0;
} }
void GBASavedataSerialize(const struct GBASavedata* savedata, struct GBASerializedState* state, bool includeData) {
state->savedata.type = savedata->type;
state->savedata.command = savedata->command;
state->savedata.flashState = savedata->flashState;
state->savedata.flashBank = savedata->currentBank == &savedata->data[0x10000];
state->savedata.readBitsRemaining = savedata->readBitsRemaining;
state->savedata.readAddress = savedata->readAddress;
state->savedata.writeAddress = savedata->writeAddress;
UNUSED(includeData); // TODO
}
void GBASavedataDeserialize(struct GBASavedata* savedata, const struct GBASerializedState* state, bool includeData) {
if (state->savedata.type == SAVEDATA_FORCE_NONE) {
return;
}
if (savedata->type != state->savedata.type) {
GBASavedataForceType(savedata, state->savedata.type);
}
savedata->command = state->savedata.command;
savedata->flashState = state->savedata.flashState;
savedata->readBitsRemaining = state->savedata.readBitsRemaining;
savedata->readAddress = state->savedata.readAddress;
savedata->writeAddress = state->savedata.writeAddress;
if (savedata->type == SAVEDATA_FLASH1M) {
_flashSwitchBank(savedata, state->savedata.flashBank);
}
UNUSED(includeData); // TODO
}
void _flashSwitchBank(struct GBASavedata* savedata, int bank) { void _flashSwitchBank(struct GBASavedata* savedata, int bank) {
GBALog(0, GBA_LOG_DEBUG, "Performing flash bank switch to bank %i", bank); GBALog(0, GBA_LOG_DEBUG, "Performing flash bank switch to bank %i", bank);
savedata->currentBank = &savedata->data[bank << 16]; savedata->currentBank = &savedata->data[bank << 16];

View File

@ -13,10 +13,10 @@ struct VFile;
enum SavedataType { enum SavedataType {
SAVEDATA_AUTODETECT = -1, SAVEDATA_AUTODETECT = -1,
SAVEDATA_FORCE_NONE = 0, SAVEDATA_FORCE_NONE = 0,
SAVEDATA_SRAM, SAVEDATA_SRAM = 1,
SAVEDATA_FLASH512, SAVEDATA_FLASH512 = 2,
SAVEDATA_FLASH1M, SAVEDATA_FLASH1M = 3,
SAVEDATA_EEPROM SAVEDATA_EEPROM = 4
}; };
enum SavedataCommand { enum SavedataCommand {
@ -42,8 +42,8 @@ enum SavedataCommand {
enum FlashStateMachine { enum FlashStateMachine {
FLASH_STATE_RAW = 0, FLASH_STATE_RAW = 0,
FLASH_STATE_START, FLASH_STATE_START = 1,
FLASH_STATE_CONTINUE FLASH_STATE_CONTINUE = 2,
}; };
enum FlashManufacturer { enum FlashManufacturer {
@ -67,9 +67,9 @@ struct GBASavedata {
int mapMode; int mapMode;
struct VFile* realVf; struct VFile* realVf;
int readBitsRemaining; int32_t readBitsRemaining;
int readAddress; uint32_t readAddress;
int writeAddress; uint32_t writeAddress;
uint8_t* currentBank; uint8_t* currentBank;
@ -94,4 +94,8 @@ void GBASavedataWriteFlash(struct GBASavedata* savedata, uint16_t address, uint8
uint16_t GBASavedataReadEEPROM(struct GBASavedata* savedata); uint16_t GBASavedataReadEEPROM(struct GBASavedata* savedata);
void GBASavedataWriteEEPROM(struct GBASavedata* savedata, uint16_t value, uint32_t writeSize); void GBASavedataWriteEEPROM(struct GBASavedata* savedata, uint16_t value, uint32_t writeSize);
struct GBASerializedState;
void GBASavedataSerialize(const struct GBASavedata* savedata, struct GBASerializedState* state, bool includeData);
void GBASavedataDeserialize(struct GBASavedata* savedata, const struct GBASerializedState* state, bool includeData);
#endif #endif

View File

@ -48,6 +48,7 @@ void GBASerialize(struct GBA* gba, struct GBASerializedState* state) {
GBAIOSerialize(gba, state); GBAIOSerialize(gba, state);
GBAVideoSerialize(&gba->video, state); GBAVideoSerialize(&gba->video, state);
GBAAudioSerialize(&gba->audio, state); GBAAudioSerialize(&gba->audio, state);
GBASavedataSerialize(&gba->memory.savedata, state, false);
state->associatedStreamId = 0; state->associatedStreamId = 0;
if (gba->rr) { if (gba->rr) {
@ -111,6 +112,7 @@ void GBADeserialize(struct GBA* gba, const struct GBASerializedState* state) {
GBAIODeserialize(gba, state); GBAIODeserialize(gba, state);
GBAVideoDeserialize(&gba->video, state); GBAVideoDeserialize(&gba->video, state);
GBAAudioDeserialize(&gba->audio, state); GBAAudioDeserialize(&gba->audio, state);
GBASavedataDeserialize(&gba->memory.savedata, state, false);
if (gba->rr) { if (gba->rr) {
gba->rr->stateLoaded(gba->rr, state); gba->rr->stateLoaded(gba->rr, state);

View File

@ -129,7 +129,7 @@ extern const uint32_t GBA_SAVESTATE_MAGIC;
* 0x00290 - 0x002C3: GPIO state * 0x00290 - 0x002C3: GPIO state
* | 0x00290 - 0x00291: Pin state * | 0x00290 - 0x00291: Pin state
* | 0x00292 - 0x00293: Direction state * | 0x00292 - 0x00293: Direction state
* | 0x00294 - 0x002B6: RTC state (see gba-hardware.h for format) * | 0x00294 - 0x002B6: RTC state (see hardware.h for format)
* | 0x002B7 - 0x002B7: GPIO devices * | 0x002B7 - 0x002B7: GPIO devices
* | bit 0: Has RTC values * | bit 0: Has RTC values
* | bit 1: Has rumble value (reserved) * | bit 1: Has rumble value (reserved)
@ -150,7 +150,20 @@ extern const uint32_t GBA_SAVESTATE_MAGIC;
* | 0x002C1 - 0x002C3: Flags * | 0x002C1 - 0x002C3: Flags
* | bits 0 - 1: Tilt state machine * | bits 0 - 1: Tilt state machine
* | bits 2 - 31: Reserved * | bits 2 - 31: Reserved
* 0x002C4 - 0x002F3: Reserved (leave zero) * 0x002C4 - 0x002DF: Reserved (leave zero)
* 0x002E0 - 0x002EF: Savedata state
* | 0x002E0 - 0x002E0: Savedata type
* | 0x002E1 - 0x002E1: Savedata command (see savedata.h)
* | 0x002E2 - 0x002E2: Flags
* | bits 0 - 1: Flash state machine
* | bits 2 - 3: Reserved
* | bit 4: Flash bank
* | bits 5 - 7: Reserved
* | 0x002E3 - 0x002E3: Reserved
* | 0x002E4 - 0x002E7: EEPROM read bits remaining
* | 0x002E8 - 0x002EB: EEPROM read address
* | 0x002EC - 0x002EBF EEPROM write address
* 0x002F0 - 0x002F3: Reserved (leave zero)
* 0x002F4 - 0x002FF: Prefetch * 0x002F4 - 0x002FF: Prefetch
* | 0x002F4 - 0x002F7: GBA BIOS bus prefetch * | 0x002F4 - 0x002F7: GBA BIOS bus prefetch
* | 0x002F8 - 0x002FB: CPU prefecth (decode slot) * | 0x002F8 - 0x002FB: CPU prefecth (decode slot)
@ -271,7 +284,22 @@ struct GBASerializedState {
unsigned : 22; unsigned : 22;
} hw; } hw;
uint32_t reservedHardware[12]; uint32_t reservedHardware[7];
struct {
unsigned type : 8;
unsigned command : 8;
unsigned flashState : 2;
unsigned : 2;
unsigned flashBank : 1;
unsigned : 3;
unsigned : 8;
int32_t readBitsRemaining;
uint32_t readAddress;
uint32_t writeAddress;
} savedata;
uint32_t reservedPadding;
uint32_t biosPrefetch; uint32_t biosPrefetch;
uint32_t cpuPrefetch[2]; uint32_t cpuPrefetch[2];