working on adding notifications, adding preferences

This commit is contained in:
Luigi Thirty 2017-08-12 01:38:57 -04:00
parent a9a12189af
commit cafacf2f18
10 changed files with 226 additions and 156 deletions

View File

@ -114,6 +114,10 @@ class AppleIIBase: NSObject, EmulatedSystem {
func doColdReset() {
CPU.sharedInstance.coldReset()
//Reinitialize peripherals in case they changed.
setupPeripherals()
doReset()
}

View File

@ -62,8 +62,6 @@ extension AppleIIBase {
}
rowNumber += Int((offset / 0x80) * 8)
//if(pixel & 0x80)
let dot0 = (pixel & 0x01) == 0x01
let dot1 = (pixel & 0x02) == 0x02
let dot2 = (pixel & 0x04) == 0x04
@ -80,48 +78,68 @@ extension AppleIIBase {
}
if(dot0) {
buffer![pixelRowOffset + 0 + pixelColumnOffset] = AppleII.LoresColors.White
buffer![pixelRowOffset + 0 + pixelColumnOffset] = AppleIIBase.HiresMode.Colors.White
} else {
buffer![pixelRowOffset + 0 + pixelColumnOffset] = AppleII.LoresColors.Black
buffer![pixelRowOffset + 0 + pixelColumnOffset] = AppleIIBase.HiresMode.Colors.Black
}
if(dot1) {
buffer![pixelRowOffset + 1 + pixelColumnOffset] = AppleII.LoresColors.White
buffer![pixelRowOffset + 1 + pixelColumnOffset] = AppleIIBase.HiresMode.Colors.White
} else {
buffer![pixelRowOffset + 1 + pixelColumnOffset] = AppleII.LoresColors.Black
buffer![pixelRowOffset + 1 + pixelColumnOffset] = AppleIIBase.HiresMode.Colors.Black
}
if(dot2) {
buffer![pixelRowOffset + 2 + pixelColumnOffset] = AppleII.LoresColors.White
buffer![pixelRowOffset + 2 + pixelColumnOffset] = AppleIIBase.HiresMode.Colors.White
} else {
buffer![pixelRowOffset + 2 + pixelColumnOffset] = AppleII.LoresColors.Black
buffer![pixelRowOffset + 2 + pixelColumnOffset] = AppleIIBase.HiresMode.Colors.Black
}
if(dot3) {
buffer![pixelRowOffset + 3 + pixelColumnOffset] = AppleII.LoresColors.White
buffer![pixelRowOffset + 3 + pixelColumnOffset] = AppleIIBase.HiresMode.Colors.White
} else {
buffer![pixelRowOffset + 3 + pixelColumnOffset] = AppleII.LoresColors.Black
buffer![pixelRowOffset + 3 + pixelColumnOffset] = AppleIIBase.HiresMode.Colors.Black
}
if(dot4) {
buffer![pixelRowOffset + 4 + pixelColumnOffset] = AppleII.LoresColors.White
buffer![pixelRowOffset + 4 + pixelColumnOffset] = AppleIIBase.HiresMode.Colors.White
} else {
buffer![pixelRowOffset + 4 + pixelColumnOffset] = AppleII.LoresColors.Black
buffer![pixelRowOffset + 4 + pixelColumnOffset] = AppleIIBase.HiresMode.Colors.Black
}
if(dot5) {
buffer![pixelRowOffset + 5 + pixelColumnOffset] = AppleII.LoresColors.White
buffer![pixelRowOffset + 5 + pixelColumnOffset] = AppleIIBase.HiresMode.Colors.White
} else {
buffer![pixelRowOffset + 5 + pixelColumnOffset] = AppleII.LoresColors.Black
buffer![pixelRowOffset + 5 + pixelColumnOffset] = AppleIIBase.HiresMode.Colors.Black
}
if(dot6) {
buffer![pixelRowOffset + 6 + pixelColumnOffset] = AppleII.LoresColors.White
buffer![pixelRowOffset + 6 + pixelColumnOffset] = AppleIIBase.HiresMode.Colors.White
} else {
buffer![pixelRowOffset + 6 + pixelColumnOffset] = AppleII.LoresColors.Black
buffer![pixelRowOffset + 6 + pixelColumnOffset] = AppleIIBase.HiresMode.Colors.Black
}
}
struct Colors {
static let Black = BitmapPixelsLE555.RGB32toLE555(r: 0, g: 0, b: 0)
static let White = BitmapPixelsLE555.RGB32toLE555(r: 255, g: 255, b: 255)
static func getColor(index: UInt8) -> BitmapPixelsLE555.PixelData {
switch index {
case 0: return AppleIIBase.HiresMode.Colors.Black
case 1: return AppleIIBase.HiresMode.Colors.White
case 2: return AppleIIBase.HiresMode.Colors.White
case 3: return AppleIIBase.HiresMode.Colors.White
case 4: return AppleIIBase.HiresMode.Colors.White
case 5: return AppleIIBase.HiresMode.Colors.White
case 6: return AppleIIBase.HiresMode.Colors.White
case 7: return AppleIIBase.HiresMode.Colors.White
default:
print("tried to get color > 15")
return AppleIIBase.HiresMode.Colors.Black
}
}
}
}
}

