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:
parent
ebce9a2e51
commit
1a44ef0469
@ -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 */,
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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] = [
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Binary file not shown.
@ -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!)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 = ""
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user