1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-25 03:32:01 +00:00

Plumbed through to allow interrupt tests, wrote an NMI test, corrected the error revealed.

This commit is contained in:
Thomas Harte 2017-06-03 17:41:45 -04:00
parent a2ec902773
commit 3e9212aaff
7 changed files with 78 additions and 0 deletions

View File

@ -8,6 +8,7 @@
/* Begin PBXBuildFile section */
4B049CDD1DA3C82F00322067 /* BCDTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B049CDC1DA3C82F00322067 /* BCDTest.swift */; };
4B08A2751EE35D56008B7065 /* Z80InterruptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B08A2741EE35D56008B7065 /* Z80InterruptTests.swift */; };
4B0BE4281D3481E700D5256B /* DigitalPhaseLockedLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0BE4261D3481E700D5256B /* DigitalPhaseLockedLoop.cpp */; };
4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0CCC421C62D0B3001CAC5F /* CRT.cpp */; };
4B121F951E05E66800BFDA12 /* PCMPatchedTrackTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B121F941E05E66800BFDA12 /* PCMPatchedTrackTests.mm */; };
@ -442,6 +443,7 @@
/* Begin PBXFileReference section */
4B046DC31CFE651500E9E45E /* CRTMachine.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRTMachine.hpp; sourceTree = "<group>"; };
4B049CDC1DA3C82F00322067 /* BCDTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BCDTest.swift; sourceTree = "<group>"; };
4B08A2741EE35D56008B7065 /* Z80InterruptTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80InterruptTests.swift; sourceTree = "<group>"; };
4B0B6E121C9DBD5D00FFB60D /* CRTConstants.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CRTConstants.hpp; sourceTree = "<group>"; };
4B0BE4261D3481E700D5256B /* DigitalPhaseLockedLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DigitalPhaseLockedLoop.cpp; sourceTree = "<group>"; };
4B0BE4271D3481E700D5256B /* DigitalPhaseLockedLoop.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = DigitalPhaseLockedLoop.hpp; sourceTree = "<group>"; };
@ -1795,6 +1797,7 @@
4BBF49AE1ED2880200AB3669 /* FUSETests.swift */,
4B1414611B58888700E04248 /* KlausDormannTests.swift */,
4B14145F1B58885000E04248 /* WolfgangLorenzTests.swift */,
4B08A2741EE35D56008B7065 /* Z80InterruptTests.swift */,
4BFCA12A1ECBE7C400AC40C1 /* ZexallTests.swift */,
4B3BA0C41D318B44005DD7A7 /* Bridges */,
4B1414631B588A1100E04248 /* Test Binaries */,
@ -2599,6 +2602,7 @@
4BC9E1EE1D23449A003FCEE4 /* 6502InterruptTests.swift in Sources */,
4BEF6AAA1D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm in Sources */,
4B924E991E74D22700B76AF1 /* AtariStaticAnalyserTests.mm in Sources */,
4B08A2751EE35D56008B7065 /* Z80InterruptTests.swift in Sources */,
4BFCA1241ECBDCB400AC40C1 /* AllRAMProcessor.cpp in Sources */,
4B50730A1DDFCFDF00C48FBD /* ArrayBuilderTests.mm in Sources */,
4BBF49AF1ED2880200AB3669 /* FUSETests.swift in Sources */,

View File

@ -66,4 +66,7 @@ typedef NS_ENUM(NSInteger, CSTestMachineZ80Register) {
@property(nonatomic, readonly) BOOL isHalted;
@property(nonatomic) BOOL nmiLine;
@property(nonatomic) BOOL irqLine;
@end

View File

@ -173,6 +173,16 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
return _processor->get_halt_line() ? YES : NO;
}
- (void)setNmiLine:(BOOL)nmiLine {
_nmiLine = nmiLine;
_processor->set_non_maskable_interrupt_line(nmiLine ? true : false);
}
- (void)setIrqLine:(BOOL)irqLine {
_irqLine = irqLine;
_processor->set_interrupt_line(irqLine ? true : false);
}
#pragma mark - Z80-specific Runner
- (void)runToNextInstruction {

View File

@ -0,0 +1,45 @@
//
// Z80InterruptTests.swift
// Clock Signal
//
// Created by Thomas Harte on 03/06/2017.
// Copyright © 2017 Thomas Harte. All rights reserved.
//
import XCTest
class Z80InterruptTests: XCTestCase {
func testNMI() {
let machine = CSTestMachineZ80()
// start the PC at 0x0100 and install two NOPs for it
machine.setValue(0x0100, for: .programCounter)
machine.setValue(0, for: .IFF1)
machine.setValue(1, for: .IFF2)
machine.setValue(0x00, atAddress: 0x0100)
machine.setValue(0x00, atAddress: 0x0101)
// put the stack at the top of memory
machine.setValue(0, for: .stackPointer)
// run for four cycles, and signal an NMI
machine.runForNumber(ofCycles: 4)
machine.nmiLine = true
// run for four more cycles to get to where the NMI should be recognised
machine.runForNumber(ofCycles: 4)
XCTAssertEqual(machine.value(for: .programCounter), 0x0102)
// run for eleven more cycles to allow the NMI to begin
machine.runForNumber(ofCycles: 11)
// confirm that the PC is now at 0x66, that the old is on the stack and
// that IFF1 has migrated to IFF2
XCTAssertEqual(machine.value(for: .programCounter), 0x66)
XCTAssertEqual(machine.value(atAddress: 0xffff), 0x01)
XCTAssertEqual(machine.value(atAddress: 0xfffe), 0x02)
XCTAssertEqual(machine.value(for: .IFF2), 0)
}
}

View File

@ -136,6 +136,7 @@ struct MicroOp {
BeginIRQ,
BeginIRQMode0,
RETN,
JumpTo66,
HALT,
DJNZ,
@ -701,6 +702,7 @@ template <class T> class Processor: public MicroOpScheduler<MicroOp> {
{ MicroOp::BeginNMI },
{ MicroOp::BusOperation, nullptr, nullptr, {ReadOpcode, 5, &pc_.full, &operation_}},
PUSH(pc_),
{ MicroOp::JumpTo66, nullptr, nullptr},
{ MicroOp::MoveToNextProgram }
};
MicroOp irq_mode0_program[] = {
@ -1476,6 +1478,10 @@ template <class T> class Processor: public MicroOpScheduler<MicroOp> {
request_status_ &= ~Interrupt::IRQ;
break;
case MicroOp::JumpTo66:
pc_.full = 0x66;
break;
case MicroOp::RETN:
iff1_ = iff2_;
if(irq_line_ && iff1_) request_status_ |= Interrupt::IRQ;

View File

@ -74,6 +74,14 @@ class ConcreteAllRAMProcessor: public AllRAMProcessor, public Processor<Concrete
void reset_power_on() {
return CPU::Z80::Processor<ConcreteAllRAMProcessor>::reset_power_on();
}
void set_interrupt_line(bool value) {
CPU::Z80::Processor<ConcreteAllRAMProcessor>::set_interrupt_line(value);
}
void set_non_maskable_interrupt_line(bool value) {
CPU::Z80::Processor<ConcreteAllRAMProcessor>::set_non_maskable_interrupt_line(value);
}
};
}

View File

@ -33,6 +33,8 @@ class AllRAMProcessor:
virtual void set_value_of_register(Register r, uint16_t value) = 0;
virtual bool get_halt_line() = 0;
virtual void reset_power_on() = 0;
virtual void set_interrupt_line(bool value) = 0;
virtual void set_non_maskable_interrupt_line(bool value) = 0;
protected:
MemoryAccessDelegate *delegate_;