diff --git a/Machines/Atari2600.hpp b/Machines/Atari2600.hpp
index 75eeda41a..9b105500f 100644
--- a/Machines/Atari2600.hpp
+++ b/Machines/Atari2600.hpp
@@ -24,6 +24,8 @@ class Machine: public CPU6502::Processor<Machine> {
 
 		void set_rom(size_t length, const uint8_t *data);
 
+		Outputs::CRT *get_crt() { return _crt; }
+
 	private:
 		uint8_t _rom[4096], _ram[128];
 		uint16_t _romMask;
diff --git a/OSBindings/Mac/Clock Signal/Atari2600.mm b/OSBindings/Mac/Clock Signal/Atari2600.mm
index 622d8e1d6..37fda8e99 100644
--- a/OSBindings/Mac/Clock Signal/Atari2600.mm	
+++ b/OSBindings/Mac/Clock Signal/Atari2600.mm	
@@ -9,8 +9,42 @@
 #import "Atari2600.h"
 #import "Atari2600.hpp"
 
+class Atari2600CRTDelegate: public Outputs::CRT::CRTDelegate {
+	void crt_did_start_vertical_retrace_with_runs(Outputs::CRT::CRTRun *runs, int runs_to_draw)
+	{
+		printf("===\n\n");
+		for(int run = 0; run < runs_to_draw; run++)
+		{
+			char character = ' ';
+			switch(runs[run].type)
+			{
+				case Outputs::CRT::CRTRun::Type::Sync:	character = '<'; break;
+				case Outputs::CRT::CRTRun::Type::Level:	character = '_'; break;
+				case Outputs::CRT::CRTRun::Type::Data:	character = '-'; break;
+				case Outputs::CRT::CRTRun::Type::Blank:	character = ' '; break;
+			}
+
+//			if(runs[run].start_point.dst_x > runs[run].end_point.dst_x)
+//			{
+//				printf("\n");
+//			}
+
+			float length = fabsf(runs[run].end_point.dst_x - runs[run].start_point.dst_x);
+			int iLength = (int)(length * 64.0);
+			for(int c = 0; c < iLength; c++)
+			{
+				putc(character, stdout);
+			}
+
+			if (runs[run].type == Outputs::CRT::CRTRun::Type::Sync) printf("\n");
+		}
+	}
+
+};
+
 @implementation CSAtari2600 {
 	Atari2600::Machine _atari2600;
+	Atari2600CRTDelegate _crtDelegate;
 }
 
 - (void)runForNumberOfCycles:(int)cycles {
@@ -21,4 +55,14 @@
 	_atari2600.set_rom(rom.length, (const uint8_t *)rom.bytes);
 }
 
+- (instancetype)init {
+	self = [super init];
+
+	if (self) {
+		_atari2600.get_crt()->set_delegate(&_crtDelegate);
+	}
+
+	return self;
+}
+
 @end
diff --git a/OSBindings/Mac/Clock Signal/Base.lproj/Atari2600Document.xib b/OSBindings/Mac/Clock Signal/Base.lproj/Atari2600Document.xib
index c74f9d9f5..d9555a642 100644
--- a/OSBindings/Mac/Clock Signal/Base.lproj/Atari2600Document.xib	
+++ b/OSBindings/Mac/Clock Signal/Base.lproj/Atari2600Document.xib	
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="8152.3" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="8164.2" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="8152.3"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="8164.2"/>
     </dependencies>
     <objects>
         <customObject id="-2" userLabel="File's Owner" customClass="Atari2600Document" customModule="Clock_Signal" customModuleProvider="target">
@@ -12,7 +12,7 @@
         </customObject>
         <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
         <customObject id="-3" userLabel="Application" customClass="NSObject"/>
-        <window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="xOd-HO-29H" userLabel="Window">
+        <window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="xOd-HO-29H" userLabel="Window">
             <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
             <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
             <rect key="contentRect" x="133" y="235" width="507" height="413"/>
diff --git a/Outputs/CRT.cpp b/Outputs/CRT.cpp
index dfc48370d..53cf5a6dd 100644
--- a/Outputs/CRT.cpp
+++ b/Outputs/CRT.cpp
@@ -12,14 +12,14 @@
 static const int bufferWidth = 512;
 static const int bufferHeight = 512;
 
-static const int syncCapacityLineChargeThreshold = 3;
-static const int millisecondsHorizontalRetraceTime = 16;
-static const int scanlinesVerticalRetraceTime = 26;
-
 using namespace Outputs;
 
 CRT::CRT(int cycles_per_line, int height_of_display, int number_of_buffers, ...)
 {
+	static const int syncCapacityLineChargeThreshold = 3;
+	static const int millisecondsHorizontalRetraceTime = 16;
+	static const int scanlinesVerticalRetraceTime = 26;
+
 	// store fundamental display configuration properties
 	_height_of_display = height_of_display;
 	_cycles_per_line = cycles_per_line;
@@ -27,6 +27,15 @@ CRT::CRT(int cycles_per_line, int height_of_display, int number_of_buffers, ...)
 	// generate timing values implied by the given arbuments
 	_hsync_error_window = cycles_per_line >> 5;
 
+	_sync_capacitor_charge_threshold = syncCapacityLineChargeThreshold * cycles_per_line;
+	_horizontal_retrace_time = (millisecondsHorizontalRetraceTime * cycles_per_line) >> 6;
+	_vertical_retrace_time = scanlinesVerticalRetraceTime * cycles_per_line;
+
+	_scanSpeed.x = 1.0f / (float)cycles_per_line;
+	_scanSpeed.y = 1.0f / (float)height_of_display;
+	_retraceSpeed.x = 1.0f / (float)_horizontal_retrace_time;
+	_retraceSpeed.y = 1.0f / (float)_vertical_retrace_time;
+
 	// generate buffers for signal storage as requested — format is
 	// number of buffers, size of buffer 1, size of buffer 2...
 	_numberOfBuffers = number_of_buffers;
@@ -49,8 +58,7 @@ CRT::CRT(int cycles_per_line, int height_of_display, int number_of_buffers, ...)
 	_run_pointer = 0;
 
 	// reset raster position
-	_horizontalOffset = 0.0f;
-	_verticalOffset = 0.0f;
+	_rasterPosition.x = _rasterPosition.y = 0.0f;
 
 	// reset flywheel sync
 	_expected_next_hsync = cycles_per_line;
@@ -62,6 +70,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;
 }
 
 CRT::~CRT()
@@ -91,15 +100,18 @@ CRT::SyncEvent CRT::advance_to_next_sync_event(bool hsync_is_requested, bool vsy
 	int proposedSyncTime = cycles_to_run_for;
 
 	// have we overrun the maximum permitted number of horizontal syncs for this frame?
-	if (_hsync_counter > _height_of_display + 10) {
-		*cycles_advanced = 0;
-		return SyncEvent::StartHSync;
+	if (!_vretrace_counter)
+	{
+		float raster_distance = _scanSpeed.y * (float)proposedSyncTime;
+		if(_rasterPosition.y < 1.02f && _rasterPosition.y + raster_distance >= 1.02f) {
+			proposedSyncTime = (int)(1.02f - _rasterPosition.y) / _scanSpeed.y;
+			proposedEvent = SyncEvent::StartVSync;
+		}
 	}
 
 	// will we end an ongoing hsync?
-	const int endOfHSyncTime = (millisecondsHorizontalRetraceTime*_cycles_per_line) >> 6;
-	if (_horizontal_counter < endOfHSyncTime && _horizontal_counter+proposedSyncTime >= endOfHSyncTime) {
-		proposedSyncTime = endOfHSyncTime - _horizontal_counter;
+	if (_horizontal_counter < _horizontal_retrace_time && _horizontal_counter+proposedSyncTime >= _horizontal_retrace_time) {
+		proposedSyncTime = _horizontal_retrace_time - _horizontal_counter;
 		proposedEvent = SyncEvent::EndHSync;
 	}
 
@@ -111,10 +123,8 @@ CRT::SyncEvent CRT::advance_to_next_sync_event(bool hsync_is_requested, bool vsy
 
 	// will an acceptable vertical sync be triggered?
 	if (vsync_is_charging && !_vretrace_counter) {
-		const int startOfVSyncTime = syncCapacityLineChargeThreshold*_cycles_per_line;
-
-		 if (_sync_capacitor_charge_level < startOfVSyncTime && _sync_capacitor_charge_level + proposedSyncTime >= startOfVSyncTime) {
-			proposedSyncTime = startOfVSyncTime - _sync_capacitor_charge_level;
+		 if (_sync_capacitor_charge_level < _sync_capacitor_charge_threshold && _sync_capacitor_charge_level + proposedSyncTime >= _sync_capacitor_charge_threshold) {
+			proposedSyncTime = _sync_capacitor_charge_threshold - _sync_capacitor_charge_level;
 			proposedEvent = SyncEvent::StartVSync;
 		 }
 	}
@@ -155,39 +165,31 @@ void CRT::advance_cycles(int number_of_cycles, bool hsync_requested, const bool
 
 		// set the type, initial raster position and type of this run
 		nextRun->type = type;
-		nextRun->start_point.dst_x = _horizontalOffset;
-		nextRun->start_point.dst_y = _verticalOffset;
+		nextRun->start_point.dst_x = _rasterPosition.x;
+		nextRun->start_point.dst_y = _rasterPosition.y;
 		nextRun->data_type = data_type;
 
 		// if this is a data or level run then store a starting data position
 		if(type == CRTRun::Type::Data || type == CRTRun::Type::Level)
 		{
 			nextRun->start_point.src_x = (_write_target_pointer + buffer_offset) & (bufferWidth - 1);
-			nextRun->start_point.dst_x = (_write_target_pointer + buffer_offset) / bufferWidth;
+			nextRun->start_point.src_y = (_write_target_pointer + buffer_offset) / bufferWidth;
 		}
 
 		// advance the raster position as dictated by current sync status
-		if (_vretrace_counter > 0)
-		{
-			_verticalOffset = std::max(0.0f, _verticalOffset - (float)number_of_cycles / (float)(scanlinesVerticalRetraceTime * _cycles_per_line));
-		}
-		else
-		{
-			_verticalOffset = std::min(1.0f, _verticalOffset + (float)number_of_cycles / (float)(_height_of_display * _cycles_per_line));
-		}
-
 		if (_is_in_hsync)
-		{
-			_horizontalOffset = std::max(0.0f, _horizontalOffset - (float)(((millisecondsHorizontalRetraceTime * _cycles_per_line) >> 6) * number_of_cycles) / (float)_cycles_per_line);
-		}
+			_rasterPosition.x = std::max(0.0f, _rasterPosition.x - (float)number_of_cycles * _retraceSpeed.x);
 		else
-		{
-			_horizontalOffset = std::min(1.0f, _horizontalOffset + (float)((((64 - millisecondsHorizontalRetraceTime) * _cycles_per_line) >> 6) * number_of_cycles) / (float)_cycles_per_line);
-		}
+			_rasterPosition.x = std::min(1.0f, _rasterPosition.x + (float)number_of_cycles * _scanSpeed.x);
+
+		if (_vretrace_counter > 0)
+			_rasterPosition.y = std::max(0.0f, _rasterPosition.y - (float)number_of_cycles * _retraceSpeed.y);
+		else
+			_rasterPosition.y = std::min(1.0f, _rasterPosition.y + (float)number_of_cycles * _scanSpeed.y);
 
 		// store the final raster position
-		nextRun->end_point.dst_x = _horizontalOffset;
-		nextRun->end_point.dst_y = _verticalOffset;
+		nextRun->end_point.dst_x = _rasterPosition.x;
+		nextRun->end_point.dst_y = _rasterPosition.y;
 
 		// if this is a data run then advance the buffer pointer
 		if(type == CRTRun::Type::Data)
@@ -199,7 +201,7 @@ void CRT::advance_cycles(int number_of_cycles, bool hsync_requested, const bool
 		if(type == CRTRun::Type::Data || type == CRTRun::Type::Level)
 		{
 			nextRun->end_point.src_x = (_write_target_pointer + buffer_offset) & (bufferWidth - 1);
-			nextRun->end_point.dst_x = (_write_target_pointer + buffer_offset) / bufferWidth;
+			nextRun->end_point.src_y = (_write_target_pointer + buffer_offset) / bufferWidth;
 		}
 
 		// decrement the number of cycles left to run for and increment the
@@ -224,7 +226,6 @@ void CRT::advance_cycles(int number_of_cycles, bool hsync_requested, const bool
 			case SyncEvent::StartHSync:
 				_horizontal_counter = 0;
 				_is_in_hsync = true;
-				_hsync_counter++;
 			break;
 
 			// end of horizontal sync: update the flywheel's velocity, note that we're no longer
@@ -240,8 +241,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 = scanlinesVerticalRetraceTime * _cycles_per_line;
-				_hsync_counter = 0;
+				_vretrace_counter = _vertical_retrace_time;
 			break;
 
 			// end of vertical sync: tell the delegate that we finished vertical sync,
@@ -259,7 +259,7 @@ void CRT::advance_cycles(int number_of_cycles, bool hsync_requested, const bool
 
 #pragma mark - delegate
 
-void CRT::set_crt_delegate(CRTDelegate *delegate)
+void CRT::set_delegate(CRTDelegate *delegate)
 {
 	_delegate = delegate;
 }
diff --git a/Outputs/CRT.hpp b/Outputs/CRT.hpp
index 799473ffa..6f7eae2d2 100644
--- a/Outputs/CRT.hpp
+++ b/Outputs/CRT.hpp
@@ -42,7 +42,7 @@ class CRT {
 			public:
 				virtual void crt_did_start_vertical_retrace_with_runs(CRTRun *runs, int runs_to_draw) = 0;
 		};
-		void set_crt_delegate(CRTDelegate *delegate);
+		void set_delegate(CRTDelegate *delegate);
 
 		void allocate_write_area(int required_length);
 		uint8_t *get_write_target_for_buffer(int buffer);
@@ -61,7 +61,9 @@ class CRT {
 		int _run_pointer;
 
 		// the current scanning position
-		float _horizontalOffset, _verticalOffset;
+		struct Vector {
+			float x, y;
+		} _rasterPosition, _scanSpeed, _retraceSpeed;
 
 		// the content buffers
 		uint8_t **_buffers;
@@ -72,20 +74,18 @@ class CRT {
 		// returned and to where the next section will begin
 		int _write_allocation_pointer, _write_target_pointer;
 
-		// a counter of horizontal syncs, to allow an automatic vertical
-		// sync to be triggered if we appear to be exiting the display
-		// (TODO: switch to evaluating _verticalOffset for this)
-		int _hsync_counter;
-
 		// outer elements of sync separation
-		bool _is_receiving_sync;			// true if the CRT is currently receiving sync (i.e. this is for edge triggering of horizontal sync)
-		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 _vretrace_counter;				// a down-counter for time during a vertical retrace
+		bool _is_receiving_sync;				// true if the CRT is currently receiving sync (i.e. this is for edge triggering of horizontal sync)
+		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;
 
 		// components of the flywheel sync
 		int _horizontal_counter;			// time run since the _start_ of the last horizontal sync
 		int _expected_next_hsync;			// our current expection of when the next horizontal sync will be encountered (which implies current flywheel velocity)
+		int _horizontal_retrace_time;
 		bool _is_in_hsync;					// true for the duration of a horizontal sync — used to determine beam running direction and speed
 
 		// the outer entry point for dispatching output_sync, output_blank, output_level and output_data