private void StartInstruction(Instruction instruction)
        {
            if (instruction == Instruction.RESET)
            {
                // Instruction count should be zero after a RESET
                instructionCounter = 0;
            }
            else
            {
                // Any other internal instruction increments the instruction counter
                instructionCounter++;
            }

            if (instruction == Instruction.FetchNewInstruction)
            {
                instructionOrigin = new InstructionOrigin(InstructionSource.Memory, null, PC);
            }
            else
            {
                instructionOrigin = InstructionOrigin.Internal;
            }
            currentInstruction = instruction;
            DecodeInstructionExecutionMethod();
        }
 private void EndInstruction()
 {
     instructionOrigin = null;
     currentInstruction = null;
     executeInstruction = null;
 }
        // Reset CPU control section and instruction decoder internal state
        private void ResetCPUControlState()
        {
            // Z80CPU.cs internal state
            tStateCounter = 0;
            machineCycleCounter = 0;
            instructionCounter = 0;
            instructionOrigin = null;
            currentInstruction = null;
            executeInstruction = null;
            halfTStateIndex = 0;
            machineCycleIndex = 0;
            machineCycleCountAfterInstruction = 0;
            currentMachineCycle = null;
            executeMachineCycle = null;

            // Z80CPU_Instruction_Decoder.cs internal state
            opcodeTableIndex = 0;

            // Z80CPU_ExternalControl.cs internal state
            busRequestPending = false;
            maskableInterruptPending = false;
            nonMaskableInterruptPending = false;
        }
        private void DecodeInterruptingDeviceInstruction()
        {
            // The interrupting device inserts an instruction code on the data bus
            InstructionCode candidateInstructionCode = Z80OpCodes.Tables[0, InternalDataBus];

            // An opcode was recognized, decode it and prepare its execution
            if (candidateInstructionCode.FetchMoreBytes == 0 && candidateInstructionCode.SwitchToTableNumber == null)
            {
                InstructionCode instructionCode = candidateInstructionCode;

                // Register decoded instruction
                instructionOrigin = new InstructionOrigin(InstructionSource.InterruptingDevice, instructionCode, 0);
                currentInstruction = new Instruction(instructionCode.InstructionTypeIndex, instructionCode.InstructionTypeParamVariant);
                DecodeInstructionExecutionMethod();

                // Correct the actual duration of the current opcode fetch cycle (depends on the instruction)
                currentMachineCycle = currentInstruction.ExecutionTimings.MachineCycles[machineCycleIndex];

                // Decrease the half T state index to execute the decoded instruction as if it was fetched from memory
                halfTStateIndex = 4;
            }
            // We need to read more bytes to recognize a multi-byte opcode
            else
            {
                throw new NotSupportedException("Multi bytes opcodes are not supported in interrupt mode 0 by this simulator");
            }

            if (TraceMicroInstructions)
            {
                TraceMicroInstruction(new MicroInstruction(Z80MicroInstructionTypes.CPUControlDecodeInterruptingDeviceInstruction));
            }
        }