diff --git a/OSBindings/Mac/Clock SignalTests/Z80InterruptTests.swift b/OSBindings/Mac/Clock SignalTests/Z80InterruptTests.swift index 5c25b9028..43ddc4a3b 100644 --- a/OSBindings/Mac/Clock SignalTests/Z80InterruptTests.swift +++ b/OSBindings/Mac/Clock SignalTests/Z80InterruptTests.swift @@ -20,6 +20,11 @@ class Z80InterruptTests: XCTestCase { } func testNMI() { + // Per http://www.z80.info/interrup.htm NMI should take 11 cycles to get to 0x66: + // M1 cycle: 5 T states to do an opcode read and decrement SP + // M2 cycle: 3 T states write high byte of PC to the stack and decrement SP + // M3 cycle: 3 T states write the low byte of PC and jump to #0066. + let machine = CSTestMachineZ80() // start the PC at 0x0100 and install two NOPs for it @@ -153,7 +158,8 @@ class Z80InterruptTests: XCTestCase { func testIRQMode1() { // In interrupt mode 1, receipt of an IRQ means that the interrupt flag is disabled, - // the PC is pushed to the stack and execution resumes at 0x38. + // the PC is pushed to the stack and execution resumes at 0x38. This should take + // 13 cycles total, per http://www.z80.info/interrup.htm let machine = CSTestMachineZ80() diff --git a/Processors/Z80/Z80.hpp b/Processors/Z80/Z80.hpp index a6db04055..e353ec3fe 100644 --- a/Processors/Z80/Z80.hpp +++ b/Processors/Z80/Z80.hpp @@ -847,11 +847,11 @@ template class Processor { }; MicroOp irq_mode1_program[] = { { MicroOp::BeginIRQ }, - BusOp(IntAckStart(7, operation_)), - BusOp(IntWait(operation_)), - BusOp(IntAckEnd(operation_)), - BusOp(Refresh(4)), - Push(pc_), + BusOp(IntAckStart(7, operation_)), // 7 half cycles (including + + BusOp(IntWait(operation_)), // [potentially 2 half cycles] + + BusOp(IntAckEnd(operation_)), // Implicitly 3 half cycles + + BusOp(Refresh(4)), // 4 half cycles + + Push(pc_), // 12 half cycles = 26 half cycles = 13 cycles { MicroOp::Move16, &temp16_.full, &pc_.full }, { MicroOp::MoveToNextProgram } };