1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-25 16:31:42 +00:00

Eliminated the vertical retrace counter; vertical retrace ends when the beam gets back to the top.

This commit is contained in:
Thomas Harte 2015-08-02 13:48:35 -04:00
parent de4f2bf5dd
commit be421587ad
3 changed files with 24 additions and 24 deletions

View File

@ -173,7 +173,7 @@ const char *fragmentShader =
"\n"
"void main(void)\n"
"{\n"
"fragColour = texture(texID, srcCoordinatesVarying) * sin(mod(srcCoordinatesVarying.y * 512, 1.0) * 2.09435310266667 + 0.52359877566668);\n" // vec4(1.0, 1.0, 1.0, 0.5)
"fragColour = texture(texID, srcCoordinatesVarying) * vec4(1.0, 1.0, 1.0, sin(mod(srcCoordinatesVarying.y * 512, 1.0) * 2.09435310266667 + 0.52359877566668));\n" // vec4(1.0, 1.0, 1.0, 0.5)
"}\n";
#if defined(DEBUG)

View File

@ -36,19 +36,19 @@ void CRT::set_new_timing(int cycles_per_line, int height_of_display)
_sync_capacitor_charge_threshold = (syncCapacityLineChargeThreshold * _cycles_per_line) >> 1;
_horizontal_retrace_time = (millisecondsHorizontalRetraceTime * _cycles_per_line) >> 6;
_vertical_retrace_time = scanlinesVerticalRetraceTime * _cycles_per_line;
const int vertical_retrace_time = scanlinesVerticalRetraceTime * _cycles_per_line;
_scanSpeed.x = kCRTFixedPointRange / _cycles_per_line;
_scanSpeed.y = kCRTFixedPointRange / (_height_of_display * _cycles_per_line);
_retraceSpeed.x = kCRTFixedPointRange / _horizontal_retrace_time;
_retraceSpeed.y = kCRTFixedPointRange / _vertical_retrace_time;
_retraceSpeed.y = kCRTFixedPointRange / vertical_retrace_time;
// precompute the lengths of all four combinations of scan direction, for fast triangle
// strip generation later
float scanSpeedXfl = 1.0f / (float)_cycles_per_line;
float scanSpeedYfl = 1.0f / (float)(_height_of_display * _cycles_per_line);
float retraceSpeedXfl = 1.0f / (float)_horizontal_retrace_time;
float retraceSpeedYfl = 1.0f / (float)(_vertical_retrace_time);
float retraceSpeedYfl = 1.0f / (float)(vertical_retrace_time);
float lengths[4];
lengths[0] = sqrtf(scanSpeedXfl*scanSpeedXfl + scanSpeedYfl*scanSpeedYfl);
@ -95,7 +95,7 @@ CRT::CRT(int cycles_per_line, int height_of_display, int number_of_buffers, ...)
// start off not in horizontal sync, not receiving a sync signal
_is_receiving_sync = false;
_is_in_hsync = false;
_vretrace_counter = 0;
_is_in_vsync = false;
}
CRT::~CRT()
@ -114,13 +114,24 @@ CRT::SyncEvent CRT::get_next_vertical_sync_event(bool vsync_is_charging, int cyc
int proposedSyncTime = cycles_to_run_for;
// have we overrun the maximum permitted number of horizontal syncs for this frame?
if (!_vretrace_counter && _rasterPosition.y == kCRTFixedPointRange) {
proposedSyncTime = 0;
proposedEvent = SyncEvent::StartVSync;
if (!_is_in_vsync) {
int time_until_end_of_frame = (kCRTFixedPointRange - _rasterPosition.y) / _scanSpeed.y;
if(time_until_end_of_frame < proposedSyncTime) {
proposedSyncTime = time_until_end_of_frame;
proposedEvent = SyncEvent::StartVSync;
}
} else {
int time_until_start_of_frame = _rasterPosition.y / _retraceSpeed.y;
if(time_until_start_of_frame < proposedSyncTime) {
proposedSyncTime = time_until_start_of_frame;
proposedEvent = SyncEvent::EndVSync;
}
}
// will an acceptable vertical sync be triggered?
if (vsync_is_charging && !_vretrace_counter) {
if (vsync_is_charging && !_is_in_vsync) {
if (_sync_capacitor_charge_level < _sync_capacitor_charge_threshold && _sync_capacitor_charge_level + proposedSyncTime >= _sync_capacitor_charge_threshold) {
uint32_t proposed_sync_y = _rasterPosition.y + (_sync_capacitor_charge_threshold - _sync_capacitor_charge_level) * _scanSpeed.y;
@ -132,14 +143,6 @@ CRT::SyncEvent CRT::get_next_vertical_sync_event(bool vsync_is_charging, int cyc
}
}
// will an ongoing vertical sync end?
if (_vretrace_counter > 0) {
if (_vretrace_counter <= proposedSyncTime) {
proposedSyncTime = _vretrace_counter;
proposedEvent = SyncEvent::EndVSync;
}
}
*cycles_advanced = proposedSyncTime;
return proposedEvent;
}
@ -223,7 +226,7 @@ void CRT::advance_cycles(int number_of_cycles, bool hsync_requested, const bool
else
_rasterPosition.x = (uint32_t)std::min((int64_t)kCRTFixedPointRange, (int64_t)_rasterPosition.x + number_of_cycles * (int64_t)_scanSpeed.x);
if (_vretrace_counter > 0)
if (_is_in_vsync)
_rasterPosition.y = (uint32_t)std::max((int64_t)0, (int64_t)_rasterPosition.y - number_of_cycles * (int64_t)_retraceSpeed.y);
else
_rasterPosition.y = (uint32_t)std::min((int64_t)kCRTFixedPointRange, (int64_t)_rasterPosition.y + number_of_cycles * (int64_t)_scanSpeed.y);
@ -257,9 +260,6 @@ void CRT::advance_cycles(int number_of_cycles, bool hsync_requested, const bool
else
_sync_capacitor_charge_level = std::max(_sync_capacitor_charge_level - next_run_length, 0);
// decrement the vertical retrace counter, making sure it stops at 0
_vretrace_counter = std::max(_vretrace_counter - next_run_length, 0);
// react to the incoming event...
if(next_run_length == time_until_horizontal_sync_event)
{
@ -293,7 +293,7 @@ void CRT::advance_cycles(int number_of_cycles, bool hsync_requested, const bool
// start of vertical sync: reset the lines-in-this-frame counter,
// load the retrace counter with the amount of time it'll take to retrace
case SyncEvent::StartVSync:
_vretrace_counter = _vertical_retrace_time;
_is_in_vsync = true;
break;
// end of vertical sync: tell the delegate that we finished vertical sync,
@ -315,6 +315,7 @@ void CRT::advance_cycles(int number_of_cycles, bool hsync_requested, const bool
else
_current_frame_builder = nullptr;
_is_in_vsync = false;
_did_detect_vsync = false;
break;

View File

@ -99,8 +99,7 @@ class CRT {
bool _did_detect_hsync; // true if horizontal sync was detected during this scanline (so, this affects flywheel adjustments)
int _sync_capacitor_charge_level; // this charges up during times of sync and depletes otherwise; needs to hit a required threshold to trigger a vertical sync
int _sync_capacitor_charge_threshold; // this charges up during times of sync and depletes otherwise; needs to hit a required threshold to trigger a vertical sync
int _vretrace_counter; // a down-counter for time during a vertical retrace
int _vertical_retrace_time;
int _is_in_vsync;
// components of the flywheel sync
int _horizontal_counter; // time run since the _start_ of the last horizontal sync