1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-26 09:29:45 +00:00
CLK/OSBindings/Mac/Clock SignalTests/6502TimingTests.swift

229 lines
7.2 KiB
Swift

//
// TimingTests.swift
// Clock Signal
//
// Created by Thomas Harte on 13/08/2015.
// Copyright © 2015 Thomas Harte. All rights reserved.
//
import Foundation
import XCTest
class MOS6502TimingTests: XCTestCase, CSTestMachineJamHandler {
fileprivate var endTime: UInt32 = 0
func testImplied() {
let code: [UInt8] = [
0xea, // [2] NOP
0x88, // [2] DEY
0xca, // [2] DEX
0x18, // [2] CLC
0x2a, // [2] ROL A
CSTestMachineJamOpcode]
self.runTest(code, expectedRunLength: 10)
}
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 testBIT() {
let code: [UInt8] = [
0x24, 0x2a, // [3] BIT $2a
0x2c, 0x2a, 0x2b, // [4] BIT $2b2a
CSTestMachineJamOpcode]
self.runTest(code, expectedRunLength: 7)
}
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 testJSR() {
let code: [UInt8] = [
0x20, 0x04, 0x02, // [6] JSR $0204
CSTestMachineJamOpcode,
0x60, // [6] RTS
]
self.runTest(code, expectedRunLength: 12)
}
func testJMP() {
let code: [UInt8] = [
0x6c, 0x04, 0x00, // [5] JMP ($0004)
0x00, 0x00, 0x00, 0x00, 0x00,
0x4c, 0x0b, 0x02, // [3] JMP 020b
CSTestMachineJamOpcode,
]
self.runTest(code, expectedRunLength: 8)
}
func testPHAPLA() {
let code: [UInt8] = [
0x48, // [3] PHA
0x48, // [3] PHA
0x68, // [4] PLA
CSTestMachineJamOpcode,
]
self.runTest(code, expectedRunLength: 10)
}
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 testSnippet1() {
let code: [UInt8] = [
0x8d, 0x08, 0x00, // [4] STA $0008
0xc6, 0xb4, // [5] DEC $B4
CSTestMachineJamOpcode]
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 testSnippet3() {
let code: [UInt8] = [
0x20, 0x04, 0x02, // [6] JSR $0204
CSTestMachineJamOpcode,
0x86, 0x09, // [3] STX $09
0x86, 0x09, // [3] STX $09
0x85, 0x09, // [3] STA $09
0x85, 0x09, // [3] STA $09
0x86, 0x09, // [3] STX $09
0x86, 0x09, // [3] STX $09
0x86, 0x09, // [3] STX $09
0x85, 0x09, // [3] STA $09
0x86, 0x09, // [3] STX $09
0x86, 0x09, // [3] STX $09
0x85, 0x09, // [3] STA $09
0x86, 0x09, // [3] STX $09
0x86, 0x09, // [3] STX $09
0x86, 0x09, // [3] STX $09
0x86, 0x09, // [3] STX $09
0x86, 0x09, // [3] STX $09
0x86, 0x09, // [3] STX $09
0x87, 0x09, // [3] SAX $09
0x60, // [6] RTS
CSTestMachineJamOpcode]
self.runTest(code, expectedRunLength: 66)
}
func testNOP() {
let code: [UInt8] = [
0x04, 0x00, // [3] NOP zpg
0x14, 0x00, // [4] NOP zpg, x
0x34, 0x00, // [4] NOP zpg, x
0x44, 0x00, // [3] NOP zpg
0x54, 0x00, // [4] NOP zpg, x
0x64, 0x00, // [3] NOP zpg
0x74, 0x00, // [4] NOP zpg, x
0x80, 0x00, // [2] NOP #
0x82, 0x00, // [2] NOP #
0x89, 0x00, // [2] NOP #
0xc2, 0x00, // [2] NOP #
0xd4, 0x00, // [4] NOP zpg, x
0xe2, 0x00, // [2] NOP #
0xf4, 0x00, // [4] NOP zpg, x
CSTestMachineJamOpcode]
self.runTest(code, expectedRunLength: 43)
}
func runTest(_ code: [UInt8], expectedRunLength: UInt32) {
let machine = CSTestMachine()
machine.jamHandler = self
let immediateCode = Data(bytes: UnsafePointer<UInt8>(code), count: code.count)
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(0x08, forAddress: 0x0004)
machine.setValue(0x02, forAddress: 0x0005)
machine.setValue(0x200, for: CSTestMachineRegister.programCounter)
machine.setValue(0xff, for: CSTestMachineRegister.X)
machine.setValue(0xfe, for: CSTestMachineRegister.Y)
self.endTime = 0
while self.endTime == 0 {
machine.runForNumber(ofCycles: 10)
}
XCTAssert(self.endTime == expectedRunLength, "Took \(self.endTime) cycles to perform rather than \(expectedRunLength)")
}
func testMachine(_ machine: CSTestMachine!, didJamAtAddress address: UInt16) {
if self.endTime == 0 {
self.endTime = machine.timestamp - 9
}
}
}