diff --git a/FruitMachine.xcodeproj/project.pbxproj b/FruitMachine.xcodeproj/project.pbxproj index 137895d..4bd83a4 100644 --- a/FruitMachine.xcodeproj/project.pbxproj +++ b/FruitMachine.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 2A044E2C1F37D65A000E8085 /* LanguageCard16K.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A044E2B1F37D65A000E8085 /* LanguageCard16K.swift */; }; + 2A044E2E1F382CA9000E8085 /* AppleIIPlus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A044E2D1F382CA9000E8085 /* AppleIIPlus.swift */; }; 2A16ADBB1F33C341004A0333 /* DiskImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A16ADBA1F33C341004A0333 /* DiskImage.swift */; }; 2A2126841F2A9FA300E43DC1 /* DebuggerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A2126831F2A9FA300E43DC1 /* DebuggerWindowController.swift */; }; 2A22EBFB1F21A7A700A36A61 /* IntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A22EBFA1F21A7A700A36A61 /* IntegerExtensions.swift */; }; @@ -24,7 +25,7 @@ 2A63C23C1F32CD4800D4F4F8 /* Peripheral.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A63C23B1F32CD4800D4F4F8 /* Peripheral.swift */; }; 2A6C2D171F31216700B8DC60 /* SoftswitchOverrides.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A6C2D161F31216700B8DC60 /* SoftswitchOverrides.swift */; }; 2A6DC7E91F3045280066FE0D /* AppleIIViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A6DC7E81F3045280066FE0D /* AppleIIViewController.swift */; }; - 2A6DC7EB1F3045C90066FE0D /* EmulatedSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A6DC7EA1F3045C90066FE0D /* EmulatedSystem.swift */; }; + 2A6DC7EB1F3045C90066FE0D /* AppleIIBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A6DC7EA1F3045C90066FE0D /* AppleIIBase.swift */; }; 2A6DC7ED1F30492C0066FE0D /* ScreenDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A6DC7EC1F30492C0066FE0D /* ScreenDelegate.swift */; }; 2A6DC7F01F30495D0066FE0D /* ScreenView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A6DC7EF1F30495D0066FE0D /* ScreenView.swift */; }; 2A7665781F2F05F600135518 /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A7665761F2F05F600135518 /* PreferencesWindowController.swift */; }; @@ -58,6 +59,7 @@ /* Begin PBXFileReference section */ 2A044E2B1F37D65A000E8085 /* LanguageCard16K.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageCard16K.swift; sourceTree = ""; }; + 2A044E2D1F382CA9000E8085 /* AppleIIPlus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleIIPlus.swift; sourceTree = ""; }; 2A16ADBA1F33C341004A0333 /* DiskImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiskImage.swift; sourceTree = ""; }; 2A2126831F2A9FA300E43DC1 /* DebuggerWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebuggerWindowController.swift; sourceTree = ""; }; 2A22EBFA1F21A7A700A36A61 /* IntegerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegerExtensions.swift; sourceTree = ""; }; @@ -74,7 +76,7 @@ 2A63C23B1F32CD4800D4F4F8 /* Peripheral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Peripheral.swift; sourceTree = ""; }; 2A6C2D161F31216700B8DC60 /* SoftswitchOverrides.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoftswitchOverrides.swift; sourceTree = ""; }; 2A6DC7E81F3045280066FE0D /* AppleIIViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleIIViewController.swift; sourceTree = ""; }; - 2A6DC7EA1F3045C90066FE0D /* EmulatedSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmulatedSystem.swift; sourceTree = ""; }; + 2A6DC7EA1F3045C90066FE0D /* AppleIIBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleIIBase.swift; sourceTree = ""; }; 2A6DC7EC1F30492C0066FE0D /* ScreenDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenDelegate.swift; sourceTree = ""; }; 2A6DC7EF1F30495D0066FE0D /* ScreenView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenView.swift; sourceTree = ""; }; 2A7665761F2F05F600135518 /* PreferencesWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesWindowController.swift; sourceTree = ""; }; @@ -164,7 +166,6 @@ 2AE3BB981F32D24D00C11060 /* Memory */, 2A6DC7E71F3044080066FE0D /* Peripherals */, 2A6DC7E61F3043E10066FE0D /* Video */, - 2A6DC7EA1F3045C90066FE0D /* EmulatedSystem.swift */, ); path = Common; sourceTree = ""; @@ -215,7 +216,9 @@ children = ( 2A63C2381F32CCDB00D4F4F8 /* Peripherals */, 2A6DC7EE1F30492E0066FE0D /* Video */, + 2A6DC7EA1F3045C90066FE0D /* AppleIIBase.swift */, 2AB6CACC1F3041A200DECAC0 /* AppleII.swift */, + 2A044E2D1F382CA9000E8085 /* AppleIIPlus.swift */, 2A86FB961F316CB500AD0C68 /* KeyboardController.swift */, 2A6C2D161F31216700B8DC60 /* SoftswitchOverrides.swift */, ); @@ -408,6 +411,7 @@ 2AD458E31F20661300F05121 /* CPUInstructions.swift in Sources */, 2A5C5BBC1F304C3A00ED351D /* A2CharacterGenerator.swift in Sources */, 2AD458D01F205EB700F05121 /* DebuggerViewController.swift in Sources */, + 2A044E2E1F382CA9000E8085 /* AppleIIPlus.swift in Sources */, 2A7665781F2F05F600135518 /* PreferencesWindowController.swift in Sources */, 2AA8B5FC1F2A8EAD002B350F /* Terminal.swift in Sources */, 2A5BC51E1F29A4C3008C03BE /* AppleIBitmapDisplay.swift in Sources */, @@ -421,7 +425,7 @@ 2AD6D5841F26E6BF008F3CF5 /* DebuggerCommands.swift in Sources */, 2AE3BB971F32CEB100C11060 /* ROMManager.swift in Sources */, 2AE5BA041F23DE4400FAA343 /* Disassembly.swift in Sources */, - 2A6DC7EB1F3045C90066FE0D /* EmulatedSystem.swift in Sources */, + 2A6DC7EB1F3045C90066FE0D /* AppleIIBase.swift in Sources */, 2A86FB971F316CB500AD0C68 /* KeyboardController.swift in Sources */, 2A63C2351F32C4F700D4F4F8 /* LoresMode.swift in Sources */, 2AE42E3A1F28628300C4900E /* AppleIViewController.swift in Sources */, @@ -491,7 +495,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -509,7 +513,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.12; - MTL_ENABLE_DEBUG_INFO = YES; + MTL_ENABLE_DEBUG_INFO = NO; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; @@ -553,7 +557,9 @@ ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = s; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -572,6 +578,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_USE_OPTIMIZATION_PROFILE = YES; CODE_SIGN_ENTITLEMENTS = FruitMachine/FruitMachine.entitlements; COMBINE_HIDPI_IMAGES = YES; GENERATE_PROFILING_CODE = YES; @@ -588,6 +595,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_USE_OPTIMIZATION_PROFILE = YES; CODE_SIGN_ENTITLEMENTS = FruitMachine/FruitMachine.entitlements; COMBINE_HIDPI_IMAGES = YES; GENERATE_PROFILING_CODE = YES; diff --git a/FruitMachine.xcodeproj/xcuserdata/luigi.xcuserdatad/xcschemes/xcschememanagement.plist b/FruitMachine.xcodeproj/xcuserdata/luigi.xcuserdatad/xcschemes/xcschememanagement.plist index 3b1ef1a..4c4af6a 100644 --- a/FruitMachine.xcodeproj/xcuserdata/luigi.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/FruitMachine.xcodeproj/xcuserdata/luigi.xcuserdatad/xcschemes/xcschememanagement.plist @@ -4,6 +4,11 @@ SchemeUserState + FruitMachine Release.xcscheme + + orderHint + 1 + FruitMachine.xcscheme orderHint diff --git a/FruitMachine/AppleI/AppleI.swift b/FruitMachine/AppleI/AppleI.swift index 8a29f90..7740e68 100644 --- a/FruitMachine/AppleI/AppleI.swift +++ b/FruitMachine/AppleI/AppleI.swift @@ -8,7 +8,7 @@ import Cocoa -class AppleI: NSObject, EmulatedSystem { +class AppleI: NSObject { var CPU_FREQUENCY: Double var FRAMES_PER_SECOND: Double var CYCLES_PER_BATCH: Int diff --git a/FruitMachine/AppleII/AppleII.swift b/FruitMachine/AppleII/AppleII.swift index 1818ba7..6bc0bc3 100644 --- a/FruitMachine/AppleII/AppleII.swift +++ b/FruitMachine/AppleII/AppleII.swift @@ -8,80 +8,35 @@ import Cocoa -final class AppleII: NSObject, EmulatedSystem { - static let sharedInstance = AppleII(cpuFrequency: (14.31818 / 7 / 2) * 1000000, fps: 60.0) - - var frameCounter: Int = 0 - - let cg = A2CharacterGenerator(romPath: "/Users/luigi/apple2/a2.chr"); - let keyboardController = KeyboardController() - var videoSoftswitches = VideoSoftswitches() - var videoMode: VideoMode - - //Peripherals - var backplane = [Int: Peripheral?]() - - var CPU_FREQUENCY: Double - var FRAMES_PER_SECOND: Double - var CYCLES_PER_BATCH: Int - - let emulatorViewDelegate = AppleII.ScreenDelegate() - let emulatorView = AppleII.ScreenView(frame: NSMakeRect(0, 16, 560, 384)) - let emuScreenLayer = CALayer() +class AppleII: AppleIIBase { + static let sharedInstance = AppleII(cpuFrequency: 1000000, fps: 60.0) required init(cpuFrequency: Double, fps: Double) { - CPU_FREQUENCY = cpuFrequency - FRAMES_PER_SECOND = fps - CYCLES_PER_BATCH = Int(cpuFrequency / fps) + super.init(cpuFrequency: cpuFrequency, + fps: fps, + delegate: ScreenDelegate(), + view: ScreenView(frame: NSMakeRect(0, 16, 560, 384))) - videoMode = .Text - - for i in 0...7 { - backplane[i] = nil - } - - super.init() - - setupMemory(ramConfig: .fortyeightK) - setupPeripherals() loadROMs() - - emuScreenLayer.shouldRasterize = true - emuScreenLayer.delegate = emulatorViewDelegate - emuScreenLayer.frame = emulatorView.bounds - - emulatorView.wantsLayer = true - - //emuScreenLayer.setNeedsDisplay() - emulatorView.layer?.addSublayer(emuScreenLayer) - - installOverrides() - doReset() } - func doReset() { - videoSoftswitches.reset() - videoMode = .Text - CPU.sharedInstance.performReset() + required init(cpuFrequency: Double, fps: Double, delegate: ScreenDelegate, view: ScreenView) { + fatalError("init(cpuFrequency:fps:delegate:view:) has not been implemented") } - func loadROMs() { + override func loadROMs() { + + /* Integer BASIC */ CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/341-0001-00.e0", offset: 0xE000, length: 0x800) CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/341-0002-00.e8", offset: 0xE800, length: 0x800) CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/341-0003-00.f0", offset: 0xF000, length: 0x800) - //Hardware handles this, really. - if(backplane[0] is LanguageCard16K) { - //Language Card ROM - CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/341-0020-00.f8", offset: 0xF800, length: 0x800) - } else { - //Integer BASIC ROM - CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/341-0004-00.f8", offset: 0xF800, length: 0x800) - } + /* Monitor */ + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/341-0004-00.f8", offset: 0xF800, length: 0x800) } - func installOverrides() { + override func installOverrides() { for (_, peripheral) in backplane { if(peripheral != nil) { peripheral!.installOverrides() @@ -111,124 +66,6 @@ final class AppleII: NSObject, EmulatedSystem { CPU.sharedInstance.memoryInterface.write_overrides.append(SoftswitchOverrides.switchC057W) } - func runFrame() { - frameCounter = (frameCounter + 1) % 60 - if(frameCounter % 15) == 0 { - emulatorViewDelegate.flashIsInverse = !emulatorViewDelegate.flashIsInverse - } - - CPU.sharedInstance.cycles = 0 - CPU.sharedInstance.cyclesInBatch = CYCLES_PER_BATCH - CPU.sharedInstance.runCyclesBatch() - - //update the video display - CVPixelBufferLockBaseAddress(emulatorViewDelegate.pixels!, CVPixelBufferLockFlags(rawValue: 0)) - let pixelBase = CVPixelBufferGetBaseAddress(emulatorViewDelegate.pixels!) - let buf = pixelBase?.assumingMemoryBound(to: BitmapPixelsLE555.PixelData.self) - - videoMode = getCurrentVideoMode(switches: videoSoftswitches) - - if(videoMode == .Text) - { - //Text mode: Get character codes from $0400-$07FF - putGlyphs(buffer: buf!, start: 0x400, end: 0x7F8) - } - else if(videoMode == .Lores) - { - putLoresPixels(buffer: buf!, start: 0x400, end: 0x7F8) - } - else if(videoMode == .MixedLores) { - //Draw the lores pixel rows. - putLoresPixels(buffer: buf!, start: 0x400, end: 0x650) - putLoresPixels(buffer: buf!, start: 0x680, end: 0x6A8) - putLoresPixels(buffer: buf!, start: 0x700, end: 0x728) - putLoresPixels(buffer: buf!, start: 0x780, end: 0x7A8) - putLoresPixels(buffer: buf!, start: 0x6A8, end: 0x6D0) - putLoresPixels(buffer: buf!, start: 0x728, end: 0x750) - putLoresPixels(buffer: buf!, start: 0x7A8, end: 0x7D0) - - //Draw the bottom 4 text rows. - putGlyphs(buffer: buf!, start: 0x650, end: 0x678) - putGlyphs(buffer: buf!, start: 0x6D0, end: 0x6F8) - putGlyphs(buffer: buf!, start: 0x750, end: 0x778) - putGlyphs(buffer: buf!, start: 0x7D0, end: 0x7F8) - } else { - print("Unimplemented video mode!") - } - - - CVPixelBufferUnlockBaseAddress(emulatorViewDelegate.pixels!, CVPixelBufferLockFlags(rawValue: 0)) - emulatorView.setNeedsDisplay(emulatorView.frame) - } - - func putLoresPixels(buffer: UnsafeMutablePointer, start: UInt16, end: UInt16) { - for address in start ..< end { - let pixelData = CPU.sharedInstance.memoryInterface.readByte(offset: UInt16(address), bypassOverrides: true) - - LoresMode.putLoresPixel(buffer: buffer, - pixel: pixelData, - address: UInt16(address)) - } - } - - func putGlyphs(buffer: UnsafeMutablePointer, start: UInt16, end: UInt16) { - for address in start ... end { - let charCode = CPU.sharedInstance.memoryInterface.readByte(offset: UInt16(address), bypassOverrides: true) - - TextMode.putGlyph(buffer: buffer, - glyph: cg.glyphs[Int(charCode & 0x3F)], - attributes: charCode & 0xC0, //d6 and d7 - pixelPosition: VideoHelpers.getPixelOffset(memoryOffset: Int(address - 0x400))) - } - } - - enum MemoryConfiguration { - case fourK - case sixteenK - case fortyeightK - } - - func setupMemory(ramConfig: MemoryConfiguration) { - let ramPages: Int - - switch ramConfig { - case .fourK: - ramPages = 4096 / 256 - case .sixteenK: - ramPages = 16384 / 256 - case .fortyeightK: - ramPages = 49152 / 256 - } - - for page in 0 ..< ramPages { - CPU.sharedInstance.memoryInterface.pages[page] = MemoryInterface.pageMode.rw //RAM - } - for page in ramPages ..< 192 { - CPU.sharedInstance.memoryInterface.pages[page] = MemoryInterface.pageMode.null //not connected - } - for page in 224 ..< 256 { - CPU.sharedInstance.memoryInterface.pages[page] = MemoryInterface.pageMode.ro //ROM - } - } - - func setupPeripherals() { - let defaults = UserDefaults.standard - - let slot0 = defaults.string(forKey: "a2_Peripherals_Slot0") - if(slot0 == "Language Card (16K)") { - backplane[0] = LanguageCard16K(slot: 0, romPath: "/Users/luigi/apple2/341-0020-00.f8") - } - - let slot6 = defaults.string(forKey: "a2_Peripherals_Slot6") - if(slot6 == "Disk II") { - backplane[6] = DiskII(slot: 6, romPath: "/Users/luigi/apple2/341-0027-a.p5") - - let drive = backplane[6]! as! DiskII - drive.attachDiskImage(imagePath: "/Users/luigi/apple2/Apex II - Apple II Diagnostic (v4.7-1986).DSK") - //drive.attachDiskImage(imagePath: "/Users/luigi/apple2/clean332sysmas.do") - } - } - @objc func debuggerBreak() { } diff --git a/FruitMachine/AppleII/AppleIIPlus.swift b/FruitMachine/AppleII/AppleIIPlus.swift new file mode 100644 index 0000000..bd5d362 --- /dev/null +++ b/FruitMachine/AppleII/AppleIIPlus.swift @@ -0,0 +1,69 @@ +// +// AppleIIPlus.swift +// FruitMachine +// +// Created by Christopher Rohl on 8/7/17. +// Copyright © 2017 Christopher Rohl. All rights reserved. +// + +import Cocoa + +class AppleIIPlus: AppleIIBase { + static let sharedInstance = AppleIIPlus(cpuFrequency: 1000000, fps: 60.0) + + required init(cpuFrequency: Double, fps: Double) { + super.init(cpuFrequency: cpuFrequency, + fps: fps, + delegate: ScreenDelegate(), + view: ScreenView(frame: NSMakeRect(0, 16, 560, 384))) + + loadROMs() + doReset() + } + + required init(cpuFrequency: Double, fps: Double, delegate: ScreenDelegate, view: ScreenView) { + fatalError("init(cpuFrequency:fps:delegate:view:) has not been implemented") + } + + override func loadROMs() { + //Applesoft BASIC + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2p/341-0011.d0", offset: 0xD000, length: 0x800) + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2p/341-0012.d8", offset: 0xD800, length: 0x800) + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2p/341-0013.e0", offset: 0xE000, length: 0x800) + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2p/341-0014.e8", offset: 0xE800, length: 0x800) + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2p/341-0015.f0", offset: 0xF000, length: 0x800) + + //Monitor + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2p/341-0020-00.f8", offset: 0xF800, length: 0x800) + } + + override func installOverrides() { + for (_, peripheral) in backplane { + if(peripheral != nil) { + peripheral!.installOverrides() + } + } + + CPU.sharedInstance.memoryInterface.read_overrides.append(SoftswitchOverrides.readKeyboard) + CPU.sharedInstance.memoryInterface.read_overrides.append(SoftswitchOverrides.clearKeypressStrobeR) + CPU.sharedInstance.memoryInterface.write_overrides.append(SoftswitchOverrides.clearKeypressStrobeW) + + CPU.sharedInstance.memoryInterface.read_overrides.append(SoftswitchOverrides.switchC050R) + CPU.sharedInstance.memoryInterface.read_overrides.append(SoftswitchOverrides.switchC051R) + CPU.sharedInstance.memoryInterface.read_overrides.append(SoftswitchOverrides.switchC052R) + CPU.sharedInstance.memoryInterface.read_overrides.append(SoftswitchOverrides.switchC053R) + CPU.sharedInstance.memoryInterface.read_overrides.append(SoftswitchOverrides.switchC054R) + CPU.sharedInstance.memoryInterface.read_overrides.append(SoftswitchOverrides.switchC055R) + CPU.sharedInstance.memoryInterface.read_overrides.append(SoftswitchOverrides.switchC056R) + CPU.sharedInstance.memoryInterface.read_overrides.append(SoftswitchOverrides.switchC057R) + + CPU.sharedInstance.memoryInterface.write_overrides.append(SoftswitchOverrides.switchC050W) + CPU.sharedInstance.memoryInterface.write_overrides.append(SoftswitchOverrides.switchC051W) + CPU.sharedInstance.memoryInterface.write_overrides.append(SoftswitchOverrides.switchC052W) + CPU.sharedInstance.memoryInterface.write_overrides.append(SoftswitchOverrides.switchC053W) + CPU.sharedInstance.memoryInterface.write_overrides.append(SoftswitchOverrides.switchC054W) + CPU.sharedInstance.memoryInterface.write_overrides.append(SoftswitchOverrides.switchC055W) + CPU.sharedInstance.memoryInterface.write_overrides.append(SoftswitchOverrides.switchC056W) + CPU.sharedInstance.memoryInterface.write_overrides.append(SoftswitchOverrides.switchC057W) + } +} diff --git a/FruitMachine/AppleII/SoftswitchOverrides.swift b/FruitMachine/AppleII/SoftswitchOverrides.swift index 6449ee9..249c34a 100644 --- a/FruitMachine/AppleII/SoftswitchOverrides.swift +++ b/FruitMachine/AppleII/SoftswitchOverrides.swift @@ -8,7 +8,7 @@ import Cocoa -extension AppleII { +extension AppleIIBase { class SoftswitchOverrides: NSObject { /* Keyboard port */ @@ -17,7 +17,7 @@ extension AppleII { //let b = CPU.sharedInstance.memoryInterface.readByte(offset: 0xC000, bypassOverrides: true) //CPU.sharedInstance.memoryInterface.writeByte(offset: 0xC000, value: b) //return b - return AppleII.sharedInstance.keyboardController.KEYBOARD + return EmulatedSystemInstance!.keyboardController.KEYBOARD } static let clearKeypressStrobeR = ReadOverride(start: 0xC010, end: 0xC010, readAnyway: false, action: SoftswitchOverrides.actionClearKeypressStrobe) @@ -30,9 +30,9 @@ extension AppleII { //CPU.sharedInstance.memoryInterface.writeByte(offset: 0xC010, value: b & 0x7F, bypassOverrides: true) //return b - let b = AppleII.sharedInstance.keyboardController.KEYBOARD - AppleII.sharedInstance.keyboardController.KEYBOARD = b & 0x7F - AppleII.sharedInstance.keyboardController.STROBE = b & 0x7F + let b = EmulatedSystemInstance!.keyboardController.KEYBOARD + EmulatedSystemInstance!.keyboardController.KEYBOARD = b & 0x7F + EmulatedSystemInstance!.keyboardController.STROBE = b & 0x7F return b } @@ -40,56 +40,56 @@ extension AppleII { static let switchC050R = ReadOverride(start: 0xC050, end: 0xC050, readAnyway: false, action: SoftswitchOverrides.actionSwitchC050) static let switchC050W = WriteOverride(start: 0xC050, end: 0xC050, writeAnyway: false, action: SoftswitchOverrides.actionSwitchC050) static func actionSwitchC050(dummy: AnyObject, address: UInt16, byte: UInt8?) -> UInt8? { - AppleII.sharedInstance.videoSoftswitches.TEXT_MODE = false + EmulatedSystemInstance!.videoSoftswitches.TEXT_MODE = false return 0x00 } static let switchC051R = ReadOverride(start: 0xC051, end: 0xC051, readAnyway: false, action: SoftswitchOverrides.actionSwitchC051) static let switchC051W = WriteOverride(start: 0xC051, end: 0xC051, writeAnyway: false, action: SoftswitchOverrides.actionSwitchC051) static func actionSwitchC051(dummy: AnyObject, address: UInt16, byte: UInt8?) -> UInt8? { - AppleII.sharedInstance.videoSoftswitches.TEXT_MODE = true + EmulatedSystemInstance!.videoSoftswitches.TEXT_MODE = true return 0x00 } static let switchC052R = ReadOverride(start: 0xC052, end: 0xC052, readAnyway: false, action: SoftswitchOverrides.actionSwitchC052) static let switchC052W = WriteOverride(start: 0xC052, end: 0xC052, writeAnyway: false, action: SoftswitchOverrides.actionSwitchC052) static func actionSwitchC052(dummy: AnyObject, address: UInt16, byte: UInt8?) -> UInt8? { - AppleII.sharedInstance.videoSoftswitches.MIX_MODE = false + EmulatedSystemInstance!.videoSoftswitches.MIX_MODE = false return 0x00 } static let switchC053R = ReadOverride(start: 0xC053, end: 0xC053, readAnyway: false, action: SoftswitchOverrides.actionSwitchC053) static let switchC053W = WriteOverride(start: 0xC053, end: 0xC053, writeAnyway: false, action: SoftswitchOverrides.actionSwitchC053) static func actionSwitchC053(dummy: AnyObject, address: UInt16, byte: UInt8?) -> UInt8? { - AppleII.sharedInstance.videoSoftswitches.MIX_MODE = true + EmulatedSystemInstance!.videoSoftswitches.MIX_MODE = true return 0x00 } static let switchC054R = ReadOverride(start: 0xC054, end: 0xC054, readAnyway: false, action: SoftswitchOverrides.actionSwitchC054) static let switchC054W = WriteOverride(start: 0xC054, end: 0xC054, writeAnyway: false, action: SoftswitchOverrides.actionSwitchC054) static func actionSwitchC054(dummy: AnyObject, address: UInt16, byte: UInt8?) -> UInt8? { - AppleII.sharedInstance.videoSoftswitches.PAGE_2 = false + EmulatedSystemInstance!.videoSoftswitches.PAGE_2 = false return 0x00 } static let switchC055R = ReadOverride(start: 0xC055, end: 0xC055, readAnyway: false, action: SoftswitchOverrides.actionSwitchC055) static let switchC055W = WriteOverride(start: 0xC055, end: 0xC055, writeAnyway: false, action: SoftswitchOverrides.actionSwitchC055) static func actionSwitchC055(dummy: AnyObject, address: UInt16, byte: UInt8?) -> UInt8? { - AppleII.sharedInstance.videoSoftswitches.MIX_MODE = true + EmulatedSystemInstance!.videoSoftswitches.MIX_MODE = true return 0x00 } static let switchC056R = ReadOverride(start: 0xC056, end: 0xC056, readAnyway: false, action: SoftswitchOverrides.actionSwitchC056) static let switchC056W = WriteOverride(start: 0xC056, end: 0xC056, writeAnyway: false, action: SoftswitchOverrides.actionSwitchC056) static func actionSwitchC056(dummy: AnyObject, address: UInt16, byte: UInt8?) -> UInt8? { - AppleII.sharedInstance.videoSoftswitches.HIRES_MODE = false + EmulatedSystemInstance!.videoSoftswitches.HIRES_MODE = false return 0x00 } static let switchC057R = ReadOverride(start: 0xC057, end: 0xC057, readAnyway: false, action: SoftswitchOverrides.actionSwitchC057) static let switchC057W = WriteOverride(start: 0xC057, end: 0xC057, writeAnyway: false, action: SoftswitchOverrides.actionSwitchC057) static func actionSwitchC057(dummy: AnyObject, address: UInt16, byte: UInt8?) -> UInt8? { - AppleII.sharedInstance.videoSoftswitches.HIRES_MODE = true + EmulatedSystemInstance!.videoSoftswitches.HIRES_MODE = true return 0x00 } } diff --git a/FruitMachine/AppleII/Video/A2CharacterGenerator.swift b/FruitMachine/AppleII/Video/A2CharacterGenerator.swift index 864c561..a13bcf8 100644 --- a/FruitMachine/AppleII/Video/A2CharacterGenerator.swift +++ b/FruitMachine/AppleII/Video/A2CharacterGenerator.swift @@ -7,11 +7,10 @@ // import Cocoa +//The Apple II character generator is an AY-5-3600. + +extension AppleIIBase { -extension AppleII { - - //The Apple II character generator is a clone of the Signetics 2513 from the Apple I. - class A2CharacterGenerator: NSObject, HasROM { static let CHAR_WIDTH = 5 static let CHAR_HEIGHT = 8 diff --git a/FruitMachine/AppleII/Video/Modes/LoresMode.swift b/FruitMachine/AppleII/Video/Modes/LoresMode.swift index 1dd6dfc..bb16b5d 100644 --- a/FruitMachine/AppleII/Video/Modes/LoresMode.swift +++ b/FruitMachine/AppleII/Video/Modes/LoresMode.swift @@ -8,7 +8,7 @@ import Cocoa -extension AppleII { +extension AppleIIBase { class LoresMode: NSObject { static func putLoresPixel(buffer: UnsafeMutablePointer?, pixel: UInt8, address: UInt16) { @@ -25,7 +25,7 @@ extension AppleII { let colorLo = LoresColors.getColor(index: pixelNybbleLo) //One lores pixel is 7px wide and 4px tall for a resolution of 40x48. - let baseOffset = AppleII.sharedInstance.emulatorViewDelegate.scanlineOffsets[Int(pixelPosition.y)] + Int(pixelPosition.x) + let baseOffset = EmulatedSystemInstance!.emulatorViewDelegate.scanlineOffsets[Int(pixelPosition.y)] + Int(pixelPosition.x) for charY in 0..<5 { let offsetHi = baseOffset + (AppleII.ScreenDelegate.PIXEL_WIDTH * charY) diff --git a/FruitMachine/AppleII/Video/Modes/TextMode.swift b/FruitMachine/AppleII/Video/Modes/TextMode.swift index b41ac24..4163711 100644 --- a/FruitMachine/AppleII/Video/Modes/TextMode.swift +++ b/FruitMachine/AppleII/Video/Modes/TextMode.swift @@ -8,7 +8,7 @@ import Cocoa -extension AppleII { +extension AppleIIBase { class TextMode: NSObject { static func putGlyph(buffer: UnsafeMutablePointer?, glyph: Glyph, attributes: UInt8, pixelPosition: CGPoint) { @@ -25,7 +25,7 @@ extension AppleII { } //Calculate the offset to reach the desired position. - let baseOffset = AppleII.sharedInstance.emulatorViewDelegate.scanlineOffsets[Int(pixelPosition.y)] + Int(pixelPosition.x) + let baseOffset = EmulatedSystemInstance!.emulatorViewDelegate.scanlineOffsets[Int(pixelPosition.y)] + Int(pixelPosition.x) for charY in 0.. CGPoint { return CGPoint(x: charCellX * 7, y: charCellY * 8) diff --git a/FruitMachine/AppleIIViewController.swift b/FruitMachine/AppleIIViewController.swift index feeef69..d627858 100644 --- a/FruitMachine/AppleIIViewController.swift +++ b/FruitMachine/AppleIIViewController.swift @@ -8,12 +8,10 @@ import Cocoa -class AppleIIViewController: NSViewController { - +class AppleIIViewController: NSViewController { @IBOutlet weak var lbl_Drive1: NSTextField! @IBOutlet weak var lbl_Drive2: NSTextField! - let computer = AppleII.sharedInstance var debuggerWindowController: DebuggerWindowController! var preferencesWindowController: PreferencesWindowController! @@ -23,9 +21,10 @@ class AppleIIViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() // Do view setup here. + EmulatedSystemInstance = AppleII.sharedInstance preferencesWindowController = PreferencesWindowController() - self.view.addSubview(computer.emulatorView) + self.view.addSubview(EmulatedSystemInstance!.emulatorView) preferencesWindowController.setupDefaultsIfRequired() setupDriveNotifications() @@ -39,7 +38,7 @@ class AppleIIViewController: NSViewController { } @objc func runEmulation() { - computer.runFrame() + EmulatedSystemInstance!.runFrame() if(!CPU.sharedInstance.isRunning) { self.frameTimer?.invalidate() } @@ -62,7 +61,7 @@ class AppleIIViewController: NSViewController { } @IBAction func doReset(_ sender: Any) { - computer.doReset() + EmulatedSystemInstance!.doReset() } override func keyDown(with event: NSEvent) { @@ -72,9 +71,9 @@ class AppleIIViewController: NSViewController { let c = returnChar(theEvent: event) if(event.keyCode == leftArrowKeyCode) { - computer.keyboardController.KEYBOARD = UInt8((0x08 | 0x80) & 0x000000FF) + EmulatedSystemInstance!.keyboardController.KEYBOARD = UInt8((0x08 | 0x80) & 0x000000FF) } else if(event.keyCode == rightArrowKeyCode) { - computer.keyboardController.KEYBOARD = UInt8((0x15 | 0x80) & 0x000000FF) + EmulatedSystemInstance!.keyboardController.KEYBOARD = UInt8((0x15 | 0x80) & 0x000000FF) } guard let ascii32 = c?.asciiValue else { @@ -82,7 +81,7 @@ class AppleIIViewController: NSViewController { } //Set the keyboard input register accordingly. Set b7 so the OS knows there's a keypress waiting - computer.keyboardController.KEYBOARD = UInt8((ascii32 | 0x80) & 0x000000FF) + EmulatedSystemInstance!.keyboardController.KEYBOARD = UInt8((ascii32 | 0x80) & 0x000000FF) } private func returnChar(theEvent: NSEvent) -> Character?{ diff --git a/FruitMachine/Common/EmulatedSystem.swift b/FruitMachine/Common/EmulatedSystem.swift deleted file mode 100644 index 9513863..0000000 --- a/FruitMachine/Common/EmulatedSystem.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// EmulatedSystem.swift -// FruitMachine -// -// Created by Christopher Rohl on 8/1/17. -// Copyright © 2017 Christopher Rohl. All rights reserved. -// - -import Cocoa - -protocol EmulatedSystem { - var CPU_FREQUENCY: Double { get } - var FRAMES_PER_SECOND: Double { get } - var CYCLES_PER_BATCH: Int { get } - - init(cpuFrequency: Double, fps: Double) - func installOverrides() -} diff --git a/FruitMachine/FruitMachine.storyboard b/FruitMachine/FruitMachine.storyboard index 50d5192..63da9f2 100644 --- a/FruitMachine/FruitMachine.storyboard +++ b/FruitMachine/FruitMachine.storyboard @@ -188,19 +188,19 @@ - + - - + + - + - - + +