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

Simplified the run builder rather; put a double check of Electron timing in place.

This commit is contained in:
Thomas Harte 2016-02-25 22:01:42 -05:00
parent 1eea28b692
commit db18c85423
5 changed files with 21 additions and 16 deletions

View File

@ -10,6 +10,7 @@
#include "TapeUEF.hpp" #include "TapeUEF.hpp"
#include <algorithm> #include <algorithm>
#include <cassert>
using namespace Electron; 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(); 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 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) 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); _crt->output_sync(320 * crt_cycles_multiplier);
if(_is_odd_field) _crt->output_blank(64 * 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_sync(9 * crt_cycles_multiplier);
_crt->output_blank(119 * crt_cycles_multiplier); _crt->output_blank(119 * crt_cycles_multiplier);
} }
_displayOutputPosition = end_of_top; assert(_displayOutputPosition == end_of_top);
reset_pixel_output(); reset_pixel_output();
} }

View File

@ -82,7 +82,7 @@ void CRT::allocate_buffers(unsigned int number, va_list sizes)
_run_builders = new CRTRunBuilder *[kCRTNumberOfFrames]; _run_builders = new CRTRunBuilder *[kCRTNumberOfFrames];
for(int builder = 0; builder < kCRTNumberOfFrames; builder++) for(int builder = 0; builder < kCRTNumberOfFrames; builder++)
{ {
_run_builders[builder] = new CRTRunBuilder(); _run_builders[builder] = new CRTRunBuilder(kCRTSizeOfVertex);
} }
va_list va; va_list va;
@ -165,7 +165,7 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi
hsync_requested = false; hsync_requested = false;
vsync_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); 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]) #define position_x(v) (*(uint16_t *)&next_run[kCRTSizeOfVertex*v + kCRTVertexOffsetOfPosition + 0])

View File

@ -295,6 +295,8 @@ class CRT {
void output_scan(); void output_scan();
struct CRTRunBuilder { struct CRTRunBuilder {
CRTRunBuilder(size_t vertex_size) : _vertex_size(vertex_size) { reset(); }
// Resets the run builder. // Resets the run builder.
void reset(); void reset();
@ -302,11 +304,8 @@ class CRT {
// from the input buffer to the screen. In composite mode input runs will map from the // 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 // input buffer to the processing buffer, and output runs will map from the processing
// buffer to the screen. // buffer to the screen.
uint8_t *get_next_input_run(); uint8_t *get_next_run();
std::vector<uint8_t> _input_runs; std::vector<uint8_t> _runs;
uint8_t *get_next_output_run();
std::vector<uint8_t> _output_runs;
// Container for total length in cycles of all contained runs. // Container for total length in cycles of all contained runs.
uint32_t duration; uint32_t duration;
@ -315,6 +314,9 @@ class CRT {
// entrusted to the CRT to update. // entrusted to the CRT to update.
size_t uploaded_vertices; size_t uploaded_vertices;
size_t number_of_vertices; size_t number_of_vertices;
private:
size_t _vertex_size;
}; };
struct CRTInputBufferBuilder { struct CRTInputBufferBuilder {

View File

@ -86,17 +86,17 @@ void CRT::CRTRunBuilder::reset()
duration = 0; duration = 0;
} }
uint8_t *CRT::CRTRunBuilder::get_next_input_run() uint8_t *CRT::CRTRunBuilder::get_next_run()
{ {
const size_t vertices_per_run = 6; const size_t vertices_per_run = 6;
// get a run from the allocated list, allocating more if we're about to overrun // 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; number_of_vertices += vertices_per_run;
return next_run; return next_run;

View File

@ -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++) 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); 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; _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) 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, glBufferSubData(GL_ARRAY_BUFFER,
(GLsizeiptr)(((run * _openGL_state->verticesPerSlice) + _run_builders[run]->uploaded_vertices) * kCRTSizeOfVertex), (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); (GLsizeiptr)((_run_builders[run]->number_of_vertices - _run_builders[run]->uploaded_vertices) * kCRTSizeOfVertex), data);