1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-19 10:29:08 +00:00

Ensure addresses tick upwards even during sync/burst; correct 2/4/8bpp character sizing.

This commit is contained in:
Thomas Harte 2021-06-28 19:00:51 -04:00
parent 36805cb120
commit daa0737ce4
2 changed files with 24 additions and 32 deletions

View File

@ -113,6 +113,8 @@ void Nick::run_for(Cycles duration) {
// TODO: test here for window < 57? Or maybe just nudge up left_/right_margin_ if they // TODO: test here for window < 57? Or maybe just nudge up left_/right_margin_ if they
// exactly equal 57? // exactly equal 57?
#define add_window(x) \ #define add_window(x) \
line_data_pointer_[0] += is_sync_or_pixels_ * line_data_per_column_increments_[0] * (x); \
line_data_pointer_[1] += is_sync_or_pixels_ * line_data_per_column_increments_[1] * (x); \
window += x; \ window += x; \
if(window == left_margin_) is_sync_or_pixels_ = true; \ if(window == left_margin_) is_sync_or_pixels_ = true; \
if(window == right_margin_) is_sync_or_pixels_ = false; if(window == right_margin_) is_sync_or_pixels_ = false;
@ -170,15 +172,10 @@ void Nick::run_for(Cycles duration) {
break; break;
case Mode::LPixel: case Mode::LPixel:
column_size_ = 8 / bpp_;
line_data_per_column_increments_[0] = 1;
line_data_per_column_increments_[1] = 0;
break;
case Mode::CH64: case Mode::CH64:
case Mode::CH128: case Mode::CH128:
case Mode::CH256: case Mode::CH256:
column_size_ = 8; column_size_ = 8 / bpp_;
line_data_per_column_increments_[0] = 1; line_data_per_column_increments_[0] = 1;
line_data_per_column_increments_[1] = 0; line_data_per_column_increments_[1] = 0;
break; break;
@ -362,13 +359,10 @@ void Nick::run_for(Cycles duration) {
set_output_type(OutputType::Pixels, true); set_output_type(OutputType::Pixels, true);
} }
columns_remaining -= output_duration; columns_remaining -= output_duration;
add_window(output_duration);
} else { } else {
// Ensure line data pointers are advanced as if there hadn't been back pressure on
// pixel rendering.
line_data_pointer_[0] += columns_remaining * line_data_per_column_increments_[0];
line_data_pointer_[1] += columns_remaining * line_data_per_column_increments_[1];
output_duration_ += columns_remaining; output_duration_ += columns_remaining;
add_window(columns_remaining);
columns_remaining = 0; columns_remaining = 0;
} }
} }
@ -382,9 +376,9 @@ void Nick::run_for(Cycles duration) {
#undef DispatchBpp #undef DispatchBpp
} else { } else {
output_duration_ += next_event - window; output_duration_ += next_event - window;
add_window(next_event - window);
} }
add_window(next_event - window);
set_output_type(is_sync_or_pixels_ ? OutputType::Pixels : OutputType::Border); set_output_type(is_sync_or_pixels_ ? OutputType::Pixels : OutputType::Border);
} }
} }
@ -392,6 +386,8 @@ void Nick::run_for(Cycles duration) {
// Check for end of line. // Check for end of line.
if(!horizontal_counter_) { if(!horizontal_counter_) {
assert(window == 57);
++lines_remaining_; ++lines_remaining_;
if(!lines_remaining_) { if(!lines_remaining_) {
should_reload_line_parameters_ = true; should_reload_line_parameters_ = true;
@ -523,12 +519,16 @@ Outputs::Display::ScanStatus Nick::get_scaled_scan_status() const {
target[0] = mapped_colour(x); \ target[0] = mapped_colour(x); \
++target ++target
template <int bpp, bool is_lpixel> void Nick::output_pixel(uint16_t *target, int columns) { template <int bpp, bool is_lpixel> void Nick::output_pixel(uint16_t *target, int columns) const {
static_assert(bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8); static_assert(bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8);
int index = 0;
for(int c = 0; c < columns; c++) { for(int c = 0; c < columns; c++) {
uint8_t pixels[2] = { ram_[line_data_pointer_[0]], ram_[(line_data_pointer_[0]+1) & 0xffff] }; uint8_t pixels[2] = {
line_data_pointer_[0] += is_lpixel ? 1 : 2; ram_[(line_data_pointer_[0] + index) & 0xffff],
ram_[(line_data_pointer_[0] + index + 1) & 0xffff]
};
index += is_lpixel ? 1 : 2;
switch(bpp) { switch(bpp) {
default: default:
@ -568,21 +568,16 @@ template <int bpp, bool is_lpixel> void Nick::output_pixel(uint16_t *target, int
} }
} }
template <int bpp, int index_bits> void Nick::output_character(uint16_t *target, int columns) { template <int bpp, int index_bits> void Nick::output_character(uint16_t *target, int columns) const {
static_assert(bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8); static_assert(bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8);
for(int c = 0; c < columns; c++) { for(int c = 0; c < columns; c++) {
const uint8_t character = ram_[line_data_pointer_[0]]; const uint8_t character = ram_[(line_data_pointer_[0] + c) & 0xffff];
++line_data_pointer_[0];
const uint8_t pixels = ram_[( const uint8_t pixels = ram_[(
(line_data_pointer_[1] << index_bits) + (line_data_pointer_[1] << index_bits) +
(character & ((1 << index_bits) - 1)) (character & ((1 << index_bits) - 1))
) & 0xffff]; ) & 0xffff];
// TODO: below looks repetitious of the above, but I've yet to factor in
// ALTINDs and [M/L]SBALTs, so I'll correct for factoring when I've done that.
switch(bpp) { switch(bpp) {
default: default:
assert(false); assert(false);
@ -601,15 +596,12 @@ template <int bpp, int index_bits> void Nick::output_character(uint16_t *target,
} }
} }
template <int bpp> void Nick::output_attributed(uint16_t *target, int columns) { template <int bpp> void Nick::output_attributed(uint16_t *target, int columns) const {
static_assert(bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8); static_assert(bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8);
for(int c = 0; c < columns; c++) { for(int c = 0; c < columns; c++) {
const uint8_t pixels = ram_[line_data_pointer_[1]]; const uint8_t pixels = ram_[(line_data_pointer_[1] + c) & 0xffff];
const uint8_t attributes = ram_[line_data_pointer_[0]]; const uint8_t attributes = ram_[(line_data_pointer_[0] + c) & 0xffff];
++line_data_pointer_[0];
++line_data_pointer_[1];
const uint16_t palette[2] = { const uint16_t palette[2] = {
palette_[attributes >> 4], palette_[attributes & 0x0f] palette_[attributes >> 4], palette_[attributes & 0x0f]

View File

@ -81,7 +81,7 @@ class Nick {
int border_duration_ = 0; int border_duration_ = 0;
// The destination for new pixels. // The destination for new pixels.
static constexpr int allocation_size = 320; static constexpr int allocation_size = 336;
static_assert((allocation_size % 16) == 0, "Allocation size must be a multiple of 16"); static_assert((allocation_size % 16) == 0, "Allocation size must be a multiple of 16");
uint16_t *pixel_pointer_ = nullptr, *allocated_pointer_ = nullptr; uint16_t *pixel_pointer_ = nullptr, *allocated_pointer_ = nullptr;
@ -97,9 +97,9 @@ class Nick {
uint16_t palette_[16]{}; uint16_t palette_[16]{};
// Specific outputters. // Specific outputters.
template <int bpp, bool is_lpixel> void output_pixel(uint16_t *target, int columns); template <int bpp, bool is_lpixel> void output_pixel(uint16_t *target, int columns) const;
template <int bpp, int index_bits> void output_character(uint16_t *target, int columns); template <int bpp, int index_bits> void output_character(uint16_t *target, int columns) const;
template <int bpp> void output_attributed(uint16_t *target, int columns); template <int bpp> void output_attributed(uint16_t *target, int columns) const;
}; };