1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +00:00

Fix vertical timing; don't miss border colour changes.

This commit is contained in:
Thomas Harte 2024-04-24 20:47:11 -04:00
parent 7c9383cd6b
commit b82af9c471

View File

@ -191,19 +191,20 @@ struct Video {
}; };
// Possibly output something. // Possibly output something.
if(new_phase != phase_) { if(new_phase != phase_ || (phase_ == Phase::Border && phased_border_colour_ != border_colour_)) {
if(time_in_phase_) { if(time_in_phase_) {
const auto duration = static_cast<int>(time_in_phase_); const auto duration = static_cast<int>(time_in_phase_);
switch(phase_) { switch(phase_) {
case Phase::Sync: crt_.output_sync(duration); break; case Phase::Sync: crt_.output_sync(duration); break;
case Phase::Blank: crt_.output_blank(duration); break; case Phase::Blank: crt_.output_blank(duration); break;
case Phase::Display: flush_pixels(); break; case Phase::Display: flush_pixels(); break;
case Phase::Border: crt_.output_level<uint16_t>(duration, border_colour_); break; case Phase::Border: crt_.output_level<uint16_t>(duration, phased_border_colour_); break;
} }
time_in_phase_ = 0; time_in_phase_ = 0;
} }
phase_ = new_phase; phase_ = new_phase;
phased_border_colour_ = border_colour_;
} }
// Update cursor pixel counter if applicable; this might mean triggering it // Update cursor pixel counter if applicable; this might mean triggering it
@ -373,18 +374,11 @@ private:
enum class Phase { enum class Phase {
Sync, Blank, Border, Display, Sync, Blank, Border, Display,
}; };
template <bool is_vertical>
struct State { struct State {
uint32_t position = 0; uint32_t position = 0;
void increment_position(const Timing &timing) { void increment_position(const Timing &timing) {
++position;
if(position == 1024) position = 0;
if(position == timing.period) {
state = DidRestart;
position = 0;
}
if(position == timing.sync_width) state |= SyncEnded; if(position == timing.sync_width) state |= SyncEnded;
if(position == timing.display_start) state |= DisplayStarted; if(position == timing.display_start) state |= DisplayStarted;
if(position == timing.display_end) state |= DisplayEnded; if(position == timing.display_end) state |= DisplayEnded;
@ -393,6 +387,14 @@ private:
cursor_active |= position == timing.cursor_start; cursor_active |= position == timing.cursor_start;
cursor_active &= position != timing.cursor_end; cursor_active &= position != timing.cursor_end;
if(position == timing.period) {
state = DidRestart;
position = 0;
} else {
++position;
if(position == 1024) position = 0;
}
} }
static constexpr uint8_t SyncEnded = 0x1; static constexpr uint8_t SyncEnded = 0x1;
@ -429,11 +431,13 @@ private:
return Phase::Display; return Phase::Display;
} }
}; };
State horizontal_state_, vertical_state_; State<false> horizontal_state_;
State<true> vertical_state_;
Phase phase_ = Phase::Sync; Phase phase_ = Phase::Sync;
uint32_t time_in_phase_ = 0; uint32_t time_in_phase_ = 0;
uint32_t pixel_count_ = 0; uint32_t pixel_count_ = 0;
uint16_t *pixels_ = nullptr; uint16_t *pixels_ = nullptr;
uint16_t phased_border_colour_;
// It is elsewhere assumed that this size is a multiple of 8. // It is elsewhere assumed that this size is a multiple of 8.
static constexpr size_t PixelBufferSize = 320; static constexpr size_t PixelBufferSize = 320;