mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-25 18:30:21 +00:00
129 lines
3.2 KiB
Swift
129 lines
3.2 KiB
Swift
//
|
|
// PatrikRakTests.swift
|
|
// Clock Signal
|
|
//
|
|
// Created by Thomas Harte on 22/02/2020.
|
|
// Copyright 2017 Thomas Harte. All rights reserved.
|
|
//
|
|
|
|
import XCTest
|
|
import Foundation
|
|
|
|
class PatrikRakTests: XCTestCase, CSTestMachineTrapHandler {
|
|
|
|
private var done = false
|
|
private var output = ""
|
|
|
|
private func runTest(_ name: 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
|
|
}
|
|
|
|
assert(dataPointer == testData.count)
|
|
|
|
// Create a machine.
|
|
let machine = CSTestMachineZ80()
|
|
machine.portLogic = .return191
|
|
|
|
// 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)
|
|
machine.setValue(0x80, atAddress: 0x7002)
|
|
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
|
|
while !done {
|
|
machine.runForNumber(ofCycles: cyclesPerIteration)
|
|
}
|
|
|
|
let successRange = output.range(of: "Result: all tests passed.")
|
|
XCTAssertNotEqual(successRange, nil)
|
|
|
|
if successRange == nil {
|
|
print("Output was: \(output)")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func testCCF() {
|
|
runTest("z80ccf")
|
|
}
|
|
|
|
func testDoc() {
|
|
runTest("z80doc")
|
|
}
|
|
|
|
func testDocFlags() {
|
|
runTest("z80docflags")
|
|
}
|
|
|
|
func testFlags() {
|
|
runTest("z80flags")
|
|
}
|
|
|
|
func testFull() {
|
|
runTest("z80full")
|
|
}
|
|
|
|
func testMemptr() {
|
|
runTest("z80memptr")
|
|
}
|
|
|
|
func testMachine(_ testMachine: CSTestMachine, didTrapAtAddress address: UInt16) {
|
|
let testMachineZ80 = testMachine as! CSTestMachineZ80
|
|
switch address {
|
|
case 0x0010:
|
|
var characterCode = testMachineZ80.value(for: .A)
|
|
|
|
// Of the control codes, retain only new line. Map the rest to space.
|
|
if characterCode < 32 && characterCode != 13 {
|
|
characterCode = 32
|
|
}
|
|
|
|
// Similarly, map down unprintables.
|
|
if characterCode >= 127 {
|
|
characterCode = 32
|
|
}
|
|
|
|
let textToAppend = UnicodeScalar(characterCode)!
|
|
output += String(textToAppend)
|
|
// print(textToAppend, terminator:"")
|
|
|
|
case 0x7003:
|
|
done = true
|
|
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
}
|