From 870136627705aca27748068f3701f7342987989f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 10 Apr 2016 21:34:40 -0400 Subject: [PATCH] Switched horizontal sync detection back to differential, switched the Electron to an XOR-style sync output (believed to be accurate, but I need to check), fixed some latent issues around vertical sync detection. --- Machines/Electron/Electron.cpp | 12 ++++++++---- Outputs/CRT/CRT.cpp | 17 +++++++++++------ Outputs/CRT/Internals/CRTOpenGL.cpp | 5 +---- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index e68efbab1..29fbbb90e 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -62,7 +62,8 @@ void Machine::setup_output() "vec4 rgb_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate)" "{" "uint texValue = texture(sampler, coordinate).r;" - "return mix(vec4(texValue & 64u, texValue & 32u, texValue & 16u, 1.0), vec4(texValue & 4u, texValue & 2u, texValue & 1u, 1.0), int(icoordinate.x * 2) & 1);" + "texValue >>= 4 - (int(icoordinate.x * 2) & 1)*4;" + "return vec4(texValue & 4u, texValue & 2u, texValue & 1u, 1.0);" "}"); _crt->set_output_device(Outputs::CRT::Monitor); @@ -697,7 +698,8 @@ inline void Machine::update_display() { // wait for the line to complete before signalling if(final_line == line) return; - _crt->output_sync(128 * crt_cycles_multiplier); + _crt->output_blank(9 * crt_cycles_multiplier); + _crt->output_sync(119 * crt_cycles_multiplier); _displayOutputPosition += 128; continue; } @@ -707,7 +709,8 @@ inline void Machine::update_display() { // wait for the line to complete before signalling if(final_line == line) return; - _crt->output_sync(64 * crt_cycles_multiplier); + _crt->output_blank(9 * crt_cycles_multiplier); + _crt->output_sync(55 * crt_cycles_multiplier); _crt->output_blank(64 * crt_cycles_multiplier); _displayOutputPosition += 128; continue; @@ -718,7 +721,8 @@ inline void Machine::update_display() { // wait for the line to complete before signalling if(final_line == line) return; - _crt->output_blank(64 * crt_cycles_multiplier); + _crt->output_sync(9 * crt_cycles_multiplier); + _crt->output_blank(55 * crt_cycles_multiplier); _crt->output_sync(64 * crt_cycles_multiplier); _displayOutputPosition += 128; continue; diff --git a/Outputs/CRT/CRT.cpp b/Outputs/CRT/CRT.cpp index e34fcf442..b3407d69e 100644 --- a/Outputs/CRT/CRT.cpp +++ b/Outputs/CRT/CRT.cpp @@ -17,7 +17,7 @@ void CRT::set_new_timing(unsigned int cycles_per_line, unsigned int height_of_di { _openGL_output_builder->set_colour_format(colour_space, colour_cycle_numerator, colour_cycle_denominator); - const unsigned int syncCapacityLineChargeThreshold = 3; + const unsigned int syncCapacityLineChargeThreshold = 2; const unsigned int millisecondsHorizontalRetraceTime = 7; // source: Dictionary of Video and Television Technology, p. 234 const unsigned int scanlinesVerticalRetraceTime = 10; // source: ibid @@ -34,7 +34,7 @@ void CRT::set_new_timing(unsigned int cycles_per_line, unsigned int height_of_di _cycles_per_line = cycles_per_line * _time_multiplier; // generate timing values implied by the given arbuments - _sync_capacitor_charge_threshold = ((syncCapacityLineChargeThreshold * _cycles_per_line) * 50) >> 7; + _sync_capacitor_charge_threshold = (int)(syncCapacityLineChargeThreshold * _cycles_per_line); // create the two flywheels _horizontal_flywheel = std::unique_ptr(new Flywheel(_cycles_per_line, (millisecondsHorizontalRetraceTime * _cycles_per_line) >> 6)); @@ -174,7 +174,7 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi _openGL_output_builder->add_to_field_time(next_run_length); // either charge or deplete the vertical retrace capacitor (making sure it stops at 0) - if (vsync_charging && !_vertical_flywheel->is_in_retrace()) + if (vsync_charging) _sync_capacitor_charge_level += next_run_length; else _sync_capacitor_charge_level = std::max(_sync_capacitor_charge_level - (int)next_run_length, 0); @@ -273,13 +273,18 @@ void CRT::output_scan(const Scan *const scan) { const bool this_is_sync = (scan->type == Scan::Type::Sync); const bool is_trailing_edge = (_is_receiving_sync && !this_is_sync); -// const bool is_leading_edge = (!_is_receiving_sync && this_is_sync); + const bool is_leading_edge = (!_is_receiving_sync && this_is_sync); _is_receiving_sync = this_is_sync; -// const bool hsync_requested = is_leading_edge; - const bool hsync_requested = is_trailing_edge && (_sync_period < (_horizontal_flywheel->get_scan_period() >> 2)); + const bool hsync_requested = is_leading_edge; +// const bool hsync_requested = is_trailing_edge && (_sync_period < (_horizontal_flywheel->get_scan_period() >> 2)); const bool vsync_requested = is_trailing_edge && (_sync_capacitor_charge_level >= _sync_capacitor_charge_threshold); +// if(is_trailing_edge && _sync_capacitor_charge_threshold - _sync_capacitor_charge_level < 3000) +// { +// printf("%d\n", _sync_capacitor_charge_threshold - _sync_capacitor_charge_level); +// } + // simplified colour burst logic: if it's within the back porch we'll take it if(scan->type == Scan::Type::ColourBurst) { diff --git a/Outputs/CRT/Internals/CRTOpenGL.cpp b/Outputs/CRT/Internals/CRTOpenGL.cpp index 57235d5bf..0afd28d18 100644 --- a/Outputs/CRT/Internals/CRTOpenGL.cpp +++ b/Outputs/CRT/Internals/CRTOpenGL.cpp @@ -374,9 +374,6 @@ char *OpenGLOutputBuilder::get_output_vertex_shader() "srcCoordinatesVarying = vec2(srcCoordinates.x / textureSize.x, (srcCoordinates.y + 0.5) / textureSize.y);" "float age = (timestampBase[int(lateralAndTimestampBaseOffset.y)] - timestamp) / ticksPerFrame;" "alpha = 10.0 * exp(-age * 2.0);" -// "vec3 alphas = vec3(10.0 * exp((-age - 1.33) * 2.0), 10.0 * exp(-(age - 0.66) * 2.0), 10.0 * exp(-age * 2.0));" -// "alpha = min(10.0 * exp(-age * 2.0), 1.0);" -// "alpha = dot(alphas, filterCoefficients);" "vec2 floatingPosition = (position / positionConversion) + lateralAndTimestampBaseOffset.x * scanNormal;" "vec2 mappedPosition = (floatingPosition - boundsOrigin) / boundsSize;" @@ -420,7 +417,7 @@ char *OpenGLOutputBuilder::get_output_fragment_shader(const char *sampling_funct "void main(void)" "{" - "fragColour = rgb_sample(texID, srcCoordinatesVarying, iSrcCoordinatesVarying) * vec4(1.0, 1.0, 1.0, alpha);" // * sin(lateralVarying) + "fragColour = rgb_sample(texID, srcCoordinatesVarying, iSrcCoordinatesVarying) * vec4(1.0, 1.0, 1.0, alpha*sin(lateralVarying));" // "}" , sampling_function); }