1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 23:52:26 +00:00

Introduces Klaus Dorman's 65C02 tests. All failing.

This commit is contained in:
Thomas Harte 2018-08-06 21:48:43 -04:00
parent ebce9a2e51
commit 1a44ef0469
11 changed files with 73 additions and 30 deletions

View File

@ -7,6 +7,7 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
4B018B89211930DE002A3937 /* 65C02_extended_opcodes_test.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4B018B88211930DE002A3937 /* 65C02_extended_opcodes_test.bin */; };
4B01A6881F22F0DB001FD6E3 /* Z80MemptrTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B01A6871F22F0DB001FD6E3 /* Z80MemptrTests.swift */; }; 4B01A6881F22F0DB001FD6E3 /* Z80MemptrTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B01A6871F22F0DB001FD6E3 /* Z80MemptrTests.swift */; };
4B0333AF2094081A0050B93D /* AppleDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0333AD2094081A0050B93D /* AppleDSK.cpp */; }; 4B0333AF2094081A0050B93D /* AppleDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0333AD2094081A0050B93D /* AppleDSK.cpp */; };
4B0333B02094081A0050B93D /* AppleDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0333AD2094081A0050B93D /* AppleDSK.cpp */; }; 4B0333B02094081A0050B93D /* AppleDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0333AD2094081A0050B93D /* AppleDSK.cpp */; };
@ -690,6 +691,7 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
4B018B88211930DE002A3937 /* 65C02_extended_opcodes_test.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = 65C02_extended_opcodes_test.bin; path = "Klaus Dormann/65C02_extended_opcodes_test.bin"; sourceTree = "<group>"; };
4B01A6871F22F0DB001FD6E3 /* Z80MemptrTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MemptrTests.swift; sourceTree = "<group>"; }; 4B01A6871F22F0DB001FD6E3 /* Z80MemptrTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MemptrTests.swift; sourceTree = "<group>"; };
4B0333AD2094081A0050B93D /* AppleDSK.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AppleDSK.cpp; sourceTree = "<group>"; }; 4B0333AD2094081A0050B93D /* AppleDSK.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AppleDSK.cpp; sourceTree = "<group>"; };
4B0333AE2094081A0050B93D /* AppleDSK.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AppleDSK.hpp; sourceTree = "<group>"; }; 4B0333AE2094081A0050B93D /* AppleDSK.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AppleDSK.hpp; sourceTree = "<group>"; };
@ -1545,14 +1547,15 @@
4B1414631B588A1100E04248 /* Test Binaries */ = { 4B1414631B588A1100E04248 /* Test Binaries */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B98A1CD1FFADEC400ADF63B /* MSX ROMs */,
4B9252CD1E74D28200B76AF1 /* Atari ROMs */, 4B9252CD1E74D28200B76AF1 /* Atari ROMs */,
4B44EBF81DC9898E00A7820C /* BCDTEST_beeb */, 4B44EBF81DC9898E00A7820C /* BCDTEST_beeb */,
4B98A1CD1FFADEC400ADF63B /* MSX ROMs */,
4B018B88211930DE002A3937 /* 65C02_extended_opcodes_test.bin */,
4B44EBF61DC9883B00A7820C /* 6502_functional_test.bin */, 4B44EBF61DC9883B00A7820C /* 6502_functional_test.bin */,
4B44EBF41DC987AE00A7820C /* AllSuiteA.bin */, 4B44EBF41DC987AE00A7820C /* AllSuiteA.bin */,
4BE9A6B21EDE294200CBCB47 /* Zexall */,
4BBF49B41ED2881600AB3669 /* FUSE */, 4BBF49B41ED2881600AB3669 /* FUSE */,
4BB297E41B587D8300A49093 /* Wolfgang Lorenz 6502 test suite */, 4BB297E41B587D8300A49093 /* Wolfgang Lorenz 6502 test suite */,
4BE9A6B21EDE294200CBCB47 /* Zexall */,
); );
name = "Test Binaries"; name = "Test Binaries";
sourceTree = "<group>"; sourceTree = "<group>";
@ -3330,6 +3333,7 @@
4BB2998A1B587D8400A49093 /* lseix in Resources */, 4BB2998A1B587D8400A49093 /* lseix in Resources */,
4BB2994E1B587D8400A49093 /* dexn in Resources */, 4BB2994E1B587D8400A49093 /* dexn in Resources */,
4BB299971B587D8400A49093 /* nopa in Resources */, 4BB299971B587D8400A49093 /* nopa in Resources */,
4B018B89211930DE002A3937 /* 65C02_extended_opcodes_test.bin in Resources */,
4BFCA1291ECBE7A700AC40C1 /* zexall.com in Resources */, 4BFCA1291ECBE7A700AC40C1 /* zexall.com in Resources */,
4BB299521B587D8400A49093 /* eoray in Resources */, 4BB299521B587D8400A49093 /* eoray in Resources */,
4BB299411B587D8400A49093 /* cpyb in Resources */, 4BB299411B587D8400A49093 /* cpyb in Resources */,

