1
0
mirror of https://github.com/TomHarte/CLK.git synced 2026-04-19 19:16:34 +00:00

Implement interlace-dependent row addressing.

This commit is contained in:
Thomas Harte
2025-09-24 17:20:04 -04:00
parent 84877c4fec
commit 90a96293de
2 changed files with 30 additions and 18 deletions
+29 -16
View File
@@ -36,7 +36,7 @@ struct BusState {
bool vsync = false; // vs
bool cursor = false;
RefreshAddress refresh; // ma_i
LineAddress line; // line_counter
LineAddress line;
// Not strictly part of the bus state; provided because the partition between 6845 and bus handler
// doesn't quite hold up in some emulated systems where the two are integrated and share more state.
@@ -179,21 +179,25 @@ public:
// ordered so that whatever assignments result don't affect any subsequent conditionals
// Do bus work.
bus_state_.display_enable = character_is_visible_ && row_is_visible_;
bus_state_.cursor = (is_cursor_line_ && bus_state_.refresh == layout_.cursor_address)
&& bus_state_.display_enable;
bus_handler_.perform_bus_cycle(bus_state_);
// TODO: exposed line address should be a function of interlaced video flag, as latched.
//
// External bus activity.
//
bus_state_.line = line_is_interlaced_ ? (line_ & LineAddress::IntT(~1)) | (odd_field_ ? 1 : 0) : line_;
bus_state_.display_enable = character_is_visible_ && row_is_visible_;
bus_state_.cursor = (is_cursor_line_ && bus_state_.refresh == layout_.cursor_address)
&& bus_state_.display_enable;
bus_handler_.perform_bus_cycle(bus_state_);
//
// Shared, stateless signals.
// Shared signals.
//
const bool character_total_hit = character_counter_ == layout_.horizontal.total; // r00_h_total_hit
const auto lines_per_row =
layout_.interlace_mode_ == InterlaceMode::SyncAndVideo ?
layout_.vertical.end_line & LineAddress::IntT(~1) : layout_.vertical.end_line; // max_scanline
const bool line_end_hit = bus_state_.line == lines_per_row && !is_in_adjustment_period_; // max_scanline_hit
const bool line_end_hit = line_ == lines_per_row && !is_in_adjustment_period_; // max_scanline_hit
const bool new_frame =
character_total_hit && eof_latched_ &&
(
@@ -202,6 +206,7 @@ public:
extra_line_
); // new_frame
//
// Addressing.
//
@@ -221,6 +226,12 @@ public:
++bus_state_.refresh;
}
// Follow hoglet's lead in means of avoiding the logic that informs line address b0 varying
// within a line if interlace mode is enabled/disabled.
if(character_total_hit) {
line_is_interlaced_ = layout_.interlace_mode_ == InterlaceMode::SyncAndVideo;
}
//
// Sync.
//
@@ -310,17 +321,17 @@ public:
// Counts in steps of 2 only if & 3) mode is InterlaceMode::SyncAndVideo and this is
// not the adjustment period. Otherwise counts in steps of 1.
if(new_frame) {
bus_state_.line = 0;
line_ = 0;
} else if(character_total_hit) {
bus_state_.line = next_line_;
line_ = next_line_;
}
if(line_end_hit) {
next_line_ = 0;
} else if(is_in_adjustment_period_ || layout_.interlace_mode_ != InterlaceMode::SyncAndVideo) {
next_line_ = bus_state_.line + 1;
next_line_ = line_ + 1;
} else {
next_line_ = bus_state_.line + 2;
next_line_ = line_ + 2;
}
// Update row counter.
@@ -401,9 +412,9 @@ public:
if constexpr (cursor_type != CursorType::None) {
// Check for cursor enable.
is_cursor_line_ |= bus_state_.line == layout_.vertical.start_cursor;
is_cursor_line_ |= line_ == layout_.vertical.start_cursor;
is_cursor_line_ &= !(
(bus_state_.line == layout_.vertical.end_cursor) ||
(line_ == layout_.vertical.end_cursor) ||
(
character_total_hit &&
line_end_hit &&
@@ -496,6 +507,7 @@ private:
Numeric::SizedCounter<3> character_reset_history_; // sol
RowAddress row_counter_; // row_counter
RowAddress next_row_counter_; // row_counter_next
LineAddress line_; // line_counter
LineAddress next_line_; // line_counter_next
uint8_t adjustment_counter_ = 0;
@@ -526,7 +538,8 @@ private:
bool reset_ = false;
Numeric::SizedCounter<3> cursor_history_; // cursor0, cursor1, cursor2
Numeric::SizedCounter<3> cursor_history_; // cursor0, cursor1, cursor2 [TODO]
bool line_is_interlaced_ = false;
};
}
+1 -2
View File
@@ -335,8 +335,7 @@ public:
// Check for a cursor leading edge.
cursor_shifter_ >>= 4;
if(state.cursor != previous_cursor_enabled_) {
if(state.cursor && state.display_enable) { // TODO: should I have to test display enable here? Or should
// the CRTC already have factored that in?
if(state.cursor) {
cursor_shifter_ =
((cursor_mask_ & 0x80) ? 0x0007 : 0) |
((cursor_mask_ & 0x40) ? 0x0070 : 0) |