diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 9bf6104c7..ed74f9c91 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -225,6 +225,12 @@ 4B643F3F1D77B88000D431D6 /* DocumentController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B643F3E1D77B88000D431D6 /* DocumentController.swift */; }; 4B65086022F4CF8D009C1100 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B65085F22F4CF8D009C1100 /* Keyboard.cpp */; }; 4B65086122F4CFE0009C1100 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B65085F22F4CF8D009C1100 /* Keyboard.cpp */; }; + 4B670A9B2401CB8400D4E002 /* z80memptr.tap in Resources */ = {isa = PBXBuildFile; fileRef = 4B670A832401CB8400D4E002 /* z80memptr.tap */; }; + 4B670A9D2401CB8400D4E002 /* z80ccf.tap in Resources */ = {isa = PBXBuildFile; fileRef = 4B670A852401CB8400D4E002 /* z80ccf.tap */; }; + 4B670A9F2401CB8400D4E002 /* z80flags.tap in Resources */ = {isa = PBXBuildFile; fileRef = 4B670A872401CB8400D4E002 /* z80flags.tap */; }; + 4B670AA12401CB8400D4E002 /* z80doc.tap in Resources */ = {isa = PBXBuildFile; fileRef = 4B670A892401CB8400D4E002 /* z80doc.tap */; }; + 4B670AB02401CB8400D4E002 /* z80full.tap in Resources */ = {isa = PBXBuildFile; fileRef = 4B670A992401CB8400D4E002 /* z80full.tap */; }; + 4B670AB12401CB8400D4E002 /* z80docflags.tap in Resources */ = {isa = PBXBuildFile; fileRef = 4B670A9A2401CB8400D4E002 /* z80docflags.tap */; }; 4B680CE223A5553100451D43 /* 68000ComparativeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B680CE123A5553100451D43 /* 68000ComparativeTests.mm */; }; 4B680CE423A555CA00451D43 /* 68000 Comparative Tests in Resources */ = {isa = PBXBuildFile; fileRef = 4B680CE323A555CA00451D43 /* 68000 Comparative Tests */; }; 4B69FB3D1C4D908A00B5F0AA /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B69FB3B1C4D908A00B5F0AA /* Tape.cpp */; }; @@ -1133,6 +1139,12 @@ 4B643F3E1D77B88000D431D6 /* DocumentController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DocumentController.swift; sourceTree = ""; }; 4B644ED023F0FB55006C0CC5 /* ScanSynchroniser.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ScanSynchroniser.hpp; sourceTree = ""; }; 4B65085F22F4CF8D009C1100 /* Keyboard.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Keyboard.cpp; sourceTree = ""; }; + 4B670A832401CB8400D4E002 /* z80memptr.tap */ = {isa = PBXFileReference; lastKnownFileType = file; path = z80memptr.tap; sourceTree = ""; }; + 4B670A852401CB8400D4E002 /* z80ccf.tap */ = {isa = PBXFileReference; lastKnownFileType = file; path = z80ccf.tap; sourceTree = ""; }; + 4B670A872401CB8400D4E002 /* z80flags.tap */ = {isa = PBXFileReference; lastKnownFileType = file; path = z80flags.tap; sourceTree = ""; }; + 4B670A892401CB8400D4E002 /* z80doc.tap */ = {isa = PBXFileReference; lastKnownFileType = file; path = z80doc.tap; sourceTree = ""; }; + 4B670A992401CB8400D4E002 /* z80full.tap */ = {isa = PBXFileReference; lastKnownFileType = file; path = z80full.tap; sourceTree = ""; }; + 4B670A9A2401CB8400D4E002 /* z80docflags.tap */ = {isa = PBXFileReference; lastKnownFileType = file; path = z80docflags.tap; sourceTree = ""; }; 4B680CE123A5553100451D43 /* 68000ComparativeTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = 68000ComparativeTests.mm; sourceTree = ""; }; 4B680CE323A555CA00451D43 /* 68000 Comparative Tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "68000 Comparative Tests"; sourceTree = ""; }; 4B698D1A1FE768A100696C91 /* SampleSource.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = SampleSource.hpp; sourceTree = ""; }; @@ -1926,6 +1938,7 @@ 4B1414631B588A1100E04248 /* Test Binaries */ = { isa = PBXGroup; children = ( + 4B670A822401CB8400D4E002 /* Patrik Rak Z80 Tests */, 4B680CE323A555CA00451D43 /* 68000 Comparative Tests */, 4B85322B227793CA00F26553 /* TOS Startup */, 4B9252CD1E74D28200B76AF1 /* Atari ROMs */, @@ -2435,6 +2448,19 @@ path = "Document Controller"; sourceTree = ""; }; + 4B670A822401CB8400D4E002 /* Patrik Rak Z80 Tests */ = { + isa = PBXGroup; + children = ( + 4B670A852401CB8400D4E002 /* z80ccf.tap */, + 4B670A892401CB8400D4E002 /* z80doc.tap */, + 4B670A9A2401CB8400D4E002 /* z80docflags.tap */, + 4B670A872401CB8400D4E002 /* z80flags.tap */, + 4B670A992401CB8400D4E002 /* z80full.tap */, + 4B670A832401CB8400D4E002 /* z80memptr.tap */, + ); + path = "Patrik Rak Z80 Tests"; + sourceTree = ""; + }; 4B69FB391C4D908A00B5F0AA /* Storage */ = { isa = PBXGroup; children = ( @@ -3957,6 +3983,7 @@ 4BB299551B587D8400A49093 /* eoriy in Resources */, 4BB298F91B587D8400A49093 /* adczx in Resources */, 4BB299F21B587D8400A49093 /* trap6 in Resources */, + 4B670A9B2401CB8400D4E002 /* z80memptr.tap in Resources */, 4BB299A91B587D8400A49093 /* plpn in Resources */, 4BB299671B587D8400A49093 /* inxn in Resources */, 4BB2998C1B587D8400A49093 /* lsez in Resources */, @@ -3998,6 +4025,7 @@ 4BB299B01B587D8400A49093 /* rlazx in Resources */, 4BB2999F1B587D8400A49093 /* oraax in Resources */, 4BB299B71B587D8400A49093 /* rorax in Resources */, + 4B670AB02401CB8400D4E002 /* z80full.tap in Resources */, 4BB299DB1B587D8400A49093 /* staz in Resources */, 4BB299961B587D8400A49093 /* nmi in Resources */, 4BB299241B587D8400A49093 /* cia1ta in Resources */, @@ -4011,6 +4039,7 @@ 4BB299B11B587D8400A49093 /* rola in Resources */, 4BB299CE1B587D8400A49093 /* secn in Resources */, 4BB298F31B587D8400A49093 /* adcax in Resources */, + 4B670A9F2401CB8400D4E002 /* z80flags.tap in Resources */, 4BB299641B587D8400A49093 /* insiy in Resources */, 4BB299E61B587D8400A49093 /* trap10 in Resources */, 4BB299651B587D8400A49093 /* insz in Resources */, @@ -4051,6 +4080,7 @@ 4BB299251B587D8400A49093 /* cia1tab in Resources */, 4BB299C21B587D8400A49093 /* rtin in Resources */, 4BB299071B587D8400A49093 /* aslax in Resources */, + 4B670AB12401CB8400D4E002 /* z80docflags.tap in Resources */, 4BB299D51B587D8400A49093 /* shyax in Resources */, 4BB2992F1B587D8400A49093 /* clin in Resources */, 4BB299D21B587D8400A49093 /* shaiy in Resources */, @@ -4078,6 +4108,7 @@ 4BB299DD1B587D8400A49093 /* stxa in Resources */, 4BB299051B587D8400A49093 /* arrb in Resources */, 4BB299DC1B587D8400A49093 /* stazx in Resources */, + 4B670A9D2401CB8400D4E002 /* z80ccf.tap in Resources */, 4BB299C41B587D8400A49093 /* sbca in Resources */, 4BB298F41B587D8400A49093 /* adcay in Resources */, 4B44EBF51DC987AF00A7820C /* AllSuiteA.bin in Resources */, @@ -4108,6 +4139,7 @@ 4BB2991E1B587D8400A49093 /* branchwrap in Resources */, 4BB299121B587D8400A49093 /* axsa in Resources */, 4BB299561B587D8400A49093 /* eorz in Resources */, + 4B670AA12401CB8400D4E002 /* z80doc.tap in Resources */, 4BB299941B587D8400A49093 /* mmu in Resources */, 4BB299E11B587D8400A49093 /* styz in Resources */, 4BB299BA1B587D8400A49093 /* rorzx in Resources */, diff --git a/OSBindings/Mac/Clock SignalTests/PatrikRakTests.swift b/OSBindings/Mac/Clock SignalTests/PatrikRakTests.swift index 59d9c7602..cc6e4a831 100644 --- a/OSBindings/Mac/Clock SignalTests/PatrikRakTests.swift +++ b/OSBindings/Mac/Clock SignalTests/PatrikRakTests.swift @@ -14,28 +14,36 @@ class PatrikRakTests: XCTestCase, CSTestMachineTrapHandler { fileprivate var done = false fileprivate var output = "" - private func runTest(_ name: String) { + private func runTest(_ name: String, targetOutput: String) { if let filename = Bundle(for: type(of: self)).path(forResource: name, ofType: "tap") { if let testData = try? Data(contentsOf: URL(fileURLWithPath: filename)) { // Do a minor parsing of the TAP file to find the final file. var dataPointer = 0 + var finalBlock = 0 while dataPointer < testData.count { let blockSize = Int(testData[dataPointer]) + Int(testData[dataPointer+1]) << 8 - + finalBlock = dataPointer + 2 dataPointer += 2 + blockSize - break } + assert(dataPointer == testData.count) + // Create a machine. let machine = CSTestMachineZ80() - machine.setData(testData, atAddress: 0x0100) + + // Copy everything from finalBlock+1 to the end of the file to $8000. + let fileContents = testData.subdata(in: finalBlock+1 ..< testData.count) + machine.setData(fileContents, atAddress: 0x8000) // Add a RET and a trap at 10h, this is the Spectrum's system call for outputting text. machine.setValue(0xc9, atAddress: 0x0010) machine.addTrapAddress(0x0010); machine.trapHandler = self + // Also add a RET at $1601, which is where the Spectrum puts 'channel open'. + machine.setValue(0xc9, atAddress: 0x1601) + // Add a call to $8000 and then an infinite loop; these tests load at $8000 and RET when done. machine.setValue(0xcd, atAddress: 0x7000) machine.setValue(0x00, atAddress: 0x7001) @@ -43,133 +51,34 @@ class PatrikRakTests: XCTestCase, CSTestMachineTrapHandler { machine.setValue(0xc3, atAddress: 0x7003) machine.setValue(0x03, atAddress: 0x7004) machine.setValue(0x70, atAddress: 0x7005) + machine.addTrapAddress(0x7003); // seed execution at 0x7000 machine.setValue(0x7000, for: .programCounter) // run! let cyclesPerIteration: Int32 = 400_000_000 - var cyclesToDate: TimeInterval = 0 - let startDate = Date() - var printDate = Date() - let printMhz = false while !done { machine.runForNumber(ofCycles: cyclesPerIteration) - cyclesToDate += TimeInterval(cyclesPerIteration) - if printMhz && printDate.timeIntervalSinceNow < -5.0 { - print("\(cyclesToDate / -startDate.timeIntervalSinceNow) Mhz") - printDate = Date() - } } - 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); } } } func testCCF() { - runTest("z80ccf") + let targetOutput = "???" + runTest("z80ccf", targetOutput: targetOutput) } func testMachine(_ testMachine: CSTestMachine, didTrapAtAddress address: UInt16) { let testMachineZ80 = testMachine as! CSTestMachineZ80 switch address { case 0x0010: - print("TODO") - - let cRegister = testMachineZ80.value(for: .C) - var textToAppend = "" - switch cRegister { - case 9: - var address = testMachineZ80.value(for: .DE) - var character: Character = " " - while true { - character = Character(UnicodeScalar(testMachineZ80.value(atAddress: address))) - if character == "$" { - break - } - textToAppend += String(character) - address = address + 1 - } - case 5: - textToAppend = String(describing: UnicodeScalar(testMachineZ80.value(for: .E))) - case 0: - done = true - default: - break - } - output += textToAppend - print(textToAppend) + let textToAppend = UnicodeScalar(testMachineZ80.value(for: .A))! + output += String(textToAppend) + print(textToAppend, terminator:"") case 0x7003: done = true