diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 3e4acf185..30a5574bb 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -403,6 +403,7 @@ 4BD69F941D98760000243FE1 /* AcornADF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD69F921D98760000243FE1 /* AcornADF.cpp */; }; 4BE77A2E1D84ADFB00BC3827 /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE77A2C1D84ADFB00BC3827 /* File.cpp */; }; 4BE7C9181E3D397100A5496D /* TIA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE7C9161E3D397100A5496D /* TIA.cpp */; }; + 4BE9A6B11EDE293000CBCB47 /* zexdoc.com in Resources */ = {isa = PBXBuildFile; fileRef = 4BE9A6B01EDE293000CBCB47 /* zexdoc.com */; }; 4BEA525E1DF33323007E74F2 /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA525D1DF33323007E74F2 /* Tape.cpp */; }; 4BEA52631DF339D7007E74F2 /* Speaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA52611DF339D7007E74F2 /* Speaker.cpp */; }; 4BEA52661DF3472B007E74F2 /* Speaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA52641DF3472B007E74F2 /* Speaker.cpp */; }; @@ -944,6 +945,7 @@ 4BE77A2D1D84ADFB00BC3827 /* File.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = File.hpp; path = ../../StaticAnalyser/Commodore/File.hpp; sourceTree = ""; }; 4BE7C9161E3D397100A5496D /* TIA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TIA.cpp; sourceTree = ""; }; 4BE7C9171E3D397100A5496D /* TIA.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TIA.hpp; sourceTree = ""; }; + 4BE9A6B01EDE293000CBCB47 /* zexdoc.com */ = {isa = PBXFileReference; lastKnownFileType = file; name = zexdoc.com; path = Zexall/zexdoc.com; sourceTree = ""; }; 4BEA525D1DF33323007E74F2 /* Tape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Tape.cpp; path = Electron/Tape.cpp; sourceTree = ""; }; 4BEA525F1DF333D8007E74F2 /* Tape.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = Tape.hpp; path = Electron/Tape.hpp; sourceTree = ""; }; 4BEA52601DF3343A007E74F2 /* Interrupts.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = Interrupts.hpp; path = Electron/Interrupts.hpp; sourceTree = ""; }; @@ -1050,7 +1052,7 @@ 4B44EBF81DC9898E00A7820C /* BCDTEST_beeb */, 4B44EBF61DC9883B00A7820C /* 6502_functional_test.bin */, 4B44EBF41DC987AE00A7820C /* AllSuiteA.bin */, - 4BFCA1281ECBE7A700AC40C1 /* zexall.com */, + 4BE9A6B21EDE294200CBCB47 /* Zexall */, 4BBF49B41ED2881600AB3669 /* FUSE */, 4BB297E41B587D8300A49093 /* Wolfgang Lorenz 6502 test suite */, ); @@ -2003,6 +2005,15 @@ path = Resources; sourceTree = ""; }; + 4BE9A6B21EDE294200CBCB47 /* Zexall */ = { + isa = PBXGroup; + children = ( + 4BFCA1281ECBE7A700AC40C1 /* zexall.com */, + 4BE9A6B01EDE293000CBCB47 /* zexdoc.com */, + ); + name = Zexall; + sourceTree = ""; + }; 4BEAC0801E7E0DF800EE56B2 /* Cartridges */ = { isa = PBXGroup; children = ( @@ -2370,6 +2381,7 @@ 4BB299781B587D8400A49093 /* ldaix in Resources */, 4B44EBF71DC9883B00A7820C /* 6502_functional_test.bin in Resources */, 4BB299291B587D8400A49093 /* cia2pb7 in Resources */, + 4BE9A6B11EDE293000CBCB47 /* zexdoc.com in Resources */, 4BB2994A1B587D8400A49093 /* deca in Resources */, 4BB299CA1B587D8400A49093 /* sbciy in Resources */, 4BB2993D1B587D8400A49093 /* cpxa in Resources */, diff --git a/OSBindings/Mac/Clock SignalTests/ZexallTests.swift b/OSBindings/Mac/Clock SignalTests/ZexallTests.swift index 8931cfdd8..ddc0ba893 100644 --- a/OSBindings/Mac/Clock SignalTests/ZexallTests.swift +++ b/OSBindings/Mac/Clock SignalTests/ZexallTests.swift @@ -15,7 +15,7 @@ class ZexallTests: XCTestCase, CSTestMachineTrapHandler { fileprivate var output = "" func testZexall() { - if let filename = Bundle(for: type(of: self)).path(forResource: "zexall", ofType: "com") { + if let filename = Bundle(for: type(of: self)).path(forResource: "zexdoc", ofType: "com") { if let testData = try? Data(contentsOf: URL(fileURLWithPath: filename)) { // install test program, at the usual CP/M place @@ -33,16 +33,100 @@ class ZexallTests: XCTestCase, CSTestMachineTrapHandler { // CP/M programs can exit machine.addTrapAddress(0); + // ensure that if the CPU hits zero, it stays there until the end of the + // sampling window + machine.setValue(0xc3, atAddress: 0x0000) + machine.setValue(0x00, atAddress: 0x0001) + machine.setValue(0x00, atAddress: 0x0002) + // seed execution at 0x0100 machine.setValue(0x0100, for: .programCounter) // run! + let cyclesPerIteration: Int32 = 400_000_000 + var cyclesToDate: TimeInterval = 0 + let startDate = Date() + var printDate = Date() while !done { - machine.runForNumber(ofCycles: 200) + machine.runForNumber(ofCycles: cyclesPerIteration) + cyclesToDate += TimeInterval(cyclesPerIteration) + if printDate.timeIntervalSinceNow < -5.0 { + print("\(cyclesToDate / -startDate.timeIntervalSinceNow) Mhz") + printDate = Date() + } } - print("Done!") - print(output) + let targetOutput = + "Z80doc instruction exerciser\n\r" + + " hl,.... OK\n\r" + + "add hl,.......... OK\n\r" + + "add ix,.......... OK\n\r" + + "add iy,.......... OK\n\r" + + "aluop a,nn.................... OK\n\r" + + "aluop a,.. OK\n\r" + + "aluop a,..... OK\n\r" + + "aluop a,(+1)........... OK\n\r" + + "bit n,(+1)............. OK\n\r" + + "bit n,.... OK\n\r" + + "cpd........................ OK\n\r" + + "cpi........................ OK\n\r" + + "............. OK\n\r" + + " a................... OK\n\r" + + " b................... OK\n\r" + + " bc.................. OK\n\r" + + " c................... OK\n\r" + + " d................... OK\n\r" + + " de.................. OK\n\r" + + " e................... OK\n\r" + + " h................... OK\n\r" + + " hl.................. OK\n\r" + + " ix.................. OK\n\r" + + " iy.................. OK\n\r" + + " l................... OK\n\r" + + " (hl)................ OK\n\r" + + " sp.................. OK\n\r" + + " (+1)......... OK\n\r" + + " ixh................. OK\n\r" + + " ixl................. OK\n\r" + + " iyh................. OK\n\r" + + " iyl................. OK\n\r" + + "ld ,(nnnn)............. OK\n\r" + + "ld hl,(nnnn).................. OK\n\r" + + "ld sp,(nnnn).................. OK\n\r" + + "ld ,(nnnn)............. OK\n\r" + + "ld (nnnn),............. OK\n\r" + + "ld (nnnn),hl.................. OK\n\r" + + "ld (nnnn),sp.................. OK\n\r" + + "ld (nnnn),............. OK\n\r" + + "ld ,nnnn......... OK\n\r" + + "ld ,nnnn............... OK\n\r" + + "ld a,<(bc),(de)>.............. OK\n\r" + + "ld ,nn.... OK\n\r" + + "ld (+1),nn............. OK\n\r" + + "ld ,(+1)...... OK\n\r" + + "ld ,(+1).......... OK\n\r" + + "ld a,(+1).............. OK\n\r" + + "ld ,nn....... OK\n\r" + + "ld ,........ OK\n\r" + + "ld ,........ OK\n\r" + + "ld a,(nnnn) / ld (nnnn),a..... OK\n\r" + + "ldd (1).................... OK\n\r" + + "ldd (2).................... OK\n\r" + + "ldi (1).................... OK\n\r" + + "ldi (2).................... OK\n\r" + + "neg........................... OK\n\r" + + "..................... OK\n\r" + + "........... OK\n\r" + + "shf/rot (+1)........... OK\n\r" + + "shf/rot .. OK\n\r" + + " n,..... OK\n\r" + + " n,(+1)....... OK\n\r" + + "ld (+1),...... OK\n\r" + + "ld (+1),.......... OK\n\r" + + "ld (+1),a.............. OK\n\r" + + "ld (),a................ OK\n\r" + + "Tests complete\n\r" + XCTAssertEqual(targetOutput, output); } } } @@ -51,6 +135,7 @@ class ZexallTests: XCTestCase, CSTestMachineTrapHandler { switch address { case 0x0005: let cRegister = testMachine.value(for: .C) + var textToAppend = "" switch cRegister { case 9: var address = testMachine.value(for: .DE) @@ -60,17 +145,18 @@ class ZexallTests: XCTestCase, CSTestMachineTrapHandler { if character == "$" { break } - output = output + String(character) + textToAppend += String(character) address = address + 1 } case 5: - output += String(describing: UnicodeScalar(testMachine.value(for: .E))) + textToAppend = String(describing: UnicodeScalar(testMachine.value(for: .E))) case 0: done = true default: break } - print(output) + print(textToAppend) + case 0x0000: done = true