From cb0dc7b434db6c73837d2c4aaac91f771fa78c53 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 31 Jul 2017 22:01:54 -0400 Subject: [PATCH] I'm sure it's not going to be this easy, but this is a genuine attempt at full horizontal and vertical timing. --- Components/6845/CRTC6845.hpp | 87 +++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/Components/6845/CRTC6845.hpp b/Components/6845/CRTC6845.hpp index 15e6b9201..289f25b1c 100644 --- a/Components/6845/CRTC6845.hpp +++ b/Components/6845/CRTC6845.hpp @@ -33,8 +33,82 @@ template class CRTC6845 { void run_for(Cycles cycles) { int cyles_remaining = cycles.as_int(); while(cyles_remaining--) { - // TODO: update state (!) + // check for end of horizontal sync + if(hsync_down_counter_) { + hsync_down_counter_--; + if(!hsync_down_counter_) { + bus_state_.hsync = false; + } + } + // advance horizontal 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; + } + + // check for end of visible characters + if(character_counter_ == registers_[1]) { + character_is_visible_ = false; + } + + // check for end-of-line + if(character_counter_ == registers_[0]+1) { + character_counter_ = 0; + character_is_visible_ = true; + + // 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_is_visible_ = true; + line_counter_ = 0; + is_in_adjustment_period_ = false; + line_address_ = (registers_[12] << 8) | registers_[13]; + bus_state_.refresh_address = line_address_; + } + } else { + // advance vertical counter + bus_state_.row_address++; + if(bus_state_.row_address == registers_[9]) { + line_address_ = bus_state_.refresh_address; + bus_state_.row_address = 0; + line_counter_++; + + // 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_ = 16; // TODO + } + + // check for entry into the overflow area + if(line_counter_ == registers_[4]) { + is_in_adjustment_period_ = true; + bus_state_.row_address = 0; + line_counter_ = 0; + } + } else { + bus_state_.refresh_address = line_address_; + } + } + } + + bus_state_.display_enable = line_is_visible_ && line_is_visible_; bus_handler_.perform_bus_cycle(bus_state_); } } @@ -53,7 +127,6 @@ template class CRTC6845 { void set_register(uint8_t value) { registers_[selected_register_] = value; - if(!selected_register_) printf("Horizontal total: %d\n", value); } private: @@ -62,6 +135,16 @@ template class CRTC6845 { uint8_t registers_[16]; int selected_register_; + + uint8_t character_counter_; + uint8_t line_counter_; + + bool character_is_visible_, line_is_visible_; + + int hsync_down_counter_; + int vsync_down_counter_; + bool is_in_adjustment_period_; + uint16_t line_address_; }; }