mirror of https://github.com/stella-emu/stella.git
State loads.
This commit is contained in:
parent
daf83faff3
commit
aee8a3e345
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue