From e691cc8723776f3160f4fedc77417fe8297f9db2 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 7 Dec 2023 14:21:09 -0500 Subject: [PATCH] Retain dark yellow for composite output. --- Machines/PCCompatible/CGA.hpp | 80 +++++++++++++++----------- Machines/PCCompatible/PCCompatible.cpp | 7 +-- Outputs/ScanTarget.hpp | 4 ++ 3 files changed, 52 insertions(+), 39 deletions(-) diff --git a/Machines/PCCompatible/CGA.hpp b/Machines/PCCompatible/CGA.hpp index 4e7b45d5e..56a356615 100644 --- a/Machines/PCCompatible/CGA.hpp +++ b/Machines/PCCompatible/CGA.hpp @@ -15,41 +15,6 @@ namespace PCCompatible { -static constexpr uint8_t DarkCyan = 0b00'10'10; -static constexpr uint8_t DarkMagenta = 0b10'00'10; -static constexpr uint8_t DarkGrey = 0b10'10'10; - -static constexpr uint8_t DarkGreen = 0b00'10'00; -static constexpr uint8_t DarkRed = 0b10'00'00; -static constexpr uint8_t DarkYellow = 0b10'10'00; - -static constexpr uint8_t Brown = 0b10'01'00; - -/// @returns @c Brown if @c source is @c DarkYellow; @c source otherwise. -constexpr uint8_t yellow_to_brown(uint8_t source) { - return (source == DarkYellow) ? Brown : source; -} - -/// @returns The brightened (i.e. high intensity) version of @c source. -constexpr uint8_t bright(uint8_t source) { - return source | (source >> 1); -} - -/// Maps the RGB TTL triplet @c source to an appropriate output colour. -constexpr uint8_t rgb(uint8_t source) { - return uint8_t( - ((source & 0x01) << 1) | - ((source & 0x02) << 2) | - ((source & 0x04) << 3) - ); -} - -/// Maps the RGBI value in @c source to an appropriate output colour, including potential yellow-to-brown conversion. -constexpr uint8_t rgbi(uint8_t source) { - const uint8_t result = rgb(source); - return (source & 0x10) ? bright(result) : yellow_to_brown(result); -} - class CGA { public: CGA() : crtc_(Motorola::CRTC::Personality::HD6845S, outputter_) {} @@ -113,6 +78,7 @@ class CGA { void set_display_type(Outputs::Display::DisplayType display_type) { outputter_.crt.set_display_type(display_type); + outputter_.set_is_composite(Outputs::Display::is_composite(display_type)); } Outputs::Display::DisplayType get_display_type() const { return outputter_.crt.get_display_type(); @@ -165,6 +131,11 @@ class CGA { update_palette(); } + void set_is_composite(bool is_composite) { + is_composite_ = is_composite; + update_palette(); + } + void set_colours(uint8_t value) { colours_ = value; update_palette(); @@ -384,6 +355,7 @@ class CGA { int pixels_per_tick = 8; uint8_t colours_ = 0; uint8_t control_ = 0; + bool is_composite_ = false; enum class Mode { Pixels640, Pixels320, Text, } mode_ = Mode::Text; @@ -425,10 +397,48 @@ class CGA { border_colour = (mode_ != Mode::Pixels640) ? palette320[0] : 0; } + // + // Named colours and mapping logic. + // + static constexpr uint8_t DarkCyan = 0b00'10'10; + static constexpr uint8_t DarkMagenta = 0b10'00'10; + static constexpr uint8_t DarkGrey = 0b10'10'10; + + static constexpr uint8_t DarkGreen = 0b00'10'00; + static constexpr uint8_t DarkRed = 0b10'00'00; + static constexpr uint8_t DarkYellow = 0b10'10'00; + + static constexpr uint8_t Brown = 0b10'01'00; + + /// @returns @c Brown if @c source is @c DarkYellow and composite output is not enabled; @c source otherwise. + constexpr uint8_t yellow_to_brown(uint8_t source) { + return (source == DarkYellow && !is_composite_) ? Brown : source; + } + + /// @returns The brightened (i.e. high intensity) version of @c source. + constexpr uint8_t bright(uint8_t source) { + return source | (source >> 1); + } + + /// Maps the RGB TTL triplet @c source to an appropriate output colour. + constexpr uint8_t rgb(uint8_t source) { + return uint8_t( + ((source & 0x01) << 1) | + ((source & 0x02) << 2) | + ((source & 0x04) << 3) + ); + } + + /// Maps the RGBI value in @c source to an appropriate output colour, including potential yellow-to-brown conversion. + constexpr uint8_t rgbi(uint8_t source) { + const uint8_t result = rgb(source); + return (source & 0x10) ? bright(result) : yellow_to_brown(result); + } } outputter_; Motorola::CRTC::CRTC6845 crtc_; int full_clock_ = 0; + }; } diff --git a/Machines/PCCompatible/PCCompatible.cpp b/Machines/PCCompatible/PCCompatible.cpp index 55529d43b..f36f0b3e7 100644 --- a/Machines/PCCompatible/PCCompatible.cpp +++ b/Machines/PCCompatible/PCCompatible.cpp @@ -1109,10 +1109,9 @@ class ConcreteMachine: void set_display_type(Outputs::Display::DisplayType display_type) override { video_.set_display_type(display_type); - ppi_handler_.hint_is_composite( - (display_type == Outputs::Display::DisplayType::CompositeColour) || - (display_type == Outputs::Display::DisplayType::CompositeMonochrome) - ); + + // Give the PPI a shout-out in case it isn't too late to switch to CGA40. + ppi_handler_.hint_is_composite(Outputs::Display::is_composite(display_type)); } Outputs::Display::DisplayType get_display_type() const override { diff --git a/Outputs/ScanTarget.hpp b/Outputs/ScanTarget.hpp index 6b01fe3cc..487559d4f 100644 --- a/Outputs/ScanTarget.hpp +++ b/Outputs/ScanTarget.hpp @@ -51,6 +51,10 @@ enum class DisplayType { CompositeMonochrome }; +constexpr bool is_composite(DisplayType type) { + return type == DisplayType::CompositeColour || type == DisplayType::CompositeMonochrome; +} + /*! Enumerates the potential formats of input data.