diff --git a/Components/6847/6847.cpp b/Components/6847/6847.cpp index acc31c600..b5910bc28 100644 --- a/Components/6847/6847.cpp +++ b/Components/6847/6847.cpp @@ -140,18 +140,38 @@ MC6847Base::MC6847Base(const Outputs::Display::Type display_type) : crt_.set_display_type(Outputs::Display::DisplayType::CompositeColour); } -void MC6847Base::pixel_line(const int line_begin, const int line_end) { - if(line_begin < LineLayout::EndOfLeftBorder && line_end >= LineLayout::EndOfLeftBorder) [[unlikely]] { - crt_.output_sync(LineLayout::EndOfSync); - if(display_type_ == Outputs::Display::Type::NTSC60) { - crt_.output_colour_burst(LineLayout::EndOfColourBurst - LineLayout::EndOfSync, ColourPhase); - } else { - crt_.output_default_colour_burst(LineLayout::EndOfColourBurst - LineLayout::EndOfSync); +void MC6847Base::sync_and_burst(const int line_begin, const int line_end) { + Numeric::if_includes( + line_begin, + line_end, + [&] { + crt_.output_sync(LineLayout::EndOfSync); + if(display_type_ == Outputs::Display::Type::NTSC60) { + crt_.output_colour_burst(LineLayout::EndOfColourBurst - LineLayout::EndOfSync, ColourPhase); + } else { + crt_.output_default_colour_burst(LineLayout::EndOfColourBurst - LineLayout::EndOfSync); + } } - crt_.output_blank(LineLayout::EndOfLeftBorder - LineLayout::EndOfColourBurst); + ); +} + +void MC6847Base::pixel_line(const int line_begin, const int line_end) { + sync_and_burst(line_begin, line_end); + Numeric::clamp( + line_begin, + line_end, + [&](const int begin, const int end) { + crt_.output_level(end - begin, border_colour_); + } + ); + Numeric::if_includes( + line_begin, + line_end, + [&] { + pixels_ = reinterpret_cast(crt_.begin_data(256)); + } + ); - pixels_ = reinterpret_cast(crt_.begin_data(256)); - } if(pixels_) [[likely]] { Numeric::clamp( line_begin, @@ -297,24 +317,43 @@ void MC6847Base::pixel_line(const int line_begin, const int line_end) { } ); } + Numeric::if_includes( + line_begin, + line_end, + [&] { + crt_.output_data(256); + } + ); + Numeric::clamp( + line_begin, + line_end, + [&](const int begin, const int end) { + crt_.output_level(end - begin, border_colour_); + } + ); if(line_end == LineLayout::EndOfLine) [[unlikely]] { - crt_.output_data(256); address_.apply_hsync(); - crt_.output_blank(LineLayout::EndOfLine - LineLayout::EndOfPixels); } } -void MC6847Base::border_line(const int, const int end) { +void MC6847Base::border_line(const int line_begin, const int line_end) { + sync_and_burst(line_begin, line_end); + Numeric::clamp( + line_begin, + line_end, + [&](const int begin, const int end) { + crt_.output_level(end - begin, border_colour_); + } + ); +} + +void MC6847Base::porch_line(const int, const int end) { if(end == LineLayout::EndOfLine) { crt_.output_sync(LineLayout::EndOfSync); crt_.output_blank(LineLayout::EndOfLine - LineLayout::EndOfSync); } } -void MC6847Base::porch_line(const int begin, const int end) { - border_line(begin, end); -} - void MC6847Base::sync_line(const int, const int end) { if(end == LineLayout::EndOfLine) { crt_.output_sync(LineLayout::EndOfLine); @@ -402,10 +441,14 @@ void MC6847Base::set_mode( address_.target_row_ = repeated_rows(mode); if(is_2bpp(mode)) { mode_ |= Mode::BPP2; + border_colour_ = colour_select ? Colours::colour1[0] : Colours::colour0[0]; + } else { + border_colour_ = colour_select ? Colours::resolution1[1] : Colours::resolution0[1]; } } else { set_32bytes(); address_.target_row_ = 12; + border_colour_ = 0; } // TODO: apply my net understanding, which is now this: diff --git a/Components/6847/6847.hpp b/Components/6847/6847.hpp index c4d12d0bb..d9f61ac00 100644 --- a/Components/6847/6847.hpp +++ b/Components/6847/6847.hpp @@ -116,6 +116,8 @@ constexpr uint8_t repeated_rows(const GraphicsMode mode) { struct MC6847Base { MC6847Base(Outputs::Display::Type); + void sync_and_burst(int begin, int end); + void pixel_line(int begin, int end); void border_line(int begin, int end); void porch_line(int begin, int end); @@ -137,6 +139,7 @@ struct MC6847Base { Outputs::CRT::CRT crt_; uint32_t *pixels_ = nullptr; + uint32_t border_colour_ = 0; void set_mode( bool graphics, diff --git a/Numeric/SegmentCounter.hpp b/Numeric/SegmentCounter.hpp index 17001a0d8..4218273a0 100644 --- a/Numeric/SegmentCounter.hpp +++ b/Numeric/SegmentCounter.hpp @@ -80,4 +80,12 @@ void clamp(const int begin, const int end, const FuncT &&function) { } } +/// Calls @c function if and only if [begin, end] contains the event point. +template +void if_includes(const int begin, const int end, const FuncT &&function) { + if(begin <= EventPoint && end > EventPoint) { + function(); + } +} + }