1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-06 01:28:57 +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 <algorithm>
#include <cassert>
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();
}

View File

@ -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])

View File

@ -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<uint8_t> _input_runs;
uint8_t *get_next_output_run();
std::vector<uint8_t> _output_runs;
uint8_t *get_next_run();
std::vector<uint8_t> _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 {

View File

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

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++)
{
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);