From ed28260aaff659a05aefa5428b43f5e0c9708d02 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 9 Jul 2017 19:33:05 -0400 Subject: [PATCH] Hardens the ZX80/81 video routines to ensure they never try to push data into the future and don't double-count time when pixels would ostensibly run into sync. You could previously see the CRT being handed negative run lengths if sync interrupted pixels or if a run of more than 320 pixels (my arbitrary buffer size) occurred, with corresponding poor behaviour given my use of unsigned numbers. --- Machines/ZX8081/Video.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Machines/ZX8081/Video.cpp b/Machines/ZX8081/Video.cpp index 0f9f64b0c..5531e7dee 100644 --- a/Machines/ZX8081/Video.cpp +++ b/Machines/ZX8081/Video.cpp @@ -50,9 +50,10 @@ void Video::flush(bool next_sync) { // sync, or if we're past its end anyway. Otherwise let it be. unsigned int data_length = (unsigned int)(line_data_pointer_ - line_data_); if(data_length < cycles_since_update_ || next_sync) { - crt_->output_data(data_length, 1); + unsigned int output_length = std::min(data_length, cycles_since_update_); + crt_->output_data(output_length, 1); line_data_pointer_ = line_data_ = nullptr; - cycles_since_update_ -= data_length; + cycles_since_update_ -= output_length; } else return; } @@ -86,19 +87,20 @@ void Video::output_byte(uint8_t byte) { // If a buffer was obtained, serialise the new pixels. if(line_data_) { + // If the buffer is full, output it now and obtain a new one + if(line_data_pointer_ - line_data_ == 320) { + crt_->output_data(320, 1); + cycles_since_update_ -= 320; + line_data_pointer_ = line_data_ = crt_->allocate_write_area(320); + if(!line_data_) return; + } + uint8_t mask = 0x80; for(int c = 0; c < 8; c++) { line_data_pointer_[c] = (byte & mask) ? 0xff : 0x00; mask >>= 1; } line_data_pointer_ += 8; - - // If that fills the buffer, output it now. - if(line_data_pointer_ - line_data_ == 320) { - crt_->output_data(320, 1); - line_data_pointer_ = line_data_ = nullptr; - cycles_since_update_ -= 160; - } } }