From 847dba8f0745b49bcf2df567c6a759d84bc3327c Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 21 Mar 2024 11:03:28 -0400 Subject: [PATCH] Divide input pixel rate. --- Machines/Acorn/Archimedes/Video.hpp | 30 +++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/Machines/Acorn/Archimedes/Video.hpp b/Machines/Acorn/Archimedes/Video.hpp index d1d56365d..c7d1d59c1 100644 --- a/Machines/Acorn/Archimedes/Video.hpp +++ b/Machines/Acorn/Archimedes/Video.hpp @@ -108,6 +108,18 @@ struct Video { case 0xe0: logger.error().append("TODO: video control: %08x", value); + + // Set pixel rate. + // + // TODO: possibly do this as a multiplier on position counts and a divider on pixels, + // to maintain a consistent CRT data clock? + switch(value & 0b11) { + case 0b00: clock_divider_ = 12; break; // 4Mhz count. + case 0b01: clock_divider_ = 8; break; // 6Mhz count. + case 0b10: clock_divider_ = 6; break; // 8Mhz count. + case 0b11: clock_divider_ = 4; break; // i.e. 48/4 = 12Mhz position counting clock. + } + sub_clock_ = 0; break; // @@ -123,7 +135,6 @@ struct Video { sound_.set_frequency(value & 0x7f); break; - default: logger.error().append("TODO: unrecognised VIDC write of %08x", value); break; @@ -131,6 +142,18 @@ struct Video { } void tick() { + // Apply clock divider to get 8, 12, 16 or 24 Mhz pixel rate as user-selected, + // which since all event positioning is at two-pixel boundaries means a + // 4, 6, 8 or 12 Mhz counting clock. + // + // tick() is called at 12Mhz. + sub_clock_ += 4; // Count at 48 Mhz. + if(sub_clock_ < clock_divider_) { + return; + } + sub_clock_ -= clock_divider_; + + // TODO: real output. For now, just count up to complete frames and pretend a retrace goes there. ++position_; if(position_ >= horizontal_.period * vertical_.period) { entered_sync_ = true; @@ -152,7 +175,7 @@ private: SoundT &sound_; // TODO: real video output. - int position_ = 0; + uint32_t position_ = 0; struct Dimension { uint32_t period = 0; @@ -166,6 +189,9 @@ private: }; Dimension horizontal_, vertical_; bool entered_sync_ = false; + + int sub_clock_ = 0; + int clock_divider_ = 0; }; }