From 7c65c69e0f93467f81726fb7bf29d481de81b870 Mon Sep 17 00:00:00 2001
From: Thomas Harte <thomas.harte@gmail.com>
Date: Thu, 15 Sep 2016 22:12:12 -0400
Subject: [PATCH] Migrated to Swift 3.

---
 .../Clock Signal.xcodeproj/project.pbxproj    | 16 +++-
 OSBindings/Mac/Clock Signal/AppDelegate.swift |  6 +-
 .../DocumentController.swift                  |  8 +-
 .../Documents/Atari2600Document.swift         | 28 ++++---
 .../Documents/ElectronDocument.swift          | 22 ++---
 .../Documents/MachineDocument.swift           | 82 +++++++++----------
 .../Documents/Vic20Document.swift             | 58 +++++--------
 .../6502InterruptTests.swift                  | 28 +++----
 .../Clock SignalTests/6502TimingTests.swift   | 16 ++--
 .../Mac/Clock SignalTests/6522Tests.swift     | 42 +++++-----
 .../Mac/Clock SignalTests/6532Tests.swift     | 52 ++++++------
 .../Clock SignalTests/AllSuiteATests.swift    | 14 ++--
 .../Mac/Clock SignalTests/C1540Tests.swift    | 24 +++---
 .../Mac/Clock SignalTests/DPLLTests.swift     | 26 +++---
 .../Clock SignalTests/KlausDormannTests.swift | 14 ++--
 .../WolfgangLorenzTests.swift                 | 48 +++++------
 16 files changed, 243 insertions(+), 241 deletions(-)

diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj
index 9cbe1041e..08acf0b6d 100644
--- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj	
+++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj	
@@ -1708,11 +1708,12 @@
 			isa = PBXProject;
 			attributes = {
 				LastSwiftUpdateCheck = 0700;
-				LastUpgradeCheck = 0700;
+				LastUpgradeCheck = 0800;
 				ORGANIZATIONNAME = "Thomas Harte";
 				TargetAttributes = {
 					4BB73E9D1B587A5100552FC2 = {
 						CreatedOnToolsVersion = 7.0;
+						LastSwiftMigration = 0800;
 						SystemCapabilities = {
 							com.apple.Sandbox = {
 								enabled = 1;
@@ -1721,10 +1722,12 @@
 					};
 					4BB73EB11B587A5100552FC2 = {
 						CreatedOnToolsVersion = 7.0;
+						LastSwiftMigration = 0800;
 						TestTargetID = 4BB73E9D1B587A5100552FC2;
 					};
 					4BB73EBC1B587A5100552FC2 = {
 						CreatedOnToolsVersion = 7.0;
+						LastSwiftMigration = 0800;
 						TestTargetID = 4BB73E9D1B587A5100552FC2;
 					};
 				};
@@ -2207,8 +2210,10 @@
 				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
 				CLANG_WARN_EMPTY_BODY = YES;
 				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
 				CLANG_WARN_INT_CONVERSION = YES;
 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				CODE_SIGN_IDENTITY = "-";
@@ -2251,8 +2256,10 @@
 				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
 				CLANG_WARN_EMPTY_BODY = YES;
 				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
 				CLANG_WARN_INT_CONVERSION = YES;
 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				CODE_SIGN_IDENTITY = "-";
@@ -2271,6 +2278,7 @@
 				MACOSX_DEPLOYMENT_TARGET = 10.10;
 				MTL_ENABLE_DEBUG_INFO = NO;
 				SDKROOT = macosx;
+				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
 			};
 			name = Release;
 		};
@@ -2289,6 +2297,7 @@
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "Clock Signal/ClockSignal-Bridging-Header.h";
 				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+				SWIFT_VERSION = 3.0;
 			};
 			name = Debug;
 		};
@@ -2306,6 +2315,7 @@
 				PRODUCT_BUNDLE_IDENTIFIER = "TH.Clock-Signal";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "Clock Signal/ClockSignal-Bridging-Header.h";
+				SWIFT_VERSION = 3.0;
 			};
 			name = Release;
 		};
@@ -2321,6 +2331,7 @@
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "Clock SignalTests/Bridges/Clock SignalTests-Bridging-Header.h";
 				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+				SWIFT_VERSION = 3.0;
 				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Clock Signal.app/Contents/MacOS/Clock Signal";
 			};
 			name = Debug;
@@ -2336,6 +2347,7 @@
 				PRODUCT_BUNDLE_IDENTIFIER = "TH.Clock-SignalTests";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "Clock SignalTests/Bridges/Clock SignalTests-Bridging-Header.h";
+				SWIFT_VERSION = 3.0;
 				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Clock Signal.app/Contents/MacOS/Clock Signal";
 			};
 			name = Release;
@@ -2348,6 +2360,7 @@
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = "TH.Clock-SignalUITests";
 				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_VERSION = 3.0;
 				TEST_TARGET_NAME = "Clock Signal";
 				USES_XCTRUNNER = YES;
 			};
@@ -2361,6 +2374,7 @@
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = "TH.Clock-SignalUITests";
 				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_VERSION = 3.0;
 				TEST_TARGET_NAME = "Clock Signal";
 				USES_XCTRUNNER = YES;
 			};
