From e956740c566151e21ff481d70835a4e8fc99320d Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 22 Aug 2017 21:54:48 -0400 Subject: [PATCH] =?UTF-8?q?Refactors=20the=206845=20more=20clearly=20to=20?= =?UTF-8?q?break=20out=20the=20acts=20of=20ending=20a=20line=20and=20endin?= =?UTF-8?q?g=20a=20frame,=20changing=20the=20way=20the=20memory=20address?= =?UTF-8?q?=20is=20altered=20=E2=80=94=20the=20end-of-line=20value=20is=20?= =?UTF-8?q?provisionally=20stored=20and=20then=20used=20if=20necessary=20?= =?UTF-8?q?=E2=80=94=20in=20order=20to=20do=20so.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Components/6845/CRTC6845.hpp | 205 ++++++++++++++++++----------------- 1 file changed, 105 insertions(+), 100 deletions(-) diff --git a/Components/6845/CRTC6845.hpp b/Components/6845/CRTC6845.hpp index 746fc8b5a..959f7f8a0 100644 --- a/Components/6845/CRTC6845.hpp +++ b/Components/6845/CRTC6845.hpp @@ -44,106 +44,6 @@ template class CRTC6845 { CRTC6845(Personality p, T &bus_handler) : personality_(p), bus_handler_(bus_handler) {} - void run_for(Cycles cycles) { - int cyles_remaining = cycles.as_int(); - while(cyles_remaining--) { - // check for end of horizontal sync - if(hsync_down_counter_) { - hsync_down_counter_--; - if(!hsync_down_counter_) { - bus_state_.hsync = false; - } - } - - // check for end of line - bool is_end_of_line = character_counter_ == registers_[0]; - - // increment counter - character_counter_++; - - // check for start of horizontal sync - if(character_counter_ == registers_[2]) { - hsync_down_counter_ = registers_[3] & 15; - if(hsync_down_counter_) bus_state_.hsync = true; - } - - // update refresh address - if(character_is_visible_) { - bus_state_.refresh_address++; - } - - // check for end of visible characters - if(character_counter_ == registers_[1]) { - character_is_visible_ = false; - } - - // check for end-of-line - if(is_end_of_line) { - // check for end of vertical sync - if(vsync_down_counter_) { - vsync_down_counter_--; - if(!vsync_down_counter_) { - bus_state_.vsync = false; - } - } - - if(is_in_adjustment_period_) { - line_counter_++; - if(line_counter_ == registers_[5]) { - line_counter_ = 0; - is_in_adjustment_period_ = false; - line_is_visible_ = true; - line_address_ = (uint16_t)((registers_[12] << 8) | registers_[13]); - bus_state_.refresh_address = line_address_; - } - } else { - // advance vertical counter - if(bus_state_.row_address == registers_[9]) { - if(!character_is_visible_) - line_address_ = bus_state_.refresh_address; - bus_state_.row_address = 0; - - bool is_at_end_of_frame = line_counter_ == registers_[4]; - line_counter_ = (line_counter_ + 1) & 0x7f; - - // check for end of visible lines - if(line_counter_ == registers_[6]) { - line_is_visible_ = false; - } - - // check for start of vertical sync - if(line_counter_ == registers_[7]) { - bus_state_.vsync = true; - vsync_down_counter_ = registers_[3] >> 4; - if(!vsync_down_counter_) vsync_down_counter_ = 16; - } - - // check for entry into the overflow area - if(is_at_end_of_frame) { - if(registers_[5]) { - is_in_adjustment_period_ = true; - } else { - line_is_visible_ = true; - line_address_ = (uint16_t)((registers_[12] << 8) | registers_[13]); - bus_state_.refresh_address = line_address_; - } - bus_state_.row_address = 0; - line_counter_ = 0; - } - } else { - bus_state_.row_address = (bus_state_.row_address + 1) & 0x1f; - } - bus_state_.refresh_address = line_address_; - } - - character_counter_ = 0; - character_is_visible_ = (registers_[1] != 0); - } - - perform_bus_cycle(); - } - } - void select_register(uint8_t r) { selected_register_ = r; } @@ -172,6 +72,48 @@ template class CRTC6845 { registers_[16] = bus_state_.refresh_address >> 8; } + void run_for(Cycles cycles) { + static int c = 0; + c++; + + int cyles_remaining = cycles.as_int(); + while(cyles_remaining--) { + // check for end of horizontal sync + if(hsync_down_counter_) { + hsync_down_counter_--; + if(!hsync_down_counter_) { + bus_state_.hsync = false; + } + } + + // check for start of horizontal sync + if(character_counter_ == registers_[2]) { + hsync_down_counter_ = registers_[3] & 15; + if(hsync_down_counter_) bus_state_.hsync = true; + } + + // check for end of visible characters + if(character_counter_ == registers_[1]) { + // TODO: consider skew in character_is_visible_. Or maybe defer until perform_bus_cycle? + character_is_visible_ = false; + end_of_line_address_ = bus_state_.refresh_address; + } + + perform_bus_cycle(); + bus_state_.refresh_address++; + + // check for end-of-line + if(character_counter_ == registers_[0]) { + character_counter_ = 0; + do_end_of_line(); + character_is_visible_ = true; + } else { + // increment counter + character_counter_++; + } + } + } + private: inline void perform_bus_cycle() { bus_state_.display_enable = character_is_visible_ && line_is_visible_; @@ -179,6 +121,67 @@ template class CRTC6845 { bus_handler_.perform_bus_cycle(bus_state_); } + inline void do_end_of_line() { + // check for end of vertical sync + if(vsync_down_counter_) { + vsync_down_counter_--; + if(!vsync_down_counter_) { + bus_state_.vsync = false; + } + } + + if(is_in_adjustment_period_) { + line_counter_++; + if(line_counter_ == registers_[5]) { + is_in_adjustment_period_ = false; + do_end_of_frame(); + } + } else { + // advance vertical counter + if(bus_state_.row_address == registers_[9]) { + bus_state_.row_address = 0; + line_address_ = end_of_line_address_; + + // check for entry into the overflow area + if(line_counter_ == registers_[4]) { + if(registers_[5]) { + line_counter_ = 0; + is_in_adjustment_period_ = true; + } else { + do_end_of_frame(); + } + } else { + line_counter_ = (line_counter_ + 1) & 0x7f; + + // check for end of visible lines + if(line_counter_ == registers_[6]) { + line_is_visible_ = false; + } + + // check for start of vertical sync + if(line_counter_ == registers_[7]) { + bus_state_.vsync = true; + vsync_down_counter_ = registers_[3] >> 4; + if(!vsync_down_counter_) vsync_down_counter_ = 16; + } + } + } else { + bus_state_.row_address = (bus_state_.row_address + 1) & 0x1f; + } + } + + bus_state_.refresh_address = line_address_; + character_counter_ = 0; + character_is_visible_ = (registers_[1] != 0); + } + + inline void do_end_of_frame() { + line_counter_ = 0; + line_is_visible_ = true; + line_address_ = (uint16_t)((registers_[12] << 8) | registers_[13]); + bus_state_.refresh_address = line_address_; + } + Personality personality_; T &bus_handler_; BusState bus_state_; @@ -194,7 +197,9 @@ template class CRTC6845 { int hsync_down_counter_; int vsync_down_counter_; bool is_in_adjustment_period_; + uint16_t line_address_; + uint16_t end_of_line_address_; }; }