From dd0f17130a404b3c89ad5532a923aa8d6232c01c Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 13 Aug 2015 02:58:39 +0100 Subject: [PATCH] Found and fixed some timing errors in absolute indexed and in (indirect), y addressing modes: neither is able in write or read-modify-write modes to shave a cycle as then can when reading. --- .../Mac/Clock SignalTests/TimingTests.swift | 41 +++++++++++++++++-- Processors/6502/CPU6502.hpp | 28 +++++++++---- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/TimingTests.swift b/OSBindings/Mac/Clock SignalTests/TimingTests.swift index 127e80e02..ddb1ad7a8 100644 --- a/OSBindings/Mac/Clock SignalTests/TimingTests.swift +++ b/OSBindings/Mac/Clock SignalTests/TimingTests.swift @@ -13,9 +13,9 @@ class TimingTests: XCTestCase, CSTestMachineJamHandler { private var endTime: UInt32 = 0 - func testImpliedNOP() { - let code: [UInt8] = [0xea, CSTestMachineJamOpcode] - self.runTest(code, expectedRunLength: 2) + func testImplied() { + let code: [UInt8] = [0xea, 0x88, 0xca, CSTestMachineJamOpcode] + self.runTest(code, expectedRunLength: 6) } func testLDA() { @@ -35,6 +35,33 @@ class TimingTests: XCTestCase, CSTestMachineJamHandler { self.runTest(code, expectedRunLength: 48) } + func testSTA() { + let code: [UInt8] = [ + 0x85, 0x00, // [3] STA $00 + 0x95, 0x00, // [4] STA $00,X + 0x8d, 0x00, 0x00, // [4] STA $0000 + 0x9d, 0x00, 0x00, // [5] STA $0000, x (no wrap) + 0x9d, 0x02, 0x00, // [5] STA $0002, x (wrap) + 0x99, 0x00, 0x00, // [5] STA $0000, y (no wrap) + 0x99, 0x10, 0x00, // [5] STA $0010, y (wrap) + 0x81, 0x44, // [6] STA ($44, x) + 0x91, 0x00, // [6] STA ($00), y (no wrap) + 0x91, 0x02, // [6] STA ($01), y (wrap) + CSTestMachineJamOpcode] + self.runTest(code, expectedRunLength: 49) + } + + func testINC() { + let code: [UInt8] = [ + 0xe6, 0x00, // [5] INC $00 + 0xf6, 0x00, // [6] INC $00,X + 0xee, 0x00, 0x00, // [6] INC $0000 + 0xfe, 0x00, 0x00, // [7] INC $0000, x (no wrap) + 0xfe, 0x02, 0x00, // [7] INC $0002, x (wrap) + CSTestMachineJamOpcode] + self.runTest(code, expectedRunLength: 31) + } + func testBCS() { let code: [UInt8] = [ 0x18, // [2] CLC @@ -70,6 +97,14 @@ class TimingTests: XCTestCase, CSTestMachineJamHandler { self.runTest(code, expectedRunLength: 9) } + func testSnippet2() { + let code: [UInt8] = [ + 0x16, 0x16, // [6] ASL $16, x + 0x46, 0x46, // [5] LSR $46 + CSTestMachineJamOpcode] + self.runTest(code, expectedRunLength: 11) + } + func runTest(code: [UInt8], expectedRunLength: UInt32) { let machine = CSTestMachine() diff --git a/Processors/6502/CPU6502.hpp b/Processors/6502/CPU6502.hpp index bd361e3ef..07aa934f8 100644 --- a/Processors/6502/CPU6502.hpp +++ b/Processors/6502/CPU6502.hpp @@ -63,7 +63,8 @@ template class Processor { CycleReadAndIncrementPC, CycleIncrementPCAndReadStack, CycleIncrementPCReadPCHLoadPCL, CycleReadPCHLoadPCL, CycleReadAddressHLoadAddressL, CycleReadPCLFromAddress, CycleReadPCHFromAddress, CycleLoadAddressAbsolute, OperationLoadAddressZeroPage, CycleLoadAddessZeroX, CycleLoadAddessZeroY, CycleAddXToAddressLow, - CycleAddYToAddressLow, OperationCorrectAddressHigh, OperationMoveToNextProgram, OperationIncrementPC, + CycleAddYToAddressLow, CycleAddXToAddressLowRead, OperationCorrectAddressHigh, CycleAddYToAddressLowRead, + OperationMoveToNextProgram, OperationIncrementPC, CycleFetchOperandFromAddress, CycleWriteOperandToAddress, OperationCopyOperandFromA, OperationCopyOperandToA, CycleIncrementPCFetchAddressLowFromOperand, CycleAddXToOperandFetchAddressLow, CycleIncrementOperandFetchAddressHigh, OperationDecrementOperand, OperationIncrementOperand, OperationORA, OperationAND, OperationEOR, @@ -137,26 +138,29 @@ template class Processor { #define Program(...) {__VA_ARGS__, OperationMoveToNextProgram} #define Absolute CycleLoadAddressAbsolute -#define AbsoluteX CycleLoadAddressAbsolute, CycleAddXToAddressLow, OperationCorrectAddressHigh -#define AbsoluteY CycleLoadAddressAbsolute, CycleAddYToAddressLow, OperationCorrectAddressHigh +#define AbsoluteXr CycleLoadAddressAbsolute, CycleAddXToAddressLow, OperationCorrectAddressHigh +#define AbsoluteYr CycleLoadAddressAbsolute, CycleAddYToAddressLow, OperationCorrectAddressHigh +#define AbsoluteX CycleLoadAddressAbsolute, CycleAddXToAddressLowRead, OperationCorrectAddressHigh +#define AbsoluteY CycleLoadAddressAbsolute, CycleAddYToAddressLowRead, OperationCorrectAddressHigh #define Zero OperationLoadAddressZeroPage #define ZeroX CycleLoadAddessZeroX #define ZeroY CycleLoadAddessZeroY #define IndexedIndirect CycleIncrementPCFetchAddressLowFromOperand, CycleAddXToOperandFetchAddressLow, CycleIncrementOperandFetchAddressHigh -#define IndirectIndexed CycleIncrementPCFetchAddressLowFromOperand, CycleIncrementOperandFetchAddressHigh, CycleAddYToAddressLow, OperationCorrectAddressHigh +#define IndirectIndexedr CycleIncrementPCFetchAddressLowFromOperand, CycleIncrementOperandFetchAddressHigh, CycleAddYToAddressLow, OperationCorrectAddressHigh +#define IndirectIndexed CycleIncrementPCFetchAddressLowFromOperand, CycleIncrementOperandFetchAddressHigh, CycleAddYToAddressLowRead, OperationCorrectAddressHigh #define Read(op) CycleFetchOperandFromAddress, op #define Write(op) op, CycleWriteOperandToAddress #define ReadModifyWrite(...) CycleFetchOperandFromAddress, CycleWriteOperandToAddress, __VA_ARGS__, CycleWriteOperandToAddress #define AbsoluteRead(op) Program(Absolute, Read(op)) -#define AbsoluteXRead(op) Program(AbsoluteX, Read(op)) -#define AbsoluteYRead(op) Program(AbsoluteY, Read(op)) +#define AbsoluteXRead(op) Program(AbsoluteXr, Read(op)) +#define AbsoluteYRead(op) Program(AbsoluteYr, Read(op)) #define ZeroRead(op) Program(Zero, Read(op)) #define ZeroXRead(op) Program(ZeroX, Read(op)) #define ZeroYRead(op) Program(ZeroY, Read(op)) #define IndexedIndirectRead(op) Program(IndexedIndirect, Read(op)) -#define IndirectIndexedRead(op) Program(IndirectIndexed, Read(op)) +#define IndirectIndexedRead(op) Program(IndirectIndexedr, Read(op)) #define AbsoluteWrite(op) Program(Absolute, Write(op)) #define AbsoluteXWrite(op) Program(AbsoluteX, Write(op)) @@ -745,6 +749,11 @@ template class Processor { throwaway_read(_address.full); } break; + case CycleAddXToAddressLowRead: + _nextAddress.full = _address.full + _x; + _address.bytes.low = _nextAddress.bytes.low; + throwaway_read(_address.full); + break; case CycleAddYToAddressLow: _nextAddress.full = _address.full + _y; _address.bytes.low = _nextAddress.bytes.low; @@ -752,6 +761,11 @@ template class Processor { throwaway_read(_address.full); } break; + case CycleAddYToAddressLowRead: + _nextAddress.full = _address.full + _y; + _address.bytes.low = _nextAddress.bytes.low; + throwaway_read(_address.full); + break; case OperationCorrectAddressHigh: _address.full = _nextAddress.full; break;