State loads.

This commit is contained in:
Christian Speckner 2024-08-14 22:25:26 +02:00
parent daf83faff3
commit aee8a3e345
7 changed files with 184 additions and 49 deletions

View File

@ -289,7 +289,34 @@ bool CartridgeELF::save(Serializer& out) const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeELF::load(Serializer& in) bool CartridgeELF::load(Serializer& in)
{ {
try {
myConfigStrictMode = in.getBool();
myConfigMips = in.getInt();
myConfigSystemType = static_cast<SystemType>(in.getByte());
resetWithConfig();
myIsBusDriven = in.getBool();
myDriveBusValue = in.getByte();
myArmCyclesOffset = in.getLong();
myExecutionStage = static_cast<ExecutionStage>(in.getByte());
myInitFunctionIndex = in.getInt();
myConsoleTiming = static_cast<ConsoleTiming>(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 false;
}
return true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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; if (type != MemoryRegionType::directCode && type != MemoryRegionType::directData) return;
serializer.putBool(dirty); out.putBool(dirty);
if (!dirty) return; if (!dirty) return;
serializer.putInt(accessWatermarkLow); out.putInt(accessWatermarkLow);
serializer.putInt(accessWatermarkHigh); out.putInt(accessWatermarkHigh);
switch (type) { switch (type) {
case MemoryRegionType::directCode: case MemoryRegionType::directCode:
serializer.putByteArray( out.putByteArray(
std::get<1>(access).backingStore + (accessWatermarkLow - base), std::get<1>(access).backingStore + (accessWatermarkLow - base),
accessWatermarkHigh - accessWatermarkLow + 1 accessWatermarkHigh - accessWatermarkLow + 1
); );
@ -579,26 +579,62 @@ void CortexM0::MemoryRegion::serialize(Serializer& serializer) const
break; break;
case MemoryRegionType::directData: case MemoryRegionType::directData:
serializer.putByteArray( out.putByteArray(
std::get<0>(access).backingStore + (accessWatermarkLow - base), std::get<0>(access).backingStore + (accessWatermarkLow - base),
accessWatermarkHigh - accessWatermarkLow + 1 accessWatermarkHigh - accessWatermarkLow + 1
); );
break; 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 { try {
for (size_t i = 0; i < 16; i++) for (size_t i = 0; i < 16; i++)
serializer.putInt(reg_norm[i]); out.putInt(reg_norm[i]);
serializer.putInt(znFlags); out.putInt(znFlags);
serializer.putInt(cFlag); out.putInt(cFlag);
serializer.putInt(vFlag); out.putInt(vFlag);
serializer.putLong(myCycleCounter); out.putLong(myCycleCounter);
} }
catch (...) { catch (...) {
cerr << "ERROR: failed to save cortex M0\n"; 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)
{ {
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 false;
}
return true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CortexM0::saveDirtyRegions(Serializer& serializer) const void CortexM0::saveDirtyRegions(Serializer& out) const
{ {
for (size_t i = 0; i < myNextRegionIndex; i++) for (size_t i = 0; i < myNextRegionIndex; i++)
myRegions[i].serialize(serializer); 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() void CortexM0::MemoryRegion::reset()

View File

@ -119,9 +119,10 @@ class CortexM0: public Serializable
CortexM0& mapDefault(BusTransactionDelegate* delegate); CortexM0& mapDefault(BusTransactionDelegate* delegate);
bool save(Serializer& serializer) const override; bool save(Serializer& out) const override;
bool load(Serializer& serializer) override; bool load(Serializer& in) override;
void saveDirtyRegions(Serializer& serialized) const; void saveDirtyRegions(Serializer& serialized) const;
void loadDirtyRegions(Serializer& serialized);
CortexM0& reset(); CortexM0& reset();
CortexM0& setPc(uInt32 pc); CortexM0& setPc(uInt32 pc);
@ -184,7 +185,8 @@ class CortexM0: public Serializable
> access; > access;
void reset(); void reset();
void serialize(Serializer& serializer) const; void saveDirtyBits(Serializer& out) const;
void loadDirtyBits(Serializer& in);
private: private:
MemoryRegion(const MemoryRegion&) = delete; MemoryRegion(const MemoryRegion&) = delete;

View File

@ -66,15 +66,15 @@ BusTransactionQueue& BusTransactionQueue::reset()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool BusTransactionQueue::save(Serializer& serializer) const bool BusTransactionQueue::save(Serializer& out) const
{ {
try { try {
serializer.putInt(myQueueSize); out.putInt(myQueueSize);
serializer.putShort(myNextInjectAddress); out.putShort(myNextInjectAddress);
serializer.putLong(myTimestamp); out.putLong(myTimestamp);
for (size_t i = 0; i < myQueueSize; i++) for (size_t i = 0; i < myQueueSize; i++)
myQueue[(myQueueNext + i) % myQueueCapacity].serialize(serializer); myQueue[(myQueueNext + i) % myQueueCapacity].serialize(out);
} }
catch (...) { catch (...) {
cerr << "ERROR: failed to save bus transaction queue\n"; 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; return true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void BusTransactionQueue::Transaction::serialize(Serializer& serializer) const void BusTransactionQueue::Transaction::serialize(Serializer& out) const
{ {
serializer.putShort(address); out.putShort(address);
serializer.putShort(mask); out.putShort(mask);
serializer.putByte(value); out.putByte(value);
serializer.putLong(timestamp); out.putLong(timestamp);
serializer.putBool(yield); out.putBool(yield);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void BusTransactionQueue::Transaction::deserialize(Serializer& in)
{
address = in.getShort();
mask = in.getShort();
value = in.getByte();
timestamp = in.getLong();
yield = in.getBool();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -37,7 +37,8 @@ class BusTransactionQueue: public Serializable {
uInt64 timestamp{0}; uInt64 timestamp{0};
bool yield{false}; bool yield{false};
void serialize(Serializer& serializer) const; void serialize(Serializer& out) const;
void deserialize(Serializer& in);
}; };
public: public:
@ -46,8 +47,8 @@ class BusTransactionQueue: public Serializable {
BusTransactionQueue& reset(); BusTransactionQueue& reset();
bool save(Serializer& serializer) const override; bool save(Serializer& out) const override;
bool load(Serializer& serializer) override; bool load(Serializer& in) override;
BusTransactionQueue& setNextInjectAddress(uInt16 address); BusTransactionQueue& setNextInjectAddress(uInt16 address);
uInt16 getNextInjectAddress() const; uInt16 getNextInjectAddress() const;

View File

@ -112,18 +112,18 @@ VcsLib::VcsLib(BusTransactionQueue& transactionQueue)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool VcsLib::save(Serializer& serializer) const bool VcsLib::save(Serializer& out) const
{ {
try { try {
serializer.putByte(myStuffMaskA); out.putByte(myStuffMaskA);
serializer.putByte(myStuffMaskX); out.putByte(myStuffMaskX);
serializer.putByte(myStuffMaskY); out.putByte(myStuffMaskY);
serializer.putBool(myIsWaitingForRead); out.putBool(myIsWaitingForRead);
serializer.putShort(myWaitingForReadAddress); out.putShort(myWaitingForReadAddress);
serializer.putShort(myCurrentAddress); out.putShort(myCurrentAddress);
serializer.putBool(myCurrentValue); out.putBool(myCurrentValue);
if (!myRand.save(serializer)) return false; if (!myRand.save(out)) return false;
} }
catch (...) { catch (...) {
cerr << "ERROR: failed to save vcslib\n"; 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)
{ {
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 false;
}
return true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -31,8 +31,8 @@ class VcsLib: public CortexM0::BusTransactionDelegate, public Serializable {
explicit VcsLib(BusTransactionQueue& transactionQueue); explicit VcsLib(BusTransactionQueue& transactionQueue);
~VcsLib() override = default; ~VcsLib() override = default;
bool save(Serializer& serializer) const override; bool save(Serializer& out) const override;
bool load(Serializer& serializer) override; bool load(Serializer& in) override;
void reset(); void reset();