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:
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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) |
|
||||
|
||||
Reference in New Issue
Block a user