View File

@ -22,8 +22,8 @@ extension AppleIIBase {
let pixelNybbleHi = pixel & 0x0F
let pixelNybbleLo = (pixel & 0xF0) >> 4
let colorHi = AppleII.LoresColors.getColor(index: pixelNybbleHi)
let colorLo = LoresColors.getColor(index: pixelNybbleLo)
let colorHi = AppleIIBase.LoresMode.Colors.getColor(index: pixelNybbleHi)
let colorLo = AppleIIBase.LoresMode.Colors.getColor(index: pixelNybbleLo)
//One lores pixel is 7px wide and 4px tall for a resolution of 40x48.
let baseOffset = EmulatedSystemInstance!.emulatorViewDelegate.scanlineOffsets[Int(pixelPosition.y)] + Int(pixelPosition.x)
@ -44,6 +44,50 @@ extension AppleIIBase {
}
}
struct Colors {
static let Black = BitmapPixelsLE555.RGB32toLE555(r: 0, g: 0, b: 0)
static let Magenta = BitmapPixelsLE555.RGB32toLE555(r: 227, g: 30, b: 96)
static let DarkBlue = BitmapPixelsLE555.RGB32toLE555(r: 96, g: 78, b: 189)
static let Purple = BitmapPixelsLE555.RGB32toLE555(r: 255, g: 68, b: 253)
static let DarkGreen = BitmapPixelsLE555.RGB32toLE555(r: 0, g: 163, b: 96)
static let Gray1 = BitmapPixelsLE555.RGB32toLE555(r: 156, g: 156, b: 156)
static let MediumBlue = BitmapPixelsLE555.RGB32toLE555(r: 20, g: 207, b: 253)
static let LightBlue = BitmapPixelsLE555.RGB32toLE555(r: 208, g: 195, b: 255)
static let Brown = BitmapPixelsLE555.RGB32toLE555(r: 96, g: 114, b: 3)
static let Orange = BitmapPixelsLE555.RGB32toLE555(r: 255, g: 106, b: 60)
static let Gray2 = BitmapPixelsLE555.RGB32toLE555(r: 156, g: 156, b: 156)
static let Pink = BitmapPixelsLE555.RGB32toLE555(r: 255, g: 160, b: 208)
static let LightGreen = BitmapPixelsLE555.RGB32toLE555(r: 20, g: 245, b: 60)
static let Yellow = BitmapPixelsLE555.RGB32toLE555(r: 208, g: 221, b: 141)
static let Aquamarine = BitmapPixelsLE555.RGB32toLE555(r: 114, g: 255, b: 208)
static let White = BitmapPixelsLE555.RGB32toLE555(r: 255, g: 255, b: 255)
static func getColor(index: UInt8) -> BitmapPixelsLE555.PixelData {
switch index {
case 0: return AppleIIBase.LoresMode.Colors.Black
case 1: return AppleIIBase.LoresMode.Colors.Magenta
case 2: return AppleIIBase.LoresMode.Colors.DarkBlue
case 3: return AppleIIBase.LoresMode.Colors.Purple
case 4: return AppleIIBase.LoresMode.Colors.DarkGreen
case 5: return AppleIIBase.LoresMode.Colors.Gray1
case 6: return AppleIIBase.LoresMode.Colors.MediumBlue
case 7: return AppleIIBase.LoresMode.Colors.LightBlue
case 8: return AppleIIBase.LoresMode.Colors.Brown
case 9: return AppleIIBase.LoresMode.Colors.Orange
case 10: return AppleIIBase.LoresMode.Colors.Gray2
case 11: return AppleIIBase.LoresMode.Colors.Pink
case 12: return AppleIIBase.LoresMode.Colors.LightGreen
case 13: return AppleIIBase.LoresMode.Colors.Yellow
case 14: return AppleIIBase.LoresMode.Colors.Aquamarine
case 15: return AppleIIBase.LoresMode.Colors.White
default:
print("tried to get color > 15")
return AppleIIBase.LoresMode.Colors.Black
}
}
}
}
}