diff --git a/OSBindings/Mac/Clock Signal/AppDelegate.swift b/OSBindings/Mac/Clock Signal/AppDelegate.swift
index 2286db90e..29283b1c1 100644
--- a/OSBindings/Mac/Clock Signal/AppDelegate.swift	
+++ b/OSBindings/Mac/Clock Signal/AppDelegate.swift	
@@ -11,16 +11,16 @@ import Cocoa
 @NSApplicationMain
 class AppDelegate: NSObject, NSApplicationDelegate {
 
-	func applicationDidFinishLaunching(aNotification: NSNotification) {
+	func applicationDidFinishLaunching(_ aNotification: Notification) {
 		// Insert code here to initialize your application
 	}
 
-	func applicationWillTerminate(aNotification: NSNotification) {
+	func applicationWillTerminate(_ aNotification: Notification) {
 		// Insert code here to tear down your application
 	}
 
 	// decline to open a new file unless the user explicitly requests it
-	func applicationShouldOpenUntitledFile(sender: NSApplication) -> Bool {
+	func applicationShouldOpenUntitledFile(_ sender: NSApplication) -> Bool {
 		return false
 	}
 }
diff --git a/OSBindings/Mac/Clock Signal/Document Controller/DocumentController.swift b/OSBindings/Mac/Clock Signal/Document Controller/DocumentController.swift
index 847db82ad..4625bdc50 100644
--- a/OSBindings/Mac/Clock Signal/Document Controller/DocumentController.swift	
+++ b/OSBindings/Mac/Clock Signal/Document Controller/DocumentController.swift	
@@ -9,18 +9,18 @@
 import Cocoa
 
 class DocumentController: NSDocumentController {
-	override func makeDocumentWithContentsOfURL(url: NSURL, ofType typeName: String) throws -> NSDocument {
-		if let analyser = CSStaticAnalyser(fileAtURL: url) {
+	override func makeDocument(withContentsOf url: URL, ofType typeName: String) throws -> NSDocument {
+		if let analyser = CSStaticAnalyser(fileAt: url) {
 			if let documentClass = analyser.documentClass as? NSDocument.Type {
 				let document = documentClass.init()
 				if let machineDocument = document as? MachineDocument {
-					machineDocument.setDisplayName(analyser.displayName)
+					machineDocument.displayName = analyser.displayName
 					machineDocument.configureAs(analyser)
 					return machineDocument
 				}
 			}
 		}
 
-		return try! super.makeDocumentWithContentsOfURL(url, ofType: typeName)
+		return try! super.makeDocument(withContentsOf: url, ofType: typeName)
 	}
 }
diff --git a/OSBindings/Mac/Clock Signal/Documents/Atari2600Document.swift b/OSBindings/Mac/Clock Signal/Documents/Atari2600Document.swift
index ac9cd7170..e48144448 100644
--- a/OSBindings/Mac/Clock Signal/Documents/Atari2600Document.swift	
+++ b/OSBindings/Mac/Clock Signal/Documents/Atari2600Document.swift	
@@ -10,7 +10,7 @@ import Cocoa
 
 class Atari2600Document: MachineDocument {
 
-	private var atari2600 = CSAtari2600()
+	fileprivate var atari2600 = CSAtari2600()
 	override var machine: CSMachine! {
 		get {
 			return atari2600
@@ -31,7 +31,7 @@ class Atari2600Document: MachineDocument {
 		return "Atari2600Document"
 	}
 
-	override func windowControllerDidLoadNib(aController: NSWindowController) {
+	override func windowControllerDidLoadNib(_ aController: NSWindowController) {
 		super.windowControllerDidLoadNib(aController)
 
 		// push whatever settings the switches have in the NIB into the emulation
@@ -39,26 +39,28 @@ class Atari2600Document: MachineDocument {
 
 		// show the options window but ensure the OpenGL view is key
 		showOptions(self)
-		self.openGLView.window?.makeKeyWindow()
+		self.openGLView.window?.makeKey()
 	}
 
 	// MARK: CSOpenGLViewResponderDelegate
-	private func inputForKey(event: NSEvent) -> Atari2600DigitalInput? {
+	fileprivate func inputForKey(_ event: NSEvent) -> Atari2600DigitalInput? {
 		switch event.keyCode {
 			case 123:	return Atari2600DigitalInputJoy1Left
 			case 126:	return Atari2600DigitalInputJoy1Up
 			case 124:	return Atari2600DigitalInputJoy1Right
 			case 125:	return Atari2600DigitalInputJoy1Down
 			case 0:		return Atari2600DigitalInputJoy1Fire
-			default: print("\(event.keyCode)"); return nil
+			default:
+				Swift.print("\(event.keyCode)")
+				return nil
 		}
 	}
 
-	override func keyDown(event: NSEvent) {
+	override func keyDown(_ event: NSEvent) {
 		super.keyDown(event)
 
 		if let input = inputForKey(event) {
-			atari2600.setState(true, forDigitalInput: input)
+			atari2600.setState(true, for: input)
 		}
 
 		if event.keyCode == 36 {
@@ -66,11 +68,11 @@ class Atari2600Document: MachineDocument {
 		}
 	}
 
-	override func keyUp(event: NSEvent) {
+	override func keyUp(_ event: NSEvent) {
 		super.keyUp(event)
 
 		if let input = inputForKey(event) {
-			atari2600.setState(false, forDigitalInput: input)
+			atari2600.setState(false, for: input)
 		}
 
 		if event.keyCode == 36 {
@@ -85,21 +87,21 @@ class Atari2600Document: MachineDocument {
 	@IBOutlet var leftPlayerDifficultyButton: NSButton!
 	@IBOutlet var rightPlayerDifficultyButton: NSButton!
 
-	@IBAction func optionDidChange(sender: AnyObject!) {
+	@IBAction func optionDidChange(_ sender: AnyObject!) {
 		pushSwitchValues()
 	}
 
-	private func pushSwitchValues() {
+	fileprivate func pushSwitchValues() {
 		atari2600.colourButton = colourButton.state == NSOnState
 		atari2600.leftPlayerDifficultyButton = leftPlayerDifficultyButton.state == NSOnState
 		atari2600.rightPlayerDifficultyButton = rightPlayerDifficultyButton.state == NSOnState
 	}
 
-	@IBAction func optionWasPressed(sender: NSButton!) {
+	@IBAction func optionWasPressed(_ sender: NSButton!) {
 		if sender == resetButton {
 			atari2600.pressResetButton()
 		} else {
 			atari2600.pressSelectButton()
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift b/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift
index d587dbc32..73aab5fee 100644
--- a/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift	
+++ b/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift	
@@ -11,7 +11,7 @@ import AudioToolbox
 
 class ElectronDocument: MachineDocument {
 
-	private lazy var electron = CSElectron()
+	fileprivate lazy var electron = CSElectron()
 	override var machine: CSMachine! {
 		get {
 			return electron
@@ -27,14 +27,14 @@ class ElectronDocument: MachineDocument {
 		return NSSize(width: 11.0, height: 10.0)
 	}
 
-	private func rom(name: String) -> NSData? {
+	fileprivate func rom(_ name: String) -> Data? {
 		return dataForResource(name, ofType: "rom", inDirectory: "ROMImages/Electron")
 	}
 
-	override func windowControllerDidLoadNib(aController: NSWindowController) {
+	override func windowControllerDidLoadNib(_ aController: NSWindowController) {
 		super.windowControllerDidLoadNib(aController)
 
-		if let os = rom("os"), basic = rom("basic") {
+		if let os = rom("os"), let basic = rom("basic") {
 			self.electron.setOSROM(os)
 			self.electron.setBASICROM(basic)
 		}
@@ -67,21 +67,21 @@ class ElectronDocument: MachineDocument {
 
 	// MARK: IBActions
 	@IBOutlet var displayTypeButton: NSPopUpButton?
-	@IBAction func setDisplayType(sender: NSPopUpButton!) {
+	@IBAction func setDisplayType(_ sender: NSPopUpButton!) {
 		electron.useTelevisionOutput = (sender.indexOfSelectedItem == 1)
-		NSUserDefaults.standardUserDefaults().setInteger(sender.indexOfSelectedItem, forKey: self.displayTypeUserDefaultsKey)
+		UserDefaults.standard.set(sender.indexOfSelectedItem, forKey: self.displayTypeUserDefaultsKey)
 	}
 
-	private let displayTypeUserDefaultsKey = "electron.displayType"
+	fileprivate let displayTypeUserDefaultsKey = "electron.displayType"
 	override func establishStoredOptions() {
 		super.establishStoredOptions()
-		let standardUserDefaults = NSUserDefaults.standardUserDefaults()
-		standardUserDefaults.registerDefaults([
+		let standardUserDefaults = UserDefaults.standard
+		standardUserDefaults.register(defaults: [
 			displayTypeUserDefaultsKey: 0,
 		])
 
-		let displayType = standardUserDefaults.integerForKey(self.displayTypeUserDefaultsKey)
+		let displayType = standardUserDefaults.integer(forKey: self.displayTypeUserDefaultsKey)
 		electron.useTelevisionOutput = (displayType == 1)
-		self.displayTypeButton?.selectItemAtIndex(displayType)
+		self.displayTypeButton?.selectItem(at: displayType)
 	}
 }
diff --git a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift
index fe8937330..03c3333c0 100644
--- a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift	
+++ b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift	
@@ -43,24 +43,24 @@ class MachineDocument:
 	}
 
 	@IBOutlet weak var optionsPanel: NSPanel!
-	@IBAction func showOptions(sender: AnyObject!) {
+	@IBAction func showOptions(_ sender: AnyObject!) {
 		optionsPanel?.setIsVisible(true)
 	}
 
-	private var audioQueue: CSAudioQueue! = nil
-	private lazy var bestEffortUpdater: CSBestEffortUpdater = {
+	fileprivate var audioQueue: CSAudioQueue! = nil
+	fileprivate lazy var bestEffortUpdater: CSBestEffortUpdater = {
 		let updater = CSBestEffortUpdater()
 		updater.delegate = self
 		return updater
 	}()
 
-	override func windowControllerDidLoadNib(aController: NSWindowController) {
+	override func windowControllerDidLoadNib(_ aController: NSWindowController) {
 		super.windowControllerDidLoadNib(aController)
 
 		// establish the output aspect ratio and audio
 		let displayAspectRatio = self.aspectRatio()
 		aController.window?.contentAspectRatio = displayAspectRatio
-		openGLView.performWithGLContext({
+		openGLView.perform(glContext: {
 			self.machine.setView(self.openGLView, aspectRatio: Float(displayAspectRatio.width / displayAspectRatio.height))
 		})
 
@@ -69,18 +69,18 @@ class MachineDocument:
 		establishStoredOptions()
 	}
 
-	func machineDidChangeClockRate(machine: CSMachine!) {
+	func machineDidChangeClockRate(_ machine: CSMachine!) {
 		setupClockRate()
 	}
 
-	func machineDidChangeClockIsUnlimited(machine: CSMachine!) {
+	func machineDidChangeClockIsUnlimited(_ machine: CSMachine!) {
 		self.bestEffortUpdater.runAsUnlimited = machine.clockIsUnlimited
 	}
 
-	private func setupClockRate() {
+	fileprivate func setupClockRate() {
 		// establish and provide the audio queue, taking advice as to an appropriate sampling rate
 		let maximumSamplingRate = CSAudioQueue.preferredSamplingRate()
-		let selectedSamplingRate = self.machine.idealSamplingRateFromRange(NSRange(location: 0, length: NSInteger(maximumSamplingRate)))
+		let selectedSamplingRate = self.machine.idealSamplingRate(from: NSRange(location: 0, length: NSInteger(maximumSamplingRate)))
 		if selectedSamplingRate > 0 {
 			audioQueue = CSAudioQueue(samplingRate: Float64(selectedSamplingRate))
 			audioQueue.delegate = self
@@ -103,89 +103,89 @@ class MachineDocument:
 	}
 
 	// MARK: configuring
-	func configureAs(analysis: CSStaticAnalyser) {
-		analysis.applyToMachine(self.machine)
+	func configureAs(_ analysis: CSStaticAnalyser) {
+		analysis.apply(to: self.machine)
 	}
 
 	// MARK: the pasteboard
-	func paste(sender: AnyObject!) {
-		let pasteboard = NSPasteboard.generalPasteboard()
-		if let string = pasteboard.stringForType(NSPasteboardTypeString) {
+	func paste(_ sender: AnyObject!) {
+		let pasteboard = NSPasteboard.general()
+		if let string = pasteboard.string(forType: NSPasteboardTypeString) {
 			self.machine.paste(string)
 		}
 	}
 
 	// MARK: CSBestEffortUpdaterDelegate
-	final func bestEffortUpdater(bestEffortUpdater: CSBestEffortUpdater!, runForCycles cycles: UInt, didSkipPreviousUpdate: Bool) {
+	final func bestEffortUpdater(_ bestEffortUpdater: CSBestEffortUpdater!, runForCycles cycles: UInt, didSkipPreviousUpdate: Bool) {
 		runForNumberOfCycles(Int32(cycles))
 	}
 
-	func runForNumberOfCycles(numberOfCycles: Int32) {
+	func runForNumberOfCycles(_ numberOfCycles: Int32) {
 		let cyclesToRunFor = min(numberOfCycles, Int32(bestEffortUpdater.clockRate / 10))
-		if actionLock.tryLock() {
-			self.machine.runForNumberOfCycles(cyclesToRunFor)
+		if actionLock.try() {
+			self.machine.runForNumber(ofCycles: cyclesToRunFor)
 			actionLock.unlock()
 		}
 	}
 
 	// MARK: Utilities for children
-	func dataForResource(name : String, ofType type: String, inDirectory directory: String) -> NSData? {
-		if let path = NSBundle.mainBundle().pathForResource(name, ofType: type, inDirectory: directory) {
-			return NSData(contentsOfFile: path)
+	func dataForResource(_ name : String, ofType type: String, inDirectory directory: String) -> Data? {
+		if let path = Bundle.main.path(forResource: name, ofType: type, inDirectory: directory) {
+			return (try? Data(contentsOf: URL(fileURLWithPath: path)))
 		}
 
 		return nil
 	}
 
 	// MARK: CSAudioQueueDelegate
-	final func audioQueueDidCompleteBuffer(audioQueue: CSAudioQueue) {
+	final func audioQueueDidCompleteBuffer(_ audioQueue: CSAudioQueue) {
 		bestEffortUpdater.update()
 	}
 
 	// MARK: CSOpenGLViewDelegate
-	final func openGLView(view: CSOpenGLView, drawViewOnlyIfDirty onlyIfDirty: Bool) {
+	final func openGLView(_ view: CSOpenGLView, drawViewOnlyIfDirty onlyIfDirty: Bool) {
 		bestEffortUpdater.update()
-		if drawLock.tryLock() {
-			self.machine.drawViewForPixelSize(view.backingSize, onlyIfDirty: onlyIfDirty)
+		if drawLock.try() {
+			self.machine.drawView(forPixelSize: view.backingSize, onlyIfDirty: onlyIfDirty)
 			drawLock.unlock()
 		}
 	}
 
 	// MARK: NSDocument overrides
-	override func dataOfType(typeName: String) throws -> NSData {
+	override func data(ofType typeName: String) throws -> Data {
 		throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
 	}
 
 	// MARK: Key forwarding
-	private func withKeyboardMachine(action: (CSKeyboardMachine) -> ()) {
+	fileprivate func withKeyboardMachine(_ action: (CSKeyboardMachine) -> ()) {
 		if let keyboardMachine = self.machine as? CSKeyboardMachine {
 			action(keyboardMachine)
 		}
 	}
 
-	func windowDidResignKey(notification: NSNotification) {
+	func windowDidResignKey(_ notification: Notification) {
 		self.withKeyboardMachine { $0.clearAllKeys() }
 	}
 
-	func keyDown(event: NSEvent) {
+	func keyDown(_ event: NSEvent) {
 		self.withKeyboardMachine { $0.setKey(event.keyCode, isPressed: true) }
 	}
 
-	func keyUp(event: NSEvent) {
+	func keyUp(_ event: NSEvent) {
 		self.withKeyboardMachine { $0.setKey(event.keyCode, isPressed: false) }
 	}
 
-	func flagsChanged(newModifiers: NSEvent) {
+	func flagsChanged(_ newModifiers: NSEvent) {
 		self.withKeyboardMachine {
-			$0.setKey(VK_Shift, isPressed: newModifiers.modifierFlags.contains(.ShiftKeyMask))
-			$0.setKey(VK_Control, isPressed: newModifiers.modifierFlags.contains(.ControlKeyMask))
-			$0.setKey(VK_Command, isPressed: newModifiers.modifierFlags.contains(.CommandKeyMask))
-			$0.setKey(VK_Option, isPressed: newModifiers.modifierFlags.contains(.AlternateKeyMask))
+			$0.setKey(VK_Shift, isPressed: newModifiers.modifierFlags.contains(.shift))
+			$0.setKey(VK_Control, isPressed: newModifiers.modifierFlags.contains(.control))
+			$0.setKey(VK_Command, isPressed: newModifiers.modifierFlags.contains(.command))
+			$0.setKey(VK_Option, isPressed: newModifiers.modifierFlags.contains(.option))
 		}
 	}
 
 	// MARK: IBActions
-	final func prefixedUserDefaultsKey(key: String) -> String {
+	final func prefixedUserDefaultsKey(_ key: String) -> String {
 		return "\(self.name).\(key)"
 	}
 	var fastLoadingUserDefaultsKey: String {
@@ -195,22 +195,22 @@ class MachineDocument:
 	}
 
 	@IBOutlet var fastLoadingButton: NSButton?
-	@IBAction func setFastLoading(sender: NSButton!) {
+	@IBAction func setFastLoading(_ sender: NSButton!) {
 		if let fastLoadingMachine = machine as? CSFastLoading {
 			let useFastLoadingHack = sender.state == NSOnState
 			fastLoadingMachine.useFastLoadingHack = useFastLoadingHack
-			NSUserDefaults.standardUserDefaults().setBool(useFastLoadingHack, forKey: fastLoadingUserDefaultsKey)
+			UserDefaults.standard.set(useFastLoadingHack, forKey: fastLoadingUserDefaultsKey)
 		}
 	}
 
 	func establishStoredOptions() {
-		let standardUserDefaults = NSUserDefaults.standardUserDefaults()
-		standardUserDefaults.registerDefaults([
+		let standardUserDefaults = UserDefaults.standard
+		standardUserDefaults.register(defaults: [
 			fastLoadingUserDefaultsKey: true
 		])
 
 		if let fastLoadingMachine = machine as? CSFastLoading {
-			let useFastLoadingHack = standardUserDefaults.boolForKey(self.fastLoadingUserDefaultsKey)
+			let useFastLoadingHack = standardUserDefaults.bool(forKey: self.fastLoadingUserDefaultsKey)
 			fastLoadingMachine.useFastLoadingHack = useFastLoadingHack
 			self.fastLoadingButton?.state = useFastLoadingHack ? NSOnState : NSOffState
 		}
diff --git a/OSBindings/Mac/Clock Signal/Documents/Vic20Document.swift b/OSBindings/Mac/Clock Signal/Documents/Vic20Document.swift
index 23dd816e4..249b7f9be 100644
--- a/OSBindings/Mac/Clock Signal/Documents/Vic20Document.swift	
+++ b/OSBindings/Mac/Clock Signal/Documents/Vic20Document.swift	
@@ -10,7 +10,7 @@ import Foundation
 
 class Vic20Document: MachineDocument {
 
-	private lazy var vic20 = CSVic20()
+	fileprivate lazy var vic20 = CSVic20()
 	override var machine: CSMachine! {
 		get {
 			return vic20
@@ -41,22 +41,8 @@ class Vic20Document: MachineDocument {
 		return "Vic20Document"
 	}
 
-	override func readFromURL(url: NSURL, ofType typeName: String) throws {
-		if let pathExtension = url.pathExtension {
-			switch pathExtension.lowercaseString {
-				case "tap":	vic20.openTAPAtURL(url)
-				case "g64":	vic20.openG64AtURL(url)
-				case "d64":	vic20.openD64AtURL(url)
-				case "prg": vic20.openPRGAtURL(url)
-				default:
-					let fileWrapper = try NSFileWrapper(URL: url, options: NSFileWrapperReadingOptions(rawValue: 0))
-					try self.readFromFileWrapper(fileWrapper, ofType: typeName)
-			}
-		}
-	}
-
 	// MARK: machine setup
-	private func rom(name: String) -> NSData? {
+	fileprivate func rom(_ name: String) -> Data? {
 		return dataForResource(name, ofType: "bin", inDirectory: "ROMImages/Vic20")
 	}
 
@@ -66,10 +52,10 @@ class Vic20Document: MachineDocument {
 		get { return prefixedUserDefaultsKey("autoload") }
 	}
 
-	@IBAction func setShouldLoadAutomatically(sender: NSButton!) {
+	@IBAction func setShouldLoadAutomatically(_ sender: NSButton!) {
 		let loadAutomatically = sender.state == NSOnState
 		vic20.shouldLoadAutomatically = loadAutomatically
-		NSUserDefaults.standardUserDefaults().setBool(loadAutomatically, forKey: self.autoloadingUserDefaultsKey)
+		UserDefaults.standard.set(loadAutomatically, forKey: self.autoloadingUserDefaultsKey)
 	}
 
 	// MARK: country selector
@@ -78,12 +64,12 @@ class Vic20Document: MachineDocument {
 		get { return prefixedUserDefaultsKey("country") }
 	}
 
-	@IBAction func setCountry(sender: NSPopUpButton!) {
-		NSUserDefaults.standardUserDefaults().setInteger(sender.indexOfSelectedItem, forKey: self.countryUserDefaultsKey)
+	@IBAction func setCountry(_ sender: NSPopUpButton!) {
+		UserDefaults.standard.set(sender.indexOfSelectedItem, forKey: self.countryUserDefaultsKey)
 		setCountry(sender.indexOfSelectedItem)
 	}
 
-	private func setCountry(countryID: Int) {
+	fileprivate func setCountry(_ countryID: Int) {
 		var charactersROM: String?
 		var kernelROM: String?
 		switch countryID {
@@ -110,8 +96,8 @@ class Vic20Document: MachineDocument {
 			default: break
 		}
 
-		if let charactersROM = charactersROM, kernelROM = kernelROM {
-			if let kernel = rom(kernelROM), basic = rom("basic"), characters = rom(charactersROM) {
+		if let charactersROM = charactersROM, let kernelROM = kernelROM {
+			if let kernel = rom(kernelROM), let basic = rom("basic"), let characters = rom(charactersROM) {
 				vic20.setKernelROM(kernel)
 				vic20.setBASICROM(basic)
 				vic20.setCharactersROM(characters)
@@ -125,7 +111,7 @@ class Vic20Document: MachineDocument {
 		get { return prefixedUserDefaultsKey("memorySize") }
 	}
 
-	@IBAction func setMemorySize(sender: NSPopUpButton!) {
+	@IBAction func setMemorySize(_ sender: NSPopUpButton!) {
 		var selectedSize: Int?
 		switch sender.indexOfSelectedItem {
 			case 0: selectedSize = 5
@@ -134,15 +120,15 @@ class Vic20Document: MachineDocument {
 			default: break
 		}
 		if let selectedSize = selectedSize {
-			NSUserDefaults.standardUserDefaults().setInteger(selectedSize, forKey: self.memorySizeUserDefaultsKey)
+			UserDefaults.standard.set(selectedSize, forKey: self.memorySizeUserDefaultsKey)
 			setMemorySize(sender.indexOfSelectedItem)
 		}
 	}
-	private func setMemorySize(sizeIndex: Int) {
+	fileprivate func setMemorySize(_ sizeIndex: Int) {
 		switch sizeIndex {
-			case 2:		vic20.memorySize = .Size32Kb
-			case 1:		vic20.memorySize = .Size8Kb
-			default:	vic20.memorySize = .Size5Kb
+			case 2:		vic20.memorySize = .size32Kb
+			case 1:		vic20.memorySize = .size8Kb
+			default:	vic20.memorySize = .size5Kb
 		}
 	}
 
@@ -150,19 +136,19 @@ class Vic20Document: MachineDocument {
 	override func establishStoredOptions() {
 		super.establishStoredOptions()
 
-		let standardUserDefaults = NSUserDefaults.standardUserDefaults()
-		standardUserDefaults.registerDefaults([
+		let standardUserDefaults = UserDefaults.standard
+		standardUserDefaults.register(defaults: [
 			self.autoloadingUserDefaultsKey: true,
 			self.memorySizeUserDefaultsKey: 5,
 			self.countryUserDefaultsKey: 1
 		])
 
-		let loadAutomatically = standardUserDefaults.boolForKey(self.autoloadingUserDefaultsKey)
+		let loadAutomatically = standardUserDefaults.bool(forKey: self.autoloadingUserDefaultsKey)
 		vic20.shouldLoadAutomatically = loadAutomatically
 		self.loadAutomaticallyButton?.state = loadAutomatically ? NSOnState : NSOffState
 
 		if !loadAutomatically {
-			let memorySize = standardUserDefaults.integerForKey(self.memorySizeUserDefaultsKey)
+			let memorySize = standardUserDefaults.integer(forKey: self.memorySizeUserDefaultsKey)
 			var indexToSelect: Int?
 			switch memorySize {
 				case 32:	indexToSelect = 2
@@ -170,14 +156,14 @@ class Vic20Document: MachineDocument {
 				default:	indexToSelect = 0
 			}
 			if let indexToSelect = indexToSelect {
-				self.memorySizeButton?.selectItemAtIndex(indexToSelect)
+				self.memorySizeButton?.selectItem(at: indexToSelect)
 				setMemorySize(indexToSelect)
 			}
 		}
 
 		// TODO: this should be part of the configuration
-		let country = standardUserDefaults.integerForKey(self.countryUserDefaultsKey)
+		let country = standardUserDefaults.integer(forKey: self.countryUserDefaultsKey)
 		setCountry(country)
-		self.countryButton?.selectItemAtIndex(country)
+		self.countryButton?.selectItem(at: country)
 	}
 }
diff --git a/OSBindings/Mac/Clock SignalTests/6502InterruptTests.swift b/OSBindings/Mac/Clock SignalTests/6502InterruptTests.swift
index 697af552b..7fd637992 100644
--- a/OSBindings/Mac/Clock SignalTests/6502InterruptTests.swift	
+++ b/OSBindings/Mac/Clock SignalTests/6502InterruptTests.swift	
@@ -28,31 +28,31 @@ class MOS6502InterruptTests: XCTestCase {
 		machine.setValue(0x58, forAddress: 0x4000)
 
 		// pick things off at 0x4000
-		machine.setValue(0x4000, forRegister: CSTestMachineRegister.ProgramCounter)
+		machine.setValue(0x4000, for: CSTestMachineRegister.programCounter)
 	}
 
     func testIRQLine() {
 		// run for six cycles; check that no interrupt has occurred
-		machine.runForNumberOfCycles(6)
-		XCTAssert(machine.valueForRegister(.ProgramCounter) == 0x4003, "No interrupt should have occurred with line low")
+		machine.runForNumber(ofCycles: 6)
+		XCTAssert(machine.value(for: .programCounter) == 0x4003, "No interrupt should have occurred with line low")
 
 		// enable the interrupt line, check that it was too late
 		machine.irqLine = true
-		machine.runForNumberOfCycles(2)
-		XCTAssert(machine.valueForRegister(.ProgramCounter) == 0x4004, "No interrupt should have occurred from interrupt raised between instructions")
+		machine.runForNumber(ofCycles: 2)
+		XCTAssert(machine.value(for: .programCounter) == 0x4004, "No interrupt should have occurred from interrupt raised between instructions")
 
 		// run for a further 7 cycles, confirm that the IRQ vector was jumped to
-		machine.runForNumberOfCycles(7)
-		XCTAssert(machine.valueForRegister(.ProgramCounter) == 0x1234, "Interrupt routine should just have begun")
+		machine.runForNumber(ofCycles: 7)
+		XCTAssert(machine.value(for: .programCounter) == 0x1234, "Interrupt routine should just have begun")
     }
 
     func testIFlagSet() {
 		// enable the interrupt line, run for eleven cycles to get past the CLIP and the following NOP and into the interrupt routine
 		machine.irqLine = true
-		machine.runForNumberOfCycles(11)
+		machine.runForNumber(ofCycles: 11)
 
-		XCTAssert(machine.valueForRegister(.ProgramCounter) == 0x1234, "Interrupt routine should just have begun")
-		XCTAssert(machine.valueForRegister(.Flags) & 0x04 == 0x04, "Interrupt status flag should be set")
+		XCTAssert(machine.value(for: .programCounter) == 0x1234, "Interrupt routine should just have begun")
+		XCTAssert(machine.value(for: .flags) & 0x04 == 0x04, "Interrupt status flag should be set")
 	}
 
     func testCLISEIFlagClear() {
@@ -61,13 +61,13 @@ class MOS6502InterruptTests: XCTestCase {
 		machine.irqLine = true
 
 		// run for four cycles; the CLI and SEI should have been performed
-		machine.runForNumberOfCycles(4)
-		XCTAssert(machine.valueForRegister(.ProgramCounter) == 0x4002, "CLI/SEI pair should have been performed in their entirety")
+		machine.runForNumber(ofCycles: 4)
+		XCTAssert(machine.value(for: .programCounter) == 0x4002, "CLI/SEI pair should have been performed in their entirety")
 
 		// run for seven more cycles
-		machine.runForNumberOfCycles(7)
+		machine.runForNumber(ofCycles: 7)
 
 		// interrupt should have taken place despite SEI
-		XCTAssert(machine.valueForRegister(.ProgramCounter) == 0x1234, "Interrupt routine should just have begun")
+		XCTAssert(machine.value(for: .programCounter) == 0x1234, "Interrupt routine should just have begun")
 	}
 }
diff --git a/OSBindings/Mac/Clock SignalTests/6502TimingTests.swift b/OSBindings/Mac/Clock SignalTests/6502TimingTests.swift
index 077c86830..550879e75 100644
--- a/OSBindings/Mac/Clock SignalTests/6502TimingTests.swift	
+++ b/OSBindings/Mac/Clock SignalTests/6502TimingTests.swift	
@@ -11,7 +11,7 @@ import XCTest
 
 class MOS6502TimingTests: XCTestCase, CSTestMachineJamHandler {
 
-	private var endTime: UInt32 = 0
+	fileprivate var endTime: UInt32 = 0
 
 	func testImplied() {
 		let code: [UInt8] = [
@@ -195,12 +195,12 @@ class MOS6502TimingTests: XCTestCase, CSTestMachineJamHandler {
 		self.runTest(code, expectedRunLength: 43)
 	}
 
-	func runTest(code: [UInt8], expectedRunLength: UInt32) {
+	func runTest(_ code: [UInt8], expectedRunLength: UInt32) {
 		let machine = CSTestMachine()
 
 		machine.jamHandler = self
 
-		let immediateCode = NSData(bytes: code, length: code.count)
+		let immediateCode = Data(bytes: UnsafePointer<UInt8>(code), count: code.count)
 		machine.setData(immediateCode, atAddress: 0x200)
 		machine.setValue(0x00, forAddress: 0x0000)
 		machine.setValue(0x00, forAddress: 0x0001)
@@ -208,19 +208,19 @@ class MOS6502TimingTests: XCTestCase, CSTestMachineJamHandler {
 		machine.setValue(0x00, forAddress: 0x0003)
 		machine.setValue(0x08, forAddress: 0x0004)
 		machine.setValue(0x02, forAddress: 0x0005)
-		machine.setValue(0x200, forRegister: CSTestMachineRegister.ProgramCounter)
-		machine.setValue(0xff, forRegister: CSTestMachineRegister.X)
-		machine.setValue(0xfe, forRegister: CSTestMachineRegister.Y)
+		machine.setValue(0x200, for: CSTestMachineRegister.programCounter)
+		machine.setValue(0xff, for: CSTestMachineRegister.X)
+		machine.setValue(0xfe, for: CSTestMachineRegister.Y)
 
 		self.endTime = 0
 		while self.endTime == 0 {
-			machine.runForNumberOfCycles(10)
+			machine.runForNumber(ofCycles: 10)
 		}
 
 		XCTAssert(self.endTime == expectedRunLength, "Took \(self.endTime) cycles to perform")
 	}
 
-	func testMachine(machine: CSTestMachine!, didJamAtAddress address: UInt16) {
+	func testMachine(_ machine: CSTestMachine!, didJamAtAddress address: UInt16) {
 		if self.endTime == 0 {
 			self.endTime = machine.timestamp - 9
 		}
diff --git a/OSBindings/Mac/Clock SignalTests/6522Tests.swift b/OSBindings/Mac/Clock SignalTests/6522Tests.swift
index cb5a7ded8..8515286e5 100644
--- a/OSBindings/Mac/Clock SignalTests/6522Tests.swift	
+++ b/OSBindings/Mac/Clock SignalTests/6522Tests.swift	
@@ -11,7 +11,7 @@ import Foundation
 
 class MOS6522Tests: XCTestCase {
 
-	private func with6522(action: (MOS6522Bridge) -> ()) {
+	fileprivate func with6522(_ action: (MOS6522Bridge) -> ()) {
 		let bridge = MOS6522Bridge()
 		action(bridge)
 	}
@@ -25,11 +25,11 @@ class MOS6522Tests: XCTestCase {
 			$0.setValue(0, forRegister: 5)
 
 			// run for 5 cycles
-			$0.runForHalfCycles(10)
+			$0.run(forHalfCycles: 10)
 
 			// check that the timer has gone down by 5
-			XCTAssert($0.valueForRegister(4) == 5, "Low order byte should be 5; was \($0.valueForRegister(4))")
-			XCTAssert($0.valueForRegister(5) == 0, "High order byte should be 0; was \($0.valueForRegister(5))")
+			XCTAssert($0.value(forRegister: 4) == 5, "Low order byte should be 5; was \($0.value(forRegister: 4))")
+			XCTAssert($0.value(forRegister: 5) == 0, "High order byte should be 0; was \($0.value(forRegister: 5))")
 		}
 	}
 
@@ -43,15 +43,15 @@ class MOS6522Tests: XCTestCase {
 			$0.setValue(0x40, forRegister: 8)
 
 			// chek that the new latched value hasn't been copied
-			XCTAssert($0.valueForRegister(8) == 0x10, "Low order byte should be 0x10; was \($0.valueForRegister(8))")
-			XCTAssert($0.valueForRegister(9) == 0x20, "High order byte should be 0x20; was \($0.valueForRegister(9))")
+			XCTAssert($0.value(forRegister: 8) == 0x10, "Low order byte should be 0x10; was \($0.value(forRegister: 8))")
+			XCTAssert($0.value(forRegister: 9) == 0x20, "High order byte should be 0x20; was \($0.value(forRegister: 9))")
 
 			// write the low-byte latch
 			$0.setValue(0x50, forRegister: 9)
 
 			// chek that the latched value has been copied
-			XCTAssert($0.valueForRegister(8) == 0x40, "Low order byte should be 0x50; was \($0.valueForRegister(8))")
-			XCTAssert($0.valueForRegister(9) == 0x50, "High order byte should be 0x40; was \($0.valueForRegister(9))")
+			XCTAssert($0.value(forRegister: 8) == 0x40, "Low order byte should be 0x50; was \($0.value(forRegister: 8))")
+			XCTAssert($0.value(forRegister: 9) == 0x50, "High order byte should be 0x40; was \($0.value(forRegister: 9))")
 		}
 	}
 
@@ -64,32 +64,32 @@ class MOS6522Tests: XCTestCase {
 			$0.setValue(0x40 | 0x80, forRegister: 14)
 
 			// run for 16 cycles
-			$0.runForHalfCycles(32)
+			$0.run(forHalfCycles: 32)
 
 			// check that the timer has gone down to 0 but not yet triggered an interrupt
-			XCTAssert($0.valueForRegister(4) == 0, "Low order byte should be 0; was \($0.valueForRegister(4))")
-			XCTAssert($0.valueForRegister(5) == 0, "High order byte should be 0; was \($0.valueForRegister(5))")
+			XCTAssert($0.value(forRegister: 4) == 0, "Low order byte should be 0; was \($0.value(forRegister: 4))")
+			XCTAssert($0.value(forRegister: 5) == 0, "High order byte should be 0; was \($0.value(forRegister: 5))")
 			XCTAssert(!$0.irqLine, "IRQ should not yet be active")
 
 			// check that two half-cycles later the timer is $ffff but IRQ still hasn't triggered
-			$0.runForHalfCycles(2)
-			XCTAssert($0.valueForRegister(4) == 0xff, "Low order byte should be 0xff; was \($0.valueForRegister(4))")
-			XCTAssert($0.valueForRegister(5) == 0xff, "High order byte should be 0xff; was \($0.valueForRegister(5))")
+			$0.run(forHalfCycles: 2)
+			XCTAssert($0.value(forRegister: 4) == 0xff, "Low order byte should be 0xff; was \($0.value(forRegister: 4))")
+			XCTAssert($0.value(forRegister: 5) == 0xff, "High order byte should be 0xff; was \($0.value(forRegister: 5))")
 			XCTAssert(!$0.irqLine, "IRQ should not yet be active")
 
 			// check that one half-cycle later the timer is still $ffff and IRQ has triggered...
-			$0.runForHalfCycles(1)
+			$0.run(forHalfCycles: 1)
 			XCTAssert($0.irqLine, "IRQ should be active")
-			XCTAssert($0.valueForRegister(4) == 0xff, "Low order byte should be 0xff; was \($0.valueForRegister(4))")
-			XCTAssert($0.valueForRegister(5) == 0xff, "High order byte should be 0xff; was \($0.valueForRegister(5))")
+			XCTAssert($0.value(forRegister: 4) == 0xff, "Low order byte should be 0xff; was \($0.value(forRegister: 4))")
+			XCTAssert($0.value(forRegister: 5) == 0xff, "High order byte should be 0xff; was \($0.value(forRegister: 5))")
 
 			// ... but that reading the timer cleared the interrupt
 			XCTAssert(!$0.irqLine, "IRQ should be active")
 
 			// check that one half-cycles later the timer has reloaded
-			$0.runForHalfCycles(1)
-			XCTAssert($0.valueForRegister(4) == 0x10, "Low order byte should be 0x10; was \($0.valueForRegister(4))")
-			XCTAssert($0.valueForRegister(5) == 0x00, "High order byte should be 0x00; was \($0.valueForRegister(5))")
+			$0.run(forHalfCycles: 1)
+			XCTAssert($0.value(forRegister: 4) == 0x10, "Low order byte should be 0x10; was \($0.value(forRegister: 4))")
+			XCTAssert($0.value(forRegister: 5) == 0x00, "High order byte should be 0x00; was \($0.value(forRegister: 5))")
 		}
 	}
 
@@ -107,7 +107,7 @@ class MOS6522Tests: XCTestCase {
 			$0.portBInput = 0xda
 
 			// test that the result of reading register B is therefore 0x8a
-			XCTAssert($0.valueForRegister(0) == 0x8a, "Data direction register should mix input and output; got \($0.valueForRegister(0))")
+			XCTAssert($0.value(forRegister: 0) == 0x8a, "Data direction register should mix input and output; got \($0.value(forRegister: 0))")
 		}
 	}
 }
diff --git a/OSBindings/Mac/Clock SignalTests/6532Tests.swift b/OSBindings/Mac/Clock SignalTests/6532Tests.swift
index 8432f572a..86150f74a 100644
--- a/OSBindings/Mac/Clock SignalTests/6532Tests.swift	
+++ b/OSBindings/Mac/Clock SignalTests/6532Tests.swift	
@@ -11,7 +11,7 @@ import Foundation
 
 class MOS6532Tests: XCTestCase {
 
-	private func with6532(action: (MOS6532Bridge) -> ()) {
+	fileprivate func with6532(_ action: (MOS6532Bridge) -> ()) {
 		let bridge = MOS6532Bridge()
 		action(bridge)
 	}
@@ -23,12 +23,12 @@ class MOS6532Tests: XCTestCase {
 			$0.setValue(128, forRegister:0x14)
 
 			// run for one clock and the count should now be 127
-			$0.runForCycles(1)
-			XCTAssert($0.valueForRegister(4) == 127, "A single tick should decrease the counter once")
+			$0.run(forCycles: 1)
+			XCTAssert($0.value(forRegister: 4) == 127, "A single tick should decrease the counter once")
 
 			// run for a further 200 clock counts; timer should reach -73 = 183
-			$0.runForCycles(200)
-			XCTAssert($0.valueForRegister(4) == 183, "Timer should underflow and keep counting")
+			$0.run(forCycles: 200)
+			XCTAssert($0.value(forRegister: 4) == 183, "Timer should underflow and keep counting")
 		}
 	}
 
@@ -39,24 +39,24 @@ class MOS6532Tests: XCTestCase {
 			$0.setValue(28, forRegister:0x15)
 
 			// run for seven clock and the count should still be 28
-			$0.runForCycles(7)
-			XCTAssert($0.valueForRegister(4) == 28, "The timer should remain unchanged for seven clocks")
+			$0.run(forCycles: 7)
+			XCTAssert($0.value(forRegister: 4) == 28, "The timer should remain unchanged for seven clocks")
 
 			// run for a further clock and the count should now be 27
-			$0.runForCycles(1)
-			XCTAssert($0.valueForRegister(4) == 27, "The timer should have decremented once after 8 cycles")
+			$0.run(forCycles: 1)
+			XCTAssert($0.value(forRegister: 4) == 27, "The timer should have decremented once after 8 cycles")
 
 			// run for a further 7 + 27*8 + 5 = 228 clock counts; timer should reach -5 = 0xfb
-			$0.runForCycles(228)
-			XCTAssert($0.valueForRegister(4) == 0xfb, "Timer should underflow and start counting at single-clock pace")
+			$0.run(forCycles: 228)
+			XCTAssert($0.value(forRegister: 4) == 0xfb, "Timer should underflow and start counting at single-clock pace")
 
 			// timer should now resume dividing by eight
-			$0.runForCycles(7)
-			XCTAssert($0.valueForRegister(4) == 0xfb, "Timer should remain unchanged for seven cycles")
+			$0.run(forCycles: 7)
+			XCTAssert($0.value(forRegister: 4) == 0xfb, "Timer should remain unchanged for seven cycles")
 
 			// timer should now resume dividing by eight
-			$0.runForCycles(1)
-			XCTAssert($0.valueForRegister(4) == 0xfa, "Timer should decrement after eighth cycle")
+			$0.run(forCycles: 1)
+			XCTAssert($0.value(forRegister: 4) == 0xfa, "Timer should decrement after eighth cycle")
 		}
 	}
 
@@ -66,23 +66,23 @@ class MOS6532Tests: XCTestCase {
 			$0.setValue(1, forRegister:0x1c)
 
 			// run for one clock and the count should now be zero
-			$0.runForCycles(1)
+			$0.run(forCycles: 1)
 
 			// interrupt shouldn't be signalled yet, bit should not be set
 			XCTAssert(!$0.irqLine, "IRQ line should not be set")
-			XCTAssert($0.valueForRegister(5) == 0x00, "Counter interrupt should not be set")
+			XCTAssert($0.value(forRegister: 5) == 0x00, "Counter interrupt should not be set")
 
 			// run for one more clock
-			$0.runForCycles(1)
+			$0.run(forCycles: 1)
 
 			// the interrupt line and bit should now be set
 			XCTAssert($0.irqLine, "IRQ line should be set")
-			XCTAssert($0.valueForRegister(5) == 0x80, "Counter interrupt should be set")
+			XCTAssert($0.value(forRegister: 5) == 0x80, "Counter interrupt should be set")
 
 			// writing again to the timer should clear both
 			$0.setValue(1, forRegister:0x1c)
 			XCTAssert(!$0.irqLine, "IRQ line should be clear")
-			XCTAssert($0.valueForRegister(5) == 0x00, "Counter interrupt should not be set")
+			XCTAssert($0.value(forRegister: 5) == 0x00, "Counter interrupt should not be set")
 		}
 	}
 
@@ -103,10 +103,10 @@ class MOS6532Tests: XCTestCase {
 
 			// confirm that the interrupt flag is set but the line is not
 			XCTAssert(!$0.irqLine, "IRQ line should not be set")
-			XCTAssert($0.valueForRegister(5) == 0x40, "Timer interrupt bit should be set")
+			XCTAssert($0.value(forRegister: 5) == 0x40, "Timer interrupt bit should be set")
 
 			// reading the status register should have reset the interrupt flag
-			XCTAssert($0.valueForRegister(5) == 0x00, "Timer interrupt bit should be reset")
+			XCTAssert($0.value(forRegister: 5) == 0x00, "Timer interrupt bit should be reset")
 		}
 	}
 
@@ -114,7 +114,7 @@ class MOS6532Tests: XCTestCase {
 		with6532 {
 			// seed port a is high; ensure interrupt bit is clear
 			$0.setValue(0x00, forRegister:0)
-			$0.valueForRegister(5)
+			$0.value(forRegister: 5)
 
 			// enable leading edge detection
 			$0.setValue(0, forRegister:7)
@@ -127,7 +127,7 @@ class MOS6532Tests: XCTestCase {
 
 			// confirm that both the interrupt flag are the line are set
 			XCTAssert($0.irqLine, "IRQ line should be set")
-			XCTAssert($0.valueForRegister(5) == 0x40, "Timer interrupt bit should be set")
+			XCTAssert($0.value(forRegister: 5) == 0x40, "Timer interrupt bit should be set")
 		}
 	}
 
@@ -135,7 +135,7 @@ class MOS6532Tests: XCTestCase {
 		with6532 {
 			// seed port a is high; ensure interrupt bit is clear
 			$0.setValue(0x80, forRegister:0)
-			$0.valueForRegister(5)
+			$0.value(forRegister: 5)
 
 			// enable trailing edge detection
 			$0.setValue(0, forRegister:6)
@@ -148,7 +148,7 @@ class MOS6532Tests: XCTestCase {
 
 			// confirm that both the interrupt flag are the line are set
 			XCTAssert($0.irqLine, "IRQ line should be set")
-			XCTAssert($0.valueForRegister(5) == 0x40, "Timer interrupt bit should be set")
+			XCTAssert($0.value(forRegister: 5) == 0x40, "Timer interrupt bit should be set")
 		}
 	}
 }
diff --git a/OSBindings/Mac/Clock SignalTests/AllSuiteATests.swift b/OSBindings/Mac/Clock SignalTests/AllSuiteATests.swift
index 27574a6cd..46e56546a 100644
--- a/OSBindings/Mac/Clock SignalTests/AllSuiteATests.swift	
+++ b/OSBindings/Mac/Clock SignalTests/AllSuiteATests.swift	
@@ -12,22 +12,22 @@ import XCTest
 class AllSuiteATests: XCTestCase {
 
 	func testAllSuiteA() {
-		if let filename = NSBundle(forClass: self.dynamicType).pathForResource("AllSuiteA", ofType: "bin") {
-			if let allSuiteA = NSData(contentsOfFile: filename) {
+		if let filename = Bundle(for: type(of: self)).path(forResource: "AllSuiteA", ofType: "bin") {
+			if let allSuiteA = try? Data(contentsOf: URL(fileURLWithPath: filename)) {
 				let machine = CSTestMachine()
 
 				machine.setData(allSuiteA, atAddress: 0x4000)
 				machine.setValue(CSTestMachineJamOpcode, forAddress:0x45c0);  // end
 
-				machine.setValue(0x4000, forRegister: CSTestMachineRegister.ProgramCounter)
+				machine.setValue(0x4000, for: CSTestMachineRegister.programCounter)
 				while !machine.isJammed {
-					machine.runForNumberOfCycles(1000)
+					machine.runForNumber(ofCycles: 1000)
 				}
 
-				if machine.valueForAddress(0x0210) != 0xff {
-					NSException(name: "Failed AllSuiteA", reason: "Failed test \(machine.valueForAddress(0x0210))", userInfo: nil).raise()
+				if machine.value(forAddress: 0x0210) != 0xff {
+					NSException(name: NSExceptionName(rawValue: "Failed AllSuiteA"), reason: "Failed test \(machine.value(forAddress: 0x0210))", userInfo: nil).raise()
 				}
 			}
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift
index add83142e..90a05d9c6 100644
--- a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift	
+++ b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift	
@@ -10,32 +10,32 @@ import XCTest
 
 class C1540Tests: XCTestCase {
 
-	private func with1540(action: (C1540Bridge) -> ()) {
+	fileprivate func with1540(_ action: (C1540Bridge) -> ()) {
 		let bridge = C1540Bridge()
 
-		if let path = NSBundle.mainBundle().pathForResource("1541", ofType: "bin", inDirectory: "ROMImages/Commodore1540") {
-			let data = NSData(contentsOfFile: path)
+		if let path = Bundle.main.path(forResource: "1541", ofType: "bin", inDirectory: "ROMImages/Commodore1540") {
+			let data = try? Data(contentsOf: URL(fileURLWithPath: path))
 			bridge.setROM(data)
 		}
 
 		action(bridge)
 	}
 
-	private func transmit(c1540: C1540Bridge, value: Int) {
+	fileprivate func transmit(_ c1540: C1540Bridge, value: Int) {
 		var shiftedValue = value
 
 		c1540.dataLine = true
-		c1540.runForCycles(256)
+		c1540.run(forCycles: 256)
 		XCTAssert(c1540.dataLine == false, "Listener should have taken data line low for start of transmission")
 
 		c1540.clockLine = true
-		c1540.runForCycles(256)	// this isn't time limited on real hardware
+		c1540.run(forCycles: 256)	// this isn't time limited on real hardware
 		XCTAssert(c1540.dataLine == true, "Listener should have let data line go high again")
 
 		// set up for byte transfer
 		c1540.clockLine = false
 		c1540.dataLine = true
-		c1540.runForCycles(40)
+		c1540.run(forCycles: 40)
 
 		// transmit bits
 		for _ in 0..<8 {
@@ -45,14 +45,14 @@ class C1540Tests: XCTestCase {
 
 			// toggle clock
 			c1540.clockLine = true
-			c1540.runForCycles(40)
+			c1540.run(forCycles: 40)
 			c1540.clockLine = false
-			c1540.runForCycles(40)
+			c1540.run(forCycles: 40)
 		}
 
 		// check for acknowledgment
 		c1540.dataLine = true
-		c1540.runForCycles(1000)
+		c1540.run(forCycles: 1000)
 		XCTAssert(c1540.dataLine == false, "Listener should have acknowledged byte")
 	}
 
@@ -61,7 +61,7 @@ class C1540Tests: XCTestCase {
 	func testTransmission() {
 		with1540 {
 			// allow some booting time
-			$0.runForCycles(2000000)
+			$0.run(forCycles: 2000000)
 
 			// I want to be talker, so hold attention and clock low with data high
 			$0.clockLine = false
@@ -69,7 +69,7 @@ class C1540Tests: XCTestCase {
 			$0.dataLine = true
 
 			// proceed 1 ms and check that the 1540 pulled the data line low
-			$0.runForCycles(1000)
+			$0.run(forCycles: 1000)
 			XCTAssert($0.dataLine == false, "Listener should have taken data line low")
 
 			// transmit LISTEN #8
diff --git a/OSBindings/Mac/Clock SignalTests/DPLLTests.swift b/OSBindings/Mac/Clock SignalTests/DPLLTests.swift
index 01d99c054..366b39da2 100644
--- a/OSBindings/Mac/Clock SignalTests/DPLLTests.swift	
+++ b/OSBindings/Mac/Clock SignalTests/DPLLTests.swift	
@@ -10,16 +10,16 @@ import XCTest
 
 class DPLLTests: XCTestCase {
 
-	func testRegularNibblesOnPLL(pll: DigitalPhaseLockedLoopBridge, bitLength: UInt) {
+	func testRegularNibblesOnPLL(_ pll: DigitalPhaseLockedLoopBridge, bitLength: UInt) {
 		// clock in two 1s, a 0, and a 1, 200 times over
 		for _ in 0 ..< 200 {
-			pll.runForCycles(bitLength/2)
+			pll.run(forCycles: bitLength/2)
 			pll.addPulse()
-			pll.runForCycles(bitLength)
+			pll.run(forCycles: bitLength)
 			pll.addPulse()
-			pll.runForCycles(bitLength*2)
+			pll.run(forCycles: bitLength*2)
 			pll.addPulse()
-			pll.runForCycles(bitLength/2)
+			pll.run(forCycles: bitLength/2)
 		}
 
 		XCTAssert((pll.stream&0xffffffff) == 0xdddddddd, "PLL should have synchronised and clocked repeating 0xd nibbles; got \(String(pll.stream, radix: 16, uppercase: false))")
@@ -27,17 +27,17 @@ class DPLLTests: XCTestCase {
 
 	func testPerfectInput() {
 		let pll = DigitalPhaseLockedLoopBridge(clocksPerBit: 100, tolerance: 20, historyLength: 3)
-		testRegularNibblesOnPLL(pll, bitLength: 100)
+		testRegularNibblesOnPLL(pll!, bitLength: 100)
 	}
 
 	func testFastButRegular() {
 		let pll = DigitalPhaseLockedLoopBridge(clocksPerBit: 100, tolerance: 20, historyLength: 3)
-		testRegularNibblesOnPLL(pll, bitLength: 90)
+		testRegularNibblesOnPLL(pll!, bitLength: 90)
 	}
 
 	func testSlowButRegular() {
 		let pll = DigitalPhaseLockedLoopBridge(clocksPerBit: 100, tolerance: 20, historyLength: 3)
-		testRegularNibblesOnPLL(pll, bitLength: 110)
+		testRegularNibblesOnPLL(pll!, bitLength: 110)
 	}
 
 	func testTwentyPercentSinePattern() {
@@ -48,14 +48,14 @@ class DPLLTests: XCTestCase {
 		for _ in 0 ..< 200 {
 			let bitLength: UInt = UInt(100 + 20 * sin(angle))
 
-			pll.runForCycles(bitLength/2)
-			pll.addPulse()
-			pll.runForCycles((bitLength*3)/2)
+			pll?.run(forCycles: bitLength/2)
+			pll?.addPulse()
+			pll?.run(forCycles: (bitLength*3)/2)
 
 			angle = angle + 0.1
 		}
 
-		let endOfStream = pll.stream&0xffffffff;
-		XCTAssert(endOfStream == 0xaaaaaaaa || endOfStream == 0x55555555, "PLL should have synchronised and clocked repeating 0xa or 0x5 nibbles; got \(String(pll.stream, radix: 16, uppercase: false))")
+		let endOfStream = (pll?.stream)!&0xffffffff;
+		XCTAssert(endOfStream == 0xaaaaaaaa || endOfStream == 0x55555555, "PLL should have synchronised and clocked repeating 0xa or 0x5 nibbles; got \(String(pll?.stream, radix: 16, uppercase: false))")
 	}
 }
diff --git a/OSBindings/Mac/Clock SignalTests/KlausDormannTests.swift b/OSBindings/Mac/Clock SignalTests/KlausDormannTests.swift
index c9a1db43c..0ab7fa839 100644
--- a/OSBindings/Mac/Clock SignalTests/KlausDormannTests.swift	
+++ b/OSBindings/Mac/Clock SignalTests/KlausDormannTests.swift	
@@ -13,7 +13,7 @@ class KlausDormannTests: XCTestCase {
 
 	func testKlausDormann() {
 
-		func errorForTrapAddress(address: UInt16) -> String? {
+		func errorForTrapAddress(_ address: UInt16) -> String? {
 			let hexAddress = String(format:"%04x", address)
 			switch address {
 				case 0x3399: return nil // success!
@@ -32,17 +32,17 @@ class KlausDormannTests: XCTestCase {
 			}
 		}
 
-		if let filename = NSBundle(forClass: self.dynamicType).pathForResource("6502_functional_test", ofType: "bin") {
-			if let functionalTest = NSData(contentsOfFile: filename) {
+		if let filename = Bundle(for: type(of: self)).path(forResource: "6502_functional_test", ofType: "bin") {
+			if let functionalTest = try? Data(contentsOf: URL(fileURLWithPath: filename)) {
 				let machine = CSTestMachine()
 
 				machine.setData(functionalTest, atAddress: 0)
-				machine.setValue(0x400, forRegister: CSTestMachineRegister.ProgramCounter)
+				machine.setValue(0x400, for: CSTestMachineRegister.programCounter)
 
 				while true {
-					let oldPC = machine.valueForRegister(CSTestMachineRegister.LastOperationAddress)
-					machine.runForNumberOfCycles(1000)
-					let newPC = machine.valueForRegister(CSTestMachineRegister.LastOperationAddress)
+					let oldPC = machine.value(for: CSTestMachineRegister.lastOperationAddress)
+					machine.runForNumber(ofCycles: 1000)
+					let newPC = machine.value(for: CSTestMachineRegister.lastOperationAddress)
 
 					if newPC == oldPC {
 						let error = errorForTrapAddress(oldPC)
diff --git a/OSBindings/Mac/Clock SignalTests/WolfgangLorenzTests.swift b/OSBindings/Mac/Clock SignalTests/WolfgangLorenzTests.swift
index 6455116a0..8bd25ecc3 100644
--- a/OSBindings/Mac/Clock SignalTests/WolfgangLorenzTests.swift	
+++ b/OSBindings/Mac/Clock SignalTests/WolfgangLorenzTests.swift	
@@ -186,29 +186,29 @@ class WolfgangLorenzTests: XCTestCase, CSTestMachineJamHandler {
 		self.runWolfgangLorenzTest("sbcb(eb)")
 	}
 
-	private func runWolfgangLorenzTest(name: String, suffixes: [String]) {
+	fileprivate func runWolfgangLorenzTest(_ name: String, suffixes: [String]) {
 		for suffix in suffixes {
 			let testName = name + suffix
 			self.runWolfgangLorenzTest(testName)
 		}
 	}
 
-	private var output: String = ""
-	private func runWolfgangLorenzTest(name: String) {
+	fileprivate var output: String = ""
+	fileprivate func runWolfgangLorenzTest(_ name: String) {
 
 		var machine: CSTestMachine!
 
-		if let filename = NSBundle(forClass: self.dynamicType).pathForResource(name, ofType: nil) {
-			if let testData = NSData(contentsOfFile: filename) {
+		if let filename = Bundle(for: type(of: self)).path(forResource: name, ofType: nil) {
+			if let testData = try? Data(contentsOf: URL(fileURLWithPath: filename)) {
 
 				machine = CSTestMachine()
 				machine.jamHandler = self
 //				machine.logActivity = true
 				output = ""
 
-				let dataPointer = UnsafePointer<UInt8>(testData.bytes)
+				let dataPointer = (testData as NSData).bytes.bindMemory(to: UInt8.self, capacity: testData.count)
 				let loadAddress = UInt16(dataPointer[0]) | (UInt16(dataPointer[1]) << 8)
-				let contents = testData.subdataWithRange(NSMakeRange(2, testData.length - 2))
+				let contents = testData.subdata(in: NSMakeRange(2, testData.count - 2))
 
 				machine.setData(contents, atAddress: loadAddress)
 
@@ -220,10 +220,10 @@ class WolfgangLorenzTests: XCTestCase, CSTestMachineJamHandler {
 				machine.setValue(0x48, forAddress: 0xfffe)
 				machine.setValue(0xff, forAddress: 0xffff)
 
-				let irqHandler = NSData(bytes: [
+				let irqHandler = Data(bytes: UnsafePointer<UInt8>([
 					0x48, 0x8a, 0x48, 0x98, 0x48, 0xba, 0xbd, 0x04, 0x01,
 					0x29, 0x10, 0xf0, 0x03, 0x6c, 0x16, 0x03, 0x6c, 0x14, 0x03
-				] as [UInt8], length: 19)
+				] as [UInt8]), count: 19)
 				machine.setData( irqHandler, atAddress: 0xff48)
 
 				machine.setValue(CSTestMachineJamOpcode, forAddress:0xffd2);  // print character
@@ -232,30 +232,30 @@ class WolfgangLorenzTests: XCTestCase, CSTestMachineJamHandler {
 				machine.setValue(CSTestMachineJamOpcode, forAddress:0x8000);  // exit
 				machine.setValue(CSTestMachineJamOpcode, forAddress:0xa474);  // exit
 
-				machine.setValue(0x0801, forRegister: CSTestMachineRegister.ProgramCounter)
-				machine.setValue(0xfd, forRegister: CSTestMachineRegister.StackPointer)
-				machine.setValue(0x04, forRegister: CSTestMachineRegister.Flags)
+				machine.setValue(0x0801, for: CSTestMachineRegister.programCounter)
+				machine.setValue(0xfd, for: CSTestMachineRegister.stackPointer)
+				machine.setValue(0x04, for: CSTestMachineRegister.flags)
 			}
 		}
 
 		if machine == nil {
-			NSException(name: "Failed Test", reason: "Couldn't load file \(name)", userInfo: nil).raise()
+			NSException(name: NSExceptionName(rawValue: "Failed Test"), reason: "Couldn't load file \(name)", userInfo: nil).raise()
 		}
 
 		while !machine.isJammed {
-			machine.runForNumberOfCycles(1000)
+			machine.runForNumber(ofCycles: 1000)
 		}
 
-		let jammedPC = machine.valueForRegister(CSTestMachineRegister.LastOperationAddress)
+		let jammedPC = machine.value(for: CSTestMachineRegister.lastOperationAddress)
 		if jammedPC != 0xe16f {
 			let hexAddress = String(format:"%04x", jammedPC)
-			NSException(name: "Failed Test", reason: "Processor jammed unexpectedly at \(hexAddress)", userInfo: nil).raise()
+			NSException(name: NSExceptionName(rawValue: "Failed Test"), reason: "Processor jammed unexpectedly at \(hexAddress)", userInfo: nil).raise()
 		}
 	}
 
 // MARK: MachineJamHandler
 
-	func petsciiToString(string: String) -> String {
+	func petsciiToString(_ string: String) -> String {
 		let petsciiToCharCommon: [String] = [
 			"?", "?", "?", "[RUN/STOP]", "?", "[WHT]", "?", "?", "[SHIFT DISABLE]", "[SHIFT ENABLE]", "?", "?", "?", "\r", "[TEXT MODE]", "?",
 			"?", "\n", "[RVS ON]", "[HOME]", "[DEL]", "?", "?", "?", "?", "?", "?", "?", "[RED]", "[RIGHT]", "[GRN]", "[BLU]",
@@ -297,33 +297,33 @@ class WolfgangLorenzTests: XCTestCase, CSTestMachineJamHandler {
 		return result
 	}
 
-	func testMachine(machine: CSTestMachine!, didJamAtAddress address: UInt16) {
+	func testMachine(_ machine: CSTestMachine!, didJamAtAddress address: UInt16) {
 
 		switch address {
 			case 0xffd2:
 				machine.setValue(0x00, forAddress: 0x030c)
 
-				let character = machine.valueForRegister(CSTestMachineRegister.A)
-				output.append(Character(UnicodeScalar(character)))
+				let character = machine.value(for: CSTestMachineRegister.A)
+				output.append(Character(UnicodeScalar(character)!))
 
 				machine.returnFromSubroutine()
 
 			case 0xffe4:
-				machine.setValue(0x3, forRegister:CSTestMachineRegister.A)
+				machine.setValue(0x3, for:CSTestMachineRegister.A)
 				machine.returnFromSubroutine()
 
 			case 0x8000, 0xa474:
-				NSException(name: "Failed test", reason: self.petsciiToString(output), userInfo: nil).raise()
+				NSException(name: NSExceptionName(rawValue: "Failed test"), reason: self.petsciiToString(output), userInfo: nil).raise()
 
 			case 0x0000:
-				NSException(name: "Failed test", reason: "Execution hit 0000", userInfo: nil).raise()
+				NSException(name: NSExceptionName(rawValue: "Failed test"), reason: "Execution hit 0000", userInfo: nil).raise()
 
 			case 0xe16f:	// load next (which we consider to be success)
 			break;
 
 			default:
 				let hexAddress = String(format:"%04x", address)
-				NSException(name: "Failed Test", reason: "Processor jammed unexpectedly at \(hexAddress)", userInfo: nil).raise()
+				NSException(name: NSExceptionName(rawValue: "Failed Test"), reason: "Processor jammed unexpectedly at \(hexAddress)", userInfo: nil).raise()
 		}
 	}