diff --git a/A2Mac.xcodeproj/project.pbxproj b/A2Mac.xcodeproj/project.pbxproj index 0ceef1f..cfc451a 100644 --- a/A2Mac.xcodeproj/project.pbxproj +++ b/A2Mac.xcodeproj/project.pbxproj @@ -20,6 +20,45 @@ 325EB64F23FBBAD100C6B4A4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 325EB64D23FBBAD100C6B4A4 /* LaunchScreen.storyboard */; }; 325EB65A23FBBAD100C6B4A4 /* A2iOSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 325EB65923FBBAD100C6B4A4 /* A2iOSTests.swift */; }; 325EB66523FBBAD100C6B4A4 /* A2iOSUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 325EB66423FBBAD100C6B4A4 /* A2iOSUITests.swift */; }; + 325EB67423FBC0AA00C6B4A4 /* RepeatingTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C45305232E3EEF0000EBA1 /* RepeatingTimer.swift */; }; + 325EB67523FBC43E00C6B4A4 /* 6502.c in Sources */ = {isa = PBXBuildFile; fileRef = 32439F7422ECD8AD0077AAE0 /* 6502.c */; }; + 325EB67623FBC44400C6B4A4 /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = 325EB63823F9E48100C6B4A4 /* common.c */; }; + 325EB67723FBC45300C6B4A4 /* woz.c in Sources */ = {isa = PBXBuildFile; fileRef = 325EB62E23F8856F00C6B4A4 /* woz.c */; }; + 325EB67823FBC45300C6B4A4 /* disk.c in Sources */ = {isa = PBXBuildFile; fileRef = 325EB63523F8F78300C6B4A4 /* disk.c */; }; + 325EB67923FBC48400C6B4A4 /* spk_dn.wav in Resources */ = {isa = PBXBuildFile; fileRef = 3262F37423E169F8008BDB95 /* spk_dn.wav */; }; + 325EB67A23FBC48400C6B4A4 /* spk_up.wav in Resources */ = {isa = PBXBuildFile; fileRef = 3262F37523E169F8008BDB95 /* spk_up.wav */; }; + 325EB67C23FBD43800C6B4A4 /* PrintChar21.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 325EB67B23FBD43800C6B4A4 /* PrintChar21.ttf */; }; + 325EB67D23FBD43800C6B4A4 /* PrintChar21.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 325EB67B23FBD43800C6B4A4 /* PrintChar21.ttf */; }; + 325EB67E23FBDEE700C6B4A4 /* apple.rom in Resources */ = {isa = PBXBuildFile; fileRef = 32439F8422ECD8AD0077AAE0 /* apple.rom */; }; + 325EB68023FBDF8F00C6B4A4 /* Apple2Plus.rom in Resources */ = {isa = PBXBuildFile; fileRef = 325EB67F23FBDF8F00C6B4A4 /* Apple2Plus.rom */; }; + 325EB68123FBDF8F00C6B4A4 /* Apple2Plus.rom in Resources */ = {isa = PBXBuildFile; fileRef = 325EB67F23FBDF8F00C6B4A4 /* Apple2Plus.rom */; }; + 325EB68323FBDFBB00C6B4A4 /* DISK_II_C600.ROM in Resources */ = {isa = PBXBuildFile; fileRef = 325EB68223FBDFBA00C6B4A4 /* DISK_II_C600.ROM */; }; + 325EB68423FBDFBB00C6B4A4 /* DISK_II_C600.ROM in Resources */ = {isa = PBXBuildFile; fileRef = 325EB68223FBDFBA00C6B4A4 /* DISK_II_C600.ROM */; }; + 325EB68623FC707A00C6B4A4 /* Apple DOS 3.3 January 1983.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB68523FC707A00C6B4A4 /* Apple DOS 3.3 January 1983.woz */; }; + 325EB68723FC707A00C6B4A4 /* Apple DOS 3.3 January 1983.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB68523FC707A00C6B4A4 /* Apple DOS 3.3 January 1983.woz */; }; + 325EB68923FDDF6200C6B4A4 /* Hard Hat Mack - Disk 1, Side A.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB68823FDDF6200C6B4A4 /* Hard Hat Mack - Disk 1, Side A.woz */; }; + 325EB68A23FDDF6200C6B4A4 /* Hard Hat Mack - Disk 1, Side A.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB68823FDDF6200C6B4A4 /* Hard Hat Mack - Disk 1, Side A.woz */; }; + 325EB68C23FDDFD200C6B4A4 /* Merlin-8 v2.48 (DOS 3.3).woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB68B23FDDFD200C6B4A4 /* Merlin-8 v2.48 (DOS 3.3).woz */; }; + 325EB68D23FDDFD200C6B4A4 /* Merlin-8 v2.48 (DOS 3.3).woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB68B23FDDFD200C6B4A4 /* Merlin-8 v2.48 (DOS 3.3).woz */; }; + 325EB69023FE028800C6B4A4 /* Donkey Kong.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB68F23FE028800C6B4A4 /* Donkey Kong.woz */; }; + 325EB69123FE028800C6B4A4 /* Donkey Kong.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB68F23FE028800C6B4A4 /* Donkey Kong.woz */; }; + 325EB69323FE6C6200C6B4A4 /* HiRes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DBF7632334657900DD50E7 /* HiRes.swift */; }; + 325EB69D2401118300C6B4A4 /* Lode Runner.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB6942401118200C6B4A4 /* Lode Runner.woz */; }; + 325EB69E2401118300C6B4A4 /* Lode Runner.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB6942401118200C6B4A4 /* Lode Runner.woz */; }; + 325EB69F2401118300C6B4A4 /* Crossfire.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB6952401118200C6B4A4 /* Crossfire.woz */; }; + 325EB6A02401118300C6B4A4 /* Crossfire.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB6952401118200C6B4A4 /* Crossfire.woz */; }; + 325EB6A12401118300C6B4A4 /* Wavy Navy.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB6962401118200C6B4A4 /* Wavy Navy.woz */; }; + 325EB6A22401118300C6B4A4 /* Wavy Navy.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB6962401118200C6B4A4 /* Wavy Navy.woz */; }; + 325EB6A32401118300C6B4A4 /* qbit.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB6972401118200C6B4A4 /* qbit.woz */; }; + 325EB6A42401118300C6B4A4 /* qbit.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB6972401118200C6B4A4 /* qbit.woz */; }; + 325EB6A52401118300C6B4A4 /* ProDOS_312.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB6982401118200C6B4A4 /* ProDOS_312.woz */; }; + 325EB6A62401118300C6B4A4 /* ProDOS_312.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB6982401118200C6B4A4 /* ProDOS_312.woz */; }; + 325EB6A72401118300C6B4A4 /* ProDOS_402_System.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB6992401118200C6B4A4 /* ProDOS_402_System.woz */; }; + 325EB6A82401118300C6B4A4 /* ProDOS_402_System.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB6992401118200C6B4A4 /* ProDOS_402_System.woz */; }; + 325EB6A92401118300C6B4A4 /* Sneakers.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB69A2401118300C6B4A4 /* Sneakers.woz */; }; + 325EB6AA2401118300C6B4A4 /* Sneakers.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB69A2401118300C6B4A4 /* Sneakers.woz */; }; + 325EB6AB2401118300C6B4A4 /* Xonix.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB69B2401118300C6B4A4 /* Xonix.woz */; }; + 325EB6AC2401118300C6B4A4 /* Xonix.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB69B2401118300C6B4A4 /* Xonix.woz */; }; 3262F37623E169F8008BDB95 /* spk_dn.wav in Resources */ = {isa = PBXBuildFile; fileRef = 3262F37423E169F8008BDB95 /* spk_dn.wav */; }; 3262F37723E169F8008BDB95 /* spk_up.wav in Resources */ = {isa = PBXBuildFile; fileRef = 3262F37523E169F8008BDB95 /* spk_up.wav */; }; 326ED2EF232D7A0000A41337 /* 6502_functional_test.bin in Resources */ = {isa = PBXBuildFile; fileRef = 326ED2EE232D7A0000A41337 /* 6502_functional_test.bin */; }; @@ -32,7 +71,6 @@ 32C4530B2331F7220000EBA1 /* 6502.c in Sources */ = {isa = PBXBuildFile; fileRef = 32439F7422ECD8AD0077AAE0 /* 6502.c */; }; 32C4530C2331F7220000EBA1 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32BFFB5C22EACC630003B53F /* ViewController.swift */; }; 32C4530D2331F7220000EBA1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32BFFB5A22EACC630003B53F /* AppDelegate.swift */; }; - 32C4530E2331F7220000EBA1 /* RepeatingTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C45305232E3EEF0000EBA1 /* RepeatingTimer.swift */; }; 32C453112331F7220000EBA1 /* fail1.txt in Resources */ = {isa = PBXBuildFile; fileRef = 32EDB7A123272CA80073AF2D /* fail1.txt */; }; 32C453122331F7220000EBA1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 32BFFB5E22EACC660003B53F /* Assets.xcassets */; }; 32C453132331F7220000EBA1 /* apple.rom in Resources */ = {isa = PBXBuildFile; fileRef = 32439F8422ECD8AD0077AAE0 /* apple.rom */; }; @@ -40,7 +78,6 @@ 32C4531D2331FED90000EBA1 /* 6502.c in Sources */ = {isa = PBXBuildFile; fileRef = 32439F7422ECD8AD0077AAE0 /* 6502.c */; }; 32C4531E2331FED90000EBA1 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32BFFB5C22EACC630003B53F /* ViewController.swift */; }; 32C4531F2331FED90000EBA1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32BFFB5A22EACC630003B53F /* AppDelegate.swift */; }; - 32C453202331FED90000EBA1 /* RepeatingTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C45305232E3EEF0000EBA1 /* RepeatingTimer.swift */; }; 32C453232331FED90000EBA1 /* fail1.txt in Resources */ = {isa = PBXBuildFile; fileRef = 32EDB7A123272CA80073AF2D /* fail1.txt */; }; 32C453242331FED90000EBA1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 32BFFB5E22EACC660003B53F /* Assets.xcassets */; }; 32C453252331FED90000EBA1 /* apple.rom in Resources */ = {isa = PBXBuildFile; fileRef = 32439F8422ECD8AD0077AAE0 /* apple.rom */; }; @@ -51,10 +88,6 @@ 32C4533123335E560000EBA1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 32BFFB6022EACC660003B53F /* Main.storyboard */; }; 32C4533223335E570000EBA1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 32BFFB6022EACC660003B53F /* Main.storyboard */; }; 32C4533323335E570000EBA1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 32BFFB6022EACC660003B53F /* Main.storyboard */; }; - 32DBF7642334657900DD50E7 /* HiRes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DBF7632334657900DD50E7 /* HiRes.swift */; }; - 32DBF7652334657900DD50E7 /* HiRes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DBF7632334657900DD50E7 /* HiRes.swift */; }; - 32DBF7662334657900DD50E7 /* HiRes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DBF7632334657900DD50E7 /* HiRes.swift */; }; - 32EDB7A223272CA80073AF2D /* fail1.txt in Resources */ = {isa = PBXBuildFile; fileRef = 32EDB7A123272CA80073AF2D /* fail1.txt */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -128,6 +161,22 @@ 325EB66023FBBAD100C6B4A4 /* A2iOSUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = A2iOSUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 325EB66423FBBAD100C6B4A4 /* A2iOSUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = A2iOSUITests.swift; sourceTree = ""; }; 325EB66623FBBAD100C6B4A4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 325EB67323FBBF0C00C6B4A4 /* A2iOS-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "A2iOS-Bridging-Header.h"; sourceTree = ""; }; + 325EB67B23FBD43800C6B4A4 /* PrintChar21.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = PrintChar21.ttf; sourceTree = ""; }; + 325EB67F23FBDF8F00C6B4A4 /* Apple2Plus.rom */ = {isa = PBXFileReference; lastKnownFileType = file; path = Apple2Plus.rom; sourceTree = ""; }; + 325EB68223FBDFBA00C6B4A4 /* DISK_II_C600.ROM */ = {isa = PBXFileReference; lastKnownFileType = file; path = DISK_II_C600.ROM; sourceTree = ""; }; + 325EB68523FC707A00C6B4A4 /* Apple DOS 3.3 January 1983.woz */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Apple DOS 3.3 January 1983.woz"; sourceTree = ""; }; + 325EB68823FDDF6200C6B4A4 /* Hard Hat Mack - Disk 1, Side A.woz */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Hard Hat Mack - Disk 1, Side A.woz"; sourceTree = ""; }; + 325EB68B23FDDFD200C6B4A4 /* Merlin-8 v2.48 (DOS 3.3).woz */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Merlin-8 v2.48 (DOS 3.3).woz"; sourceTree = ""; }; + 325EB68F23FE028800C6B4A4 /* Donkey Kong.woz */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Donkey Kong.woz"; sourceTree = ""; }; + 325EB6942401118200C6B4A4 /* Lode Runner.woz */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Lode Runner.woz"; sourceTree = ""; }; + 325EB6952401118200C6B4A4 /* Crossfire.woz */ = {isa = PBXFileReference; lastKnownFileType = file; path = Crossfire.woz; sourceTree = ""; }; + 325EB6962401118200C6B4A4 /* Wavy Navy.woz */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Wavy Navy.woz"; sourceTree = ""; }; + 325EB6972401118200C6B4A4 /* qbit.woz */ = {isa = PBXFileReference; lastKnownFileType = file; path = qbit.woz; sourceTree = ""; }; + 325EB6982401118200C6B4A4 /* ProDOS_312.woz */ = {isa = PBXFileReference; lastKnownFileType = file; path = ProDOS_312.woz; sourceTree = ""; }; + 325EB6992401118200C6B4A4 /* ProDOS_402_System.woz */ = {isa = PBXFileReference; lastKnownFileType = file; path = ProDOS_402_System.woz; sourceTree = ""; }; + 325EB69A2401118300C6B4A4 /* Sneakers.woz */ = {isa = PBXFileReference; lastKnownFileType = file; path = Sneakers.woz; sourceTree = ""; }; + 325EB69B2401118300C6B4A4 /* Xonix.woz */ = {isa = PBXFileReference; lastKnownFileType = file; path = Xonix.woz; sourceTree = ""; }; 3262F37423E169F8008BDB95 /* spk_dn.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = spk_dn.wav; sourceTree = ""; }; 3262F37523E169F8008BDB95 /* spk_up.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = spk_up.wav; sourceTree = ""; }; 3264261023284F6F008B615F /* Apple2_mmio_8bit_ioaddr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Apple2_mmio_8bit_ioaddr.h; sourceTree = ""; }; @@ -274,6 +323,7 @@ 325EB63723F9492200C6B4A4 /* util */ = { isa = PBXGroup; children = ( + 32C45305232E3EEF0000EBA1 /* RepeatingTimer.swift */, 32439F8622ECD8AD0077AAE0 /* common.h */, 325EB63823F9E48100C6B4A4 /* common.c */, 32DBF76723373FB400DD50E7 /* disassembler.h */, @@ -310,6 +360,7 @@ 325EB64B23FBBAD100C6B4A4 /* Assets.xcassets */, 325EB64D23FBBAD100C6B4A4 /* LaunchScreen.storyboard */, 325EB65023FBBAD100C6B4A4 /* Info.plist */, + 325EB67323FBBF0C00C6B4A4 /* A2iOS-Bridging-Header.h */, ); path = A2iOS; sourceTree = ""; @@ -337,6 +388,22 @@ children = ( 3262F37423E169F8008BDB95 /* spk_dn.wav */, 3262F37523E169F8008BDB95 /* spk_up.wav */, + 325EB67B23FBD43800C6B4A4 /* PrintChar21.ttf */, + 32439F8422ECD8AD0077AAE0 /* apple.rom */, + 325EB67F23FBDF8F00C6B4A4 /* Apple2Plus.rom */, + 325EB68223FBDFBA00C6B4A4 /* DISK_II_C600.ROM */, + 325EB68523FC707A00C6B4A4 /* Apple DOS 3.3 January 1983.woz */, + 325EB68823FDDF6200C6B4A4 /* Hard Hat Mack - Disk 1, Side A.woz */, + 325EB68B23FDDFD200C6B4A4 /* Merlin-8 v2.48 (DOS 3.3).woz */, + 325EB6952401118200C6B4A4 /* Crossfire.woz */, + 325EB6942401118200C6B4A4 /* Lode Runner.woz */, + 325EB6982401118200C6B4A4 /* ProDOS_312.woz */, + 325EB68F23FE028800C6B4A4 /* Donkey Kong.woz */, + 325EB6992401118200C6B4A4 /* ProDOS_402_System.woz */, + 325EB6972401118200C6B4A4 /* qbit.woz */, + 325EB69A2401118300C6B4A4 /* Sneakers.woz */, + 325EB6962401118200C6B4A4 /* Wavy Navy.woz */, + 325EB69B2401118300C6B4A4 /* Xonix.woz */, ); path = Resources; sourceTree = ""; @@ -377,16 +444,14 @@ 32BFFB5922EACC630003B53F /* A2Mac */ = { isa = PBXGroup; children = ( - 32439F8422ECD8AD0077AAE0 /* apple.rom */, 326ED2EE232D7A0000A41337 /* 6502_functional_test.bin */, 32B18438233FAB3900DBB4AB /* verticies.swift */, 32BFFB5A22EACC630003B53F /* AppDelegate.swift */, 32BFFB5C22EACC630003B53F /* ViewController.swift */, 32B18435233F10BC00DBB4AB /* Shaders.metal */, 32C4532D233345420000EBA1 /* MonitorView.swift */, - 32DBF7632334657900DD50E7 /* HiRes.swift */, 32C453072331C0910000EBA1 /* NSLayoutManager-Extension.swift */, - 32C45305232E3EEF0000EBA1 /* RepeatingTimer.swift */, + 32DBF7632334657900DD50E7 /* HiRes.swift */, 32EDB7A123272CA80073AF2D /* fail1.txt */, 32BFFB5E22EACC660003B53F /* Assets.xcassets */, 32BFFB6022EACC660003B53F /* Main.storyboard */, @@ -623,9 +688,27 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 325EB6A22401118300C6B4A4 /* Wavy Navy.woz in Resources */, + 325EB67E23FBDEE700C6B4A4 /* apple.rom in Resources */, 325EB64F23FBBAD100C6B4A4 /* LaunchScreen.storyboard in Resources */, + 325EB68423FBDFBB00C6B4A4 /* DISK_II_C600.ROM in Resources */, + 325EB69E2401118300C6B4A4 /* Lode Runner.woz in Resources */, + 325EB68123FBDF8F00C6B4A4 /* Apple2Plus.rom in Resources */, + 325EB6AA2401118300C6B4A4 /* Sneakers.woz in Resources */, + 325EB6A82401118300C6B4A4 /* ProDOS_402_System.woz in Resources */, + 325EB69123FE028800C6B4A4 /* Donkey Kong.woz in Resources */, + 325EB68A23FDDF6200C6B4A4 /* Hard Hat Mack - Disk 1, Side A.woz in Resources */, + 325EB6A02401118300C6B4A4 /* Crossfire.woz in Resources */, + 325EB67923FBC48400C6B4A4 /* spk_dn.wav in Resources */, 325EB64C23FBBAD100C6B4A4 /* Assets.xcassets in Resources */, + 325EB68D23FDDFD200C6B4A4 /* Merlin-8 v2.48 (DOS 3.3).woz in Resources */, + 325EB6A62401118300C6B4A4 /* ProDOS_312.woz in Resources */, + 325EB6AC2401118300C6B4A4 /* Xonix.woz in Resources */, + 325EB67D23FBD43800C6B4A4 /* PrintChar21.ttf in Resources */, + 325EB6A42401118300C6B4A4 /* qbit.woz in Resources */, + 325EB68723FC707A00C6B4A4 /* Apple DOS 3.3 January 1983.woz in Resources */, 325EB64A23FBBACF00C6B4A4 /* Main.storyboard in Resources */, + 325EB67A23FBC48400C6B4A4 /* spk_up.wav in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -647,10 +730,24 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 32EDB7A223272CA80073AF2D /* fail1.txt in Resources */, + 325EB6A12401118300C6B4A4 /* Wavy Navy.woz in Resources */, + 325EB68023FBDF8F00C6B4A4 /* Apple2Plus.rom in Resources */, + 325EB68323FBDFBB00C6B4A4 /* DISK_II_C600.ROM in Resources */, + 325EB67C23FBD43800C6B4A4 /* PrintChar21.ttf in Resources */, + 325EB69D2401118300C6B4A4 /* Lode Runner.woz in Resources */, 3262F37723E169F8008BDB95 /* spk_up.wav in Resources */, + 325EB6A92401118300C6B4A4 /* Sneakers.woz in Resources */, + 325EB6A72401118300C6B4A4 /* ProDOS_402_System.woz in Resources */, + 325EB69023FE028800C6B4A4 /* Donkey Kong.woz in Resources */, + 325EB68923FDDF6200C6B4A4 /* Hard Hat Mack - Disk 1, Side A.woz in Resources */, + 325EB69F2401118300C6B4A4 /* Crossfire.woz in Resources */, 32C4533123335E560000EBA1 /* Main.storyboard in Resources */, 32BFFB5F22EACC660003B53F /* Assets.xcassets in Resources */, + 325EB68C23FDDFD200C6B4A4 /* Merlin-8 v2.48 (DOS 3.3).woz in Resources */, + 325EB6A52401118300C6B4A4 /* ProDOS_312.woz in Resources */, + 325EB6AB2401118300C6B4A4 /* Xonix.woz in Resources */, + 325EB68623FC707A00C6B4A4 /* Apple DOS 3.3 January 1983.woz in Resources */, + 325EB6A32401118300C6B4A4 /* qbit.woz in Resources */, 32439F8822ECD8AD0077AAE0 /* apple.rom in Resources */, 326ED2EF232D7A0000A41337 /* 6502_functional_test.bin in Resources */, 3262F37623E169F8008BDB95 /* spk_dn.wav in Resources */, @@ -702,9 +799,14 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 325EB67623FBC44400C6B4A4 /* common.c in Sources */, + 325EB67523FBC43E00C6B4A4 /* 6502.c in Sources */, + 325EB67823FBC45300C6B4A4 /* disk.c in Sources */, 325EB64723FBBACF00C6B4A4 /* ViewController.swift in Sources */, 325EB64323FBBACF00C6B4A4 /* AppDelegate.swift in Sources */, + 325EB67723FBC45300C6B4A4 /* woz.c in Sources */, 325EB64523FBBACF00C6B4A4 /* SceneDelegate.swift in Sources */, + 325EB67423FBC0AA00C6B4A4 /* RepeatingTimer.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -729,10 +831,10 @@ buildActionMask = 2147483647; files = ( 32439F8722ECD8AD0077AAE0 /* 6502.c in Sources */, - 32DBF7642334657900DD50E7 /* HiRes.swift in Sources */, 325EB63623F8F78300C6B4A4 /* disk.c in Sources */, 325EB63923F9E48100C6B4A4 /* common.c in Sources */, 32BFFB5D22EACC630003B53F /* ViewController.swift in Sources */, + 325EB69323FE6C6200C6B4A4 /* HiRes.swift in Sources */, 32C4532E233345430000EBA1 /* MonitorView.swift in Sources */, 325EB62F23F8856F00C6B4A4 /* woz.c in Sources */, 32BFFB5B22EACC630003B53F /* AppDelegate.swift in Sources */, @@ -761,11 +863,9 @@ buildActionMask = 2147483647; files = ( 32C4530B2331F7220000EBA1 /* 6502.c in Sources */, - 32DBF7652334657900DD50E7 /* HiRes.swift in Sources */, 32C4530C2331F7220000EBA1 /* ViewController.swift in Sources */, 32C4532F233345820000EBA1 /* MonitorView.swift in Sources */, 32C4530D2331F7220000EBA1 /* AppDelegate.swift in Sources */, - 32C4530E2331F7220000EBA1 /* RepeatingTimer.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -774,11 +874,9 @@ buildActionMask = 2147483647; files = ( 32C4531D2331FED90000EBA1 /* 6502.c in Sources */, - 32DBF7662334657900DD50E7 /* HiRes.swift in Sources */, 32C4531E2331FED90000EBA1 /* ViewController.swift in Sources */, 32C45330233345820000EBA1 /* MonitorView.swift in Sources */, 32C4531F2331FED90000EBA1 /* AppDelegate.swift in Sources */, - 32C453202331FED90000EBA1 /* RepeatingTimer.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -847,9 +945,11 @@ "$(inherited)", "@executable_path/Frameworks", ); + OTHER_SWIFT_FLAGS = "-DHIRES -DHIRESDRAW -D_NO_HIRESLOW"; PRODUCT_BUNDLE_IDENTIFIER = com.gamealloy.A2iOS; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; + SWIFT_OBJC_BRIDGING_HEADER = "A2iOS/A2iOS-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -867,9 +967,11 @@ "$(inherited)", "@executable_path/Frameworks", ); + OTHER_SWIFT_FLAGS = "-DHIRES -DHIRESDRAW -D_NO_HIRESLOW"; PRODUCT_BUNDLE_IDENTIFIER = com.gamealloy.A2iOS; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; + SWIFT_OBJC_BRIDGING_HEADER = "A2iOS/A2iOS-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; @@ -1106,8 +1208,9 @@ OTHER_CFLAGS = ( "-DDISASSEMBLER", "-DINTERRUPT_CHECK_PER_STEP", + "-DCLK_ABSOLUTE_PRECISE", ); - OTHER_SWIFT_FLAGS = "-D_NO_HIRES -DHIRESDRAW -D_NO_HIRESLOW"; + OTHER_SWIFT_FLAGS = "-DHIRES -DHIRESDRAW -D_NO_HIRESLOW"; PRODUCT_BUNDLE_IDENTIFIER = com.gamealloy.A2Mac; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; @@ -1141,8 +1244,9 @@ OTHER_CFLAGS = ( "-DDISASSEMBLER", "-DINTERRUPT_CHECK_PER_STEP", + "-DCLK_ABSOLUTE_PRECISE", ); - OTHER_SWIFT_FLAGS = "-D_NO_HIRES -DHIRESDRAW -D_NO_HIRESLOW"; + OTHER_SWIFT_FLAGS = "-DHIRES -DHIRESDRAW -D_NO_HIRESLOW"; PRODUCT_BUNDLE_IDENTIFIER = com.gamealloy.A2Mac; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "A2Mac/A2Mac-Bridging-Header.h"; diff --git a/A2Mac.xcodeproj/xcuserdata/trudnai.xcuserdatad/xcschemes/xcschememanagement.plist b/A2Mac.xcodeproj/xcuserdata/trudnai.xcuserdatad/xcschemes/xcschememanagement.plist index e43a239..46971ae 100644 --- a/A2Mac.xcodeproj/xcuserdata/trudnai.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/A2Mac.xcodeproj/xcuserdata/trudnai.xcuserdatad/xcschemes/xcschememanagement.plist @@ -32,6 +32,21 @@ SuppressBuildableAutocreation + 325EB63F23FBBACF00C6B4A4 + + primary + + + 325EB65423FBBAD100C6B4A4 + + primary + + + 325EB65F23FBBAD100C6B4A4 + + primary + + 32BFFB5622EACC630003B53F primary diff --git a/A2Mac/A2Mac-Bridging-Header.h b/A2Mac/A2Mac-Bridging-Header.h index 14d9f9d..0cc9672 100644 --- a/A2Mac/A2Mac-Bridging-Header.h +++ b/A2Mac/A2Mac-Bridging-Header.h @@ -1,5 +1,19 @@ // +// A2Mac-Bridging-Header.h +// A2Mac +// +// Created by Tamas Rudnai on 2/17/20. +// Copyright Β© 2020 GameAlloy. All rights reserved. +// +// // Use this file to import your target's public headers that you would like to expose to Swift. // +#ifndef A2Mac_Bridging_Header_h +#define A2Mac_Bridging_Header_h + + #import "6502.h" + + +#endif /* A2Mac_Bridging_Header_h */ diff --git a/A2Mac/Base.lproj/Main.storyboard b/A2Mac/Base.lproj/Main.storyboard index ea975b4..8a33c27 100644 --- a/A2Mac/Base.lproj/Main.storyboard +++ b/A2Mac/Base.lproj/Main.storyboard @@ -756,6 +756,9 @@ + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/A2iOS/Info.plist b/A2iOS/Info.plist index 2a3483c..6e96b82 100644 --- a/A2iOS/Info.plist +++ b/A2iOS/Info.plist @@ -60,5 +60,9 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + UIAppFonts + + PrintChar21.ttf + diff --git a/A2iOS/ViewController.swift b/A2iOS/ViewController.swift index 75d0ca0..382a422 100644 --- a/A2iOS/ViewController.swift +++ b/A2iOS/ViewController.swift @@ -7,14 +7,465 @@ // import UIKit +import AVFoundation + + + +let K : Double = 1000.0 +let M : Double = (K * K) +let G : Double = (M * K) +let T : Double = (G * K) + +let KB : Double = 1024.0 +let MB : Double = (KB * KB) +let GB : Double = (MB * KB) +let TB : Double = (GB * KB) + + +var spk_up: AVAudioPlayer? +var spk_dn: AVAudioPlayer? + +@_cdecl("ViewController_spk_up_play") +func spk_up_play() { + spk_up?.stop() + spk_dn?.stop() + spk_up?.play() +} + +@_cdecl("ViewController_spk_dn_play") +func spk_dn_play() { + spk_up?.stop() + spk_dn?.stop() + spk_dn?.play() +} + + +#if METAL_YES +import Metal +#endif class ViewController: UIViewController { + @IBOutlet weak var displayField: UITextView! + @IBOutlet weak var display: UITableViewCell! + @IBOutlet weak var speedometer: UILabel! // UITextFieldCell! + @IBOutlet weak var diskAccel: UILabel! // UITextFieldCell! + @IBOutlet weak var hires: HiRes! + + +// static let charConvStr : String = +// "@πŸ„°πŸ„±πŸ„²πŸ„³πŸ„΄πŸ„΅πŸ„ΆπŸ„·πŸ„ΈπŸ„ΉπŸ„ΊπŸ„»πŸ„ΌπŸ„½πŸ„ΎπŸ„ΏπŸ…€πŸ…πŸ…‚πŸ…ƒπŸ…„πŸ……πŸ…†πŸ…‡πŸ…ˆπŸ…‰[\\]^_ !\"#$%&'()*+,-./0123456789:;<=>?" + +// "@πŸ…°πŸ…±πŸ…²πŸ…³πŸ…΄πŸ…΅πŸ…ΆπŸ…·πŸ…ΈπŸ…ΉπŸ…ΊπŸ…»πŸ…ΌπŸ…½πŸ…ΎπŸ…ΏπŸ†€πŸ†πŸ†‚πŸ†ƒπŸ†„πŸ†…πŸ††πŸ†‡πŸ†ˆπŸ†‰[\\]^_β¬›οΈŽ!\"#$%&'()*+,-./0123456789:;<=>?" + // FL +// "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ !\"#$%&'()*+,-./0123456789:;<=>?" + +// "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~?" + +// static let charConvStr : String = +// "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ !\"#$%&'()*+,-./0123456789:;<=>?" + +// "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_β–‘!\"#$%&'()*+,-./0123456789:;<=>?" + // FL +// "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\u{E0A0}!\"#$%&'()*+,-./0123456789:;<=>?" + +// "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~?" + +// static let charConvStr : String = +// "\u{E140}\u{E141}\u{E142}\u{E143}\u{E144}\u{E145}\u{E146}\u{E147}\u{E148}\u{E149}\u{E14A}\u{E14B}\u{E14C}\u{E14D}\u{E14E}\u{E14F}\u{E150}\u{E151}\u{E152}\u{E153}\u{E154}\u{E155}\u{E156}\u{E157}\u{E158}\u{E159}\u{E15A}\u{E15B}\u{E15C}\u{E15D}\u{E15E}\u{E15F}\u{E120}\u{E121}\u{E122}\u{E123}\u{E124}\u{E125}\u{E126}\u{E127}\u{E128}\u{E129}\u{E12A}\u{E12B}\u{E12C}\u{E12D}\u{E12E}\u{E12F}\u{E130}\u{E131}\u{E132}\u{E133}\u{E134}\u{E135}\u{E136}\u{E137}\u{E138}\u{E139}\u{E13A}\u{E13B}\u{E13C}\u{E13D}\u{E13E}\u{E13F}" + +// "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_β–‘!\"#$%&'()*+,-./0123456789:;<=>?" + // FL +// "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\u{E0A0}!\"#$%&'()*+,-./0123456789:;<=>?" + +// "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~?" + + static let charConvStrFlashOff : String = + "\u{E140}\u{E141}\u{E142}\u{E143}\u{E144}\u{E145}\u{E146}\u{E147}\u{E148}\u{E149}\u{E14A}\u{E14B}\u{E14C}\u{E14D}\u{E14E}\u{E14F}\u{E150}\u{E151}\u{E152}\u{E153}\u{E154}\u{E155}\u{E156}\u{E157}\u{E158}\u{E159}\u{E15A}\u{E15B}\u{E15C}\u{E15D}\u{E15E}\u{E15F}\u{E120}\u{E121}\u{E122}\u{E123}\u{E124}\u{E125}\u{E126}\u{E127}\u{E128}\u{E129}\u{E12A}\u{E12B}\u{E12C}\u{E12D}\u{E12E}\u{E12F}\u{E130}\u{E131}\u{E132}\u{E133}\u{E134}\u{E135}\u{E136}\u{E137}\u{E138}\u{E139}\u{E13A}\u{E13B}\u{E13C}\u{E13D}\u{E13E}\u{E13F}" + + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ !\"#$%&'()*+,-./0123456789:;<=>?" + // FL + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ !\"#$%&'()*+,-./0123456789:;<=>?" + + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~?" + + static let charConvStrFlashOn : String = + "\u{E140}\u{E141}\u{E142}\u{E143}\u{E144}\u{E145}\u{E146}\u{E147}\u{E148}\u{E149}\u{E14A}\u{E14B}\u{E14C}\u{E14D}\u{E14E}\u{E14F}\u{E150}\u{E151}\u{E152}\u{E153}\u{E154}\u{E155}\u{E156}\u{E157}\u{E158}\u{E159}\u{E15A}\u{E15B}\u{E15C}\u{E15D}\u{E15E}\u{E15F}\u{E120}\u{E121}\u{E122}\u{E123}\u{E124}\u{E125}\u{E126}\u{E127}\u{E128}\u{E129}\u{E12A}\u{E12B}\u{E12C}\u{E12D}\u{E12E}\u{E12F}\u{E130}\u{E131}\u{E132}\u{E133}\u{E134}\u{E135}\u{E136}\u{E137}\u{E138}\u{E139}\u{E13A}\u{E13B}\u{E13C}\u{E13D}\u{E13E}\u{E13F}" + + "\u{E140}\u{E141}\u{E142}\u{E143}\u{E144}\u{E145}\u{E146}\u{E147}\u{E148}\u{E149}\u{E14A}\u{E14B}\u{E14C}\u{E14D}\u{E14E}\u{E14F}\u{E150}\u{E151}\u{E152}\u{E153}\u{E154}\u{E155}\u{E156}\u{E157}\u{E158}\u{E159}\u{E15A}\u{E15B}\u{E15C}\u{E15D}\u{E15E}\u{E15F}\u{E120}\u{E121}\u{E122}\u{E123}\u{E124}\u{E125}\u{E126}\u{E127}\u{E128}\u{E129}\u{E12A}\u{E12B}\u{E12C}\u{E12D}\u{E12E}\u{E12F}\u{E130}\u{E131}\u{E132}\u{E133}\u{E134}\u{E135}\u{E136}\u{E137}\u{E138}\u{E139}\u{E13A}\u{E13B}\u{E13C}\u{E13D}\u{E13E}\u{E13F}" + + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ !\"#$%&'()*+,-./0123456789:;<=>?" + + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~?" + + static let charConvTblFlashOn = Array( charConvStrFlashOn ) + static let charConvTblFlashOff = Array( charConvStrFlashOff ) + + static var charConvTbl = charConvTblFlashOn + + let textLineOfs : [Int] = [ + 0x000, 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x028, 0x0A8, 0x128, 0x1A8, + 0x228, 0x2A8, 0x328, 0x3A8, 0x050, 0x0D0, 0x150, 0x1D0, 0x250, 0x2D0, 0x350, 0x3D0 + ] + + var workItem : DispatchWorkItem? = nil; + @IBAction func Power(_ sender: Any) { + + + #if SPEEDTEST + if ( workItem != nil ) { + workItem!.cancel(); + workItem = nil; + } + else { + workItem = DispatchWorkItem { + DispatchQueue.global(qos: .userInteractive).async { +// DispatchQueue.global(qos: .userInitiated).async { +// DispatchQueue.global(qos: .background).async { + tst6502() + } + } + DispatchQueue.global().async(execute: workItem!); + } + #else + m6502_ColdReset( Bundle.main.bundlePath ) + #endif + } + + @IBAction func Reset(_ sender: Any) { +// let resetPointer = UnsafeRawBufferPointer(start: &RAM + 0x3F2, count: 2) +// let ral = UInt16(resetPointer[0]) +// let rah = UInt16(resetPointer[1]) +// let resetAddr = rah << 8 + ral +// +// let hex = String(resetAddr, radix: 16, uppercase: true) +// print("reset to:\(hex)\n") +// m6502.pc = resetAddr + + m6502.interrupt = SOFTRESET; + } + + + @IBAction func Command(_ sender: UIButton) { + + if let label = sender.titleLabel, let command = label.text { + for c in command { + kbdInput(c.asciiValue! + 128); + } + kbdInput(Character("\r").asciiValue! + 128); + } + + } + + + // AppleScript Keycodes + let leftArrowKey = 123 + let rightArrowKey = 124 + let upArrowKey = 126 + let downArrowKey = 125 + +// override func keyDown(with event: UIEvent) { +//// print("KBD Event") +//// switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) { +//// case [.command] where event.characters == "l", +//// [.command, .shift] where event.characters == "l": +//// print("command-l or command-shift-l") +//// default: +//// break +//// } +//// print( "key = " + (event.charactersIgnoringModifiers ?? "")) +//// print( "\ncharacter = " + (event.characters ?? "")) +// +// #if FUNCTIONTEST +// #else +// let keyCode = Int(event.keyCode) +// switch keyCode { +// case leftArrowKey: +// kbdInput(0x08) +// case rightArrowKey: +// kbdInput(0x15) +// case leftArrowKey: +// kbdInput(0x0B) +// case rightArrowKey: +// kbdInput(0x0A) +// default: +//// print("keycode: %d", keyCode) +// if let chars = event.characters { +// let char = chars.uppercased()[chars.startIndex] +// if let ascii = char.asciiValue { +// kbdInput(ascii) +// } +// } +// } +// #endif +// +// } + +// override func flagsChanged(with event: NSEvent) { +// switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) { +// case [.shift]: +// print("shift key is pressed") +// case [.control]: +// print("control key is pressed") +// case [.option] : +// print("option key is pressed") +// case [.command]: +// print("Command key is pressed") +// case [.control, .shift]: +// print("control-shift keys are pressed") +// case [.option, .shift]: +// print("option-shift keys are pressed") +// case [.command, .shift]: +// print("command-shift keys are pressed") +// case [.control, .option]: +// print("control-option keys are pressed") +// case [.control, .command]: +// print("control-command keys are pressed") +// case [.option, .command]: +// print("option-command keys are pressed") +// case [.shift, .control, .option]: +// print("shift-control-option keys are pressed") +// case [.shift, .control, .command]: +// print("shift-control-command keys are pressed") +// case [.control, .option, .command]: +// print("control-option-command keys are pressed") +// case [.shift, .command, .option]: +// print("shift-command-option keys are pressed") +// case [.shift, .control, .option, .command]: +// print("shift-control-option-command keys are pressed") +// default: +// print("no modifier keys are pressed") +// } +// } + + static let textBaseAddr = 0x400 + static let textBufferSize = 0x400 + let textLines = 24 + let textCols = 40 + let lineEndChars = 1 + + var frameCnt = 0 +// let spaceChar : Character = "\u{E17F}" +// let blockChar : Character = "\u{E07F}" + let spaceChar : Character = " " + let blockChar : Character = "β–‘" + var flashingSpace : Character = " " + + let ramBufferPointer = UnsafeRawBufferPointer(start: RAM, count: 64 * 1024) + let textBufferPointer = UnsafeRawBufferPointer(start: RAM + textBaseAddr, count: textBufferSize) + let txtClear = [Character](repeating: " ", count: textBufferSize) + var txtArr = txtClear + + var s = String() + + func HexDump() { + var txt : String = "" + + for y in 0...textLines - 1 { + txt += String(format: "%04X: ", y * 16) + for x in 0...15 { + let byte = ramBufferPointer[ y * 16 + x ] + let chr = String(format: "%02X ", byte) + txt += chr + } + txt += "\n" + } + + DispatchQueue.main.async { + self.displayField.text = txt + self.speedometer.text = String(format: "%0.3lf MHz", mhz); + } + } + + + var was = 0; + + func Update() { + + #if SPEEDTEST + #else + m6502_Run() + #endif + +// render() +// hires.compute() + +// HexDump() +// return + + frameCnt += 1 + if ( frameCnt == fps / 2 ) { +// flashingSpace = blockChar + ViewController.charConvTbl = ViewController.charConvTblFlashOn + } + else if ( frameCnt >= fps ) { +// flashingSpace = spaceChar + ViewController.charConvTbl = ViewController.charConvTblFlashOff + frameCnt = 0 + } + + var txt : String = "" + + for y in 0...textLines-1 { +// let textAddr = textBaseAddr + textLineOfs[y] + +// let linePointer = UnsafeMutableRawPointer( mutating: &RAM + textBaseAddr + y * textCols ) //( start: &RAM + 0x400, count: 0x400) +// let lineStr = String(bytesNoCopy: linePointer, length: textCols, encoding: .ascii, freeWhenDone: false)! +// txt += lineStr + "\n" + + for x in 0...textCols-1 { + let byte = textBufferPointer[ textLineOfs[y] + x ] + let idx = Int(byte); + let chr = ViewController.charConvTbl[idx] + // is it a cursor? (slashing space) +// if ( chr == "blockChar" ) { +// chr = flashingSpace +// } + // print("byte \(index): \(chr)") +// txt = txt + "\(chr)" + txtArr[ y * (textCols + lineEndChars) + x ] = chr + } + + +// for (_, byte) in textBufferPointer.enumerated() { +// let idx = Int(byte); +// var chr = ViewController.charConvTbl[idx] +// // is it a cursor? (slashing space) +// if ( chr == blockChar ) { +// chr = flashingSpace +// } +// // print("byte \(index): \(chr)") +// txt = txt + "\(chr)" +// } + +// txt = txt + "\n" + txtArr[ y * (textCols + lineEndChars) + textCols ] = "\n" + } +// txtArr[ textLines * (textCols+1) + textCols ] = "\0" + txt = String(txtArr) + + DispatchQueue.main.async { + self.displayField.text = txt +// self.display.stringValue = "testing\nit\nout" + + if ( (mhz < 10) && (mhz != floor(mhz)) ) { + self.speedometer.text = String(format: "%0.3lf MHz", mhz); + } + else { + self.speedometer.text = String(format: "%.0lf MHz", mhz); + } + + #if HIRES +// if ( self.was < 300 ) { +// self.was += 1 +// +// for x in stride(from: 0, to: 280, by: 7) { +// for y in stride(from: 0, to: 192, by: 8) { +// self.hires.setNeedsDisplay( CGRect(x: x, y: y, width: 7, height: 8) ) +// } +// } +// } + +// self.HiRes.setNeedsDisplay(self.HiRes.frame) +// self.hires.setNeedsDisplay( CGRect(x: 0, y: 191-50, width: 50, height: 50) ) + self.hires.needsDisplay = true +// } + #endif + } + } + + +// func FromBuf(ptr: UnsafeMutablePointer, length len: Int) -> String? { +// // convert the bytes using the UTF8 encoding +// if let theString = NSString(bytes: ptr, length: len, encoding: NSUTF8StringEncoding) { +// return theString as String +// } else { +// return nil // the bytes aren't valid UTF8 +// } +// } + + + let upd = RepeatingTimer(timeInterval: 1/Double(fps)) + + + override var prefersStatusBarHidden: Bool { + return true + } + + override func viewDidLoad() { super.viewDidLoad() - // Do any additional setup after loading the view. + + let spk_up_path = Bundle.main.path(forResource: "spk_up", ofType:"wav")! + let spk_up_url = URL(fileURLWithPath: spk_up_path) + do { + spk_up = try AVAudioPlayer(contentsOf: spk_up_url) +// spk_up?.play() + } catch { + // couldn't load file :( + } + + let spk_dn_path = Bundle.main.path(forResource: "spk_dn", ofType:"wav")! + let spk_dn_url = URL(fileURLWithPath: spk_dn_path) + do { + spk_dn = try AVAudioPlayer(contentsOf: spk_dn_url) +// spk_up?.play() + } catch { + // couldn't load file :( + } + + + + + //view.frame = CGRect(origin: CGPoint(), size: NSScreen.main!.visibleFrame.size) + +// createHiRes() + +// self.displayField.scaleUnitSquare(to: NSSize(width: 1, height: 1)) + +// NSEvent.removeMonitor(NSEvent.EventType.flagsChanged) +// NSEvent.addLocalMonitorForEvents(matching: .flagsChanged) { +// self.flagsChanged(with: $0) +// return $0 +// } + +// // NSEvent.removeMonitor(NSEvent.EventType.keyDown) +// NSEvent.addLocalMonitorForEvents(matching: .keyDown) { +//// print("keyDown event") +// self.keyDown(with: $0) +// return $0 +// } + + displayField.textContainer.maximumNumberOfLines = textLines +// displayField.preferredMaxLayoutWidth = displayField.frame.width + +// DispatchQueue.main.asyncAfter(deadline: .now() + 1/fps, execute: { +// self.update() +// }) + +// #if FUNCTIONTEST +// #else +// DispatchQueue.global(qos: .background).async { +// self.update() +// } + + upd.eventHandler = { + self.Update() + } + upd.resume() +// #endif } + + func setCPUClockSpeed( freq : Double ) { + mhz = freq + MHz_6502 = UInt64(mhz * M) + clk_6502_per_frm = MHz_6502 / UInt64(fps) + clk_6502_per_frm_set = clk_6502_per_frm + } + + @IBAction func speedSelected(_ sender: UIButton) { + if ( sender.titleLabel?.text == "Max" ) { + clk_6502_per_frm = UINT64_MAX + } + else if let freqValue = sender.titleLabel?.text, let freq = Double( freqValue ) { + setCPUClockSpeed(freq: freq) + } + } + + @IBAction func diskAccelSepected(_ sender: UIButton) { + if let freqValue = sender.titleLabel?.text, let freq = Int32( freqValue ) { + diskAccelerator_speed = freq + diskAccel.text = "Disk Accel: " + freqValue + } + } + } + diff --git a/Resources/Apple DOS 3.3 January 1983.woz b/Resources/Apple DOS 3.3 January 1983.woz new file mode 100644 index 0000000..55a8ccd Binary files /dev/null and b/Resources/Apple DOS 3.3 January 1983.woz differ diff --git a/A2Mac/apple.rom b/Resources/Apple2Plus.rom similarity index 100% rename from A2Mac/apple.rom rename to Resources/Apple2Plus.rom diff --git a/Resources/Crossfire.woz b/Resources/Crossfire.woz new file mode 100644 index 0000000..c5e5e78 Binary files /dev/null and b/Resources/Crossfire.woz differ diff --git a/Resources/DISK_II_C600.ROM b/Resources/DISK_II_C600.ROM new file mode 100644 index 0000000..56698b0 Binary files /dev/null and b/Resources/DISK_II_C600.ROM differ diff --git a/Resources/Donkey Kong.woz b/Resources/Donkey Kong.woz new file mode 100644 index 0000000..5acc1ec Binary files /dev/null and b/Resources/Donkey Kong.woz differ diff --git a/Resources/Hard Hat Mack - Disk 1, Side A.woz b/Resources/Hard Hat Mack - Disk 1, Side A.woz new file mode 100644 index 0000000..4ed7d20 Binary files /dev/null and b/Resources/Hard Hat Mack - Disk 1, Side A.woz differ diff --git a/Resources/Lode Runner.woz b/Resources/Lode Runner.woz new file mode 100644 index 0000000..e5233b2 Binary files /dev/null and b/Resources/Lode Runner.woz differ diff --git a/Resources/Merlin-8 v2.48 (DOS 3.3).woz b/Resources/Merlin-8 v2.48 (DOS 3.3).woz new file mode 100644 index 0000000..a147d0d Binary files /dev/null and b/Resources/Merlin-8 v2.48 (DOS 3.3).woz differ diff --git a/Resources/PrintChar21.ttf b/Resources/PrintChar21.ttf new file mode 100644 index 0000000..f5efa9a Binary files /dev/null and b/Resources/PrintChar21.ttf differ diff --git a/Resources/ProDOS_312.woz b/Resources/ProDOS_312.woz new file mode 100644 index 0000000..39085b0 Binary files /dev/null and b/Resources/ProDOS_312.woz differ diff --git a/Resources/ProDOS_402_System.woz b/Resources/ProDOS_402_System.woz new file mode 100644 index 0000000..83beae5 Binary files /dev/null and b/Resources/ProDOS_402_System.woz differ diff --git a/Resources/Sneakers.woz b/Resources/Sneakers.woz new file mode 100644 index 0000000..25f1893 Binary files /dev/null and b/Resources/Sneakers.woz differ diff --git a/Resources/Wavy Navy.woz b/Resources/Wavy Navy.woz new file mode 100644 index 0000000..0c072f0 Binary files /dev/null and b/Resources/Wavy Navy.woz differ diff --git a/Resources/Xonix.woz b/Resources/Xonix.woz new file mode 100644 index 0000000..c707124 Binary files /dev/null and b/Resources/Xonix.woz differ diff --git a/Resources/apple.rom b/Resources/apple.rom new file mode 100644 index 0000000..cb94b9f Binary files /dev/null and b/Resources/apple.rom differ diff --git a/Resources/qbit.woz b/Resources/qbit.woz new file mode 100644 index 0000000..b51cd1e Binary files /dev/null and b/Resources/qbit.woz differ diff --git a/src/cpu/6502.c b/src/cpu/6502.c index de465c6..77900c1 100644 --- a/src/cpu/6502.c +++ b/src/cpu/6502.c @@ -14,14 +14,14 @@ #include #include #include "6502.h" -#include "woz.h" +#include "../dev/disk/woz.h" void ViewController_spk_up_play(void); void ViewController_spk_dn_play(void); -#include "common.h" +#include "../util/common.h" #define SOFTRESET_VECTOR 0x3F2 @@ -43,12 +43,12 @@ unsigned long long clk_6502_per_frm_set = default_MHz_6502 / fps; unsigned long long tick_per_sec = G; unsigned long long tick_6502_per_sec = 0; -INLINE unsigned long long rdtsc(void) -{ - unsigned hi, lo; - __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi) ); - return ( (unsigned long long)lo) | ( ((unsigned long long)hi) << 32 ); -} +//INLINE unsigned long long rdtsc(void) +//{ +// unsigned hi, lo; +// __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi) ); +// return ( (unsigned long long)lo) | ( ((unsigned long long)hi) << 32 ); +//} m6502_t m6502 = { 0, // A @@ -538,7 +538,7 @@ INLINE int m6502_Step() { case 0x75: ADC( src_zp_X() ); return 4; // ADC zpg,X case 0x76: ROR( dest_zp_X() ); return 6; // ROR zpg,X // case 0x77: - case 0x78: SEI(); break; // SEI + case 0x78: SEI(); return 2; // SEI case 0x79: ADC( src_abs_Y() ); return 4; // ADC abs,Y // case 0x7A: // case 0x7B: @@ -610,8 +610,8 @@ INLINE int m6502_Step() { case 0xBD: LDA( src_abs_X() ); return 4; // LDA abs,X case 0xBE: LDX( src_abs_Y() ); return 4; // LDX abs,Y // case 0xBF: - case 0xC0: CPY( imm() ); break; // CPY imm - case 0xC1: CMP( src_X_ind() ) ; break; // LDA X,ind + case 0xC0: CPY( imm() ); return 2; // CPY imm + case 0xC1: CMP( src_X_ind() ) ; return 6; // LDA X,ind // case 0xC2: // case 0xC3: case 0xC4: CPY( src_zp() ); return 3; // CPY zpg @@ -624,7 +624,7 @@ INLINE int m6502_Step() { // case 0xCB: case 0xCC: CPY( src_abs() ); return 4; // CPY abs case 0xCD: CMP( src_abs() ); return 4; // CMP abs - case 0xCE: DEC( dest_abs() ); return 4; // DEC abs + case 0xCE: DEC( dest_abs() ); return 6; // DEC abs // case 0xCF: case 0xD0: BNE( rel_addr() ); return 2; // BNE rel case 0xD1: CMP( src_ind_Y() ); return 5; // CMP ind,Y @@ -672,7 +672,7 @@ INLINE int m6502_Step() { // case 0xFB: // case 0xFC: case 0xFD: SBC( src_abs_X() ); return 4; // SBC abs,X - case 0xFE: INC( dest_abs_X() ); return 6; // INC abs,X + case 0xFE: INC( dest_abs_X() ); return 7; // INC abs,X // case 0xFF: default: @@ -804,6 +804,11 @@ void m6502_Run() { } +// if ( m6502.clktime - disk.clk_last_access > clk_diskAcceleratorTimeout ) { + clk_6502_per_frm = clk_6502_per_frm_set; +// } + + // clock_t end = clock(); // double execution_time = ((double) (end - start)) / CLOCKS_PER_SEC; // unsigned long long e = rdtsc(); @@ -814,10 +819,17 @@ void m6502_Run() { // mhz = clktime / (execution_time * M); } -void read_rom( const char * filename, uint8_t * rom, const uint16_t addr ) { - FILE * f = fopen(filename, "rb"); +void read_rom( const char * bundlePath, const char * filename, uint8_t * rom, const uint16_t addr ) { + + char fullPath[256]; + + strcpy( fullPath, bundlePath ); + strcat(fullPath, "/"); + strcat(fullPath, filename); + + FILE * f = fopen(fullPath, "rb"); if (f == NULL) { - perror("Failed: "); + perror("Failed to read ROM: "); return; } @@ -831,15 +843,17 @@ void read_rom( const char * filename, uint8_t * rom, const uint16_t addr ) { } -void m6502_ColdReset() { +void m6502_ColdReset( const char * bundlePath ) { inst_cnt = 0; mhz = (double)MHz_6502 / M; + + printf("Bundlepath: %s", bundlePath); - epoch = rdtsc(); - sleep(1); - unsigned long long e = rdtsc(); - tick_per_sec = e - epoch; - tick_6502_per_sec = tick_per_sec / MHz_6502; +// epoch = rdtsc(); +// sleep(1); +// unsigned long long e = rdtsc(); +// tick_per_sec = e - epoch; +// tick_6502_per_sec = tick_per_sec / MHz_6502; memset( RAM, 0, sizeof(Apple2_64K_RAM) ); memset( RAM + 0xC000, 0, 0x1000 ); // I/O area should be 0 @@ -865,19 +879,42 @@ void m6502_ColdReset() { #else // Apple ][+ ROM - read_rom("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/Apple2Plus.rom", Apple2_12K_ROM, 0); + read_rom( bundlePath, "Apple2Plus.rom", Apple2_12K_ROM, 0); +// read_rom( "/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/", "Apple2Plus.rom", Apple2_12K_ROM, 0); +// read_rom("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/Apple2Plus.rom", Apple2_12K_ROM, 0); memcpy(Apple2_64K_RAM + 0xD000, Apple2_12K_ROM, sizeof(Apple2_12K_ROM)); // Disk ][ ROM in Slot 6 - read_rom("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/DISK_II_C600.ROM", Apple2_64K_RAM, 0xC600); - + read_rom( bundlePath, "DISK_II_C600.ROM", Apple2_64K_RAM, 0xC600); +// read_rom( "/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/", "DISK_II_C600.ROM", Apple2_64K_RAM, 0xC600); + // WOZ DISK // woz_loadFile("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/DOS 3.3 System Master.woz"); // woz_loadFile("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/Hard Hat Mack - Disk 1, Side A.woz"); // woz_loadFile("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/Merlin-8 v2.48 (DOS 3.3).woz"); // woz_loadFile("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/DOS3.3.Launcher.2.2.woz"); - woz_loadFile("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/Apple DOS 3.3 January 1983.woz"); +// woz_loadFile("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/", "Apple DOS 3.3 January 1983.woz"); + + // GAMES +//woz_loadFile( bundlePath, "qbit.woz"); // Lode Runner, Hard Hat Mack, QBit, Crossfire, Heat Seaker, Flight Simulator +// woz_loadFile( bundlePath, "Donkey Kong.woz"); + +/**/// woz_loadFile( bundlePath, "Crossfire.woz"); +// woz_loadFile( bundlePath, "Lode Runner.woz"); +/**/// woz_loadFile( bundlePath, "Sneakers.woz"); +/**/// woz_loadFile( bundlePath, "Wavy Navy.woz"); +/**/// woz_loadFile( bundlePath, "Xonix.woz"); +/**/// woz_loadFile( bundlePath, "Hard Hat Mack - Disk 1, Side A.woz"); + + + // SYSTEM +/* Requires 64K */// woz_loadFile( bundlePath, "ProDOS_312.woz"); + +// woz_loadFile( bundlePath, "Merlin-8 v2.48 (DOS 3.3).woz"); + woz_loadFile( bundlePath, "Apple DOS 3.3 January 1983.woz"); + + m6502.A = m6502.X = m6502.Y = 0xFF; // reset vector m6502.SP = 0xFF; //-3; @@ -1004,10 +1041,10 @@ void tst6502() { // insert code here... printf("6502\n"); - m6502_ColdReset(); + m6502_ColdReset( "" ); // clock_t start = clock(); - epoch = rdtsc(); +// epoch = rdtsc(); m6502_Run(); // clock_t end = clock(); // double execution_time = ((double) (end - start)) / CLOCKS_PER_SEC; diff --git a/src/cpu/6502.h b/src/cpu/6502.h index e4fbe2d..463195e 100644 --- a/src/cpu/6502.h +++ b/src/cpu/6502.h @@ -10,7 +10,7 @@ #define __6502_H__ #include -#include "common.h" +#include "../../src/util/common.h" extern unsigned long long MHz_6502; @@ -92,6 +92,21 @@ typedef struct disassembly_s { } disassembly_t; +typedef union videoMode_u { + struct { + uint8_t text : 1; // 0: graphics 1: text + uint8_t col80 : 1; // 0: 40 col 1: 80 col + uint8_t altChr : 1; // 0: normal 1: alternate character set + uint8_t mixed : 1; // 0: no mix 1: mixed graphics and text when in graphics mode + uint8_t hires : 1; // 0: loRes 1: hiRes + uint8_t page : 1; // 0: page 1 1: page 2 (aux video memory) + }; + uint8_t mode; +} videoMode_t; + +extern videoMode_t videoMode; + + extern m6502_t m6502; extern uint8_t * RAM; extern uint32_t * videoMemPtr; @@ -101,12 +116,13 @@ extern void hires_Update(void); extern double mips; extern double mhz; -#define fps 15 +#define fps 30 extern void tst6502(void); -extern void m6502_ColdReset(void); +extern void m6502_ColdReset( const char * bundlePath ); extern void m6502_Run(void); extern void kbdInput ( uint8_t code ); +extern void setIO ( uint16_t ioaddr, uint8_t val ); diff --git a/src/cpu/instructions/6502_instr_branch.h b/src/cpu/instructions/6502_instr_branch.h index 517917a..e7c69a6 100644 --- a/src/cpu/instructions/6502_instr_branch.h +++ b/src/cpu/instructions/6502_instr_branch.h @@ -10,8 +10,13 @@ #define __6502_INSTR_BRANCH_H__ INLINE void BRA( int8_t reladdr ) { + uint8_t pg = m6502.PC >> 8; m6502.PC += reladdr; +#ifdef CLK_ABSOLUTE_PRECISE + m6502.clktime += m6502.PC >> 8 == pg ? 1 : 2; +#else m6502.clktime++; +#endif #ifdef DEBUG if ( reladdr == -2 ) { dbgPrintf2("Infinite Loop at %04X!\n", m6502.PC); diff --git a/src/cpu/instructions/6502_instr_call_ret_jump.h b/src/cpu/instructions/6502_instr_call_ret_jump.h index 23a0caf..1a244ce 100644 --- a/src/cpu/instructions/6502_instr_call_ret_jump.h +++ b/src/cpu/instructions/6502_instr_call_ret_jump.h @@ -68,9 +68,9 @@ INLINE void RTS() { // disk accelerator would only work for a certain amount of time // currently it is 200ms simulated times - if ( m6502.clktime - disk.clk_last_access > clk_diskAcceleratorTimeout ) { - clk_6502_per_frm = clk_6502_per_frm_set; - } +// if ( m6502.clktime - disk.clk_last_access > clk_diskAcceleratorTimeout ) { +// clk_6502_per_frm = clk_6502_per_frm_set; +// } } /** diff --git a/src/dev/disk/disk.c b/src/dev/disk/disk.c index 02d8f2b..aff8aa6 100644 --- a/src/dev/disk/disk.c +++ b/src/dev/disk/disk.c @@ -7,8 +7,8 @@ // #include "disk.h" -#include "6502.h" -#include "common.h" +#include "../../cpu/6502.h" +#include "../../util/common.h" #include "woz.h" @@ -17,8 +17,9 @@ disk_t disk = { 0, // clk_since_last_read }; -const unsigned long long clk_6502_per_frm_diskAccelerator = 25 * M / fps; // disk acceleration bumps up CPU clock to 25 MHz -const unsigned long long clk_diskAcceleratorTimeout = 200000ULL; +int diskAccelerator_speed = 25; // 0 means no acceleration +//const unsigned long long clk_6502_per_frm_diskAccelerator = 25 * M / fps; // disk acceleration bumps up CPU clock to 25 MHz +//const unsigned long long clk_diskAcceleratorTimeout = 1000ULL; // motor position from the magnet state @@ -61,7 +62,10 @@ void disk_phase() { // printf(", p:%d d:%d l:%d: ph:%u trk:%u)", position, direction, lastPosition, phase.count, woz_tmap.phase[phase.count]); disk.clk_last_access = m6502.clktime; - clk_6502_per_frm = clk_6502_per_frm_diskAccelerator; + if ( diskAccelerator_speed > clk_6502_per_frm ) { +// clk_6502_per_frm = clk_6502_per_frm_diskAccelerator; + clk_6502_per_frm = diskAccelerator_speed * M / fps; // clk_6502_per_frm_diskAccelerator; + } } else { @@ -75,7 +79,9 @@ void disk_phase() { uint8_t disk_read() { dbgPrintf("io_DISK_READ (S%u)\n", 6); disk.clk_last_access = m6502.clktime; - clk_6502_per_frm = clk_6502_per_frm_diskAccelerator; + if ( diskAccelerator_speed > 2 ) { + clk_6502_per_frm = diskAccelerator_speed * M / fps; // clk_6502_per_frm_diskAccelerator; + } return woz_read(); } diff --git a/src/dev/disk/disk.h b/src/dev/disk/disk.h index 77202b3..976a04b 100644 --- a/src/dev/disk/disk.h +++ b/src/dev/disk/disk.h @@ -9,7 +9,7 @@ #ifndef disk_h #define disk_h -#include "common.h" +#include "../../util/common.h" #define minDiskTrackNum 0 @@ -52,8 +52,10 @@ extern disk_t disk; extern const int magnet_to_Poistion[16]; extern const int position_to_direction[8][8]; -extern const unsigned long long clk_6502_per_frm_diskAccelerator; -extern const unsigned long long clk_diskAcceleratorTimeout; + +extern int diskAccelerator_speed; // 0 means no acceleration +//extern const unsigned long long clk_6502_per_frm_diskAccelerator; +//extern const unsigned long long clk_diskAcceleratorTimeout; extern void disk_phase(void); extern uint8_t disk_read(void); diff --git a/src/dev/disk/woz.c b/src/dev/disk/woz.c index 2babbfe..3e78fdc 100644 --- a/src/dev/disk/woz.c +++ b/src/dev/disk/woz.c @@ -7,6 +7,7 @@ // #include +#include #include "woz.h" #include "disk.h" @@ -85,13 +86,12 @@ uint8_t woz_read() { return rand(); } +#ifdef WOZ_REAL_SPIN if ( track != track_loaded ) { woz_loadTrack(track); track_loaded = track; } -#ifdef WOZ_REAL_SPIN - WOZread.shift32 = 0; bitOffset = (m6502.clktime >> 2) & 7; trackOffset = (m6502.clktime >> 5) % WOZ_TRACK_BYTE_COUNT; @@ -253,23 +253,25 @@ uint8_t woz_read() { #else // WOZ_REAL_SPIN clkelpased = m6502.clktime - m6502.clklast; m6502.clklast = m6502.clktime; + + uint16_t usedBytes = woz_trks[track].bytes_used < WOZ_TRACK_BYTE_COUNT ? woz_trks[track].bytes_used : WOZ_TRACK_BYTE_COUNT; if ( clkelpased > 100 ) { // printf("NEED SYNC : %llu\n", clkelpased); bitOffset = (clkelpased >> 2) & 7; - trackOffset += ((clkelpased >> 5) +100) % WOZ_TRACK_BYTE_COUNT; + trackOffset += ((clkelpased >> 5) +100) % usedBytes; WOZread.data = woz_trks[track].data[trackOffset]; } // to avoid infinite loop and to search for bit 7 high - for ( int i = 0; i < WOZ_TRACK_BYTE_COUNT * 8; i++ ) { + for ( int i = 0; i < usedBytes * 8; i++ ) { if ( ++bitOffset >= 8 ) { bitOffset = 0; // if ( ++trackOffset >= WOZ_TRACK_BYTE_COUNT ) { // trackOffset = 0; // } trackOffset++; - trackOffset %= WOZ_TRACK_BYTE_COUNT; + trackOffset %= usedBytes; // printf("offs:%u\n", trackOffset); WOZread.data = woz_trks[track].data[trackOffset]; @@ -292,10 +294,17 @@ uint8_t woz_read() { } -void woz_loadFile( const char * filename ) { - FILE * f = fopen(filename, "rb"); +void woz_loadFile( const char * bundlePath, const char * filename ) { + + char fullpath[256]; + + strcpy(fullpath, bundlePath); + strcat(fullpath, "/"); + strcat(fullpath, filename); + + FILE * f = fopen(fullpath, "rb"); if (f == NULL) { - perror("Failed: "); + perror("Failed to read WOZ: "); return; } diff --git a/src/dev/disk/woz.h b/src/dev/disk/woz.h index 20ea9ab..f45a731 100644 --- a/src/dev/disk/woz.h +++ b/src/dev/disk/woz.h @@ -120,7 +120,7 @@ extern uint8_t WOZlatch; extern uint8_t woz_read(void); -extern void woz_loadFile( const char * filename ); +extern void woz_loadFile( const char * bundlePath, const char * filename ); #endif /* woz_h */ diff --git a/src/dev/mem/mmio.h b/src/dev/mem/mmio.h index 8c2e6b2..1124eca 100644 --- a/src/dev/mem/mmio.h +++ b/src/dev/mem/mmio.h @@ -24,6 +24,8 @@ typedef union address16_u { } address16_t; +videoMode_t videoMode = { 1 }; // 40 col text, page 1 + uint8_t Apple2_Dummy_Page[ 1 * PG ]; // Dummy Page for discarding data uint8_t Apple2_512_AUX[ 2 * PG ] = {0}; // Auxiliary bank for page 0 and 1 @@ -178,11 +180,35 @@ struct MEMcfg_s { } MEMcfg = { 1, 0, 0, 0, 0 }; enum mmio { + // Keyboard io_KBD = 0xC000, io_KBDSTRB = 0xC010, + // Audio io_SPKR = 0xC030, + + // Video + io_VID_80col_OFF = 0xC00C, + io_VID_80col_ON = 0xC00D, + io_VID_AltChar_OFF = 0xC00E, + io_VID_AltChar_ON = 0xC00F, + io_VID_Text_OFF = 0xC050, + io_VID_Text_ON = 0xC051, + io_VID_Mixed_OFF = 0xC052, + io_VID_Mixed_ON = 0xC053, + io_VID_Page2_OFF = 0xC054, + io_VID_Page2_ON = 0xC055, + io_VID_Hires_OFF = 0xC056, + io_VID_Hires_ON = 0xC057, + // Game Controller + io_PDL0 = 0xC064, + io_PDL1 = 0xC065, + io_PDL2 = 0xC066, + io_PDL3 = 0xC067, + io_PDL_STROBE = 0xC070, + + // Disk ][ io_DISK_PHASE0_OFF = 0xC080, io_DISK_PHASE0_ON = 0xC081, io_DISK_PHASE1_OFF = 0xC082, @@ -200,6 +226,7 @@ enum mmio { io_DISK_CLEAR = 0xC08E, io_DISK_SHIFT = 0xC08F, + // Memory io_MEM_RDRAM_NOWR_2 = 0xC080, io_MEM_RDROM_WRAM_2 = 0xC081, io_MEM_RDROM_NOWR_2 = 0xC082, @@ -239,6 +266,64 @@ INLINE uint8_t ioRead( uint16_t addr ) { return RAM[io_SPKR]; + case io_VID_80col_OFF: + videoMode.col80 = 0; + break; + + case io_VID_80col_ON: + videoMode.col80 = 1; + break; + + case io_VID_AltChar_OFF: + videoMode.altChr = 0; + break; + + case io_VID_AltChar_ON: + videoMode.altChr = 1; + break; + + case io_VID_Text_OFF: + videoMode.text = 0; + break; + + case io_VID_Text_ON: + videoMode.text = 1; + break; + + case io_VID_Mixed_OFF: + videoMode.mixed = 0; + break; + + case io_VID_Mixed_ON: + videoMode.mixed = 1; + break; + + case io_VID_Page2_OFF: + videoMode.page = 0; + break; + + case io_VID_Page2_ON: + videoMode.page = 1; + break; + + case io_VID_Hires_OFF: + videoMode.hires = 0; + break; + + case io_VID_Hires_ON: + videoMode.hires = 1; + break; + + + case io_PDL0: + case io_PDL1: + case io_PDL2: + case io_PDL3: +// if ( RAM[addr] > 127 ) { +// RAM[addr]--; +// } + return RAM[addr]; + case io_MEM_RDRAM_NOWR_2: case io_MEM_RDROM_WRAM_2: case io_MEM_RDROM_NOWR_2: @@ -380,6 +465,11 @@ INLINE uint8_t ioRead( uint16_t addr ) { } +void setIO ( uint16_t ioaddr, uint8_t val ) { + RAM[ioaddr] = val; +} + + void kbdInput ( uint8_t code ) { // printf("kbdInput: %02X ('%c')\n", code, isprint(code) ? code : ' '); switch ( code ) { @@ -397,7 +487,7 @@ void kbdInput ( uint8_t code ) { code |= 0x80; - while ( RAM[io_KBD] > 0x7F ) { + for( int i = 1000; i && ( RAM[io_KBD] > 0x7F ); --i ) { usleep(10); } @@ -483,6 +573,11 @@ static void memwrite( uint16_t addr, uint8_t byte ) { **/ INLINE uint8_t fetch() { disHexB( disassembly.pOpcode, RAM[m6502.PC] ); +#ifdef CLK_ABSOLUTE_PRECISE + if ( (m6502.PC & 0xFF) >= 0xFF ) { + m6502.clktime++; + } +#endif return memread( m6502.PC++ ); } @@ -493,6 +588,11 @@ INLINE uint8_t fetch() { INLINE uint16_t fetch16() { uint16_t word = memread16( m6502.PC ); // disPrintf(disassembly.comment, "fetch16:%04X", word); + #ifdef CLK_ABSOLUTE_PRECISE + if ( (m6502.PC & 0xFF) >= 0xFE ) { + m6502.clktime++; + } + #endif m6502.PC += 2; disHexW( disassembly.pOpcode, word ); return word; diff --git a/A2Mac/RepeatingTimer.swift b/src/util/RepeatingTimer.swift similarity index 100% rename from A2Mac/RepeatingTimer.swift rename to src/util/RepeatingTimer.swift