diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index 4eb61814e..3f36eed91 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -10,6 +10,7 @@ #include "TapeUEF.hpp" #include +#include using namespace Electron; @@ -285,7 +286,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin unsigned int start_of_graphics = get_first_graphics_cycle(); const unsigned int real_time_clock_interrupt_time = start_of_graphics + 99*128; - const unsigned int display_end_interrupt_time = start_of_graphics + 256*128; + const unsigned int display_end_interrupt_time = start_of_graphics + 257*128 + 64; if(_fieldCycles < real_time_clock_interrupt_time && _fieldCycles + cycles >= real_time_clock_interrupt_time) { @@ -572,14 +573,16 @@ inline void Machine::update_display() { _crt->output_sync(320 * crt_cycles_multiplier); if(_is_odd_field) _crt->output_blank(64 * crt_cycles_multiplier); + _displayOutputPosition += 320 + (_is_odd_field ? 64 : 0); - for(int y = 3; y < first_graphics_line; y++) + while(_displayOutputPosition < end_of_top) { + _displayOutputPosition += 128; _crt->output_sync(9 * crt_cycles_multiplier); _crt->output_blank(119 * crt_cycles_multiplier); } - _displayOutputPosition = end_of_top; + assert(_displayOutputPosition == end_of_top); reset_pixel_output(); } diff --git a/Outputs/CRT/CRT.cpp b/Outputs/CRT/CRT.cpp index 5539ea499..95284e195 100644 --- a/Outputs/CRT/CRT.cpp +++ b/Outputs/CRT/CRT.cpp @@ -82,7 +82,7 @@ void CRT::allocate_buffers(unsigned int number, va_list sizes) _run_builders = new CRTRunBuilder *[kCRTNumberOfFrames]; for(int builder = 0; builder < kCRTNumberOfFrames; builder++) { - _run_builders[builder] = new CRTRunBuilder(); + _run_builders[builder] = new CRTRunBuilder(kCRTSizeOfVertex); } va_list va; @@ -165,7 +165,7 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi hsync_requested = false; vsync_requested = false; - uint8_t *next_run = ((is_output_run && next_run_length) && !_horizontal_flywheel->is_in_retrace() && !_vertical_flywheel->is_in_retrace()) ? _run_builders[_run_write_pointer]->get_next_input_run() : nullptr; + uint8_t *next_run = ((is_output_run && next_run_length) && !_horizontal_flywheel->is_in_retrace() && !_vertical_flywheel->is_in_retrace()) ? _run_builders[_run_write_pointer]->get_next_run() : nullptr; int lengthMask = (_horizontal_flywheel->is_in_retrace() ? kRetraceXMask : 0) | (_vertical_flywheel->is_in_retrace() ? kRetraceYMask : 0); #define position_x(v) (*(uint16_t *)&next_run[kCRTSizeOfVertex*v + kCRTVertexOffsetOfPosition + 0]) diff --git a/Outputs/CRT/CRT.hpp b/Outputs/CRT/CRT.hpp index e935f5b19..121be4eb9 100644 --- a/Outputs/CRT/CRT.hpp +++ b/Outputs/CRT/CRT.hpp @@ -295,6 +295,8 @@ class CRT { void output_scan(); struct CRTRunBuilder { + CRTRunBuilder(size_t vertex_size) : _vertex_size(vertex_size) { reset(); } + // Resets the run builder. void reset(); @@ -302,11 +304,8 @@ class CRT { // from the input buffer to the screen. In composite mode input runs will map from the // input buffer to the processing buffer, and output runs will map from the processing // buffer to the screen. - uint8_t *get_next_input_run(); - std::vector _input_runs; - - uint8_t *get_next_output_run(); - std::vector _output_runs; + uint8_t *get_next_run(); + std::vector _runs; // Container for total length in cycles of all contained runs. uint32_t duration; @@ -315,6 +314,9 @@ class CRT { // entrusted to the CRT to update. size_t uploaded_vertices; size_t number_of_vertices; + + private: + size_t _vertex_size; }; struct CRTInputBufferBuilder { diff --git a/Outputs/CRT/CRTBuilders.cpp b/Outputs/CRT/CRTBuilders.cpp index 7eebd9433..7e73d477d 100644 --- a/Outputs/CRT/CRTBuilders.cpp +++ b/Outputs/CRT/CRTBuilders.cpp @@ -86,17 +86,17 @@ void CRT::CRTRunBuilder::reset() duration = 0; } -uint8_t *CRT::CRTRunBuilder::get_next_input_run() +uint8_t *CRT::CRTRunBuilder::get_next_run() { const size_t vertices_per_run = 6; // get a run from the allocated list, allocating more if we're about to overrun - if((number_of_vertices + vertices_per_run) * kCRTSizeOfVertex >= _input_runs.size()) + if((number_of_vertices + vertices_per_run) * _vertex_size >= _runs.size()) { - _input_runs.resize(_input_runs.size() + kCRTSizeOfVertex * vertices_per_run * 100); + _runs.resize(_runs.size() + _vertex_size * vertices_per_run * 100); } - uint8_t *next_run = &_input_runs[number_of_vertices * kCRTSizeOfVertex]; + uint8_t *next_run = &_runs[number_of_vertices * _vertex_size]; number_of_vertices += vertices_per_run; return next_run; diff --git a/Outputs/CRT/CRTOpenGL.cpp b/Outputs/CRT/CRTOpenGL.cpp index 80c815920..da53f5b15 100644 --- a/Outputs/CRT/CRTOpenGL.cpp +++ b/Outputs/CRT/CRTOpenGL.cpp @@ -142,7 +142,7 @@ void CRT::draw_frame(unsigned int output_width, unsigned int output_height, bool for(unsigned int c = 0; c < kCRTNumberOfFrames; c++) { - uint8_t *data = &_run_builders[c]->_input_runs[0]; + uint8_t *data = &_run_builders[c]->_runs[0]; glBufferSubData(GL_ARRAY_BUFFER, (GLsizeiptr)(c * _openGL_state->verticesPerSlice * kCRTSizeOfVertex), (GLsizeiptr)(_run_builders[c]->number_of_vertices * kCRTSizeOfVertex), data); _run_builders[c]->uploaded_vertices = _run_builders[c]->number_of_vertices; } @@ -163,7 +163,7 @@ void CRT::draw_frame(unsigned int output_width, unsigned int output_height, bool if(_run_builders[run]->uploaded_vertices != _run_builders[run]->number_of_vertices) { - uint8_t *data = &_run_builders[run]->_input_runs[_run_builders[run]->uploaded_vertices * kCRTSizeOfVertex]; + uint8_t *data = &_run_builders[run]->_runs[_run_builders[run]->uploaded_vertices * kCRTSizeOfVertex]; glBufferSubData(GL_ARRAY_BUFFER, (GLsizeiptr)(((run * _openGL_state->verticesPerSlice) + _run_builders[run]->uploaded_vertices) * kCRTSizeOfVertex), (GLsizeiptr)((_run_builders[run]->number_of_vertices - _run_builders[run]->uploaded_vertices) * kCRTSizeOfVertex), data);