From fd271d920bd1acfa799e003c2e23c88ec4326cfe Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 25 Apr 2021 14:00:12 -0400 Subject: [PATCH] Adds capture and forwarding of border colour. --- Machines/Sinclair/ZXSpectrum/State.hpp | 3 ++ Machines/Sinclair/ZXSpectrum/Video.hpp | 36 ++++++++++++++------- Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp | 6 ++-- Storage/State/SNA.cpp | 3 +- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/Machines/Sinclair/ZXSpectrum/State.hpp b/Machines/Sinclair/ZXSpectrum/State.hpp index 60b6db78f..1333c8d62 100644 --- a/Machines/Sinclair/ZXSpectrum/State.hpp +++ b/Machines/Sinclair/ZXSpectrum/State.hpp @@ -11,6 +11,7 @@ #include "../../../Reflection/Struct.hpp" #include "../../../Processors/Z80/State/State.hpp" +#include "Video.hpp" namespace Sinclair { namespace ZXSpectrum { @@ -18,11 +19,13 @@ namespace ZXSpectrum { struct State: public Reflection::StructImpl { CPU::Z80::State z80; + Video::State video; std::vector ram; State() { if(needs_declare()) { DeclareField(z80); + DeclareField(video); DeclareField(ram); } } diff --git a/Machines/Sinclair/ZXSpectrum/Video.hpp b/Machines/Sinclair/ZXSpectrum/Video.hpp index c48392a61..8363d0ad3 100644 --- a/Machines/Sinclair/ZXSpectrum/Video.hpp +++ b/Machines/Sinclair/ZXSpectrum/Video.hpp @@ -12,12 +12,15 @@ #include "../../../Outputs/CRT/CRT.hpp" #include "../../../ClockReceiver/ClockReceiver.hpp" +#include "../../../Reflection/Struct.hpp" + #include namespace Sinclair { namespace ZXSpectrum { +namespace Video { -enum class VideoTiming { +enum class Timing { FortyEightK, OneTwoEightK, Plus3, @@ -47,7 +50,7 @@ enum class VideoTiming { */ -template class Video { +template class Video { private: struct Timings { // Number of cycles per line. Will be 224 or 228. @@ -78,17 +81,17 @@ template class Video { }; static constexpr Timings get_timings() { - if constexpr (timing == VideoTiming::Plus3) { + if constexpr (timing == Timing::Plus3) { constexpr int delays[] = {1, 0, 7, 6, 5, 4, 3, 2}; return Timings(228, 311, 6, 129, 14361, delays); } - if constexpr (timing == VideoTiming::OneTwoEightK) { + if constexpr (timing == Timing::OneTwoEightK) { constexpr int delays[] = {6, 5, 4, 3, 2, 1, 0, 0}; return Timings(228, 311, 4, 128, 14361, delays); } - if constexpr (timing == VideoTiming::FortyEightK) { + if constexpr (timing == Timing::FortyEightK) { constexpr int delays[] = {6, 5, 4, 3, 2, 1, 0, 0}; return Timings(224, 312, 4, 128, 14335, delays); } @@ -103,7 +106,7 @@ template class Video { constexpr int sync_line = (timings.interrupt_time / timings.cycles_per_line) + 1; - constexpr int sync_position = (timing == VideoTiming::FortyEightK) ? 164 * 2 : 166 * 2; + constexpr int sync_position = (timing == Timing::FortyEightK) ? 164 * 2 : 166 * 2; constexpr int sync_length = 17 * 2; constexpr int burst_position = sync_position + 40; constexpr int burst_length = 17; @@ -220,7 +223,7 @@ template class Video { if(offset >= burst_position && offset < burst_position+burst_length && end_offset > offset) { const int burst_duration = std::min(burst_position + burst_length, end_offset) - offset; - if constexpr (timing >= VideoTiming::OneTwoEightK) { + if constexpr (timing >= Timing::OneTwoEightK) { crt_.output_colour_burst(burst_duration, 116, is_alternate_line_); // The colour burst phase above is an empirical guess. I need to research further. } else { @@ -248,7 +251,7 @@ template class Video { } static constexpr int half_cycles_per_line() { - if constexpr (timing == VideoTiming::FortyEightK) { + if constexpr (timing == Timing::FortyEightK) { // TODO: determine real figure here, if one exists. // The source I'm looking at now suggests that the theoretical // ideal of 224*2 ignores the real-life effects of separate @@ -328,7 +331,7 @@ template class Video { */ uint8_t get_floating_value() const { constexpr auto timings = get_timings(); - const uint8_t out_of_bounds = (timing == VideoTiming::Plus3) ? last_contended_access_ : 0xff; + const uint8_t out_of_bounds = (timing == Timing::Plus3) ? last_contended_access_ : 0xff; const int line = time_into_frame_ / timings.cycles_per_line; if(line >= 192) { @@ -342,7 +345,7 @@ template class Video { // The +2a and +3 always return the low bit as set. const uint8_t value = last_fetches_[(time_into_line >> 1) & 3]; - if constexpr (timing == VideoTiming::Plus3) { + if constexpr (timing == Timing::Plus3) { return value | 1; } return value; @@ -354,7 +357,7 @@ template class Video { bus is accessed when the gate array isn't currently reading. */ void set_last_contended_area_access([[maybe_unused]] uint8_t value) { - if constexpr (timing == VideoTiming::Plus3) { + if constexpr (timing == Timing::Plus3) { last_contended_access_ = value | 1; } } @@ -408,6 +411,17 @@ template class Video { #undef RGB }; +struct State: public Reflection::StructImpl { + uint8_t border_colour; + + State() { + if(needs_declare()) { + DeclareField(border_colour); + } + } +}; + +} } } diff --git a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp index 7e026dfdb..83a07ab98 100644 --- a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp +++ b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp @@ -775,10 +775,10 @@ template class ConcreteMachine: // MARK: - Video. using VideoType = std::conditional_t< - model <= Model::FortyEightK, Video, + model <= Model::FortyEightK, Video::Video, std::conditional_t< - model <= Model::Plus2, Video, - Video + model <= Model::Plus2, Video::Video, + Video::Video > >; JustInTimeActor video_; diff --git a/Storage/State/SNA.cpp b/Storage/State/SNA.cpp index 2dce6657f..7d29faf62 100644 --- a/Storage/State/SNA.cpp +++ b/Storage/State/SNA.cpp @@ -64,8 +64,7 @@ std::unique_ptr SNA::load(const std::string &file_name state->z80.registers.interrupt_mode = file.get8(); // 1A border colour - const uint8_t border_colour = file.get8(); - (void)border_colour; // TODO. + state->video.border_colour = file.get8(); // 1B– 48kb RAM contents state->ram = file.read(48*1024);