From 794adf470bb654749db1209e892e91a2b3adce1c Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 8 Jan 2023 21:25:22 -0500 Subject: [PATCH] Break assumption that cycles = pixels; fix pixel clocking. --- Components/9918/Implementation/9918.cpp | 16 +++++++----- .../9918/Implementation/ClockConverter.hpp | 25 ++++++++++++++++--- Machines/MSX/MSX.cpp | 2 +- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/Components/9918/Implementation/9918.cpp b/Components/9918/Implementation/9918.cpp index 3c47a6878..dd447d963 100644 --- a/Components/9918/Implementation/9918.cpp +++ b/Components/9918/Implementation/9918.cpp @@ -417,23 +417,25 @@ void TMS9918::run_for(const HalfCycles cycles) { line_buffer.next_border_column, if(!this->asked_for_write_area_) { this->asked_for_write_area_ = true; + + // TODO: how many pixels across is this mode? this->pixel_origin_ = this->pixel_target_ = reinterpret_cast( - this->crt_.begin_data(size_t(line_buffer.next_border_column - line_buffer.first_pixel_output_column)) + this->crt_.begin_data(256) ); } if(this->pixel_target_) { switch(line_buffer.line_mode) { - case LineMode::SMS: draw(draw_sms(relative_start, relative_end, cram_value), to_tms_access_clock); break; - case LineMode::Character: draw(draw_tms_character(relative_start, relative_end), to_tms_access_clock); break; - case LineMode::Text: draw(draw_tms_text(relative_start, relative_end), to_tms_access_clock); break; + case LineMode::SMS: draw(draw_sms(relative_start, relative_end, cram_value), to_tms_pixel_clock); break; + case LineMode::Character: draw(draw_tms_character(relative_start, relative_end), to_tms_pixel_clock); break; + case LineMode::Text: draw(draw_tms_text(relative_start, relative_end), to_tms_pixel_clock); break; case LineMode::Refresh: break; /* Dealt with elsewhere. */ } } if(end == line_buffer.next_border_column) { - const int length = line_buffer.next_border_column - line_buffer.first_pixel_output_column; + const int length = 256;//line_buffer.next_border_column - line_buffer.first_pixel_output_column; // TODO: proper number of pixels, as above. this->crt_.output_data(this->clock_converter_.to_crt_clock(length), size_t(length)); this->pixel_origin_ = this->pixel_target_ = nullptr; this->asked_for_write_area_ = false; @@ -713,7 +715,9 @@ HalfCycles TMS9918::get_next_sequence_point() const { ) % frame_length; if(!time_until_frame_interrupt) time_until_frame_interrupt = frame_length; - if(!this->enable_line_interrupts_) return this->clock_converter_.half_cycles_before_internal_cycles(time_until_frame_interrupt); + if(!this->enable_line_interrupts_) { + return this->clock_converter_.half_cycles_before_internal_cycles(time_until_frame_interrupt); + } // Calculate when the next line interrupt will occur. int next_line_interrupt_row = -1; diff --git a/Components/9918/Implementation/ClockConverter.hpp b/Components/9918/Implementation/ClockConverter.hpp index ab1b438cf..f6ae33bd5 100644 --- a/Components/9918/Implementation/ClockConverter.hpp +++ b/Components/9918/Implementation/ClockConverter.hpp @@ -155,7 +155,7 @@ template class ClockConverter { case Personality::V9938: case Personality::V9958: - return HalfCycles(internal_cycles / 3); + return HalfCycles((internal_cycles + 2) / 3); case Personality::MDVDP: return HalfCycles( @@ -166,8 +166,7 @@ template class ClockConverter { /*! Converts a position in internal cycles to its corresponding position - on the TMS memory-access clock, i.e. scales down to 171 clocks - per line + on the TMS memory-access clock, i.e. scales to 171 clocks per line. */ static constexpr int to_tms_access_clock(int source) { switch(personality) { @@ -183,6 +182,24 @@ template class ClockConverter { } } + /*! + Converts a position in internal cycles to its corresponding position + on the TMS pixel clock, i.e. scales to 342 clocks per line. + */ + static constexpr int to_tms_pixel_clock(int source) { + switch(personality) { + default: + return source; + + case Personality::V9938: + case Personality::V9958: + return source >> 2; + + case Personality::MDVDP: + return source / 10; + } + } + /*! Convers a position in internal cycles to its corresponding position on the CRT's output clock, which [TODO] is clocked so that @@ -191,7 +208,7 @@ template class ClockConverter { static constexpr int to_crt_clock(int source) { switch(personality) { default: - return source * 4; + return source << 2; case Personality::V9938: case Personality::V9958: diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp index 6bc06bda0..2ec502788 100644 --- a/Machines/MSX/MSX.cpp +++ b/Machines/MSX/MSX.cpp @@ -743,7 +743,7 @@ class ConcreteMachine: }; CPU::Z80::Processor z80_; - JustInTimeActor> vdp_; + JustInTimeActor> vdp_; Intel::i8255::i8255 i8255_; Concurrency::AsyncTaskQueue audio_queue_;