2016-06-28 21:29:43 -04:00
|
|
|
//
|
|
|
|
// 6502InterruptTests.swift
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 28/06/2016.
|
2018-05-13 15:19:52 -04:00
|
|
|
// Copyright 2016 Thomas Harte. All rights reserved.
|
2016-06-28 21:29:43 -04:00
|
|
|
//
|
|
|
|
|
|
|
|
import XCTest
|
|
|
|
|
|
|
|
class MOS6502InterruptTests: XCTestCase {
|
|
|
|
|
2017-05-15 08:18:57 -04:00
|
|
|
var machine: CSTestMachine6502! = nil
|
2016-06-28 21:29:43 -04:00
|
|
|
override func setUp() {
|
|
|
|
super.setUp()
|
|
|
|
|
2020-10-17 22:42:54 -04:00
|
|
|
// Create a machine full of NOPs.
|
2020-09-26 22:31:50 -04:00
|
|
|
machine = CSTestMachine6502(processor: .processor6502)
|
2016-06-28 21:29:43 -04:00
|
|
|
for c in 0...65535 {
|
2020-10-13 21:38:30 -04:00
|
|
|
machine.setValue(0xea, forAddress: UInt32(c))
|
2016-06-28 21:29:43 -04:00
|
|
|
}
|
|
|
|
|
2020-10-17 22:42:54 -04:00
|
|
|
// Set the IRQ vector to 0x1234.
|
2016-06-28 21:29:43 -04:00
|
|
|
machine.setValue(0x34, forAddress: 0xfffe)
|
|
|
|
machine.setValue(0x12, forAddress: 0xffff)
|
|
|
|
|
2020-10-17 22:42:54 -04:00
|
|
|
// Add a CLI.
|
2016-06-28 21:29:43 -04:00
|
|
|
machine.setValue(0x58, forAddress: 0x4000)
|
|
|
|
|
2020-10-17 22:42:54 -04:00
|
|
|
// Begin at 0x4000.
|
|
|
|
machine.setValue(0x4000, for: .programCounter)
|
2016-06-28 21:29:43 -04:00
|
|
|
}
|
|
|
|
|
2018-09-09 20:33:56 -04:00
|
|
|
func testIRQLine() {
|
2020-10-17 22:42:54 -04:00
|
|
|
// Run for six cycles; check that no interrupt has occurred.
|
2016-09-15 22:12:12 -04:00
|
|
|
machine.runForNumber(ofCycles: 6)
|
2020-10-17 22:42:54 -04:00
|
|
|
XCTAssertEqual(machine.value(for: .programCounter), 0x4003, "No interrupt should have occurred with line low")
|
2016-06-28 21:29:43 -04:00
|
|
|
|
|
|
|
// enable the interrupt line, check that it was too late
|
|
|
|
machine.irqLine = true
|
2016-09-15 22:12:12 -04:00
|
|
|
machine.runForNumber(ofCycles: 2)
|
2020-10-17 22:42:54 -04:00
|
|
|
XCTAssertEqual(machine.value(for: .programCounter), 0x4004, "No interrupt should have occurred from interrupt raised between instructions")
|
2016-06-28 21:29:43 -04:00
|
|
|
|
|
|
|
// run for a further 7 cycles, confirm that the IRQ vector was jumped to
|
2016-10-11 22:22:53 -04:00
|
|
|
machine.runForNumber(ofCycles: 6)
|
2020-10-17 22:42:54 -04:00
|
|
|
XCTAssertNotEqual(machine.value(for: .programCounter), 0x1234, "Interrupt routine should not yet have begun")
|
2016-10-11 22:22:53 -04:00
|
|
|
machine.runForNumber(ofCycles: 1)
|
2020-10-17 22:42:54 -04:00
|
|
|
XCTAssertEqual(machine.value(for: .programCounter), 0x1234, "Interrupt routine should just have begun")
|
2018-09-09 20:33:56 -04:00
|
|
|
}
|
2016-06-29 19:42:39 -04:00
|
|
|
|
2018-09-09 20:33:56 -04:00
|
|
|
func testIFlagSet() {
|
2016-06-29 19:42:39 -04:00
|
|
|
// enable the interrupt line, run for eleven cycles to get past the CLIP and the following NOP and into the interrupt routine
|
|
|
|
machine.irqLine = true
|
2016-09-15 22:12:12 -04:00
|
|
|
machine.runForNumber(ofCycles: 11)
|
2016-06-29 19:42:39 -04:00
|
|
|
|
2020-10-17 22:42:54 -04:00
|
|
|
XCTAssertEqual(machine.value(for: .programCounter), 0x1234, "Interrupt routine should just have begun")
|
|
|
|
XCTAssertEqual(machine.value(for: .flags) & 0x04, 0x04, "Interrupt status flag should be set")
|
2016-06-29 19:42:39 -04:00
|
|
|
}
|
|
|
|
|
2018-09-09 20:33:56 -04:00
|
|
|
func testCLISEIFlagClear() {
|
2016-06-29 19:42:39 -04:00
|
|
|
// set up an SEI as the second instruction, enable the IRQ line
|
|
|
|
machine.setValue(0x78, forAddress: 0x4001)
|
|
|
|
machine.irqLine = true
|
|
|
|
|
|
|
|
// run for four cycles; the CLI and SEI should have been performed
|
2016-09-15 22:12:12 -04:00
|
|
|
machine.runForNumber(ofCycles: 4)
|
2020-10-17 22:42:54 -04:00
|
|
|
XCTAssertEqual(machine.value(for: .programCounter), 0x4002, "CLI/SEI pair should have been performed in their entirety")
|
2016-06-29 19:42:39 -04:00
|
|
|
|
|
|
|
// run for seven more cycles
|
2016-09-15 22:12:12 -04:00
|
|
|
machine.runForNumber(ofCycles: 7)
|
2016-06-29 19:42:39 -04:00
|
|
|
|
|
|
|
// interrupt should have taken place despite SEI
|
2020-10-17 22:42:54 -04:00
|
|
|
XCTAssertEqual(machine.value(for: .programCounter), 0x1234, "Interrupt routine should just have begun")
|
2016-06-29 19:42:39 -04:00
|
|
|
}
|
2020-10-17 22:42:54 -04:00
|
|
|
|
2016-06-28 21:29:43 -04:00
|
|
|
}
|