2015-07-17 00:52:16 +00:00
|
|
|
//
|
|
|
|
// KlausDormanTests.swift
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// 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-17 00:52:16 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
import XCTest
|
|
|
|
|
|
|
|
class KlausDormannTests: XCTestCase {
|
|
|
|
|
2020-10-18 02:42:54 +00:00
|
|
|
private func runTest(resource: String, processor: CSTestMachine6502Processor) -> UInt16 {
|
2018-08-07 01:48:43 +00:00
|
|
|
if let filename = Bundle(for: type(of: self)).path(forResource: resource, ofType: "bin") {
|
|
|
|
if let functionalTest = try? Data(contentsOf: URL(fileURLWithPath: filename)) {
|
2020-09-29 22:49:58 +00:00
|
|
|
let machine = CSTestMachine6502(processor: processor)
|
2018-08-07 01:48:43 +00:00
|
|
|
|
|
|
|
machine.setData(functionalTest, atAddress: 0)
|
|
|
|
machine.setValue(0x400, for: .programCounter)
|
|
|
|
|
|
|
|
while true {
|
|
|
|
let oldPC = machine.value(for: .lastOperationAddress)
|
|
|
|
machine.runForNumber(ofCycles: 1000)
|
|
|
|
let newPC = machine.value(for: .lastOperationAddress)
|
|
|
|
|
|
|
|
if newPC == oldPC {
|
2018-08-11 02:27:01 +00:00
|
|
|
machine.runForNumber(ofCycles: 7)
|
|
|
|
|
|
|
|
let retestPC = machine.value(for: .lastOperationAddress)
|
|
|
|
if retestPC == oldPC {
|
|
|
|
return newPC
|
|
|
|
}
|
2018-08-07 01:48:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0
|
|
|
|
}
|
2015-07-17 00:52:16 +00:00
|
|
|
|
2020-10-18 02:42:54 +00:00
|
|
|
private func runTest6502(processor: CSTestMachine6502Processor) {
|
2016-09-16 02:12:12 +00:00
|
|
|
func errorForTrapAddress(_ address: UInt16) -> String? {
|
2015-07-31 00:51:32 +00:00
|
|
|
switch address {
|
|
|
|
case 0x3399: return nil // success!
|
2015-07-17 00:52:16 +00:00
|
|
|
|
2020-10-07 23:57:58 +00:00
|
|
|
case 0x052a: return "TAX, DEX or LDA did not correctly set flags, or BEQ did not branch correctly"
|
2020-10-08 00:23:53 +00:00
|
|
|
case 0x05db: return "PLP did not affect N flag correctly"
|
2020-10-08 01:47:58 +00:00
|
|
|
case 0x26d2: return "ASL zpg,x produced incorrect flags"
|
2015-07-31 00:51:32 +00:00
|
|
|
case 0x33a7: return "Decimal ADC result has wrong value"
|
|
|
|
case 0x33b9: return "Decimal SBC result has wrong value"
|
|
|
|
case 0x33c0: return "Decimal SBC wrong carry flag"
|
2020-10-08 01:47:58 +00:00
|
|
|
case 0x3502: return "Binary SBC result has wrong value"
|
|
|
|
case 0x364a: return "JMP (addr) acted as JMP addr"
|
2015-07-17 00:52:16 +00:00
|
|
|
case 0x36ac, 0x36f6: return "Improper JSR return address on stack"
|
2015-07-31 20:44:53 +00:00
|
|
|
case 0x36c6: return "Unexpected RESET"
|
2020-10-08 01:47:58 +00:00
|
|
|
case 0x36d1: return "BRK: unexpected BRK or IRQ"
|
2020-10-08 21:52:13 +00:00
|
|
|
case 0x36e5: return "BRK flag not set on stack following BRK"
|
|
|
|
case 0x36ea: return "BRK did not set the I flag"
|
|
|
|
case 0x36fd: return "Wrong address put on stack by BRK"
|
2015-07-17 00:52:16 +00:00
|
|
|
|
2018-08-07 01:48:43 +00:00
|
|
|
case 0: return "Didn't find tests"
|
|
|
|
|
|
|
|
default: return "Unknown error at \(String(format:"%04x", address))"
|
2015-07-31 00:51:32 +00:00
|
|
|
}
|
|
|
|
}
|
2015-07-17 00:52:16 +00:00
|
|
|
|
2020-09-29 22:49:58 +00:00
|
|
|
let destination = runTest(resource: "6502_functional_test", processor: processor)
|
2018-08-07 01:48:43 +00:00
|
|
|
let error = errorForTrapAddress(destination)
|
|
|
|
XCTAssert(error == nil, "Failed with error \(error!)")
|
|
|
|
}
|
2015-07-17 00:52:16 +00:00
|
|
|
|
2020-10-18 02:42:54 +00:00
|
|
|
private func runTest65C02(processor: CSTestMachine6502Processor) {
|
2018-08-07 01:48:43 +00:00
|
|
|
func errorForTrapAddress(_ address: UInt16) -> String? {
|
|
|
|
switch address {
|
2018-08-11 02:42:35 +00:00
|
|
|
case 0x24f1: return nil // success!
|
|
|
|
|
2018-08-07 01:48:43 +00:00
|
|
|
case 0x0423: return "PHX: value of X not on stack page"
|
|
|
|
case 0x0428: return "PHX: stack pointer not decremented"
|
|
|
|
case 0x042d: return "PLY: didn't acquire value 0xaa from stack"
|
|
|
|
case 0x0432: return "PLY: didn't acquire value 0x55 from stack"
|
|
|
|
case 0x0437: return "PLY: stack pointer not incremented"
|
|
|
|
case 0x043c: return "PLY: stack pointer not incremented"
|
2015-07-17 00:52:16 +00:00
|
|
|
|
2018-08-07 02:37:30 +00:00
|
|
|
case 0x066a: return "BRA: branch not taken"
|
|
|
|
case 0x0730: return "BBS: branch not taken"
|
|
|
|
case 0x0733: return "BBR: branch taken"
|
|
|
|
|
2018-08-09 00:00:14 +00:00
|
|
|
case 0x2884: return "JMP (abs) exhibited 6502 page-crossing bug"
|
2018-08-09 02:26:57 +00:00
|
|
|
case 0x16ca: return "JMP (abs, x) failed"
|
|
|
|
|
|
|
|
case 0x2785: return "BRK didn't clear the decimal mode flag"
|
|
|
|
|
|
|
|
case 0x177b: return "INC A didn't function"
|
2018-08-09 00:00:14 +00:00
|
|
|
|
2018-08-10 01:51:14 +00:00
|
|
|
case 0x1834: return "LDA (zp) acted as JAM"
|
|
|
|
case 0x183a: return "STA (zp) acted as JAM"
|
|
|
|
case 0x1849: return "LDA/STA (zp) left flags in incorrect state"
|
|
|
|
|
2018-08-11 01:17:02 +00:00
|
|
|
case 0x1983: return "STZ didn't store zero"
|
|
|
|
|
|
|
|
case 0x1b03: return "BIT didn't set flags correctly"
|
2018-08-11 02:04:45 +00:00
|
|
|
case 0x1c6c: return "BIT immediate didn't set flags correctly"
|
|
|
|
|
|
|
|
case 0x1d88: return "TRB set Z flag incorrectly"
|
|
|
|
case 0x1e7c: return "RMB set flags incorrectly"
|
2018-08-11 01:17:02 +00:00
|
|
|
|
2018-08-11 02:13:51 +00:00
|
|
|
case 0x2245: return "CMP (zero) didn't work"
|
2018-08-11 02:27:01 +00:00
|
|
|
case 0x2506: return "Decimal ADC set flags incorrectly"
|
2018-08-11 02:13:51 +00:00
|
|
|
|
2018-08-07 01:48:43 +00:00
|
|
|
case 0: return "Didn't find tests"
|
|
|
|
default: return "Unknown error at \(String(format:"%04x", address))"
|
2015-07-31 00:51:32 +00:00
|
|
|
}
|
|
|
|
}
|
2018-08-07 01:48:43 +00:00
|
|
|
|
2020-09-29 22:49:58 +00:00
|
|
|
let destination = runTest(resource: "65C02_extended_opcodes_test", processor: processor)
|
2018-08-07 01:48:43 +00:00
|
|
|
let error = errorForTrapAddress(destination)
|
|
|
|
XCTAssert(error == nil, "Failed with error \(error!)")
|
2015-07-31 00:51:32 +00:00
|
|
|
}
|
2020-09-29 22:49:58 +00:00
|
|
|
|
2020-10-19 23:27:16 +00:00
|
|
|
private func runTest65C02NoRockwell(processor: CSTestMachine6502Processor) {
|
|
|
|
func errorForTrapAddress(_ address: UInt16) -> String? {
|
|
|
|
switch address {
|
|
|
|
case 0x11e0: return nil // success!
|
|
|
|
|
|
|
|
case 0x1474: return "BRK didn't clear the decimal flag"
|
|
|
|
case 0x0e3d: return "TRB set flags incorrectly"
|
|
|
|
|
|
|
|
case 0: return "Didn't find tests"
|
|
|
|
default: return "Unknown error at \(String(format:"%04x", address))"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let destination = runTest(resource: "65C02_no_Rockwell_test", processor: processor)
|
|
|
|
let error = errorForTrapAddress(destination)
|
|
|
|
XCTAssert(error == nil, "Failed with error \(error!)")
|
|
|
|
}
|
|
|
|
|
2020-09-29 22:49:58 +00:00
|
|
|
|
|
|
|
/// Runs Klaus Dormann's 6502 tests.
|
|
|
|
func test6502() {
|
|
|
|
runTest6502(processor: .processor6502)
|
|
|
|
}
|
|
|
|
|
2020-10-18 02:31:32 +00:00
|
|
|
/// Runs Klaus Dormann's standard 6502 tests on a 65C02.
|
|
|
|
func test65C02As6502() {
|
|
|
|
runTest6502(processor: .processor65C02)
|
|
|
|
}
|
|
|
|
|
2020-09-29 22:49:58 +00:00
|
|
|
/// Runs Klaus Dormann's standard 6502 tests on a 65816.
|
|
|
|
func test65816As6502() {
|
|
|
|
runTest6502(processor: .processor65816)
|
|
|
|
}
|
|
|
|
|
2020-10-19 23:27:16 +00:00
|
|
|
/// Runs Klaus Dormann's standard 6502 tests on a 65816.
|
|
|
|
func test65816AsNonRockwell65C02() {
|
|
|
|
runTest65C02NoRockwell(processor: .processor65816)
|
|
|
|
}
|
|
|
|
|
2020-09-29 22:49:58 +00:00
|
|
|
/// Runs Klaus Dormann's 65C02 tests.
|
|
|
|
func test65C02() {
|
|
|
|
runTest65C02(processor: .processor65C02)
|
|
|
|
}
|
|
|
|
|
2020-10-10 22:19:48 +00:00
|
|
|
/* Dormann's 65C02 tests aren't applicable to the 65816; e.g. they test BBR/BBS, which the 65816 doesn't implement. */
|
2015-07-17 00:52:16 +00:00
|
|
|
}
|