diff --git a/FruitMachine.xcodeproj/project.pbxproj b/FruitMachine.xcodeproj/project.pbxproj index 7f92441..cc93e21 100644 --- a/FruitMachine.xcodeproj/project.pbxproj +++ b/FruitMachine.xcodeproj/project.pbxproj @@ -48,6 +48,7 @@ 2AD458E31F20661300F05121 /* CPUInstructions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD458E21F20661300F05121 /* CPUInstructions.swift */; }; 2AD458E51F2070DF00F05121 /* Opcodes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD458E41F2070DF00F05121 /* Opcodes.swift */; }; 2AD6D5841F26E6BF008F3CF5 /* DebuggerCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD6D5831F26E6BF008F3CF5 /* DebuggerCommands.swift */; }; + 2ADBE6BA1F400821005BF2B1 /* AppleIIe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ADBE6B91F400821005BF2B1 /* AppleIIe.swift */; }; 2AE3BB971F32CEB100C11060 /* ROMManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE3BB961F32CEB100C11060 /* ROMManager.swift */; }; 2AE42E081F2850F400C4900E /* ReadOverride.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE42E071F2850F400C4900E /* ReadOverride.swift */; }; 2AE42E0A1F28521E00C4900E /* WriteOverride.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE42E091F28521E00C4900E /* WriteOverride.swift */; }; @@ -104,6 +105,7 @@ 2AD458E21F20661300F05121 /* CPUInstructions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CPUInstructions.swift; sourceTree = ""; }; 2AD458E41F2070DF00F05121 /* Opcodes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Opcodes.swift; sourceTree = ""; }; 2AD6D5831F26E6BF008F3CF5 /* DebuggerCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebuggerCommands.swift; sourceTree = ""; }; + 2ADBE6B91F400821005BF2B1 /* AppleIIe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleIIe.swift; sourceTree = ""; }; 2AE3BB961F32CEB100C11060 /* ROMManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ROMManager.swift; sourceTree = ""; }; 2AE42E071F2850F400C4900E /* ReadOverride.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadOverride.swift; sourceTree = ""; }; 2AE42E091F28521E00C4900E /* WriteOverride.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WriteOverride.swift; sourceTree = ""; }; @@ -219,11 +221,10 @@ 2AB6CAC71F30407200DECAC0 /* AppleII */ = { isa = PBXGroup; children = ( + 2ADBE6B81F4007E5005BF2B1 /* Models */, 2A63C2381F32CCDB00D4F4F8 /* Peripherals */, 2A6DC7EE1F30492E0066FE0D /* Video */, 2A6DC7EA1F3045C90066FE0D /* AppleIIBase.swift */, - 2AB6CACC1F3041A200DECAC0 /* AppleII.swift */, - 2A044E2D1F382CA9000E8085 /* AppleIIPlus.swift */, 2A86FB961F316CB500AD0C68 /* KeyboardController.swift */, 2A6C2D161F31216700B8DC60 /* SoftswitchOverrides.swift */, ); @@ -279,6 +280,16 @@ path = M6502; sourceTree = ""; }; + 2ADBE6B81F4007E5005BF2B1 /* Models */ = { + isa = PBXGroup; + children = ( + 2AB6CACC1F3041A200DECAC0 /* AppleII.swift */, + 2A044E2D1F382CA9000E8085 /* AppleIIPlus.swift */, + 2ADBE6B91F400821005BF2B1 /* AppleIIe.swift */, + ); + path = Models; + sourceTree = ""; + }; 2AE3BB981F32D24D00C11060 /* Memory */ = { isa = PBXGroup; children = ( @@ -414,6 +425,7 @@ 2A6C2D171F31216700B8DC60 /* SoftswitchOverrides.swift in Sources */, 2A5C5BBE1F304D4B00ED351D /* Glyph.swift in Sources */, 2A2126841F2A9FA300E43DC1 /* DebuggerWindowController.swift in Sources */, + 2ADBE6BA1F400821005BF2B1 /* AppleIIe.swift in Sources */, 2AD458E31F20661300F05121 /* CPUInstructions.swift in Sources */, 2A5C5BBC1F304C3A00ED351D /* A2CharacterGenerator.swift in Sources */, 2AD458D01F205EB700F05121 /* DebuggerViewController.swift in Sources */, @@ -509,7 +521,7 @@ GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; + GCC_OPTIMIZATION_LEVEL = 3; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", @@ -567,7 +579,7 @@ GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; + GCC_OPTIMIZATION_LEVEL = 3; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; diff --git a/FruitMachine/AppleII/AppleIIBase.swift b/FruitMachine/AppleII/AppleIIBase.swift index b260dfb..878f05e 100644 --- a/FruitMachine/AppleII/AppleIIBase.swift +++ b/FruitMachine/AppleII/AppleIIBase.swift @@ -12,8 +12,10 @@ protocol EmulatedSystem { var CPU_FREQUENCY: Double { get } var FRAMES_PER_SECOND: Double { get } var CYCLES_PER_BATCH: Int { get } + var cg: AppleIIBase.A2CharacterGenerator { get } - init(cpuFrequency: Double, fps: Double, delegate: AppleIIBase.ScreenDelegate, view: AppleIIBase.ScreenView) + init(cpuFrequency: Double, fps: Double, delegate: AppleIIBase.ScreenDelegate, view: AppleIIBase.ScreenView, chargen: AppleIIBase.A2CharacterGenerator + ) func installOverrides() func loadROMs() } @@ -30,21 +32,25 @@ class AppleIIBase: NSObject, EmulatedSystem { var FRAMES_PER_SECOND: Double var CYCLES_PER_BATCH: Int + let cg: A2CharacterGenerator + var videoSoftswitches = VideoSoftswitches() var videoMode: VideoMode = .Text - let cg = A2CharacterGenerator(romPath: "/Users/luigi/apple2/a2.chr"); + //let cg = A2CharacterGenerator(romPath: "/Users/luigi/apple2/apple2/a2.chr"); let keyboardController = KeyboardController() var emulatorViewDelegate: ScreenDelegate var emulatorView: ScreenView var emuScreenLayer = CALayer() - required init(cpuFrequency: Double, fps: Double, delegate: ScreenDelegate, view: ScreenView) { + required init(cpuFrequency: Double, fps: Double, delegate: ScreenDelegate, view: ScreenView, chargen: A2CharacterGenerator) { CPU_FREQUENCY = cpuFrequency FRAMES_PER_SECOND = fps CYCLES_PER_BATCH = Int(CPU_FREQUENCY / FRAMES_PER_SECOND) + cg = chargen + emulatorViewDelegate = delegate emulatorView = view @@ -101,13 +107,14 @@ class AppleIIBase: NSObject, EmulatedSystem { 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") + backplane[0] = LanguageCard16K(slot: 0, romPath: "/Users/luigi/apple2/peripherals/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") - //(backplane[6] as! DiskII).attachDiskImage(imagePath: "/Users/luigi/apple2/Prodos_2_4_1.po") + backplane[6] = DiskII(slot: 6, romPath: "/Users/luigi/apple2/peripherals/341-0027-a.p5") + (backplane[6] as! DiskII).attachDiskImage(imagePath: "/Users/luigi/apple2/Prodos_2_4_1.po") + //(backplane[6] as! DiskII).attachDiskImage(imagePath: "/Users/luigi/apple2/Apex II - Apple II Diagnostic (v4.7-1986).do") } } diff --git a/FruitMachine/AppleII/AppleII.swift b/FruitMachine/AppleII/Models/AppleII.swift similarity index 87% rename from FruitMachine/AppleII/AppleII.swift rename to FruitMachine/AppleII/Models/AppleII.swift index 9e5f93e..31b39ee 100644 --- a/FruitMachine/AppleII/AppleII.swift +++ b/FruitMachine/AppleII/Models/AppleII.swift @@ -15,25 +15,26 @@ class AppleII: AppleIIBase { super.init(cpuFrequency: cpuFrequency, fps: fps, delegate: ScreenDelegate(), - view: ScreenView(frame: NSMakeRect(0, 16, 560, 384))) + view: ScreenView(frame: NSMakeRect(0, 16, 560, 384)), + chargen: A2CharacterGenerator(romPath: "/Users/luigi/apple2/apple2/a2.chr")) loadROMs() doReset() } - required init(cpuFrequency: Double, fps: Double, delegate: ScreenDelegate, view: ScreenView) { + required init(cpuFrequency: Double, fps: Double, delegate: ScreenDelegate, view: ScreenView, chargen: A2CharacterGenerator) { fatalError("init(cpuFrequency:fps:delegate:view:) has not been implemented") } 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) + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/apple2/341-0001-00.e0", offset: 0xE000, length: 0x800) + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/apple2/341-0002-00.e8", offset: 0xE800, length: 0x800) + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/apple2/341-0003-00.f0", offset: 0xF000, length: 0x800) /* Monitor */ - CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/341-0004-00.f8", offset: 0xF800, length: 0x800) + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/apple2/341-0004-00.f8", offset: 0xF800, length: 0x800) } override func installOverrides() { diff --git a/FruitMachine/AppleII/AppleIIPlus.swift b/FruitMachine/AppleII/Models/AppleIIPlus.swift similarity index 84% rename from FruitMachine/AppleII/AppleIIPlus.swift rename to FruitMachine/AppleII/Models/AppleIIPlus.swift index 9f31905..f92ec7c 100644 --- a/FruitMachine/AppleII/AppleIIPlus.swift +++ b/FruitMachine/AppleII/Models/AppleIIPlus.swift @@ -15,26 +15,27 @@ class AppleIIPlus: AppleIIBase { super.init(cpuFrequency: cpuFrequency, fps: fps, delegate: ScreenDelegate(), - view: ScreenView(frame: NSMakeRect(0, 16, 560, 384))) + view: ScreenView(frame: NSMakeRect(0, 16, 560, 384)), + chargen: A2CharacterGenerator(romPath: "/Users/luigi/apple2/apple2/a2.chr")) loadROMs() doReset() } - required init(cpuFrequency: Double, fps: Double, delegate: ScreenDelegate, view: ScreenView) { + required init(cpuFrequency: Double, fps: Double, delegate: ScreenDelegate, view: ScreenView, chargen: A2CharacterGenerator) { 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) + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/apple2p/341-0011.d0", offset: 0xD000, length: 0x800) + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/apple2p/341-0012.d8", offset: 0xD800, length: 0x800) + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/apple2p/341-0013.e0", offset: 0xE000, length: 0x800) + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/apple2p/341-0014.e8", offset: 0xE800, length: 0x800) + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/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) + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/apple2p/341-0020-00.f8", offset: 0xF800, length: 0x800) } override func installOverrides() { diff --git a/FruitMachine/AppleII/Models/AppleIIe.swift b/FruitMachine/AppleII/Models/AppleIIe.swift new file mode 100644 index 0000000..e6d2ed0 --- /dev/null +++ b/FruitMachine/AppleII/Models/AppleIIe.swift @@ -0,0 +1,65 @@ +// +// AppleIIe.swift +// FruitMachine +// +// Created by Christopher Rohl on 8/13/17. +// Copyright © 2017 Christopher Rohl. All rights reserved. +// + +import Cocoa + +class AppleIIe: AppleIIBase { + + static let sharedInstance = AppleIIe(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)), + chargen: A2CharacterGenerator(romPath: "/Users/luigi/apple2/apple2e/342-0133-a.chr")) + + loadROMs() + doReset() + } + + required init(cpuFrequency: Double, fps: Double, delegate: ScreenDelegate, view: ScreenView, chargen: A2CharacterGenerator) { + fatalError("init(cpuFrequency:fps:delegate:view:chargen:) has not been implemented") + } + + override func loadROMs() { + //Applesoft BASIC + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/apple2e/342-0135-b.64", offset: 0xD000, length: 0x1000) + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/apple2e/342-0134-a.64", offset: 0xE000, length: 0x1000) + } + + 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/Peripherals/DiskII/DiskII.swift b/FruitMachine/AppleII/Peripherals/DiskII/DiskII.swift index 431aa7f..2191664 100644 --- a/FruitMachine/AppleII/Peripherals/DiskII/DiskII.swift +++ b/FruitMachine/AppleII/Peripherals/DiskII/DiskII.swift @@ -35,7 +35,7 @@ import Cocoa */ class DiskII: NSObject, Peripheral, HasROM { - let debug = true + let debug = false enum MotorPhase { case Phase0 diff --git a/FruitMachine/AppleII/Peripherals/DiskII/DiskImage.swift b/FruitMachine/AppleII/Peripherals/DiskII/DiskImage.swift index 599e157..9814c27 100644 --- a/FruitMachine/AppleII/Peripherals/DiskII/DiskImage.swift +++ b/FruitMachine/AppleII/Peripherals/DiskII/DiskImage.swift @@ -49,9 +49,8 @@ class ProdosImage: DiskImageFormat { static let TRACKS_PER_DISK: Int = 35 static let BYTES_PER_TRACK: Int = BYTES_PER_SECTOR * SECTORS_PER_TRACK - //Sectors in a track are in this order. - static let SECTOR_ORDER = [0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15] - //static let SECTOR_ORDER = [0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15] + //Sectors in a track are still in DOS order for our purposes. + static let SECTOR_ORDER = [0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15] static func readTrackAndSector(imageData: [UInt8], trackNum: Int, sectorNum: Int) -> [UInt8] { //Find the track in our disk. @@ -222,7 +221,7 @@ class DiskImage: NSObject { } } else if(image is ProdosImage) { for i in 0 ..< ProdosImage.SECTORS_PER_TRACK { - let sectorOffset: Int = 0x47 + (0x18C * ProdosImage.SECTOR_ORDER.index(of: i)!) + let sectorOffset: Int = 0x47 + (0x18C * Dos33Image.SECTOR_ORDER.index(of: i)!) let nibbles: [UInt8] = [UInt8](track[sectorOffset ... sectorOffset + 343]) trackBytes.append(contentsOf: DecodeSectorSixAndTwo(nibbles: nibbles)) } diff --git a/FruitMachine/AppleIIViewController.swift b/FruitMachine/AppleIIViewController.swift index dae74e8..bceb0e1 100644 --- a/FruitMachine/AppleIIViewController.swift +++ b/FruitMachine/AppleIIViewController.swift @@ -45,6 +45,8 @@ class AppleIIViewController: NSViewController { EmulatedSystemInstance = AppleII.sharedInstance } else if(model == "Apple ][+") { EmulatedSystemInstance = AppleIIPlus.sharedInstance + } else if(model == "Apple IIe") { + EmulatedSystemInstance = AppleIIe.sharedInstance } else { /* ??? */ EmulatedSystemInstance = AppleII.sharedInstance