mirror of https://github.com/mgba-emu/mgba.git
GBA: Savestates now take into account savedata state machines (fixes #109)
This commit is contained in:
parent
d36c0ec7df
commit
c1d02a1369
1
CHANGES
1
CHANGES
|
@ -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:
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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];
|
||||||
|
|
Loading…
Reference in New Issue