1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-11 08:30:55 +00:00

Merge pull request #146 from TomHarte/MSCrash

Corrects accounting errors in ZX80/81 video
This commit is contained in:
Thomas Harte 2017-07-09 20:09:44 -04:00 committed by GitHub
commit f56d96267e
4 changed files with 22 additions and 9 deletions

View File

@ -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;
}
}
}

View File

@ -143,6 +143,9 @@ void CRT::advance_cycles(unsigned int number_of_cycles, bool hsync_requested, bo
bool did_retain_source_data = openGL_output_builder_.texture_builder.retain_latest();
if(did_retain_source_data) {
next_run = openGL_output_builder_.array_builder.get_input_storage(SourceVertexSize);
if(!next_run) {
openGL_output_builder_.texture_builder.discard_latest();
}
}
}

View File

@ -128,6 +128,11 @@ bool TextureBuilder::retain_latest() {
return true;
}
void TextureBuilder::discard_latest() {
if(was_full_) return;
number_of_write_areas_--;
}
bool TextureBuilder::is_full() {
return is_full_;
}

View File

@ -79,6 +79,9 @@ class TextureBuilder {
/// @returns @c true if a retain succeeded; @c false otherwise.
bool retain_latest();
// Undoes the most recent retain_latest. Undefined behaviour if a submission has occurred in the interim.
void discard_latest();
/// @returns @c true if all future calls to @c allocate_write_area will fail on account of the input texture
/// being full; @c false if calls may succeed.
bool is_full();