Share save data for sram and flash

This commit is contained in:
SimoneN64
2023-11-07 22:52:01 +01:00
parent 8bca9bf530
commit 7cceefd7fc
3 changed files with 38 additions and 31 deletions

View File

@@ -7,7 +7,7 @@
#include <unarr.h> #include <unarr.h>
namespace n64 { namespace n64 {
Mem::Mem() { Mem::Mem() : flash(saveData) {
memset(readPages, 0, PAGE_COUNT); memset(readPages, 0, PAGE_COUNT);
memset(writePages, 0, PAGE_COUNT); memset(writePages, 0, PAGE_COUNT);
@@ -24,10 +24,11 @@ Mem::Mem() {
void Mem::Reset() { void Mem::Reset() {
memset(rom.cart, 0, CART_SIZE); memset(rom.cart, 0, CART_SIZE);
flash.Reset(); flash.Reset();
if(sram.is_mapped()) { if (saveData.is_mapped()) {
std::error_code error; std::error_code error;
sram.sync(error); saveData.sync(error);
sram.unmap(); if (error) { Util::panic("Could not sync save data"); }
saveData.unmap();
} }
mmio.Reset(); mmio.Reset();
} }
@@ -36,10 +37,10 @@ void Mem::LoadSRAM(SaveType save_type, fs::path path) {
if(save_type == SAVE_SRAM_256k) { if(save_type == SAVE_SRAM_256k) {
std::error_code error; std::error_code error;
sramPath = path.replace_extension(".sram").string(); sramPath = path.replace_extension(".sram").string();
if(sram.is_mapped()) { if(saveData.is_mapped()) {
sram.sync(error); saveData.sync(error);
if(error) { Util::panic("Could not sync {}", sramPath); } if(error) { Util::panic("Could not sync {}", sramPath); }
sram.unmap(); saveData.unmap();
} }
FILE *f = fopen(sramPath.c_str(), "rb"); FILE *f = fopen(sramPath.c_str(), "rb");
@@ -56,7 +57,7 @@ void Mem::LoadSRAM(SaveType save_type, fs::path path) {
Util::panic("Corrupt SRAM!"); Util::panic("Corrupt SRAM!");
} }
fclose(f); fclose(f);
sram = mio::make_mmap_sink( saveData = mio::make_mmap_sink(
sramPath, 0, mio::map_entire_file, error); sramPath, 0, mio::map_entire_file, error);
if (error) { Util::panic("Could not open {}", sramPath); } if (error) { Util::panic("Could not open {}", sramPath); }
} }
@@ -578,8 +579,9 @@ u8 Mem::BackupRead8(u32 addr) {
Util::panic("Invalid backup Read8 if save data is not initialized"); Util::panic("Invalid backup Read8 if save data is not initialized");
} }
case SAVE_SRAM_256k: case SAVE_SRAM_256k:
if(sram.is_mapped()) { if(saveData.is_mapped()) {
return sram[addr & 0x8000]; assert(addr < saveData.size());
return saveData[addr];
} else { } else {
Util::panic("Invalid backup Read8 if save data is not initialized"); Util::panic("Invalid backup Read8 if save data is not initialized");
} }
@@ -602,8 +604,9 @@ void Mem::BackupWrite8(u32 addr, u8 val) {
} }
break; break;
case SAVE_SRAM_256k: case SAVE_SRAM_256k:
if(sram.is_mapped()) { if(saveData.is_mapped()) {
sram[addr & 0x8000] = val; assert(addr < saveData.size());
saveData[addr] = val;
} else { } else {
Util::panic("Invalid backup Write8 if save data is not initialized"); Util::panic("Invalid backup Write8 if save data is not initialized");
} }
@@ -623,7 +626,7 @@ std::vector<u8> Mem::Serialize() {
res.insert(res.begin(), sMMIO.begin(), sMMIO.end()); res.insert(res.begin(), sMMIO.begin(), sMMIO.end());
res.insert(res.end(), sFLASH.begin(), sFLASH.end()); res.insert(res.end(), sFLASH.begin(), sFLASH.end());
res.insert(res.end(), sram.begin(), sram.end()); res.insert(res.end(), saveData.begin(), saveData.end());
return res; return res;
} }
@@ -631,6 +634,6 @@ std::vector<u8> Mem::Serialize() {
void Mem::Deserialize(const std::vector<u8>& data) { void Mem::Deserialize(const std::vector<u8>& data) {
mmio.Deserialize(std::vector<u8>(data.begin(), data.begin() + mmioSize)); mmio.Deserialize(std::vector<u8>(data.begin(), data.begin() + mmioSize));
flash.Deserialize(std::vector<u8>(data.begin() + mmioSize, data.begin() + mmioSize + flashSize)); flash.Deserialize(std::vector<u8>(data.begin() + mmioSize, data.begin() + mmioSize + flashSize));
memcpy(sram.data(), data.data() + mmioSize + flashSize, sram.size()); memcpy(saveData.data(), data.data() + mmioSize + flashSize, saveData.size());
} }
} }

View File

@@ -42,7 +42,7 @@ enum FlashState : u8 {
}; };
struct Flash { struct Flash {
Flash() = default; Flash(mio::mmap_sink&);
~Flash() = default; ~Flash() = default;
void Reset(); void Reset();
void Load(SaveType, const std::string&); void Load(SaveType, const std::string&);
@@ -51,8 +51,8 @@ struct Flash {
size_t eraseOffs{}; size_t eraseOffs{};
size_t writeOffs{}; size_t writeOffs{};
u8 writeBuf[128]{}; u8 writeBuf[128]{};
mio::mmap_sink flash;
std::string flashPath{}; std::string flashPath{};
mio::mmap_sink& saveData;
enum FlashCommands : u8 { enum FlashCommands : u8 {
FLASH_COMMAND_EXECUTE = 0xD2, FLASH_COMMAND_EXECUTE = 0xD2,
@@ -237,9 +237,9 @@ private:
friend struct AI; friend struct AI;
friend struct RSP; friend struct RSP;
friend struct Core; friend struct Core;
mio::mmap_sink sram;
u8 isviewer[ISVIEWER_SIZE]{}; u8 isviewer[ISVIEWER_SIZE]{};
std::string sramPath{}; std::string sramPath{};
mio::mmap_sink saveData;
int mmioSize, flashSize; int mmioSize, flashSize;
FORCE_INLINE bool IsROMPAL() { FORCE_INLINE bool IsROMPAL() {

View File

@@ -3,24 +3,20 @@
namespace n64 { namespace n64 {
constexpr auto FLASH_SIZE = 1_mb; constexpr auto FLASH_SIZE = 1_mb;
Flash::Flash(mio::mmap_sink &saveData) : saveData(saveData) {}
void Flash::Reset() { void Flash::Reset() {
state = Idle; state = Idle;
if (flash.is_mapped()) {
std::error_code error;
flash.sync(error);
if (error) { Util::panic("Could not sync {}", flashPath); }
flash.unmap();
}
} }
void Flash::Load(SaveType saveType, const std::string& path) { void Flash::Load(SaveType saveType, const std::string& path) {
if(saveType == SAVE_FLASH_1m) { if(saveType == SAVE_FLASH_1m) {
flashPath = fs::path(path).replace_extension(".flash").string(); flashPath = fs::path(path).replace_extension(".flash").string();
std::error_code error; std::error_code error;
if (flash.is_mapped()) { if (saveData.is_mapped()) {
flash.sync(error); saveData.sync(error);
if (error) { Util::panic("Could not sync {}", flashPath); } if (error) { Util::panic("Could not sync {}", flashPath); }
flash.unmap(); saveData.unmap();
} }
FILE *f = fopen(flashPath.c_str(), "rb"); FILE *f = fopen(flashPath.c_str(), "rb");
@@ -38,7 +34,7 @@ void Flash::Load(SaveType saveType, const std::string& path) {
} }
fclose(f); fclose(f);
flash = mio::make_mmap_sink( saveData = mio::make_mmap_sink(
flashPath, 0, mio::map_entire_file, error); flashPath, 0, mio::map_entire_file, error);
if (error) { Util::panic("Could not open {}", path); } if (error) { Util::panic("Could not open {}", path); }
} }
@@ -50,13 +46,21 @@ void Flash::CommandExecute() {
case FlashState::Idle: case FlashState::Idle:
break; break;
case FlashState::Erase: case FlashState::Erase:
for (int i = 0; i < 128; i++) { if(saveData.is_mapped()) {
flash[eraseOffs + i] = 0xFF; for (int i = 0; i < 128; i++) {
saveData[eraseOffs + i] = 0xFF;
}
} else {
Util::panic("Accessing flash when not mapped!");
} }
break; break;
case FlashState::Write: case FlashState::Write:
for (int i = 0; i < 128; i++) { if(saveData.is_mapped()) {
flash[writeOffs + i] = writeBuf[i]; for (int i = 0; i < 128; i++) {
saveData[writeOffs + i] = writeBuf[i];
}
} else {
Util::panic("Accessing flash when not mapped!");
} }
break; break;
case FlashState::Read: case FlashState::Read: