public void Nmi_resets_IFF1() { Sut.RegisterInterruptSource(InterruptSource1); Sut.Memory[0] = NOP_opcode; Sut.Memory[1] = RET_opcode; Sut.Memory[0x66] = RET_opcode; bool nmiFired = false; Sut.Reset(); Sut.Registers.IFF1 = 1; Sut.AutoStopOnRetWithStackEmpty = true; Sut.BeforeInstructionFetch += (sender, args) => { if (!nmiFired) { InterruptSource1.FireNmi(); nmiFired = true; } }; Sut.Continue(); Assert.True(nmiFired); Assert.AreEqual(0, Sut.Registers.IFF1); }
public void Halted_processor_awakes_on_interrupt(bool isNmi) { Sut.RegisterInterruptSource(InterruptSource1); Sut.Memory[0] = NOP_opcode; Sut.Memory[1] = HALT_opcode; Sut.Memory[2] = RET_opcode; Sut.Memory[3] = RET_opcode; Sut.Memory[0x66] = RET_opcode; Sut.Memory[0x38] = RET_opcode; Sut.AutoStopOnDiPlusHalt = false; Sut.AutoStopOnRetWithStackEmpty = true; Sut.Reset(); Sut.Registers.IFF1 = 1; Sut.InterruptMode = 1; var instructionsExecutedCount = 0; Sut.BeforeInstructionFetch += (sender, args) => { if (instructionsExecutedCount == 10) { if (isNmi) { InterruptSource1.FireNmi(); } else { InterruptSource1.IntLineIsActive = true; } } if (instructionsExecutedCount == 15) { args.ExecutionStopper.Stop(); } else { instructionsExecutedCount++; } }; Sut.Continue(); Assert.False(Sut.IsHalted); Assert.AreEqual(13, instructionsExecutedCount); //10 + extra NOP + RET on 0x66 + RET on 2 Assert.AreEqual(StopReason.RetWithStackEmpty, Sut.StopReason); }
public void Nmi_is_not_accepted_after_EI_or_DI(byte opcode) { Sut.RegisterInterruptSource(InterruptSource1); Sut.Memory[0] = opcode; Sut.Memory[1] = RET_opcode; Sut.Memory[0x66] = RET_opcode; bool nmiFired = false; bool serviceRoutineInvoked = false; Sut.Reset(); Sut.Registers.IFF1 = 1; Sut.AutoStopOnRetWithStackEmpty = true; Sut.BeforeInstructionFetch += (sender, args) => { if (!nmiFired) { InterruptSource1.FireNmi(); nmiFired = true; } if (Sut.Registers.PC == 0x66) { serviceRoutineInvoked = true; } if (Sut.Registers.PC == 1) { args.ExecutionStopper.Stop(); } }; Sut.Continue(); Assert.True(nmiFired); Assert.False(serviceRoutineInvoked); }
public void Nmi_is_accepted_after_instruction_execution() { Sut.RegisterInterruptSource(InterruptSource1); Sut.Memory[0] = NOP_opcode; Sut.Memory[1] = RET_opcode; Sut.Memory[0x66] = RET_opcode; bool nmiFired = false; bool serviceRoutineInvoked = false; bool serviceRoutineReturned = false; Sut.AutoStopOnRetWithStackEmpty = true; Sut.BeforeInstructionFetch += (sender, args) => { if (!nmiFired) { InterruptSource1.FireNmi(); nmiFired = true; } if (Sut.Registers.PC == 1) { serviceRoutineReturned = true; } if (Sut.Registers.PC == 0x66) { serviceRoutineInvoked = true; } }; Sut.Start(); Assert.True(serviceRoutineInvoked); Assert.True(serviceRoutineReturned); }