diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index c6fe3f06f..44bacb00d 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -379,12 +379,19 @@ inline void Machine::update_display() { const int current_line = _displayOutputPosition >> 7; const int line_position = _displayOutputPosition & 127; + const int cycles_left = _frameCycles - _displayOutputPosition; // all lines then start with 9 cycles of sync - if(!line_position) + if(line_position < 9) { - _crt.output_sync(9 * crt_cycles_multiplier); - _displayOutputPosition += 9; + int remaining_period = std::min(9 - line_position, cycles_left); + _displayOutputPosition += remaining_period; + + if(line_position + remaining_period == 9) + { +// printf("!%d!", 9); + _crt.output_sync(9 * crt_cycles_multiplier); + } } else { @@ -395,33 +402,37 @@ inline void Machine::update_display() if(isBlankLine) { - if(line_position == 9) - { - _crt.output_blank(119 * crt_cycles_multiplier); - _displayOutputPosition += 119; - } + int remaining_period = std::min(128 - line_position, cycles_left); + _crt.output_blank((unsigned int)remaining_period * crt_cycles_multiplier); +// printf(".[%d]", remaining_period); + _displayOutputPosition += remaining_period; } else { // there are then 15 cycles of blank, 80 cycles of pixels, and 24 further cycles of blank - if(line_position == 9) + if(line_position < 24) { - _crt.output_blank(15 * crt_cycles_multiplier); - _displayOutputPosition += 15; + int remaining_period = std::min(24 - line_position, cycles_left); + _crt.output_blank((unsigned int)remaining_period * crt_cycles_multiplier); +// printf("/(%d)(%d)[%d]", 24 - line_position, cycles_left, remaining_period); + _displayOutputPosition += remaining_period; - switch(_screenMode) + if(line_position + remaining_period == 24) { - case 0: case 3: _currentOutputDivider = 1; break; - case 1: case 4: case 6: _currentOutputDivider = 2; break; - case 2: case 5: _currentOutputDivider = 4; break; + switch(_screenMode) + { + case 0: case 3: _currentOutputDivider = 1; break; + case 1: case 4: case 6: _currentOutputDivider = 2; break; + case 2: case 5: _currentOutputDivider = 4; break; + } + + _crt.allocate_write_area(80 * crt_cycles_multiplier / _currentOutputDivider); + _currentLine = _writePointer = (uint8_t *)_crt.get_write_target_for_buffer(0); + + if(current_line == first_graphics_line) + _startLineAddress = _startScreenAddress; + _currentScreenAddress = _startLineAddress; } - - _crt.allocate_write_area(80 * crt_cycles_multiplier / _currentOutputDivider); - _currentLine = _writePointer = (uint8_t *)_crt.get_write_target_for_buffer(0); - - if(current_line == first_graphics_line) - _startLineAddress = _startScreenAddress; - _currentScreenAddress = _startLineAddress; } if(line_position >= 24 && line_position < 104) @@ -446,6 +457,7 @@ inline void Machine::update_display() int pixels_to_output = std::min(_frameCycles - _displayOutputPosition, 104 - line_position); _displayOutputPosition += pixels_to_output; +// printf("<- %d ->", pixels_to_output); if(_screenMode >= 4) { // just shifting wouldn't be enough if both @@ -514,23 +526,29 @@ inline void Machine::update_display() #undef GetNextPixels - if(line_position == 104) + if(line_position >= 104) { - _currentOutputLine++; - if(!(_currentOutputLine&7)) - { - _startLineAddress += ((_screenMode < 4) ? 80 : 40)*8 - 7; - } - else - _startLineAddress++; + int pixels_to_output = std::min(_frameCycles - _displayOutputPosition, 128 - line_position); + _crt.output_blank((unsigned int)pixels_to_output * crt_cycles_multiplier); + _displayOutputPosition += pixels_to_output; - if(_writePointer) - _crt.output_data((unsigned int)((_writePointer - _currentLine) * _currentOutputDivider), _currentOutputDivider); - else - _crt.output_data(80 * crt_cycles_multiplier, _currentOutputDivider); - _crt.output_blank(24 * crt_cycles_multiplier); - _displayOutputPosition += 24; - _currentLine = nullptr; + if(line_position + pixels_to_output == 128) + { + _currentOutputLine++; +// printf("\n%d: ", _currentOutputLine); + if(!(_currentOutputLine&7)) + { + _startLineAddress += ((_screenMode < 4) ? 80 : 40)*8 - 7; + } + else + _startLineAddress++; + + if(_writePointer) + _crt.output_data((unsigned int)((_writePointer - _currentLine) * _currentOutputDivider), _currentOutputDivider); + else + _crt.output_data(80 * crt_cycles_multiplier, _currentOutputDivider); + _currentLine = nullptr; + } } } } @@ -708,6 +726,12 @@ inline void Tape::set_data_register(uint8_t value) _output_bits_remaining = 9; } +inline uint8_t Tape::get_data_register() +{ + int shift = std::max(_bits_since_start - 7, 0); + return (uint8_t)(_data_register >> shift); +} + inline void Tape::run_for_cycles(unsigned int number_of_cycles) { if(_is_enabled) diff --git a/Machines/Electron/Electron.hpp b/Machines/Electron/Electron.hpp index 7e2db617d..d730be65a 100644 --- a/Machines/Electron/Electron.hpp +++ b/Machines/Electron/Electron.hpp @@ -63,7 +63,7 @@ class Tape { void set_tape(std::shared_ptr tape); - inline uint8_t get_data_register() { return (uint8_t)(_data_register >> 2); } + inline uint8_t get_data_register(); inline void set_data_register(uint8_t value); inline void set_counter(uint8_t value); diff --git a/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift b/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift index 2e2f31dc4..ba3243a39 100644 --- a/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift +++ b/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift @@ -28,7 +28,7 @@ class ElectronDocument: MachineDocument { super.windowControllerDidLoadNib(aController) electron.view = openGLView electron.audioQueue = self.audioQueue - openGLView.frameBounds = CGRectMake(0.0225, 0.0625, 0.75, 0.75) +// openGLView.frameBounds = CGRectMake(0.0225, 0.0625, 0.75, 0.75) } override var windowNibName: String? { diff --git a/OSBindings/Mac/Clock Signal/Views/CSCathodeRayView.m b/OSBindings/Mac/Clock Signal/Views/CSCathodeRayView.m index 3ba042ca0..7f08a7107 100644 --- a/OSBindings/Mac/Clock Signal/Views/CSCathodeRayView.m +++ b/OSBindings/Mac/Clock Signal/Views/CSCathodeRayView.m @@ -302,10 +302,8 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt @"phase = srcCoordinates.x * 6.283185308;\n" "\n" "srcCoordinatesVarying[0] = vec2(srcCoordinates.x / textureSize.x, (srcCoordinates.y + 0.5) / textureSize.y);\n" - "srcCoordinatesVarying[3] = srcCoordinatesVarying[0] + vec2(0.375 / textureSize.x, 0.0);\n" - "srcCoordinatesVarying[2] = srcCoordinatesVarying[0] + vec2(0.125 / textureSize.x, 0.0);\n" - "srcCoordinatesVarying[1] = srcCoordinatesVarying[0] - vec2(0.125 / textureSize.x, 0.0);\n" - "srcCoordinatesVarying[0] = srcCoordinatesVarying[0] - vec2(0.325 / textureSize.x, 0.0);\n"; + "srcCoordinatesVarying[1] = srcCoordinatesVarying[0] - vec2(0.5 / textureSize.x, 0.0);\n" + "srcCoordinatesVarying[2] = srcCoordinatesVarying[0] - vec2(0.25 / textureSize.x, 0.0);\n"; NSString *const rgbVertexShaderGlobals = @"out vec2 srcCoordinatesVarying[5];\n"; @@ -385,21 +383,22 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt "const mat3 yiqToRGB = mat3(1.0, 1.0, 1.0, 1.1389784, -0.3240608, -1.3176884, 0.6490692, -0.6762444, 1.7799756);\n"; NSString *const ntscFragmentShaderBody = - @"vec4 angles = vec4(phase) + vec4(-2.35619449019234, -0.78539816339745, 0.78539816339745, 2.35619449019234);\n" - "vec4 samples = vec4(" + @"vec3 angles = vec3(phase) + vec3(0.0, -3.141592654, -1.570796327);\n" + "vec3 samples = vec3(" " sample(srcCoordinatesVarying[0], angles.x)," " sample(srcCoordinatesVarying[1], angles.y)," - " sample(srcCoordinatesVarying[2], angles.z)," - " sample(srcCoordinatesVarying[3], angles.w)" + " sample(srcCoordinatesVarying[2], angles.z)" ");\n" "\n" - "float y = dot(vec4(0.25), samples);\n" - "samples -= vec4(y);\n" + "float y = dot(vec2(0.5), samples.xy);\n" + "samples -= vec3(y);\n" "\n" - "float i = dot(cos(angles), samples);\n" - "float q = dot(sin(angles), samples);\n" + "float i = dot(vec3(0.75), cos(angles) * samples);\n" + "float q = dot(vec3(0.75), sin(angles) * samples);\n" "\n" - "fragColour = 5.0 * texture(shadowMaskTexID, shadowMaskCoordinates) * vec4(yiqToRGB * vec3(y, i, q), 1.0);//sin(lateralVarying));\n"; + "fragColour = vec4(yiqToRGB * vec3(y, i, q), 1.0);\n"; //sin(lateralVarying)); + // 5.0 * texture(shadowMaskTexID, shadowMaskCoordinates) * +// "float y2 = dot(vec2(0.5), samples.zw);\n" NSString *const rgbFragmentShaderGlobals = @"in vec2 srcCoordinatesVarying[5];\n"; // texture(shadowMaskTexID, shadowMaskCoordinates) * diff --git a/Outputs/CRT.cpp b/Outputs/CRT.cpp index efd4451ea..e87d8b8c2 100644 --- a/Outputs/CRT.cpp +++ b/Outputs/CRT.cpp @@ -275,7 +275,7 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi position_y(5) = InternalToUInt16(kCRTFixedPointOffset + _rasterPosition.y + _beamWidth[lengthMask].y); // if this is a data run then advance the buffer pointer - if(type == Type::Data) tex_x += next_run_length / (_time_multiplier * source_divider); + if(type == Type::Data && source_divider) tex_x += next_run_length / (_time_multiplier * source_divider); // if this is a data or level run then store the end point tex_x(2) = tex_x(3) = tex_x(5) = tex_x;