From aee8a3e345a72d2a7f830ed36730e5042ba95c7d Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Wed, 14 Aug 2024 22:25:26 +0200 Subject: [PATCH] State loads. --- src/emucore/CartELF.cxx | 29 +++++++- src/emucore/CortexM0.cxx | 94 ++++++++++++++++++++----- src/emucore/CortexM0.hxx | 8 ++- src/emucore/elf/BusTransactionQueue.cxx | 51 ++++++++++---- src/emucore/elf/BusTransactionQueue.hxx | 7 +- src/emucore/elf/VcsLib.cxx | 40 ++++++++--- src/emucore/elf/VcsLib.hxx | 4 +- 7 files changed, 184 insertions(+), 49 deletions(-) diff --git a/src/emucore/CartELF.cxx b/src/emucore/CartELF.cxx index d3b533a97..131437046 100644 --- a/src/emucore/CartELF.cxx +++ b/src/emucore/CartELF.cxx @@ -289,7 +289,34 @@ bool CartridgeELF::save(Serializer& out) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeELF::load(Serializer& in) { - return false; + try { + myConfigStrictMode = in.getBool(); + myConfigMips = in.getInt(); + myConfigSystemType = static_cast(in.getByte()); + + resetWithConfig(); + + myIsBusDriven = in.getBool(); + myDriveBusValue = in.getByte(); + myArmCyclesOffset = in.getLong(); + myExecutionStage = static_cast(in.getByte()); + myInitFunctionIndex = in.getInt(); + myConsoleTiming = static_cast(in.getByte()); + + in.getByteArray(myLastPeekResult.get(), 0x1000); + + if (!myTransactionQueue.load(in)) return false; + if (!myCortexEmu.load(in)) return false; + if (!myVcsLib.load(in)) return false; + + myCortexEmu.loadDirtyRegions(in); + } + catch(...) { + cerr << "ERROR: failed to load ELF\n"; + return false; + } + + return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CortexM0.cxx b/src/emucore/CortexM0.cxx index 930cfdc54..3dae40e63 100644 --- a/src/emucore/CortexM0.cxx +++ b/src/emucore/CortexM0.cxx @@ -559,19 +559,19 @@ CortexM0::CortexM0() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CortexM0::MemoryRegion::serialize(Serializer& serializer) const +void CortexM0::MemoryRegion::saveDirtyBits(Serializer& out) const { if (type != MemoryRegionType::directCode && type != MemoryRegionType::directData) return; - serializer.putBool(dirty); + out.putBool(dirty); if (!dirty) return; - serializer.putInt(accessWatermarkLow); - serializer.putInt(accessWatermarkHigh); + out.putInt(accessWatermarkLow); + out.putInt(accessWatermarkHigh); switch (type) { case MemoryRegionType::directCode: - serializer.putByteArray( + out.putByteArray( std::get<1>(access).backingStore + (accessWatermarkLow - base), accessWatermarkHigh - accessWatermarkLow + 1 ); @@ -579,26 +579,62 @@ void CortexM0::MemoryRegion::serialize(Serializer& serializer) const break; case MemoryRegionType::directData: - serializer.putByteArray( + out.putByteArray( std::get<0>(access).backingStore + (accessWatermarkLow - base), accessWatermarkHigh - accessWatermarkLow + 1 ); break; + + default: + break; } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CortexM0::save(Serializer& serializer) const +void CortexM0::MemoryRegion::loadDirtyBits(Serializer& in) +{ + if (type != MemoryRegionType::directCode && type != MemoryRegionType::directData) return; + + dirty = in.getBool(); + if (!dirty) return; + + accessWatermarkLow = in.getInt(); + accessWatermarkHigh = in.getInt(); + + switch (type) { + case MemoryRegionType::directCode: + in.getByteArray( + std::get<1>(access).backingStore + (accessWatermarkLow - base), + accessWatermarkHigh - accessWatermarkLow + 1 + ); + + break; + + case MemoryRegionType::directData: + in.getByteArray( + std::get<0>(access).backingStore + (accessWatermarkLow - base), + accessWatermarkHigh - accessWatermarkLow + 1 + ); + + break; + + default: + break; + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CortexM0::save(Serializer& out) const { try { for (size_t i = 0; i < 16; i++) - serializer.putInt(reg_norm[i]); + out.putInt(reg_norm[i]); - serializer.putInt(znFlags); - serializer.putInt(cFlag); - serializer.putInt(vFlag); - serializer.putLong(myCycleCounter); + out.putInt(znFlags); + out.putInt(cFlag); + out.putInt(vFlag); + out.putLong(myCycleCounter); } catch (...) { cerr << "ERROR: failed to save cortex M0\n"; @@ -609,18 +645,42 @@ bool CortexM0::save(Serializer& serializer) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CortexM0::load(Serializer& serializer) +bool CortexM0::load(Serializer& in) { - return false; + try { + reset(); + + for (size_t i = 0; i < 16; i++) + reg_norm[i] = in.getInt(); + + znFlags = in.getInt(); + cFlag = in.getInt(); + vFlag = in.getInt(); + myCycleCounter = in.getLong(); + } + catch (...) { + cerr << "ERROR: failed to load cortex M0\n"; + return false; + } + + return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CortexM0::saveDirtyRegions(Serializer& serializer) const +void CortexM0::saveDirtyRegions(Serializer& out) const { -for (size_t i = 0; i < myNextRegionIndex; i++) - myRegions[i].serialize(serializer); + for (size_t i = 0; i < myNextRegionIndex; i++) + myRegions[i].saveDirtyBits(out); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CortexM0::loadDirtyRegions(Serializer& in) +{ + for (size_t i = 0; i < myNextRegionIndex; i++) + myRegions[i].loadDirtyBits(in); + + recompileCodeRegions(); +} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CortexM0::MemoryRegion::reset() diff --git a/src/emucore/CortexM0.hxx b/src/emucore/CortexM0.hxx index 52e709b81..e65966499 100644 --- a/src/emucore/CortexM0.hxx +++ b/src/emucore/CortexM0.hxx @@ -119,9 +119,10 @@ class CortexM0: public Serializable CortexM0& mapDefault(BusTransactionDelegate* delegate); - bool save(Serializer& serializer) const override; - bool load(Serializer& serializer) override; + bool save(Serializer& out) const override; + bool load(Serializer& in) override; void saveDirtyRegions(Serializer& serialized) const; + void loadDirtyRegions(Serializer& serialized); CortexM0& reset(); CortexM0& setPc(uInt32 pc); @@ -184,7 +185,8 @@ class CortexM0: public Serializable > access; void reset(); - void serialize(Serializer& serializer) const; + void saveDirtyBits(Serializer& out) const; + void loadDirtyBits(Serializer& in); private: MemoryRegion(const MemoryRegion&) = delete; diff --git a/src/emucore/elf/BusTransactionQueue.cxx b/src/emucore/elf/BusTransactionQueue.cxx index 7c0833421..95e2bf927 100644 --- a/src/emucore/elf/BusTransactionQueue.cxx +++ b/src/emucore/elf/BusTransactionQueue.cxx @@ -66,15 +66,15 @@ BusTransactionQueue& BusTransactionQueue::reset() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool BusTransactionQueue::save(Serializer& serializer) const +bool BusTransactionQueue::save(Serializer& out) const { try { - serializer.putInt(myQueueSize); - serializer.putShort(myNextInjectAddress); - serializer.putLong(myTimestamp); + out.putInt(myQueueSize); + out.putShort(myNextInjectAddress); + out.putLong(myTimestamp); for (size_t i = 0; i < myQueueSize; i++) - myQueue[(myQueueNext + i) % myQueueCapacity].serialize(serializer); + myQueue[(myQueueNext + i) % myQueueCapacity].serialize(out); } catch (...) { cerr << "ERROR: failed to save bus transaction queue\n"; @@ -85,19 +85,46 @@ bool BusTransactionQueue::save(Serializer& serializer) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool BusTransactionQueue::load(Serializer& serializer) +bool BusTransactionQueue::load(Serializer& in) { + try { + reset(); + + myQueueSize = in.getInt(); + myNextInjectAddress = in.getShort(); + myTimestamp = in.getLong(); + + if (myQueueSize > myQueueCapacity) return false; + + for (size_t i = 0; i < myQueueSize; i++) + myQueue[i].deserialize(in); + } + catch(...) { + cerr << "ERROR: failed to load bus transaction queue\n"; + return false; + } + return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BusTransactionQueue::Transaction::serialize(Serializer& serializer) const +void BusTransactionQueue::Transaction::serialize(Serializer& out) const { - serializer.putShort(address); - serializer.putShort(mask); - serializer.putByte(value); - serializer.putLong(timestamp); - serializer.putBool(yield); + out.putShort(address); + out.putShort(mask); + out.putByte(value); + out.putLong(timestamp); + out.putBool(yield); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void BusTransactionQueue::Transaction::deserialize(Serializer& in) +{ + address = in.getShort(); + mask = in.getShort(); + value = in.getByte(); + timestamp = in.getLong(); + yield = in.getBool(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/elf/BusTransactionQueue.hxx b/src/emucore/elf/BusTransactionQueue.hxx index 3f4bace5f..35f20aa6f 100644 --- a/src/emucore/elf/BusTransactionQueue.hxx +++ b/src/emucore/elf/BusTransactionQueue.hxx @@ -37,7 +37,8 @@ class BusTransactionQueue: public Serializable { uInt64 timestamp{0}; bool yield{false}; - void serialize(Serializer& serializer) const; + void serialize(Serializer& out) const; + void deserialize(Serializer& in); }; public: @@ -46,8 +47,8 @@ class BusTransactionQueue: public Serializable { BusTransactionQueue& reset(); - bool save(Serializer& serializer) const override; - bool load(Serializer& serializer) override; + bool save(Serializer& out) const override; + bool load(Serializer& in) override; BusTransactionQueue& setNextInjectAddress(uInt16 address); uInt16 getNextInjectAddress() const; diff --git a/src/emucore/elf/VcsLib.cxx b/src/emucore/elf/VcsLib.cxx index 83f193542..6798d27a7 100644 --- a/src/emucore/elf/VcsLib.cxx +++ b/src/emucore/elf/VcsLib.cxx @@ -112,18 +112,18 @@ VcsLib::VcsLib(BusTransactionQueue& transactionQueue) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool VcsLib::save(Serializer& serializer) const +bool VcsLib::save(Serializer& out) const { try { - serializer.putByte(myStuffMaskA); - serializer.putByte(myStuffMaskX); - serializer.putByte(myStuffMaskY); - serializer.putBool(myIsWaitingForRead); - serializer.putShort(myWaitingForReadAddress); - serializer.putShort(myCurrentAddress); - serializer.putBool(myCurrentValue); + out.putByte(myStuffMaskA); + out.putByte(myStuffMaskX); + out.putByte(myStuffMaskY); + out.putBool(myIsWaitingForRead); + out.putShort(myWaitingForReadAddress); + out.putShort(myCurrentAddress); + out.putBool(myCurrentValue); - if (!myRand.save(serializer)) return false; + if (!myRand.save(out)) return false; } catch (...) { cerr << "ERROR: failed to save vcslib\n"; @@ -134,9 +134,27 @@ bool VcsLib::save(Serializer& serializer) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool VcsLib::load(Serializer& serializer) +bool VcsLib::load(Serializer& in) { - return false; + reset(); + + try { + myStuffMaskA = in.getByte(); + myStuffMaskX = in.getByte(); + myStuffMaskY = in.getByte(); + myIsWaitingForRead = in.getBool(); + myWaitingForReadAddress = in.getShort(); + myCurrentAddress = in.getShort(); + myCurrentValue = in.getBool(); + + if (!myRand.load(in)) return false; + } + catch(...) { + cerr << "ERROR: failed to load vcslib\n"; + return false; + } + + return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/elf/VcsLib.hxx b/src/emucore/elf/VcsLib.hxx index 22140cab3..0fab154ae 100644 --- a/src/emucore/elf/VcsLib.hxx +++ b/src/emucore/elf/VcsLib.hxx @@ -31,8 +31,8 @@ class VcsLib: public CortexM0::BusTransactionDelegate, public Serializable { explicit VcsLib(BusTransactionQueue& transactionQueue); ~VcsLib() override = default; - bool save(Serializer& serializer) const override; - bool load(Serializer& serializer) override; + bool save(Serializer& out) const override; + bool load(Serializer& in) override; void reset();