View File

@ -15,7 +15,7 @@ class MOS6502InterruptTests: XCTestCase {
super.setUp() super.setUp()
// create a machine full of NOPs // create a machine full of NOPs
machine = CSTestMachine6502() machine = CSTestMachine6502(is65C02: false)
for c in 0...65535 { for c in 0...65535 {
machine.setValue(0xea, forAddress: UInt16(c)) machine.setValue(0xea, forAddress: UInt16(c))
} }

View File

@ -12,7 +12,7 @@ import XCTest
class MOS6502TimingTests: XCTestCase, CSTestMachineTrapHandler { class MOS6502TimingTests: XCTestCase, CSTestMachineTrapHandler {
private var endTime: UInt32 = 0 private var endTime: UInt32 = 0
private let machine = CSTestMachine6502() private let machine = CSTestMachine6502(is65C02: false)
func testImplied() { func testImplied() {
let code: [UInt8] = [ let code: [UInt8] = [

View File

@ -13,7 +13,7 @@ class AllSuiteATests: XCTestCase {
func testAllSuiteA() { func testAllSuiteA() {
if let filename = Bundle(for: type(of: self)).path(forResource: "AllSuiteA", ofType: "bin") { if let filename = Bundle(for: type(of: self)).path(forResource: "AllSuiteA", ofType: "bin") {
if let allSuiteA = try? Data(contentsOf: URL(fileURLWithPath: filename)) { if let allSuiteA = try? Data(contentsOf: URL(fileURLWithPath: filename)) {
let machine = CSTestMachine6502() let machine = CSTestMachine6502(is65C02: false)
machine.setData(allSuiteA, atAddress: 0x4000) machine.setData(allSuiteA, atAddress: 0x4000)
machine.setValue(CSTestMachine6502JamOpcode, forAddress:0x45c0); // end machine.setValue(CSTestMachine6502JamOpcode, forAddress:0x45c0); // end

View File

@ -14,7 +14,7 @@ class BCDTest: XCTestCase, CSTestMachineTrapHandler {
func testBCD() { func testBCD() {
if let filename = Bundle(for: type(of: self)).path(forResource: "BCDTEST_beeb", ofType: nil) { if let filename = Bundle(for: type(of: self)).path(forResource: "BCDTEST_beeb", ofType: nil) {
if let bcdTest = try? Data(contentsOf: URL(fileURLWithPath: filename)) { if let bcdTest = try? Data(contentsOf: URL(fileURLWithPath: filename)) {
let machine = CSTestMachine6502() let machine = CSTestMachine6502(is65C02: false)
machine.trapHandler = self machine.trapHandler = self
machine.setData(bcdTest, atAddress: 0x2900) machine.setData(bcdTest, atAddress: 0x2900)

View File

@ -23,7 +23,11 @@ extern const uint8_t CSTestMachine6502JamOpcode;
@interface CSTestMachine6502 : CSTestMachine @interface CSTestMachine6502 : CSTestMachine
- (void)setData:(NSData *)data atAddress:(uint16_t)startAddress; - (nonnull instancetype)init NS_UNAVAILABLE;
- (nonnull instancetype)initIs65C02:(BOOL)is65C02;
- (void)setData:(nonnull NSData *)data atAddress:(uint16_t)startAddress;
- (void)runForNumberOfCycles:(int)cycles; - (void)runForNumberOfCycles:(int)cycles;
- (void)setValue:(uint8_t)value forAddress:(uint16_t)address; - (void)setValue:(uint8_t)value forAddress:(uint16_t)address;

View File

@ -35,11 +35,12 @@ static CPU::MOS6502::Register registerForRegister(CSTestMachine6502Register reg)
#pragma mark - Lifecycle #pragma mark - Lifecycle
- (instancetype)init { - (instancetype)initIs65C02:(BOOL)is65C02 {
self = [super init]; self = [super init];
if(self) { if(self) {
_processor = CPU::MOS6502::AllRAMProcessor::Processor(CPU::MOS6502::Personality::P6502); _processor = CPU::MOS6502::AllRAMProcessor::Processor(
is65C02 ? CPU::MOS6502::Personality::P65C02 : CPU::MOS6502::Personality::P6502);
} }
return self; return self;

View File

@ -11,10 +11,32 @@ import XCTest
class KlausDormannTests: XCTestCase { class KlausDormannTests: XCTestCase {
func testKlausDormann() { fileprivate func runTest(resource: String, is65C02: Bool) -> UInt16 {
if let filename = Bundle(for: type(of: self)).path(forResource: resource, ofType: "bin") {
if let functionalTest = try? Data(contentsOf: URL(fileURLWithPath: filename)) {
let machine = CSTestMachine6502(is65C02: is65C02)
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 {
return newPC
}
}
}
}
return 0
}
/// Runs Klaus Dorman's 6502 tests.
func test6502() {
func errorForTrapAddress(_ address: UInt16) -> String? { func errorForTrapAddress(_ address: UInt16) -> String? {
let hexAddress = String(format:"%04x", address)
switch address { switch address {
case 0x3399: return nil // success! case 0x3399: return nil // success!
@ -28,29 +50,35 @@ class KlausDormannTests: XCTestCase {
case 0x26d2: return "ASL zpg,x produced incorrect flags" case 0x26d2: return "ASL zpg,x produced incorrect flags"
case 0x36c6: return "Unexpected RESET" case 0x36c6: return "Unexpected RESET"
default: return "Unknown error at \(hexAddress)" case 0: return "Didn't find tests"
default: return "Unknown error at \(String(format:"%04x", address))"
} }
} }
if let filename = Bundle(for: type(of: self)).path(forResource: "6502_functional_test", ofType: "bin") { let destination = runTest(resource: "6502_functional_test", is65C02: false)
if let functionalTest = try? Data(contentsOf: URL(fileURLWithPath: filename)) { let error = errorForTrapAddress(destination)
let machine = CSTestMachine6502() XCTAssert(error == nil, "Failed with error \(error!)")
}
machine.setData(functionalTest, atAddress: 0) /// Runs Klaus Dorman's 65C02 tests.
machine.setValue(0x400, for: .programCounter) func test65C02() {
func errorForTrapAddress(_ address: UInt16) -> String? {
switch address {
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"
while true { case 0: return "Didn't find tests"
let oldPC = machine.value(for: .lastOperationAddress) default: return "Unknown error at \(String(format:"%04x", address))"
machine.runForNumber(ofCycles: 1000)
let newPC = machine.value(for: .lastOperationAddress)
if newPC == oldPC {
let error = errorForTrapAddress(oldPC)
XCTAssert(error == nil, "Failed with error \(error!)")
return
}
}
} }
} }
let destination = runTest(resource: "65C02_extended_opcodes_test", is65C02: true)
let error = errorForTrapAddress(destination)
XCTAssert(error == nil, "Failed with error \(error!)")
} }
} }

View File

@ -200,7 +200,7 @@ class WolfgangLorenzTests: XCTestCase, CSTestMachineTrapHandler {
if let filename = Bundle(for: type(of: self)).path(forResource: name, ofType: nil) { if let filename = Bundle(for: type(of: self)).path(forResource: name, ofType: nil) {
if let testData = try? Data(contentsOf: URL(fileURLWithPath: filename)) { if let testData = try? Data(contentsOf: URL(fileURLWithPath: filename)) {
machine = CSTestMachine6502() machine = CSTestMachine6502(is65C02: false)
machine.trapHandler = self machine.trapHandler = self
// machine.logActivity = true // machine.logActivity = true
output = "" output = ""

View File

@ -69,7 +69,7 @@ using namespace CPU::MOS6502;
#define JAM {CycleFetchOperand, CycleScheduleJam} #define JAM {CycleFetchOperand, CycleScheduleJam}
ProcessorStorage::ProcessorStorage(Personality) { ProcessorStorage::ProcessorStorage(Personality personality) {
// only the interrupt flag is defined upon reset but get_flags isn't going to // only the interrupt flag is defined upon reset but get_flags isn't going to
// mask the other flags so we need to do that, at least // mask the other flags so we need to do that, at least
carry_flag_ &= Flag::Carry; carry_flag_ &= Flag::Carry;
@ -214,7 +214,13 @@ ProcessorStorage::ProcessorStorage(Personality) {
/* 0xfe INC abs, x */ AbsoluteXReadModifyWrite(OperationINC), /* 0xff INS abs, x */ AbsoluteXReadModifyWrite(OperationINS), /* 0xfe INC abs, x */ AbsoluteXReadModifyWrite(OperationINC), /* 0xff INS abs, x */ AbsoluteXReadModifyWrite(OperationINS),
}; };
// Install the basic 6502 table.
memcpy(operations_, operations_6502, sizeof(operations_)); memcpy(operations_, operations_6502, sizeof(operations_));
// Patch the table according to the chip's personality.
switch(personality) {
default: break;
}
} }
#undef Program #undef Program