From 252c534a90019a961c358acf6b41cbacb360d243 Mon Sep 17 00:00:00 2001 From: Dirk Hoffmann Date: Fri, 2 Aug 2024 11:30:28 +0200 Subject: [PATCH] Work on CoreComponent (loading and saving) --- Emulator/Base/CoreComponent.cpp | 83 +++++++++++++++++++-------------- Emulator/Base/CoreComponent.h | 12 +++-- Emulator/Components/Amiga.cpp | 19 -------- Emulator/Components/Amiga.h | 4 -- Emulator/config.cpp | 2 +- 5 files changed, 57 insertions(+), 63 deletions(-) diff --git a/Emulator/Base/CoreComponent.cpp b/Emulator/Base/CoreComponent.cpp index 50532b2a9..a4638af5f 100644 --- a/Emulator/Base/CoreComponent.cpp +++ b/Emulator/Base/CoreComponent.cpp @@ -236,8 +236,9 @@ CoreComponent::unfocus() } isize -CoreComponent::size() +CoreComponent::size(bool recursive) { + // Count elements SerCounter counter; *this << counter; isize result = counter.count; @@ -245,7 +246,9 @@ CoreComponent::size() // Add 8 bytes for the checksum result += 8; - for (CoreComponent *c : subComponents) { result += c->size(); } + // Add size of subcomponents if requested + if (recursive) for (CoreComponent *c : subComponents) { result += c->size(); } + return result; } @@ -253,53 +256,65 @@ isize CoreComponent::load(const u8 *buffer) { assert(!isRunning()); - - const u8 *ptr = buffer; - // Load internal state of all subcomponents - for (CoreComponent *c : subComponents) { - ptr += c->load(ptr); - } + isize result = 0; - // Load the checksum for this component - auto hash = read64(ptr); + postorderWalk([this, buffer, &result](CoreComponent *c) { - // Load internal state of this component - SerReader reader(ptr); - *this << reader; - ptr = reader.ptr; + const u8 *ptr = buffer + result; - // Check integrity - if (hash != checksum(false) || FORCE_SNAP_CORRUPTED) { - throw Error(ERROR_SNAP_CORRUPTED); - } + // Load the checksum for this component + auto hash = read64(ptr); + + // Load the internal state of this component + SerReader reader(ptr); *c << reader; + + // Determine the number of loaded bytes + isize count = (isize)(reader.ptr - (buffer + result)); + + // Check integrity + if (hash != c->checksum(false) || FORCE_SNAP_CORRUPTED) { + if (SNP_DEBUG) { fatalError; } else { throw Error(ERROR_SNAP_CORRUPTED); } + } + + debug(SNP_DEBUG, "Loaded %ld bytes (expected %ld)\n", count, c->size(false)); + result += count; + }); + + postorderWalk([](CoreComponent *c) { c->_didLoad(); }); - isize result = (isize)(ptr - buffer); - debug(SNP_DEBUG, "Loaded %ld bytes (expected %ld)\n", result, size()); return result; } isize CoreComponent::save(u8 *buffer) { - u8 *ptr = buffer; + isize result = 0; - // Save internal state of all subcomponents - for (CoreComponent *c : subComponents) { - ptr += c->save(ptr); - } + postorderWalk([this, buffer, &result](CoreComponent *c) { + + u8 *ptr = buffer + result; + + // Save the checksum for this component + write64(ptr, c->checksum(false)); + + // Save the internal state of this component + SerWriter writer(ptr); *c << writer; - // Save the checksum for this component - write64(ptr, checksum(false)); + // Determine the number of written bytes + isize count = (isize)(writer.ptr - (buffer + result)); + + // Check integrity + if (count != c->size(false) || FORCE_SNAP_CORRUPTED) { + if (SNP_DEBUG) { fatalError; } else { throw Error(ERROR_SNAP_CORRUPTED); } + } + + debug(SNP_DEBUG, "Saved %ld bytes (expected %ld)\n", count, c->size(false)); + result += count; + }); - // Save the internal state of this component - SerWriter writer(ptr); - *this << writer; - ptr = writer.ptr; + postorderWalk([](CoreComponent *c) { c->_didSave(); }); - isize result = (isize)(ptr - buffer); - debug(SNP_DEBUG, "Saved %ld bytes (expected %ld)\n", result, size()); - assert(result == size()); return result; } diff --git a/Emulator/Base/CoreComponent.h b/Emulator/Base/CoreComponent.h index 4d6ce63ca..1ac7ed4bc 100644 --- a/Emulator/Base/CoreComponent.h +++ b/Emulator/Base/CoreComponent.h @@ -174,21 +174,23 @@ public CoreObject, public Serializable, public Suspendable, public Synchronizabl public: // Returns the size of the internal state in bytes - isize size(); + isize size(bool recursive = true); // Resets the internal state - void hardReset() { reset(true); } - void softReset() { reset(false); } void reset(bool hard); virtual void _willReset(bool hard) { } virtual void _didReset(bool hard) { } + // Convenience wrappers + void hardReset() { reset(true); } + void softReset() { reset(false); } + // Loads the internal state from a memory buffer - virtual isize load(const u8 *buf) throws; + isize load(const u8 *buf) throws; virtual void _didLoad() { } // Saves the internal state to a memory buffer - virtual isize save(u8 *buf); + isize save(u8 *buf); virtual void _didSave() { } diff --git a/Emulator/Components/Amiga.cpp b/Emulator/Components/Amiga.cpp index 46de548fe..5d184ddee 100644 --- a/Emulator/Components/Amiga.cpp +++ b/Emulator/Components/Amiga.cpp @@ -591,25 +591,6 @@ Amiga::_trackOff() msgQueue.put(MSG_TRACK, 0); } -isize -Amiga::load(const u8 *buffer) -{ - auto result = CoreComponent::load(buffer); - postorderWalk([](CoreComponent *c) { c->_didLoad(); }); - - return result; -} - -isize -Amiga::save(u8 *buffer) -{ - auto result = CoreComponent::save(buffer); - postorderWalk([](CoreComponent *c) { c->_didSave(); }); - - return result; -} - - void Amiga::computeFrame() { diff --git a/Emulator/Components/Amiga.h b/Emulator/Components/Amiga.h index b8f6b8942..c02a8b892 100644 --- a/Emulator/Components/Amiga.h +++ b/Emulator/Components/Amiga.h @@ -262,10 +262,6 @@ class Amiga final : public CoreComponent, public Inspectable { public: - isize load(const u8 *buffer) override; - isize save(u8 *buffer) override; - - void prefix() const override; private: diff --git a/Emulator/config.cpp b/Emulator/config.cpp index 0c64e5412..b598de86d 100644 --- a/Emulator/config.cpp +++ b/Emulator/config.cpp @@ -25,7 +25,7 @@ debugflag QUEUE_DEBUG = 0; debugflag SNP_DEBUG = 0; // Run ahead -debugflag RUA_DEBUG = 1; +debugflag RUA_DEBUG = 0; debugflag RUA_CHECKSUM = 0; debugflag RUA_ON_STEROIDS = 0;