From 3348167c4640563951d3bde139d212cf63f80e6a Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 26 Apr 2021 17:39:11 -0400 Subject: [PATCH] Ensures AY registers are conveyed. --- Components/AY38910/AY38910.hpp | 24 +++++++++++++++++++++ Machines/Sinclair/ZXSpectrum/State.hpp | 4 ++++ Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp | 1 + Storage/State/Z80.cpp | 2 +- 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/Components/AY38910/AY38910.hpp b/Components/AY38910/AY38910.hpp index f13a00810..cbd7e19b7 100644 --- a/Components/AY38910/AY38910.hpp +++ b/Components/AY38910/AY38910.hpp @@ -12,6 +12,8 @@ #include "../../Outputs/Speaker/Implementation/SampleSource.hpp" #include "../../Concurrency/AsyncTaskQueue.hpp" +#include "../../Reflection/Struct.hpp" + namespace GI { namespace AY38910 { @@ -162,6 +164,8 @@ template class AY38910: public ::Outputs::Speaker::SampleSource uint8_t a_left_ = 255, a_right_ = 255; uint8_t b_left_ = 255, b_right_ = 255; uint8_t c_left_ = 255, c_right_ = 255; + + friend struct State; }; /*! @@ -192,6 +196,26 @@ struct Utility { }; +struct State: public Reflection::StructImpl { + uint8_t registers[16]{}; + + // TODO: all audio-production thread state. + + State() { + if(needs_declare()) { + DeclareField(registers); + } + } + + template void apply(AY &target) { + // Establish emulator-thread state + for(uint8_t c = 0; c < 16; c++) { + target.select_register(c); + target.set_register_value(registers[c]); + } + } +}; + } } diff --git a/Machines/Sinclair/ZXSpectrum/State.hpp b/Machines/Sinclair/ZXSpectrum/State.hpp index ae9632ecd..69d23c5f5 100644 --- a/Machines/Sinclair/ZXSpectrum/State.hpp +++ b/Machines/Sinclair/ZXSpectrum/State.hpp @@ -11,7 +11,9 @@ #include "../../../Reflection/Struct.hpp" #include "../../../Processors/Z80/State/State.hpp" + #include "Video.hpp" +#include "../../../Components/AY38910/AY38910.hpp" namespace Sinclair { namespace ZXSpectrum { @@ -29,6 +31,7 @@ struct State: public Reflection::StructImpl { // Meaningful for 128kb machines only. uint8_t last_7ffd = 0; uint8_t last_fffd = 0; + GI::AY38910::State ay; // Meaningful for the +2a and +3 only. uint8_t last_1ffd = 0; @@ -41,6 +44,7 @@ struct State: public Reflection::StructImpl { DeclareField(last_7ffd); DeclareField(last_fffd); DeclareField(last_1ffd); + DeclareField(ay); } } }; diff --git a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp index 1a2f4ed0f..e3c242d81 100644 --- a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp +++ b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp @@ -128,6 +128,7 @@ template class ConcreteMachine: const auto state = static_cast(target.state.get()); state->z80.apply(z80_); state->video.apply(*video_.last_valid()); + state->ay.apply(ay_); // If this is a 48k or 16k machine, remap source data from its original // linear form to whatever the banks end up being; otherwise copy as is. diff --git a/Storage/State/Z80.cpp b/Storage/State/Z80.cpp index 9cf63eeee..4f5c9d390 100644 --- a/Storage/State/Z80.cpp +++ b/Storage/State/Z80.cpp @@ -142,7 +142,7 @@ std::unique_ptr Z80::load(const std::string &file_name } state->last_fffd = file.get8(); - file.seek(16, SEEK_CUR); // Sound chip registers: TODO. + file.read(state->ay.registers, 16); if(bonus_header_size != 23) { // More Z80, the emulator, lack of encapsulation to deal with here.