From afeec09902f1caaaffdc4e921079d274e14ae3bc Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 6 Sep 2018 23:23:19 -0400 Subject: [PATCH] Gets explicit about DHIRES being annunciator 3; implements four-colour high res mode. --- Machines/AppleII/AppleII.cpp | 6 +++--- Machines/AppleII/Video.cpp | 15 +++++++++------ Machines/AppleII/Video.hpp | 34 ++++++++++++++++++---------------- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/Machines/AppleII/AppleII.cpp b/Machines/AppleII/AppleII.cpp index 66527c50d..3c993aacc 100644 --- a/Machines/AppleII/AppleII.cpp +++ b/Machines/AppleII/AppleII.cpp @@ -534,7 +534,7 @@ template class ConcreteMachine: #undef IIeSwitchRead case 0xc07f: - if(is_iie()) *value = (*value & 0x7f) | (video_->get_double_high_resolution() ? 0x80 : 0x00); + if(is_iie()) *value = (*value & 0x7f) | (video_->get_annunciator_3() ? 0x80 : 0x00); break; } } else { @@ -611,7 +611,7 @@ template class ConcreteMachine: analogue_charge_ = 0.0f; } break; - /* Read-write switches. */ + /* Switches triggered by reading or writing. */ case 0xc050: case 0xc051: update_video(); @@ -636,7 +636,7 @@ template class ConcreteMachine: case 0xc05f: if(is_iie()) { update_video(); - video_->set_double_high_resolution(!(address&1)); + video_->set_annunciator_3(!(address&1)); } break; diff --git a/Machines/AppleII/Video.cpp b/Machines/AppleII/Video.cpp index 7435f3c1f..f51ba8606 100644 --- a/Machines/AppleII/Video.cpp +++ b/Machines/AppleII/Video.cpp @@ -131,15 +131,16 @@ bool VideoBase::get_high_resolution() { return set_high_resolution_; } -void VideoBase::set_double_high_resolution(bool double_high_resolution) { - set_double_high_resolution_ = double_high_resolution; +void VideoBase::set_annunciator_3(bool annunciator_3) { + set_annunciator_3_ = annunciator_3; deferrer_.defer(Cycles(2), [=] { - double_high_resolution_ = double_high_resolution; + annunciator_3_ = annunciator_3; + high_resolution_mask_ = annunciator_3_ ? 0x7f : 0xff; }); } -bool VideoBase::get_double_high_resolution() { - return set_double_high_resolution_; +bool VideoBase::get_annunciator_3() { + return set_annunciator_3_; } void VideoBase::set_character_rom(const std::vector &character_rom) { @@ -276,7 +277,9 @@ void VideoBase::output_high_resolution(uint8_t *target, const uint8_t *const sou for(size_t c = 0; c < length; ++c) { // High resolution graphics shift out LSB to MSB, optionally with a delay of half a pixel. // If there is a delay, the previous output level is held to bridge the gap. - if(source[c] & 0x80) { + // Delays may be ignored on a IIe if Annunciator 3 is set; that's the state that + // high_resolution_mask_ models. + if(source[c] & high_resolution_mask_ & 0x80) { target[0] = graphics_carry_; target[1] = target[2] = source[c] & 0x01; target[3] = target[4] = source[c] & 0x02; diff --git a/Machines/AppleII/Video.hpp b/Machines/AppleII/Video.hpp index a992b61a6..fd87541e4 100644 --- a/Machines/AppleII/Video.hpp +++ b/Machines/AppleII/Video.hpp @@ -128,18 +128,19 @@ class VideoBase { bool get_high_resolution(); /*! - Setter for DHIRES ($C05E/$C05F; triggers on write only). + Setter for annunciator 3. - * On: turn on double-high resolution. - * Off: turn off double-high resolution. + * On: turn on annunciator 3. + * Off: turn off annunciator 3. - DHIRES doesn't exist on a II/II+. On the IIe there is another - register usually grouped with the graphics setters called IOUDIS - that affects visibility of this switch. But it has no effect on - video, so it's not modelled by this class. + This exists on both the II/II+ and the IIe, but has no effect on + video on the older machines. It's intended to be used on the IIe + to confirm double-high resolution mode but has side effects in + selecting mixed mode output and discarding high-resolution + delay bits. */ - void set_double_high_resolution(bool); - bool get_double_high_resolution(); + void set_annunciator_3(bool); + bool get_annunciator_3(); // Setup for text mode. void set_character_rom(const std::vector &); @@ -176,13 +177,14 @@ class VideoBase { bool text_ = true, set_text_ = true; bool mixed_ = false, set_mixed_ = false; bool high_resolution_ = false, set_high_resolution_ = false; - bool double_high_resolution_ = false, set_double_high_resolution_ = false; + bool annunciator_3_ = false, set_annunciator_3_ = false; // Graphics carry is the final level output in a fetch window; // it carries on into the next if it's high resolution with // the delay bit set. mutable uint8_t graphics_carry_ = 0; bool was_double_ = false; + uint8_t high_resolution_mask_ = 0xff; // This holds a copy of the character ROM. The regular character // set is assumed to be in the first 64*8 bytes; the alternative @@ -539,14 +541,14 @@ template class Video: public VideoBase { } GraphicsMode graphics_mode(int row) { - if(text_) return columns_80_ ? GraphicsMode::DoubleText : GraphicsMode::Text; - if(mixed_ && row >= 160 && row < 192) { - return (columns_80_ || double_high_resolution_) ? GraphicsMode::DoubleText : GraphicsMode::Text; - } + if( + text_ || + (mixed_ && row >= 160 && row < 192) + ) return columns_80_ ? GraphicsMode::DoubleText : GraphicsMode::Text; if(high_resolution_) { - return double_high_resolution_ ? GraphicsMode::DoubleHighRes : GraphicsMode::HighRes; + return (annunciator_3_ && columns_80_) ? GraphicsMode::DoubleHighRes : GraphicsMode::HighRes; } else { - return double_high_resolution_ ? GraphicsMode::DoubleLowRes : GraphicsMode::LowRes; + return annunciator_3_ ? GraphicsMode::DoubleLowRes : GraphicsMode::LowRes; } }