1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-24 12:30:17 +00:00

Added a couple of timing tests, both of which seem to pass for now.

This commit is contained in:
Thomas Harte 2015-08-13 01:55:23 +01:00
parent e8f70398c1
commit 503d684af0
5 changed files with 67 additions and 8 deletions

View File

@ -56,6 +56,5 @@ class KlausDormannTests: XCTestCase {
} }
} }
} }
} }
} }

View File

@ -13,7 +13,9 @@ typedef NS_ENUM(NSInteger, CSTestMachineRegister) {
CSTestMachineRegisterProgramCounter, CSTestMachineRegisterProgramCounter,
CSTestMachineRegisterStackPointer, CSTestMachineRegisterStackPointer,
CSTestMachineRegisterFlags, CSTestMachineRegisterFlags,
CSTestMachineRegisterA CSTestMachineRegisterA,
CSTestMachineRegisterX,
CSTestMachineRegisterY,
}; };
extern const uint8_t CSTestMachineJamOpcode; extern const uint8_t CSTestMachineJamOpcode;

View File

@ -51,6 +51,8 @@ class MachineJamHandler: public CPU6502::AllRAMProcessor::JamHandler {
case CSTestMachineRegisterLastOperationAddress: return CPU6502::Register::LastOperationAddress; case CSTestMachineRegisterLastOperationAddress: return CPU6502::Register::LastOperationAddress;
case CSTestMachineRegisterFlags: return CPU6502::Register::Flags; case CSTestMachineRegisterFlags: return CPU6502::Register::Flags;
case CSTestMachineRegisterA: return CPU6502::Register::A; case CSTestMachineRegisterA: return CPU6502::Register::A;
case CSTestMachineRegisterX: return CPU6502::Register::X;
case CSTestMachineRegisterY: return CPU6502::Register::Y;
case CSTestMachineRegisterStackPointer: return CPU6502::Register::S; case CSTestMachineRegisterStackPointer: return CPU6502::Register::S;
default: break; default: break;
} }

View File

