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);
        }