2016-06-18 13:28:46 +00:00
|
|
|
//
|
|
|
|
// 6522Tests.swift
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 18/06/2016.
|
|
|
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import XCTest
|
|
|
|
import Foundation
|
|
|
|
|
|
|
|
class MOS6522Tests: XCTestCase {
|
2016-06-18 17:57:10 +00:00
|
|
|
|
2016-09-16 02:12:12 +00:00
|
|
|
fileprivate func with6522(_ action: (MOS6522Bridge) -> ()) {
|
2016-06-18 17:57:10 +00:00
|
|
|
let bridge = MOS6522Bridge()
|
|
|
|
action(bridge)
|
|
|
|
}
|
|
|
|
|
2016-06-18 20:40:01 +00:00
|
|
|
// MARK: Timer tests
|
|
|
|
|
2016-06-18 17:57:10 +00:00
|
|
|
func testTimerCount() {
|
|
|
|
with6522 {
|
2016-06-18 18:30:23 +00:00
|
|
|
// set timer 1 to a value of $000a
|
2016-06-18 17:57:10 +00:00
|
|
|
$0.setValue(10, forRegister: 4)
|
|
|
|
$0.setValue(0, forRegister: 5)
|
|
|
|
|
2016-11-05 16:58:56 +00:00
|
|
|
// complete the setting cycle
|
|
|
|
$0.run(forHalfCycles: 2)
|
|
|
|
|
2016-06-18 18:30:23 +00:00
|
|
|
// run for 5 cycles
|
2016-09-16 02:12:12 +00:00
|
|
|
$0.run(forHalfCycles: 10)
|
2016-06-18 17:57:10 +00:00
|
|
|
|
2016-06-18 18:30:23 +00:00
|
|
|
// check that the timer has gone down by 5
|
2016-09-16 02:12:12 +00:00
|
|
|
XCTAssert($0.value(forRegister: 4) == 5, "Low order byte should be 5; was \($0.value(forRegister: 4))")
|
|
|
|
XCTAssert($0.value(forRegister: 5) == 0, "High order byte should be 0; was \($0.value(forRegister: 5))")
|
2016-06-18 20:10:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func testTimerLatches() {
|
|
|
|
with6522 {
|
|
|
|
// set timer 2 to $1020
|
|
|
|
$0.setValue(0x10, forRegister: 8)
|
|
|
|
$0.setValue(0x20, forRegister: 9)
|
|
|
|
|
|
|
|
// change the low-byte latch
|
|
|
|
$0.setValue(0x40, forRegister: 8)
|
|
|
|
|
2016-11-05 16:58:56 +00:00
|
|
|
// complete the cycle
|
|
|
|
$0.run(forHalfCycles: 2)
|
|
|
|
|
2016-06-18 20:10:46 +00:00
|
|
|
// chek that the new latched value hasn't been copied
|
2016-09-16 02:12:12 +00:00
|
|
|
XCTAssert($0.value(forRegister: 8) == 0x10, "Low order byte should be 0x10; was \($0.value(forRegister: 8))")
|
|
|
|
XCTAssert($0.value(forRegister: 9) == 0x20, "High order byte should be 0x20; was \($0.value(forRegister: 9))")
|
2016-06-18 20:10:46 +00:00
|
|
|
|
|
|
|
// write the low-byte latch
|
|
|
|
$0.setValue(0x50, forRegister: 9)
|
|
|
|
|
2016-11-05 16:58:56 +00:00
|
|
|
// complete the cycle
|
|
|
|
$0.run(forHalfCycles: 2)
|
|
|
|
|
2016-06-18 20:10:46 +00:00
|
|
|
// chek that the latched value has been copied
|
2016-09-16 02:12:12 +00:00
|
|
|
XCTAssert($0.value(forRegister: 8) == 0x40, "Low order byte should be 0x50; was \($0.value(forRegister: 8))")
|
|
|
|
XCTAssert($0.value(forRegister: 9) == 0x50, "High order byte should be 0x40; was \($0.value(forRegister: 9))")
|
2016-06-18 18:30:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func testTimerReload() {
|
|
|
|
with6522 {
|
|
|
|
// set timer 1 to a value of $0010, enable repeating mode
|
|
|
|
$0.setValue(16, forRegister: 4)
|
|
|
|
$0.setValue(0, forRegister: 5)
|
|
|
|
$0.setValue(0x40, forRegister: 11)
|
|
|
|
$0.setValue(0x40 | 0x80, forRegister: 14)
|
|
|
|
|
2016-11-05 16:58:56 +00:00
|
|
|
// complete the cycle to set initial values
|
|
|
|
$0.run(forHalfCycles: 2)
|
|
|
|
|
2016-06-18 18:30:23 +00:00
|
|
|
// run for 16 cycles
|
2016-09-16 02:12:12 +00:00
|
|
|
$0.run(forHalfCycles: 32)
|
2016-06-18 18:30:23 +00:00
|
|
|
|
|
|
|
// check that the timer has gone down to 0 but not yet triggered an interrupt
|
2016-09-16 02:12:12 +00:00
|
|
|
XCTAssert($0.value(forRegister: 4) == 0, "Low order byte should be 0; was \($0.value(forRegister: 4))")
|
|
|
|
XCTAssert($0.value(forRegister: 5) == 0, "High order byte should be 0; was \($0.value(forRegister: 5))")
|
2016-06-18 18:30:23 +00:00
|
|
|
XCTAssert(!$0.irqLine, "IRQ should not yet be active")
|
|
|
|
|
|
|
|
// check that two half-cycles later the timer is $ffff but IRQ still hasn't triggered
|
2016-09-16 02:12:12 +00:00
|
|
|
$0.run(forHalfCycles: 2)
|
|
|
|
XCTAssert($0.value(forRegister: 4) == 0xff, "Low order byte should be 0xff; was \($0.value(forRegister: 4))")
|
|
|
|
XCTAssert($0.value(forRegister: 5) == 0xff, "High order byte should be 0xff; was \($0.value(forRegister: 5))")
|
2016-06-18 18:30:23 +00:00
|
|
|
XCTAssert(!$0.irqLine, "IRQ should not yet be active")
|
|
|
|
|
2016-06-18 20:10:46 +00:00
|
|
|
// check that one half-cycle later the timer is still $ffff and IRQ has triggered...
|
2016-09-16 02:12:12 +00:00
|
|
|
$0.run(forHalfCycles: 1)
|
2016-06-18 18:30:23 +00:00
|
|
|
XCTAssert($0.irqLine, "IRQ should be active")
|
2016-09-16 02:12:12 +00:00
|
|
|
XCTAssert($0.value(forRegister: 4) == 0xff, "Low order byte should be 0xff; was \($0.value(forRegister: 4))")
|
|
|
|
XCTAssert($0.value(forRegister: 5) == 0xff, "High order byte should be 0xff; was \($0.value(forRegister: 5))")
|
2016-06-18 20:10:46 +00:00
|
|
|
|
|
|
|
// ... but that reading the timer cleared the interrupt
|
|
|
|
XCTAssert(!$0.irqLine, "IRQ should be active")
|
2016-06-18 18:30:23 +00:00
|
|
|
|
|
|
|
// check that one half-cycles later the timer has reloaded
|
2016-09-16 02:12:12 +00:00
|
|
|
$0.run(forHalfCycles: 1)
|
|
|
|
XCTAssert($0.value(forRegister: 4) == 0x10, "Low order byte should be 0x10; was \($0.value(forRegister: 4))")
|
|
|
|
XCTAssert($0.value(forRegister: 5) == 0x00, "High order byte should be 0x00; was \($0.value(forRegister: 5))")
|
2016-06-18 17:57:10 +00:00
|
|
|
}
|
|
|
|
}
|
2016-06-18 20:40:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
// MARK: Data direction tests
|
|
|
|
func testDataDirection() {
|
|
|
|
with6522 {
|
|
|
|
// set low four bits of register B as output, the top four as input
|
2016-06-18 21:17:03 +00:00
|
|
|
$0.setValue(0xf0, forRegister: 2)
|
2016-06-18 20:40:01 +00:00
|
|
|
|
|
|
|
// ask to output 0x8c
|
|
|
|
$0.setValue(0x8c, forRegister: 0)
|
|
|
|
|
2016-11-05 16:58:56 +00:00
|
|
|
// complete the cycle
|
|
|
|
$0.run(forHalfCycles: 2)
|
|
|
|
|
2016-06-18 20:40:01 +00:00
|
|
|
// set current input as 0xda
|
|
|
|
$0.portBInput = 0xda
|
|
|
|
|
|
|
|
// test that the result of reading register B is therefore 0x8a
|
2016-09-16 02:12:12 +00:00
|
|
|
XCTAssert($0.value(forRegister: 0) == 0x8a, "Data direction register should mix input and output; got \($0.value(forRegister: 0))")
|
2016-06-18 20:40:01 +00:00
|
|
|
}
|
|
|
|
}
|
2016-06-18 13:28:46 +00:00
|
|
|
}
|