@ -18,6 +18,50 @@ class TimingTests: XCTestCase, CSTestMachineJamHandler {
self.runTest(code, expectedRunLength: 2) self.runTest(code, expectedRunLength: 2)
} }
func testLDA() {
let code: [UInt8] = [
0xa9, 0x00, // [2] LDA #$00
0xa5, 0x00, // [3] LDA $00
0xb5, 0x00, // [4] LDA $00,X
0xad, 0x00, 0x00, // [4] LDA $0000
0xbd, 0x00, 0x00, // [4] LDA $0000, x (no wrap)
0xbd, 0x02, 0x00, // [5] LDA $0002, x (wrap)
0xb9, 0x00, 0x00, // [4] LDA $0000, y (no wrap)
0xb9, 0x10, 0x00, // [5] LDA $0010, y (wrap)
0xa1, 0x44, // [6] LDA ($44, x)
0xb1, 0x00, // [5] LDA ($00), y (no wrap)
0xb1, 0x02, // [6] LDA ($01), y (wrap)
CSTestMachineJamOpcode]
self.runTest(code, expectedRunLength: 48)
}
func testBCS() {
let code: [UInt8] = [
0x18, // [2] CLC
0xb0, 0xff, // [2] BCS -1 (not taken)
0x90, 0x7f, // [3] BCC +7f (taken)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x90, 0x00, // [3] BCC 0 (taken)
0x90, 0x7f, // [4] BCC +6f (taken, page wrap)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
CSTestMachineJamOpcode]
self.runTest(code, expectedRunLength: 14)
}
func runTest(code: [UInt8], expectedRunLength: UInt32) { func runTest(code: [UInt8], expectedRunLength: UInt32) {
let machine = CSTestMachine() let machine = CSTestMachine()
@ -25,7 +69,13 @@ class TimingTests: XCTestCase, CSTestMachineJamHandler {
let immediateCode = NSData(bytes: code, length: code.count) let immediateCode = NSData(bytes: code, length: code.count)
machine.setData(immediateCode, atAddress: 0x200) machine.setData(immediateCode, atAddress: 0x200)
machine.setValue(0x00, forAddress: 0x0000)
machine.setValue(0x00, forAddress: 0x0001)
machine.setValue(0xff, forAddress: 0x0002)
machine.setValue(0x00, forAddress: 0x0003)
machine.setValue(0x200, forRegister: CSTestMachineRegister.ProgramCounter) machine.setValue(0x200, forRegister: CSTestMachineRegister.ProgramCounter)
machine.setValue(0xff, forRegister: CSTestMachineRegister.X)
machine.setValue(0xfe, forRegister: CSTestMachineRegister.Y)
self.endTime = 0 self.endTime = 0
while self.endTime == 0 { while self.endTime == 0 {
@ -37,7 +87,7 @@ class TimingTests: XCTestCase, CSTestMachineJamHandler {
func testMachine(machine: CSTestMachine!, didJamAtAddress address: UInt16) { func testMachine(machine: CSTestMachine!, didJamAtAddress address: UInt16) {
if self.endTime == 0 { if self.endTime == 0 {
self.endTime = machine.timestamp - 3 self.endTime = machine.timestamp - 7
} }
} }
} }

View File

@ -20,6 +20,8 @@ enum class Register {
StackPointer, StackPointer,
Flags, Flags,
A, A,
X,
Y,
S S
}; };
@ -61,7 +63,7 @@ template <class T> class Processor {
CycleReadAndIncrementPC, CycleIncrementPCAndReadStack, CycleIncrementPCReadPCHLoadPCL, CycleReadPCHLoadPCL, CycleReadAndIncrementPC, CycleIncrementPCAndReadStack, CycleIncrementPCReadPCHLoadPCL, CycleReadPCHLoadPCL,
CycleReadAddressHLoadAddressL, CycleReadPCLFromAddress, CycleReadPCHFromAddress, CycleLoadAddressAbsolute, CycleReadAddressHLoadAddressL, CycleReadPCLFromAddress, CycleReadPCHFromAddress, CycleLoadAddressAbsolute,
OperationLoadAddressZeroPage, CycleLoadAddessZeroX, CycleLoadAddessZeroY, CycleAddXToAddressLow, OperationLoadAddressZeroPage, CycleLoadAddessZeroX, CycleLoadAddessZeroY, CycleAddXToAddressLow,
CycleAddYToAddressLow, CycleCorrectAddressHigh, OperationMoveToNextProgram, OperationIncrementPC, CycleAddYToAddressLow, OperationCorrectAddressHigh, OperationMoveToNextProgram, OperationIncrementPC,
CycleFetchOperandFromAddress, CycleWriteOperandToAddress, OperationCopyOperandFromA, OperationCopyOperandToA, CycleFetchOperandFromAddress, CycleWriteOperandToAddress, OperationCopyOperandFromA, OperationCopyOperandToA,
CycleIncrementPCFetchAddressLowFromOperand, CycleAddXToOperandFetchAddressLow, CycleIncrementOperandFetchAddressHigh, OperationDecrementOperand, CycleIncrementPCFetchAddressLowFromOperand, CycleAddXToOperandFetchAddressLow, CycleIncrementOperandFetchAddressHigh, OperationDecrementOperand,
OperationIncrementOperand, OperationORA, OperationAND, OperationEOR, OperationIncrementOperand, OperationORA, OperationAND, OperationEOR,
@ -135,13 +137,13 @@ template <class T> class Processor {
#define Program(...) {__VA_ARGS__, OperationMoveToNextProgram} #define Program(...) {__VA_ARGS__, OperationMoveToNextProgram}
#define Absolute CycleLoadAddressAbsolute #define Absolute CycleLoadAddressAbsolute
#define AbsoluteX CycleLoadAddressAbsolute, CycleAddXToAddressLow, CycleCorrectAddressHigh #define AbsoluteX CycleLoadAddressAbsolute, CycleAddXToAddressLow, OperationCorrectAddressHigh
#define AbsoluteY CycleLoadAddressAbsolute, CycleAddYToAddressLow, CycleCorrectAddressHigh #define AbsoluteY CycleLoadAddressAbsolute, CycleAddYToAddressLow, OperationCorrectAddressHigh
#define Zero OperationLoadAddressZeroPage #define Zero OperationLoadAddressZeroPage
#define ZeroX CycleLoadAddessZeroX #define ZeroX CycleLoadAddessZeroX
#define ZeroY CycleLoadAddessZeroY #define ZeroY CycleLoadAddessZeroY
#define IndexedIndirect CycleIncrementPCFetchAddressLowFromOperand, CycleAddXToOperandFetchAddressLow, CycleIncrementOperandFetchAddressHigh #define IndexedIndirect CycleIncrementPCFetchAddressLowFromOperand, CycleAddXToOperandFetchAddressLow, CycleIncrementOperandFetchAddressHigh
#define IndirectIndexed CycleIncrementPCFetchAddressLowFromOperand, CycleIncrementOperandFetchAddressHigh, CycleAddYToAddressLow, CycleCorrectAddressHigh #define IndirectIndexed CycleIncrementPCFetchAddressLowFromOperand, CycleIncrementOperandFetchAddressHigh, CycleAddYToAddressLow, OperationCorrectAddressHigh
#define Read(op) CycleFetchOperandFromAddress, op #define Read(op) CycleFetchOperandFromAddress, op
#define Write(op) op, CycleWriteOperandToAddress #define Write(op) op, CycleWriteOperandToAddress
@ -750,7 +752,7 @@ template <class T> class Processor {
throwaway_read(_address.full); throwaway_read(_address.full);
} }
break; break;
case CycleCorrectAddressHigh: case OperationCorrectAddressHigh:
_address.full = _nextAddress.full; _address.full = _nextAddress.full;
break; break;
case CycleIncrementPCFetchAddressLowFromOperand: case CycleIncrementPCFetchAddressLowFromOperand:
@ -888,6 +890,8 @@ template <class T> class Processor {
case Register::StackPointer: return _s; case Register::StackPointer: return _s;
case Register::Flags: return get_flags(); case Register::Flags: return get_flags();
case Register::A: return _a; case Register::A: return _a;
case Register::X: return _x;
case Register::Y: return _y;
case Register::S: return _s; case Register::S: return _s;
default: break; default: break;
} }
@ -900,6 +904,8 @@ template <class T> class Processor {
case Register::StackPointer: _s = value; break; case Register::StackPointer: _s = value; break;
case Register::Flags: set_flags(value); break; case Register::Flags: set_flags(value); break;
case Register::A: _a = value; break; case Register::A: _a = value; break;
case Register::X: _x = value; break;
case Register::Y: _y = value; break;
case Register::S: _s = value; break; case Register::S: _s = value; break;
default: break; default: break;
} }