View File

@ -37,50 +37,6 @@ extension AppleIIBase {
case MixedHires
}
struct LoresColors {
static let Black = BitmapPixelsLE555.RGB32toLE555(r: 0, g: 0, b: 0)
static let Magenta = BitmapPixelsLE555.RGB32toLE555(r: 227, g: 30, b: 96)
static let DarkBlue = BitmapPixelsLE555.RGB32toLE555(r: 96, g: 78, b: 189)
static let Purple = BitmapPixelsLE555.RGB32toLE555(r: 255, g: 68, b: 253)
static let DarkGreen = BitmapPixelsLE555.RGB32toLE555(r: 0, g: 163, b: 96)
static let Gray1 = BitmapPixelsLE555.RGB32toLE555(r: 156, g: 156, b: 156)
static let MediumBlue = BitmapPixelsLE555.RGB32toLE555(r: 20, g: 207, b: 253)
static let LightBlue = BitmapPixelsLE555.RGB32toLE555(r: 208, g: 195, b: 255)
static let Brown = BitmapPixelsLE555.RGB32toLE555(r: 96, g: 114, b: 3)
static let Orange = BitmapPixelsLE555.RGB32toLE555(r: 255, g: 106, b: 60)
static let Gray2 = BitmapPixelsLE555.RGB32toLE555(r: 156, g: 156, b: 156)
static let Pink = BitmapPixelsLE555.RGB32toLE555(r: 255, g: 160, b: 208)
static let LightGreen = BitmapPixelsLE555.RGB32toLE555(r: 20, g: 245, b: 60)
static let Yellow = BitmapPixelsLE555.RGB32toLE555(r: 208, g: 221, b: 141)
static let Aquamarine = BitmapPixelsLE555.RGB32toLE555(r: 114, g: 255, b: 208)
static let White = BitmapPixelsLE555.RGB32toLE555(r: 255, g: 255, b: 255)
static func getColor(index: UInt8) -> BitmapPixelsLE555.PixelData {
switch index {
case 0: return AppleII.LoresColors.Black
case 1: return AppleII.LoresColors.Magenta
case 2: return AppleII.LoresColors.DarkBlue
case 3: return AppleII.LoresColors.Purple
case 4: return AppleII.LoresColors.DarkGreen
case 5: return AppleII.LoresColors.Gray1
case 6: return AppleII.LoresColors.MediumBlue
case 7: return AppleII.LoresColors.LightBlue
case 8: return AppleII.LoresColors.Brown
case 9: return AppleII.LoresColors.Orange
case 10: return AppleII.LoresColors.Gray2
case 11: return AppleII.LoresColors.Pink
case 12: return AppleII.LoresColors.LightGreen
case 13: return AppleII.LoresColors.Yellow
case 14: return AppleII.LoresColors.Aquamarine
case 15: return AppleII.LoresColors.White
default:
print("tried to get color > 15")
return AppleII.LoresColors.Black
}
}
}
func getCurrentVideoMode(switches: VideoSoftswitches) -> VideoMode {
if(switches.TEXT_MODE == true)
{

View File

@ -8,6 +8,11 @@
import Cocoa
class EmulationNotifications {
static let StartEmulation = Notification.Name("StartEmulation")
static let StopEmulation = Notification.Name("StopEmulation")
}
class AppleIIViewController: NSViewController {
@IBOutlet weak var lbl_Drive1: NSTextField!
@IBOutlet weak var lbl_Drive2: NSTextField!
@ -21,20 +26,34 @@ class AppleIIViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
EmulatedSystemInstance = AppleIIPlus.sharedInstance
preferencesWindowController = PreferencesWindowController()
setModel()
self.view.addSubview(EmulatedSystemInstance!.emulatorView)
preferencesWindowController.setupDefaultsIfRequired()
setupDriveNotifications()
NotificationCenter.default.addObserver(self, selector: #selector(self.debuggerBreak), name: DebuggerNotifications.Break, object: nil)
self.frameTimer = Timer.scheduledTimer(timeInterval: 1.0/60.0,
target: self,
selector: #selector(runEmulation),
userInfo: nil,
repeats: true)
NotificationCenter.default.addObserver(self, selector: #selector(self.stopFrameTimer), name: EmulationNotifications.StopEmulation, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.startFrameTimer), name: EmulationNotifications.StartEmulation, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.breakpointHit), name: CPUNotifications.BreakpointHit, object: nil)
startFrameTimer()
}
func setModel() {
let model = UserDefaults.standard.string(forKey: "a2_Model")
if (model == "Apple ][ (Original") {
EmulatedSystemInstance = AppleII.sharedInstance
} else if(model == "Apple ][+") {
EmulatedSystemInstance = AppleIIPlus.sharedInstance
} else {
/* ??? */
EmulatedSystemInstance = AppleII.sharedInstance
}
}
@objc func breakpointHit() {
stopFrameTimer()
showDebugger(self)
}
@objc func runEmulation() {
@ -44,20 +63,30 @@ class AppleIIViewController: NSViewController {
}
}
@objc func debuggerBreak() {
frameTimer?.invalidate()
CPU.sharedInstance.isRunning = false
@objc func stopFrameTimer() {
self.frameTimer?.invalidate()
}
@IBAction func showDebugger(_ sender: Any) {
@objc func startFrameTimer() {
self.frameTimer = Timer.scheduledTimer(timeInterval: 1.0/60.0,
target: self,
selector: #selector(runEmulation),
userInfo: nil,
repeats: true)
}
@IBAction func showDebugger(_ sender: Any) {
stopFrameTimer()
let debuggerStoryboard = NSStoryboard(name: NSStoryboard.Name(rawValue: "Debugger"), bundle: nil)
debuggerWindowController = debuggerStoryboard.instantiateInitialController() as! DebuggerWindowController
debuggerWindowController.showWindow(self)
}
@IBAction func showPreferences(_ sender: Any) {
stopFrameTimer()
preferencesWindowController.loadWindow()
preferencesWindowController.showWindow(self)
preferencesWindowController.setupPreferences()
}
@IBAction func doReset(_ sender: Any) {
@ -65,6 +94,7 @@ class AppleIIViewController: NSViewController {
}
@IBAction func doColdReset(_ sender: Any) {
setModel() //In case it changed
EmulatedSystemInstance!.doColdReset()
}

View File

@ -17,6 +17,10 @@ enum CPUModel {
case M65C02
}
class CPUNotifications {
static let BreakpointHit = Notification.Name("BreakpointHit")
}
struct StatusRegister {
var negative: Bool //N - 0x80
var overflow: Bool //V - 0x40
@ -253,6 +257,7 @@ final class CPU: NSObject {
}
final func executeNextInstruction() throws {
instruction_register = memoryInterface.readByte(offset: program_counter)
let operation = InstructionTable[instruction_register]
if(operation == nil) {
@ -301,6 +306,11 @@ final class CPU: NSObject {
/* Running */
final func cpuStep() {
do {
if(breakpoints.contains(program_counter)) {
isRunning = false
NotificationCenter.default.post(name: CPUNotifications.BreakpointHit, object: nil)
return
}
try executeNextInstruction()
} catch CPUExceptions.invalidInstruction {
print("Invalid instruction at \(program_counter.asHexString())")
@ -313,13 +323,8 @@ final class CPU: NSObject {
func runCyclesBatch() {
isRunning = true
while(!outOfCycles()) {
while(!outOfCycles() && isRunning) {
cpuStep()
if (breakpoints.contains(program_counter)) {
isRunning = false
}
}
}

View File

@ -360,6 +360,9 @@
</subviews>
</view>
<connections>
<outlet property="btn_Break" destination="94S-pW-GeW" id="aal-zp-5kg"/>
<outlet property="btn_Run" destination="oRf-MK-DEX" id="Dv1-Tg-Ht7"/>
<outlet property="btn_Step" destination="HdY-Jc-lNK" id="uvQ-eY-ika"/>
<outlet property="debuggerTableView" destination="MuT-J3-VZ6" id="TMx-Do-29u"/>
<outlet property="text_CPU_A" destination="WjO-ue-iRg" id="kaI-Bh-Efs"/>
<outlet property="text_CPU_Flags" destination="ecN-Ge-1hE" id="dDw-IG-xNd"/>

View File

@ -25,6 +25,10 @@ class DebuggerViewController: NSViewController {
@IBOutlet weak var debuggerTableView: NSTableView!
@IBOutlet weak var btn_Break: NSButton!
@IBOutlet weak var btn_Step: NSButton!
@IBOutlet weak var btn_Run: NSButton!
var cpuInstance = CPU.sharedInstance
var isRunning = false
@ -74,24 +78,6 @@ class DebuggerViewController: NSViewController {
}
}
func debugRun() {
isRunning = true
cpuInstance.cycles = 0
cpuInstance.cyclesInBatch = 10000
while(!cpuInstance.outOfCycles() && isRunning) {
cpuInstance.cpuStep()
if (cpuInstance.breakpoints.contains(cpuInstance.program_counter)) {
isRunning = false
updateCPUStatusFields()
debugConsolePrint(str: "Breakpoint reached at $\(cpuInstance.program_counter.asHexString())", newline: true)
}
}
}
func queueCPUStep(queue: DispatchQueue) {
queue.async {
self.cpuInstance.cpuStep()
@ -105,17 +91,18 @@ class DebuggerViewController: NSViewController {
}
@IBAction func btn_Break(_ sender: Any) {
isRunning = false
_ = 0
NotificationCenter.default.post(name: EmulationNotifications.StopEmulation, object: nil)
btn_Step.isEnabled = true
}
@IBAction func btn_CPURun(_ sender: Any) {
debugRun()
NotificationCenter.default.post(name: EmulationNotifications.StartEmulation, object: nil)
btn_Step.isEnabled = false
}
@IBAction func btn_CPU_Restart(_ sender: Any) {
cpuInstance.performReset()
cpuInstance.program_counter = 0x400
cpuInstance.program_counter = CPU.sharedInstance.memoryInterface.readWord(offset: 0xFFFC)
debugConsolePrint(str: "CPU restarted from \(cpuInstance.program_counter)", newline: true)
}

View File

@ -1,13 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13168.3" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13178.6" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13168.3"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13178.6"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="PreferencesWindowController" customModule="FruitMachine" customModuleProvider="target">
<connections>
<outlet property="a2_Model" destination="TU9-bs-2Ym" id="9ZX-6b-QuF"/>
<outlet property="a2_Peripherals_Slot0" destination="vWt-St-7kp" id="4VF-4b-kcd"/>
<outlet property="a2_Peripherals_Slot6" destination="1CB-yF-5GW" id="zcX-Ts-Jd4"/>
<outlet property="path_ROMBasic" destination="ilU-dc-qbI" id="HXt-ut-QQs"/>
@ -39,7 +40,7 @@
</view>
</tabViewItem>
<tabViewItem label="Paths" identifier="2" id="zXY-01-Th8">
<view key="view" ambiguous="YES" id="tiQ-eh-pdD">
<view key="view" id="tiQ-eh-pdD">
<rect key="frame" x="10" y="33" width="554" height="338"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
@ -140,12 +141,12 @@
</view>
</tabViewItem>
<tabViewItem label="Apple II" identifier="" id="aVa-m9-VEl">
<view key="view" id="mjS-Jn-KXO">
<view key="view" ambiguous="YES" id="mjS-Jn-KXO">
<rect key="frame" x="10" y="33" width="554" height="338"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Vav-pa-mvK">
<rect key="frame" x="15" y="318" width="40" height="17"/>
<rect key="frame" x="15" y="260" width="40" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Slot 0" id="WlR-dZ-W72">
<font key="font" metaFont="system"/>
@ -154,7 +155,7 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Rlr-ba-8ra">
<rect key="frame" x="15" y="292" width="40" height="17"/>
<rect key="frame" x="15" y="234" width="40" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Slot 1" id="9CT-bF-2b1">
<font key="font" metaFont="system"/>
@ -163,7 +164,7 @@
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Lvh-92-Ob0">
<rect key="frame" x="59" y="286" width="200" height="26"/>
<rect key="frame" x="59" y="228" width="200" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Nothing" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="D6o-nP-s6d" id="RLd-bf-oyA">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -178,7 +179,7 @@
</popUpButtonCell>
</popUpButton>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tQA-LM-0T1">
<rect key="frame" x="59" y="260" width="200" height="26"/>
<rect key="frame" x="59" y="202" width="200" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Nothing" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="RXL-80-c5U" id="M1v-yb-ebb">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -193,7 +194,7 @@
</popUpButtonCell>
</popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="oeY-9x-3x1">
<rect key="frame" x="15" y="239" width="40" height="17"/>
<rect key="frame" x="15" y="181" width="40" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Slot 3" id="qwP-Fk-pIB">
<font key="font" metaFont="system"/>
@ -202,7 +203,7 @@
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ron-Jc-5NS">
<rect key="frame" x="59" y="233" width="200" height="26"/>
<rect key="frame" x="59" y="175" width="200" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Nothing" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="khL-Nw-Yyb" id="5Uy-Yz-oHu">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -217,7 +218,7 @@
</popUpButtonCell>
</popUpButton>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vWt-St-7kp">
<rect key="frame" x="59" y="313" width="200" height="26"/>
<rect key="frame" x="59" y="255" width="200" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Nothing" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="hE4-yk-CCz" id="SSf-AV-4XO">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -230,8 +231,22 @@
</menu>
</popUpButtonCell>
</popUpButton>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="TU9-bs-2Ym">
<rect key="frame" x="59" y="311" width="200" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Apple ][ (Original)" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="4DB-sZ-RHB" id="tYw-7u-gRo">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="H16-YD-aYe">
<items>
<menuItem title="Apple ][ (Original)" state="on" id="4DB-sZ-RHB"/>
<menuItem title="Apple ][+" id="lk3-qa-sTr"/>
</items>
</menu>
</popUpButtonCell>
</popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wql-7f-Cmb">
<rect key="frame" x="15" y="212" width="40" height="17"/>
<rect key="frame" x="15" y="154" width="40" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Slot 4" id="uVy-Wv-hRJ">
<font key="font" metaFont="system"/>
@ -240,7 +255,7 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZVS-Jk-MpZ">
<rect key="frame" x="15" y="186" width="40" height="17"/>
<rect key="frame" x="15" y="128" width="40" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Slot 5" id="ua9-zw-Mzd">
<font key="font" metaFont="system"/>
@ -249,7 +264,7 @@
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="sjp-qD-NrB">
<rect key="frame" x="59" y="180" width="200" height="26"/>
<rect key="frame" x="59" y="122" width="200" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Nothing" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="LS7-45-B1l" id="6hp-fp-PHh">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -264,7 +279,7 @@
</popUpButtonCell>
</popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nm9-Zu-F6e">
<rect key="frame" x="15" y="160" width="40" height="17"/>
<rect key="frame" x="15" y="102" width="40" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Slot 6" id="SWC-La-cqL">
<font key="font" metaFont="system"/>
@ -273,7 +288,7 @@
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1CB-yF-5GW">
<rect key="frame" x="59" y="154" width="200" height="26"/>
<rect key="frame" x="59" y="96" width="200" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Disk II" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="2jc-dw-NSC" id="bnz-0t-Peo">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -287,7 +302,7 @@
</popUpButtonCell>
</popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rtE-66-3Uw">
<rect key="frame" x="15" y="133" width="40" height="17"/>
<rect key="frame" x="15" y="75" width="40" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Slot 7" id="9oV-LI-9Pq">
<font key="font" metaFont="system"/>
@ -296,7 +311,7 @@
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="al0-aZ-uIH">
<rect key="frame" x="59" y="127" width="200" height="26"/>
<rect key="frame" x="59" y="69" width="200" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Nothing" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Nxx-1S-5RB" id="eNb-sq-3kP">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -311,7 +326,7 @@
</popUpButtonCell>
</popUpButton>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cyH-8e-Kfo">
<rect key="frame" x="59" y="207" width="200" height="26"/>
<rect key="frame" x="59" y="149" width="200" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Nothing" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="F24-4g-S0w" id="UNW-s2-DPf">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -326,7 +341,7 @@
</popUpButtonCell>
</popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xvm-ee-hrf">
<rect key="frame" x="15" y="266" width="40" height="17"/>
<rect key="frame" x="15" y="208" width="40" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Slot 2" id="IDk-eE-egh">
<font key="font" metaFont="system"/>
@ -334,6 +349,15 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bx6-PM-jSt">
<rect key="frame" x="15" y="317" width="40" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Model" id="wZ2-pR-lRr">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
</view>
</tabViewItem>

View File

@ -15,6 +15,7 @@ class PreferencesWindowController: NSWindowController {
@IBOutlet weak var path_ROMBasic: NSTextField!
/* Apple II ROM paths */
@IBOutlet weak var a2_Model: NSPopUpButton!
/* Apple II Peripherals */
@IBOutlet weak var a2_Peripherals_Slot0: NSPopUpButton!
@ -22,63 +23,59 @@ class PreferencesWindowController: NSWindowController {
let defaults = UserDefaults.standard
override func windowDidLoad() {
override func windowDidLoad() {
NotificationCenter.default.addObserver(
self,
selector: #selector(windowWillClose),
name: NSWindow.willCloseNotification,
object: nil)
setupPreferences()
super.windowDidLoad()
}
func setupDefaultsIfRequired() {
// UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
// UserDefaults.standard.synchronize()
var model = defaults.string(forKey: "a2_Model")
if(model == nil) { model = "Apple ][+" }
defaults.set(model, forKey: "a2_Model")
var slot0 = defaults.string(forKey: "a2_Peripherals_Slot0")
var slot6 = defaults.string(forKey: "a2_Peripherals_Slot6")
if(slot0 == nil) { slot0 = "Language Card (16K)" }
if(slot6 == nil) { slot6 = "Disk II" }
defaults.set(slot0, forKey: "a2_Peripherals_Slot0")
var slot6 = defaults.string(forKey: "a2_Peripherals_Slot6")
if(slot6 == nil) { slot6 = "Disk II" }
defaults.set(slot6, forKey: "a2_Peripherals_Slot6")
}
func setupPreferences() {
setupA1RomPaths()
setupA2Peripherals()
setPreference(dropdown: a2_Model, key: "a2_Model")
}
func setupA1RomPaths() {
let monitorPath = defaults.string(forKey: "path_ROMMonitor")
let characterPath = defaults.string(forKey: "path_ROMCharacter")
let basicPath = defaults.string(forKey: "path_ROMBasic")
if (monitorPath != nil) {
path_ROMMonitor.stringValue = monitorPath!
}
if (characterPath != nil) {
path_ROMCharacter.stringValue = characterPath!
}
if (basicPath != nil) {
path_ROMBasic.stringValue = basicPath!
}
setPreference(textfield: path_ROMMonitor, key: "path_ROMMonitor")
setPreference(textfield: path_ROMCharacter, key: "path_ROMCharacter")
setPreference(textfield: path_ROMBasic, key: "path_ROMBasic")
}
func setupA2Peripherals() {
let slot0 = defaults.string(forKey: "a2_Peripherals_Slot0")
if(slot0 != nil) {
a2_Peripherals_Slot6.selectItem(withTitle: slot0!)
setPreference(dropdown: a2_Peripherals_Slot0, key: "a2_Peripherals_Slot0")
setPreference(dropdown: a2_Peripherals_Slot6, key: "a2_Peripherals_Slot6")
}
func setPreference(dropdown: NSPopUpButton, key: String) {
let pref = defaults.string(forKey: key)
if(pref != nil) {
dropdown.selectItem(withTitle: pref!)
}
let slot6 = defaults.string(forKey: "a2_Peripherals_Slot6")
if(slot6 != nil) {
a2_Peripherals_Slot6.selectItem(withTitle: slot6!)
}
func setPreference(textfield: NSTextField, key: String) {
let pref = defaults.string(forKey: key)
if(pref != nil) {
textfield.stringValue = pref!
}
}
@ -91,6 +88,8 @@ class PreferencesWindowController: NSWindowController {
defaults.set(a2_Peripherals_Slot6.selectedItem?.title, forKey: "a2_Peripherals_Slot6")
defaults.synchronize()
NotificationCenter.default.post(name: EmulationNotifications.StartEmulation, object: nil)
}
override var windowNibName : NSNib.Name? {
@ -115,7 +114,7 @@ class PreferencesWindowController: NSWindowController {
@IBAction func btn_click_Character(_ sender: NSButton) {
let picker = NSOpenPanel()
picker.title = "Select your Monitor ROM (apple1.vid)"
picker.title = "Select your Character ROM (apple1.vid)"
picker.showsHiddenFiles = false
picker.canChooseFiles = true
picker.canChooseDirectories = false
@ -130,7 +129,7 @@ class PreferencesWindowController: NSWindowController {
@IBAction func btn_click_BASIC(_ sender: NSButton) {
let picker = NSOpenPanel()
picker.title = "Select your Monitor ROM (basic.bin)"
picker.title = "Select your BASIC ROM (basic.bin)"
picker.showsHiddenFiles = false
picker.canChooseFiles = true
picker.canChooseDirectories = false