From e94e051c87db5a1c3b3b79c26f3f3f33de2b11c1 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 15 Jun 2021 22:03:41 -0400 Subject: [PATCH] Adds an allocator for pixels. --- Machines/Enterprise/Nick.cpp | 38 +++++++++++++++++++++++++++--------- Machines/Enterprise/Nick.hpp | 6 ++++++ 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/Machines/Enterprise/Nick.cpp b/Machines/Enterprise/Nick.cpp index b5456d3b6..0068d6dd9 100644 --- a/Machines/Enterprise/Nick.cpp +++ b/Machines/Enterprise/Nick.cpp @@ -179,23 +179,35 @@ void Nick::run_for(HalfCycles duration) { if(state_ == State::Border) { border_duration_ += next_event - window; } else { - // TODO: something proper here. - uint16_t *const colour_pointer = reinterpret_cast(crt_.begin_data(1)); - if(colour_pointer) *colour_pointer = 0xfff; - crt_.output_level(next_event - window); + if(!allocated_pointer_) { + flush_pixels(); + pixel_pointer_ = allocated_pointer_ = reinterpret_cast(crt_.begin_data(allocation_size)); + } + + // TODO: real pixels. + if(allocated_pointer_) { + for(int c = 0; c < next_event - window; c++) { + pixel_pointer_[0] = uint16_t(0xfff ^ (window + c)); + ++pixel_pointer_; + } + } else { + pixel_pointer_ += next_event - window; + } + + pixel_duration_ += next_event - window; + if(pixel_pointer_ - allocated_pointer_ == allocation_size) { + flush_pixels(); + } } window = next_event; if(window == left_margin_) { flush_border(); state_ = State::Pixels; - - // TODO: probably allocate some pixels here? } if(window == right_margin_) { + flush_pixels(); state_ = State::Border; - - // TODO: probably output pixels here? } } } @@ -205,7 +217,7 @@ void Nick::run_for(HalfCycles duration) { if(state_ == State::Border) { flush_border(); } else { - // TODO: output pixels. + flush_pixels(); } } } @@ -236,6 +248,14 @@ void Nick::flush_border() { border_duration_ = 0; } +void Nick::flush_pixels() { + if(!pixel_duration_) return; + crt_.output_data(pixel_duration_, size_t(pixel_pointer_ - allocated_pointer_)); + pixel_duration_ = 0; + pixel_pointer_ = nullptr; + allocated_pointer_ = nullptr; +} + // MARK: - CRT passthroughs. void Nick::set_scan_target(Outputs::Display::ScanTarget *scan_target) { diff --git a/Machines/Enterprise/Nick.hpp b/Machines/Enterprise/Nick.hpp index 48693e8a6..5f99cb0f2 100644 --- a/Machines/Enterprise/Nick.hpp +++ b/Machines/Enterprise/Nick.hpp @@ -66,6 +66,12 @@ class Nick { // An accumulator for border output regions. int border_duration_ = 0; void flush_border(); + + // The destination for new pixels. + static constexpr int allocation_size = 320; + uint16_t *pixel_pointer_ = nullptr, *allocated_pointer_ = nullptr; + int pixel_duration_ = 0; + void flush_pixels(); };