1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-10 23:05:01 +00:00
CLK/OSBindings/Mac/Clock SignalTests/6502TimingTests.swift

230 lines
7.1 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, CSTestMachineTrapHandler {
private var endTime: UInt32 = 0
private let machine = CSTestMachine6502()
func testImplied() {
let code: [UInt8] = [
0xea, // [2] NOP
0x88, // [2] DEY
0xca, // [2] DEX
0x18, // [2] CLC
0x2a, // [2] ROL A
]
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)
]
self.runTest(code, expectedRunLength: 48)
}
func testBIT() {
let code: [UInt8] = [
0x24, 0x2a, // [3] BIT $2a
0x2c, 0x2a, 0x2b, // [4] BIT $2b2a
]
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)
]
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)
]
self.runTest(code, expectedRunLength: 31)
}
func testJSR() {
let code: [UInt8] = [
0x20, 0x04, 0x02, // [6] JSR $0204
0x00,
0x60, // [6] RTS
]
machine.addTrapAddress(0x0203)
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
]
self.runTest(code, expectedRunLength: 8)
}
func testPHAPLA() {
let code: [UInt8] = [
0x48, // [3] PHA
0x48, // [3] PHA
0x68, // [4] PLA
]
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,
]
self.runTest(code, expectedRunLength: 14)
}
func testSnippet1() {
let code: [UInt8] = [
0x8d, 0x08, 0x00, // [4] STA $0008
0xc6, 0xb4, // [5] DEC $B4
]
self.runTest(code, expectedRunLength: 9)
}
func testSnippet2() {
let code: [UInt8] = [
0x16, 0x16, // [6] ASL $16, x
0x46, 0x46, // [5] LSR $46
]
self.runTest(code, expectedRunLength: 11)
}
func testSnippet3() {
let code: [UInt8] = [
0x20, 0x04, 0x02, // [6] JSR $0204
0x00,
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
]
machine.addTrapAddress(0x0203)
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
]
self.runTest(code, expectedRunLength: 43)
}
func runTest(_ code: [UInt8], expectedRunLength: UInt32) {
machine.trapHandler = self
let immediateCode = Data(bytes: UnsafePointer<UInt8>(code), count: code.count)
machine.setData(immediateCode, atAddress: 0x200)
machine.addTrapAddress(UInt16(0x200 + code.count))
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: CSTestMachine6502Register.programCounter)
machine.setValue(0xff, for: CSTestMachine6502Register.X)
machine.setValue(0xfe, for: CSTestMachine6502Register.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(_ testMachine: CSTestMachine, didTrapAtAddress address: UInt16) {
if self.endTime == 0 {
self.endTime = (machine.timestamp / 2) - 1
}
}
}