2015-07-16 23:53:53 +00:00
|
|
|
//
|
2015-07-17 00:52:16 +00:00
|
|
|
// WolfgangLorenzTests.swift
|
|
|
|
// Clock Signal
|
2015-07-16 23:53:53 +00:00
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 16/07/2015.
|
2018-05-13 19:19:52 +00:00
|
|
|
// Copyright 2015 Thomas Harte. All rights reserved.
|
2015-07-16 23:53:53 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
import XCTest
|
2015-07-17 00:52:16 +00:00
|
|
|
import Foundation
|
2015-07-16 23:53:53 +00:00
|
|
|
|
2017-06-04 01:54:42 +00:00
|
|
|
class WolfgangLorenzTests: XCTestCase, CSTestMachineTrapHandler {
|
2020-10-10 13:34:29 +00:00
|
|
|
|
2020-10-10 14:11:57 +00:00
|
|
|
// MARK: - 6502 Tests
|
2017-11-08 03:51:06 +00:00
|
|
|
|
2020-10-10 14:11:57 +00:00
|
|
|
func testStart() {
|
|
|
|
runTest(" start", processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testLDA() {
|
|
|
|
runTest("lda", suffixes: ["b", "z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor6502)
|
2020-10-10 02:23:54 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testSTA() {
|
|
|
|
runTest("sta", suffixes: ["z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor6502)
|
2020-10-10 03:26:35 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testLDX() {
|
|
|
|
runTest("ldx", suffixes: ["b", "z", "zy", "a", "ay"], processor: .processor6502)
|
2020-10-10 03:26:35 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testSTX() {
|
|
|
|
runTest("stx", suffixes: ["z", "zy", "a"], processor: .processor6502)
|
2020-10-10 03:26:35 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testLDY() {
|
|
|
|
runTest("ldy", suffixes: ["b", "z", "zx", "a", "ax"], processor: .processor6502)
|
2020-10-10 03:26:35 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testSTY() {
|
|
|
|
runTest("sty", suffixes: ["z", "zx", "a"], processor: .processor6502)
|
2020-10-10 13:34:29 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testTransfers() {
|
|
|
|
testTransfers(processor: .processor6502)
|
2020-10-10 13:34:29 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testStack() {
|
|
|
|
testStack(processor: .processor6502)
|
2020-10-10 03:26:35 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testIncsAndDecs() {
|
|
|
|
testIncsAndDecs(processor: .processor6502)
|
2020-10-10 02:23:54 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testASL() {
|
|
|
|
self.runTest("asl", suffixes: ["n", "z", "zx", "a", "ax"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testLSR() {
|
|
|
|
self.runTest("lsr", suffixes: ["n", "z", "zx", "a", "ax"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testROL() {
|
|
|
|
self.runTest("rol", suffixes: ["n", "z", "zx", "a", "ax"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testROR() {
|
|
|
|
self.runTest("ror", suffixes: ["n", "z", "zx", "a", "ax"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testAND() {
|
|
|
|
self.runTest("and", suffixes: ["b", "z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testORA() {
|
|
|
|
self.runTest("ora", suffixes: ["b", "z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testEOR() {
|
|
|
|
self.runTest("eor", suffixes: ["b", "z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor6502)
|
2020-10-10 13:34:29 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testFlagManipulation() {
|
|
|
|
self.runTest("clcn", processor: .processor6502)
|
|
|
|
self.runTest("secn", processor: .processor6502)
|
|
|
|
self.runTest("cldn", processor: .processor6502)
|
|
|
|
self.runTest("sedn", processor: .processor6502)
|
|
|
|
self.runTest("clin", processor: .processor6502)
|
|
|
|
self.runTest("sein", processor: .processor6502)
|
|
|
|
self.runTest("clvn", processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testADC() {
|
|
|
|
self.runTest("adc", suffixes: ["b", "z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testSBC() {
|
|
|
|
self.runTest("sbc", suffixes: ["b", "z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testCompare() {
|
|
|
|
self.runTest("cmp", suffixes: ["b", "z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor6502)
|
|
|
|
self.runTest("cpx", suffixes: ["b", "z", "a"], processor: .processor6502)
|
|
|
|
self.runTest("cpy", suffixes: ["b", "z", "a"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testBIT() {
|
|
|
|
self.runTest("bit", suffixes: ["z", "a"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testFlow() {
|
|
|
|
self.runTest("brkn", processor: .processor6502)
|
|
|
|
self.runTest("rtin", processor: .processor6502)
|
|
|
|
self.runTest("jsrw", processor: .processor6502)
|
|
|
|
self.runTest("rtsn", processor: .processor6502)
|
|
|
|
self.runTest("jmpw", processor: .processor6502)
|
|
|
|
self.runTest("jmpi", processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testBranch() {
|
|
|
|
self.runTest("beqr", processor: .processor6502)
|
|
|
|
self.runTest("bner", processor: .processor6502)
|
|
|
|
self.runTest("bmir", processor: .processor6502)
|
|
|
|
self.runTest("bplr", processor: .processor6502)
|
|
|
|
self.runTest("bcsr", processor: .processor6502)
|
|
|
|
self.runTest("bccr", processor: .processor6502)
|
|
|
|
self.runTest("bvsr", processor: .processor6502)
|
|
|
|
self.runTest("bvcr", processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testNOP() {
|
|
|
|
self.runTest("nop", suffixes: ["n", "b", "z", "zx", "a", "ax"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testASO() {
|
|
|
|
self.runTest("aso", suffixes: ["z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testRLA() {
|
|
|
|
self.runTest("rla", suffixes: ["z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testLSE() {
|
|
|
|
self.runTest("lse", suffixes: ["z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testRRA() {
|
|
|
|
self.runTest("rra", suffixes: ["z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testDCM() {
|
|
|
|
self.runTest("dcm", suffixes: ["z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testINS() {
|
|
|
|
self.runTest("ins", suffixes: ["z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testLAX() {
|
|
|
|
self.runTest("lax", suffixes: ["z", "zy", "a", "ay", "ix", "iy"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testAXS() {
|
|
|
|
self.runTest("axs", suffixes: ["z", "zy", "a", "ix"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testALR() {
|
|
|
|
self.runTest("alrb", processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testARR() {
|
|
|
|
self.runTest("arrb", processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testSBX() {
|
|
|
|
self.runTest("sbxb", processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testSHA() {
|
|
|
|
self.runTest("sha", suffixes: ["ay", "iy"], processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testSHX() {
|
|
|
|
self.runTest("shxay", processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testSHY() {
|
|
|
|
self.runTest("shyax", processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testSHS() {
|
|
|
|
self.runTest("shsay", processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testLXA() {
|
|
|
|
self.runTest("lxab", processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testANE() {
|
|
|
|
self.runTest("aneb", processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testANC() {
|
|
|
|
self.runTest("ancb", processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testLAS() {
|
|
|
|
self.runTest("lasay", processor: .processor6502)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testSBCB() {
|
|
|
|
self.runTest("sbcb(eb)", processor: .processor6502)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// MARK: - 65816 Tests
|
|
|
|
|
|
|
|
func testStart65816() {
|
|
|
|
runTest(" start", processor: .processor65816)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testLDA65816() {
|
|
|
|
runTest("lda", suffixes: ["b", "z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor65816)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testSTA65816() {
|
|
|
|
runTest("sta", suffixes: ["z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor65816)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testLDX65816() {
|
|
|
|
runTest("ldx", suffixes: ["b", "z", "zy", "a", "ay"], processor: .processor65816)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testSTX65816() {
|
|
|
|
runTest("stx", suffixes: ["z", "zy", "a"], processor: .processor65816)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testLDY65816() {
|
|
|
|
runTest("ldy", suffixes: ["b", "z", "zx", "a", "ax"], processor: .processor65816)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testSTY65816() {
|
|
|
|
runTest("sty", suffixes: ["z", "zx", "a"], processor: .processor65816)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testTransfers65816() {
|
|
|
|
testTransfers(processor: .processor65816)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testStack65816() {
|
|
|
|
testStack(processor: .processor65816)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testIncsAndDecs65816() {
|
|
|
|
testIncsAndDecs(processor: .processor65816)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2020-10-10 14:11:57 +00:00
|
|
|
func testASL65816() {
|
|
|
|
self.runTest("asl", suffixes: ["n", "z", "zx", "a", "ax"], processor: .processor65816)
|
|
|
|
}
|
|
|
|
func testLSR65816() {
|
|
|
|
self.runTest("lsr", suffixes: ["n", "z", "zx", "a", "ax"], processor: .processor65816)
|
|
|
|
}
|
|
|
|
func testROL65816() {
|
|
|
|
self.runTest("rol", suffixes: ["n", "z", "zx", "a", "ax"], processor: .processor65816)
|
|
|
|
}
|
|
|
|
func testROR65816() {
|
|
|
|
self.runTest("ror", suffixes: ["n", "z", "zx", "a", "ax"], processor: .processor65816)
|
|
|
|
}
|
|
|
|
func testAND65816() {
|
|
|
|
self.runTest("and", suffixes: ["b", "z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor65816)
|
|
|
|
}
|
|
|
|
func testORA65816() {
|
|
|
|
self.runTest("ora", suffixes: ["b", "z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor65816)
|
|
|
|
}
|
|
|
|
func testEOR65816() {
|
|
|
|
self.runTest("eor", suffixes: ["b", "z", "zx", "a", "ax", "ay", "ix", "iy"], processor: .processor65816)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// MARK: - Collections
|
|
|
|
|
|
|
|
func testTransfers(processor: CSTestMachine6502Processor) {
|
|
|
|
self.runTest("taxn", processor: processor)
|
|
|
|
self.runTest("tayn", processor: processor)
|
|
|
|
self.runTest("txan", processor: processor)
|
|
|
|
self.runTest("tyan", processor: processor)
|
|
|
|
self.runTest("tsxn", processor: processor)
|
|
|
|
self.runTest("txsn", processor: processor)
|
|
|
|
}
|
|
|
|
func testStack(processor: CSTestMachine6502Processor) {
|
|
|
|
self.runTest("phan", processor: processor)
|
|
|
|
self.runTest("plan", processor: processor)
|
|
|
|
self.runTest("phpn", processor: processor)
|
|
|
|
self.runTest("plpn", processor: processor)
|
|
|
|
}
|
|
|
|
func testIncsAndDecs(processor: CSTestMachine6502Processor) {
|
|
|
|
self.runTest("inxn", processor: processor)
|
|
|
|
self.runTest("inyn", processor: processor)
|
|
|
|
self.runTest("dexn", processor: processor)
|
|
|
|
self.runTest("deyn", processor: processor)
|
|
|
|
self.runTest("incz", processor: processor)
|
|
|
|
self.runTest("inczx", processor: processor)
|
|
|
|
self.runTest("inca", processor: processor)
|
|
|
|
self.runTest("incax", processor: processor)
|
|
|
|
self.runTest("decz", processor: processor)
|
|
|
|
self.runTest("deczx", processor: processor)
|
|
|
|
self.runTest("deca", processor: processor)
|
|
|
|
self.runTest("decax", processor: processor)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// MARK: - Test Running
|
2015-07-17 00:15:30 +00:00
|
|
|
|
2020-10-10 14:11:57 +00:00
|
|
|
fileprivate func runTest(_ name: String, suffixes: [String], processor: CSTestMachine6502Processor) {
|
2015-07-17 00:15:30 +00:00
|
|
|
for suffix in suffixes {
|
|
|
|
let testName = name + suffix
|
2020-10-10 14:11:57 +00:00
|
|
|
self.runTest(testName, processor: processor)
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-16 02:12:12 +00:00
|
|
|
fileprivate var output: String = ""
|
2020-10-10 14:11:57 +00:00
|
|
|
fileprivate func runTest(_ name: String, processor: CSTestMachine6502Processor) {
|
2017-05-15 12:18:57 +00:00
|
|
|
var machine: CSTestMachine6502!
|
2015-07-17 00:15:30 +00:00
|
|
|
|
2016-09-16 02:12:12 +00:00
|
|
|
if let filename = Bundle(for: type(of: self)).path(forResource: name, ofType: nil) {
|
|
|
|
if let testData = try? Data(contentsOf: URL(fileURLWithPath: filename)) {
|
2015-07-17 00:15:30 +00:00
|
|
|
|
2020-10-10 01:44:47 +00:00
|
|
|
machine = CSTestMachine6502(processor: processor)
|
2017-06-04 01:54:42 +00:00
|
|
|
machine.trapHandler = self
|
2015-07-17 00:15:30 +00:00
|
|
|
output = ""
|
|
|
|
|
2016-09-16 02:12:12 +00:00
|
|
|
let dataPointer = (testData as NSData).bytes.bindMemory(to: UInt8.self, capacity: testData.count)
|
2015-07-31 00:51:32 +00:00
|
|
|
let loadAddress = UInt16(dataPointer[0]) | (UInt16(dataPointer[1]) << 8)
|
2016-10-04 02:03:39 +00:00
|
|
|
let contents = testData.subdata(in: 2..<(testData.count - 2))
|
2015-07-31 00:51:32 +00:00
|
|
|
|
|
|
|
machine.setData(contents, atAddress: loadAddress)
|
|
|
|
|
2020-10-10 01:39:34 +00:00
|
|
|
// Cf. http://www.softwolves.com/arkiv/cbm-hackers/7/7114.html for the steps being taken here.
|
|
|
|
|
|
|
|
// Initialise memory locations as instructed.
|
2015-07-31 00:51:32 +00:00
|
|
|
machine.setValue(0x00, forAddress: 0x0002)
|
|
|
|
machine.setValue(0x00, forAddress: 0xa002)
|
|
|
|
machine.setValue(0x80, forAddress: 0xa003)
|
|
|
|
machine.setValue(0xff, forAddress: 0x01fe)
|
|
|
|
machine.setValue(0x7f, forAddress: 0x01ff)
|
|
|
|
machine.setValue(0x48, forAddress: 0xfffe)
|
|
|
|
machine.setValue(0xff, forAddress: 0xffff)
|
|
|
|
|
2020-10-10 01:39:34 +00:00
|
|
|
// Place the Commodore's default IRQ handler.
|
2020-09-28 02:20:13 +00:00
|
|
|
let irqHandler: [UInt8] = [
|
2015-07-31 00:51:32 +00:00
|
|
|
0x48, 0x8a, 0x48, 0x98, 0x48, 0xba, 0xbd, 0x04, 0x01,
|
|
|
|
0x29, 0x10, 0xf0, 0x03, 0x6c, 0x16, 0x03, 0x6c, 0x14, 0x03
|
2020-09-28 02:20:13 +00:00
|
|
|
]
|
|
|
|
machine.setData(Data(irqHandler), atAddress: 0xff48)
|
2015-07-31 00:51:32 +00:00
|
|
|
|
2020-10-10 01:39:34 +00:00
|
|
|
// Set a couple of trap addresses to capture test output.
|
2017-06-04 01:54:42 +00:00
|
|
|
machine.addTrapAddress(0xffd2) // print character
|
|
|
|
machine.addTrapAddress(0xffe4) // scan keyboard
|
|
|
|
|
2020-10-10 01:39:34 +00:00
|
|
|
// Set a couple of test addresses that indicate failure.
|
2017-06-04 01:54:42 +00:00
|
|
|
machine.addTrapAddress(0x8000) // exit
|
|
|
|
machine.addTrapAddress(0xa474) // exit
|
|
|
|
|
2020-10-10 01:39:34 +00:00
|
|
|
// Ensure that any of those addresses return control.
|
2017-06-04 01:54:42 +00:00
|
|
|
machine.setValue(0x60, forAddress:0xffd2) // 0x60 is RTS
|
|
|
|
machine.setValue(0x60, forAddress:0xffe4)
|
|
|
|
machine.setValue(0x60, forAddress:0x8000)
|
|
|
|
machine.setValue(0x60, forAddress:0xa474)
|
|
|
|
|
2020-10-10 01:39:34 +00:00
|
|
|
// Commodore's load routine resides at $e16f; this is used to spot the end of a test.
|
|
|
|
machine.setData(Data([0x4c, 0x6f, 0xe1]), atAddress: 0xe16f)
|
2015-07-31 00:51:32 +00:00
|
|
|
|
2020-10-10 01:39:34 +00:00
|
|
|
// Seed program entry.
|
|
|
|
machine.setValue(0x0801, for: .programCounter)
|
|
|
|
machine.setValue(0xfd, for: .stackPointer)
|
|
|
|
machine.setValue(0x04, for: .flags)
|
2020-10-10 03:22:48 +00:00
|
|
|
|
|
|
|
// For consistency when debugging; otherwise immaterial.
|
|
|
|
machine.setValue(0x00, for: .A)
|
|
|
|
machine.setValue(0x00, for: .X)
|
|
|
|
machine.setValue(0x00, for: .Y)
|
2015-07-31 00:51:32 +00:00
|
|
|
}
|
|
|
|
}
|
2015-07-17 00:15:30 +00:00
|
|
|
|
|
|
|
if machine == nil {
|
2016-09-16 02:12:12 +00:00
|
|
|
NSException(name: NSExceptionName(rawValue: "Failed Test"), reason: "Couldn't load file \(name)", userInfo: nil).raise()
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
|
|
|
|
2020-10-10 01:39:34 +00:00
|
|
|
while machine.value(for: .lastOperationAddress) != 0xe16f && !machine.isJammed {
|
2016-09-16 02:12:12 +00:00
|
|
|
machine.runForNumber(ofCycles: 1000)
|
2015-07-31 00:51:32 +00:00
|
|
|
}
|
2015-07-17 00:15:30 +00:00
|
|
|
|
2020-10-10 01:39:34 +00:00
|
|
|
if machine.isJammed {
|
|
|
|
let hexAddress = String(format:"%04x", machine.value(for: .lastOperationAddress))
|
2016-09-16 02:12:12 +00:00
|
|
|
NSException(name: NSExceptionName(rawValue: "Failed Test"), reason: "Processor jammed unexpectedly at \(hexAddress)", userInfo: nil).raise()
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
2015-07-31 00:51:32 +00:00
|
|
|
}
|
2015-07-17 00:15:30 +00:00
|
|
|
|
2016-09-16 02:12:12 +00:00
|
|
|
func petsciiToString(_ string: String) -> String {
|
2015-07-31 00:51:32 +00:00
|
|
|
let petsciiToCharCommon: [String] = [
|
|
|
|
"?", "?", "?", "[RUN/STOP]", "?", "[WHT]", "?", "?", "[SHIFT DISABLE]", "[SHIFT ENABLE]", "?", "?", "?", "\r", "[TEXT MODE]", "?",
|
|
|
|
"?", "\n", "[RVS ON]", "[HOME]", "[DEL]", "?", "?", "?", "?", "?", "?", "?", "[RED]", "[RIGHT]", "[GRN]", "[BLU]",
|
|
|
|
|
|
|
|
" ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/",
|
|
|
|
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?",
|
|
|
|
];
|
|
|
|
|
|
|
|
let petsciiToCharRegular: [String] = [
|
|
|
|
"@", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
|
|
|
|
"p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "[", "£", "]", "↑", "←",
|
|
|
|
]
|
|
|
|
let petsciiToCharInverse: [String] = [
|
|
|
|
"@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
|
|
|
|
"P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "£", "]", "↑", "←",
|
|
|
|
]
|
|
|
|
|
|
|
|
var result: String = ""
|
|
|
|
for character in string.utf16 {
|
|
|
|
let charInt: Int = Int(character)
|
|
|
|
|
|
|
|
var stringToAppend = ""
|
|
|
|
|
|
|
|
if charInt&0x7f < petsciiToCharCommon.count {
|
|
|
|
stringToAppend = petsciiToCharCommon[charInt&0x7f]
|
|
|
|
} else {
|
|
|
|
let lookupTable = (charInt > 0x80) ? petsciiToCharInverse : petsciiToCharRegular
|
|
|
|
let lookupIndex = (charInt&0x7f) - petsciiToCharCommon.count
|
|
|
|
if lookupIndex < lookupTable.count {
|
|
|
|
stringToAppend = lookupTable[lookupIndex]
|
|
|
|
} else {
|
|
|
|
stringToAppend += "!"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result += stringToAppend
|
|
|
|
}
|
2015-07-17 00:15:30 +00:00
|
|
|
|
2015-07-31 00:51:32 +00:00
|
|
|
return result
|
|
|
|
}
|
2015-07-17 00:15:30 +00:00
|
|
|
|
2017-06-04 01:54:42 +00:00
|
|
|
func testMachine(_ testMachine: CSTestMachine, didTrapAtAddress address: UInt16) {
|
|
|
|
let testMachine6502 = testMachine as! CSTestMachine6502
|
2015-07-31 00:51:32 +00:00
|
|
|
switch address {
|
|
|
|
case 0xffd2:
|
2017-06-04 01:54:42 +00:00
|
|
|
testMachine6502.setValue(0x00, forAddress: 0x030c)
|
2015-07-17 00:15:30 +00:00
|
|
|
|
2017-06-04 01:54:42 +00:00
|
|
|
let character = testMachine6502.value(for: CSTestMachine6502Register.A)
|
2016-09-16 02:12:12 +00:00
|
|
|
output.append(Character(UnicodeScalar(character)!))
|
2015-07-17 00:15:30 +00:00
|
|
|
|
2015-07-31 00:51:32 +00:00
|
|
|
case 0xffe4:
|
2017-06-04 01:54:42 +00:00
|
|
|
testMachine6502.setValue(0x3, for:CSTestMachine6502Register.A)
|
2015-07-17 00:15:30 +00:00
|
|
|
|
2015-07-31 00:51:32 +00:00
|
|
|
case 0x8000, 0xa474:
|
2016-09-16 02:12:12 +00:00
|
|
|
NSException(name: NSExceptionName(rawValue: "Failed test"), reason: self.petsciiToString(output), userInfo: nil).raise()
|
2015-07-17 00:15:30 +00:00
|
|
|
|
|
|
|
case 0x0000:
|
2016-09-16 02:12:12 +00:00
|
|
|
NSException(name: NSExceptionName(rawValue: "Failed test"), reason: "Execution hit 0000", userInfo: nil).raise()
|
2015-07-17 00:15:30 +00:00
|
|
|
|
2015-07-31 00:51:32 +00:00
|
|
|
default:
|
2015-07-17 00:15:30 +00:00
|
|
|
let hexAddress = String(format:"%04x", address)
|
2016-09-16 02:12:12 +00:00
|
|
|
NSException(name: NSExceptionName(rawValue: "Failed Test"), reason: "Processor jammed unexpectedly at \(hexAddress)", userInfo: nil).raise()
|
2015-07-31 00:51:32 +00:00
|
|
|
}
|
|
|
|
}
|
2015-07-17 00:15:30 +00:00
|
|
|
|
2015-07-16 23:53:53 +00:00
|
|
|
}
|