1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-01 11:49:58 +00:00

This looks a lot closer to correct. The loss of horizontal sync during vertical sync is odd but the two should be fully decoupled in here. I'll have to check. Probably I've got something wrong. There are approximate sinusoidals when re-establishing sync, so that's promising as to the flywheel.

This commit is contained in:
Thomas Harte 2015-07-20 21:58:32 -04:00
parent 4695295dd1
commit 4fa315ab4d
2 changed files with 14 additions and 11 deletions

View File

@ -41,12 +41,11 @@ CRT::CRT(int cycles_per_line, int number_of_buffers, ...)
_write_allocation_pointer = 0; _write_allocation_pointer = 0;
_cycles_per_line = cycles_per_line; _cycles_per_line = cycles_per_line;
_expected_next_hsync = cycles_per_line; _expected_next_hsync = cycles_per_line;
_hsync_error_window = cycles_per_line / 10; _hsync_error_window = cycles_per_line >> 5;
_horizontal_counter = 0; _horizontal_counter = 0;
_sync_capacitor_charge_level = 0; _sync_capacitor_charge_level = 0;
_is_in_sync = false; _is_in_sync = false;
_vsync_is_proposed = false;
} }
CRT::~CRT() CRT::~CRT()
@ -64,9 +63,12 @@ CRT::~CRT()
CRT::SyncEvent CRT::advance_to_next_sync_event(bool hsync_is_requested, bool vsync_is_charging, int cycles_to_run_for, int *cycles_advanced) CRT::SyncEvent CRT::advance_to_next_sync_event(bool hsync_is_requested, bool vsync_is_charging, int cycles_to_run_for, int *cycles_advanced)
{ {
// do we recognise this hsync, thereby adjusting time expectations? // do we recognise this hsync, thereby adjusting time expectations?
if (_horizontal_counter >= _expected_next_hsync - _hsync_error_window && hsync_is_requested) { if ((_horizontal_counter < _hsync_error_window || _horizontal_counter >= _expected_next_hsync - _hsync_error_window) && hsync_is_requested) {
_did_detect_hsync = true; _did_detect_hsync = true;
_expected_next_hsync = (_expected_next_hsync + _horizontal_counter) >> 1;
int time_now = (_horizontal_counter < _hsync_error_window) ? _expected_next_hsync + _horizontal_counter : _horizontal_counter;
_expected_next_hsync = (_expected_next_hsync + time_now) >> 1;
// printf("to %d for %d\n", _expected_next_hsync, time_now);
} }
SyncEvent proposedEvent = SyncEvent::None; SyncEvent proposedEvent = SyncEvent::None;
@ -119,10 +121,10 @@ void CRT::advance_cycles(int number_of_cycles, bool hsync_requested, const bool
{ {
switch(type) switch(type)
{ {
case CRTRun::Type::Data: putc('-', stdout); break; case CRTRun::Type::Data: putc('-', stdout); break;
case CRTRun::Type::Blank: putc(' ', stdout); break; case CRTRun::Type::Blank: putc(' ', stdout); break;
case CRTRun::Type::Level: putc('_', stdout); break; case CRTRun::Type::Level: putc('_', stdout); break;
case CRTRun::Type::Sync: putc('<', stdout); break; case CRTRun::Type::Sync: putc('<', stdout); break;
} }
} }
// printf("[[%d]%d:%d]", type, next_event, next_run_length); // printf("[[%d]%d:%d]", type, next_event, next_run_length);
@ -142,11 +144,14 @@ void CRT::advance_cycles(int number_of_cycles, bool hsync_requested, const bool
default: break; default: break;
case SyncEvent::StartHSync: case SyncEvent::StartHSync:
_horizontal_counter = 0; _horizontal_counter = 0;
printf("\n");
break;
case SyncEvent::EndHSync:
if (!_did_detect_hsync) { if (!_did_detect_hsync) {
_expected_next_hsync = (_expected_next_hsync + _cycles_per_line) >> 1; _expected_next_hsync = (_expected_next_hsync + (_hsync_error_window >> 1) + _cycles_per_line) >> 1;
} }
_did_detect_hsync = false; _did_detect_hsync = false;
printf("\n");
break; break;
case SyncEvent::StartVSync: case SyncEvent::StartVSync:
_vretrace_counter = scanlinesVerticalRetraceTime * _cycles_per_line; _vretrace_counter = scanlinesVerticalRetraceTime * _cycles_per_line;

View File

@ -68,10 +68,7 @@ class CRT {
void do_hsync(); void do_hsync();
void do_vsync(); void do_vsync();
int _cycles_per_line; int _cycles_per_line;
bool _is_in_sync, _vsync_is_proposed, _did_detect_hsync;
enum SyncEvent { enum SyncEvent {
None, None,
@ -79,6 +76,7 @@ class CRT {
StartVSync, EndVSync StartVSync, EndVSync
}; };
SyncEvent advance_to_next_sync_event(bool hsync_is_requested, bool vsync_is_charging, int cycles_to_run_for, int *cycles_advanced); SyncEvent advance_to_next_sync_event(bool hsync_is_requested, bool vsync_is_charging, int cycles_to_run_for, int *cycles_advanced);
bool _is_in_sync, _did_detect_hsync;
int _sync_capacitor_charge_level, _vretrace_counter; int _sync_capacitor_charge_level, _vretrace_counter;
int _horizontal_counter, _expected_next_hsync, _hsync_error_window; int _horizontal_counter, _expected_next_hsync, _hsync_error_window;