mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-28 22:30:30 +00:00
230 lines
7.1 KiB
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
|
|
}
|
|
}
|
|
}
|