Share save data for sram and flash
This commit is contained in:
@@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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:
|
||||||
|
if(saveData.is_mapped()) {
|
||||||
for (int i = 0; i < 128; i++) {
|
for (int i = 0; i < 128; i++) {
|
||||||
flash[eraseOffs + i] = 0xFF;
|
saveData[eraseOffs + i] = 0xFF;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Util::panic("Accessing flash when not mapped!");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FlashState::Write:
|
case FlashState::Write:
|
||||||
|
if(saveData.is_mapped()) {
|
||||||
for (int i = 0; i < 128; i++) {
|
for (int i = 0; i < 128; i++) {
|
||||||
flash[writeOffs + i] = writeBuf[i];
|
saveData[writeOffs + i] = writeBuf[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Util::panic("Accessing flash when not mapped!");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FlashState::Read:
|
case FlashState::Read:
|
||||||
|
|||||||
Reference in New Issue
Block a user