예제 #1
0
        public static bool ForceInterrupt(ModuleBase module, MixInstruction.Instance instance)
        {
            if (!(module is Mix))
            {
                module.ReportRuntimeError(string.Format("The {0} instruction is only available in Mix", instance.Instruction.Mnemonic));
                return(false);
            }

            InterruptHandler.HandleInterrupt((Mix)module, new Interrupt(Interrupt.Types.Forced));

            return(false);
        }
예제 #2
0
파일: Mix.cs 프로젝트: arlm/MixEmul
        public void Tick()
        {
            if (Mode != RunMode.Module)
            {
                if (mInterruptQueue.Count > 0 && mCurrentInstructionTicksLeft == 0 && Mode != RunMode.Control && (Status == RunStatus.Running || Status == RunStatus.Stepping || Status == RunStatus.Idle))
                {
                    if (mInterruptExecuted)
                    {
                        mInterruptExecuted = false;
                    }
                    else
                    {
                        InterruptHandler.HandleInterrupt(this, mInterruptQueue.Dequeue());
                    }
                }

                IncreaseTickCounter();

                if (Status == RunStatus.Halted)
                {
                    if (!mDevices.IsAnyBusy)
                    {
                        Status = RunStatus.Idle;
                    }
                    return;
                }
            }

            IMemoryFullWord instructionWord = Memory[ProgramCounter];
            var             instruction     = InstructionSet.Instance.GetInstruction(instructionWord[MixInstruction.OpcodeByte], new FieldSpec(instructionWord[MixInstruction.FieldSpecByte]));

            if (instruction == null)
            {
                ReportInvalidInstruction("Opcode (and field) do not encode an instruction");
                if (Mode == RunMode.Module)
                {
                    ResetMode();
                }

                return;
            }

            var instance = instruction.CreateInstance(instructionWord);
            var errors   = instance.Validate();

            if (errors != null)
            {
                ReportInvalidInstruction(errors);
                if (Mode == RunMode.Module)
                {
                    ResetMode();
                }

                return;
            }

            if (mCurrentInstructionAddress != ProgramCounter || mCurrentInstructionMnemonic != instruction.Mnemonic || (mCurrentInstructionTicksLeft <= 0 && Mode != RunMode.Module))
            {
                mCurrentInstructionAddress   = ProgramCounter;
                mCurrentInstructionTicksLeft = instruction.TickCount;
                mCurrentInstructionMnemonic  = instruction.Mnemonic;
                if (Mode == RunMode.Module)
                {
                    ResetMode();
                }
            }

            if (Mode != RunMode.Module && mCurrentInstructionTicksLeft > 0)
            {
                mCurrentInstructionTicksLeft--;

                if (ExecutionSettings.ProfilingEnabled)
                {
                    instructionWord.IncreaseProfilingTickCount(1);
                }
            }

            int programCounter;

            if (Mode == RunMode.Module || mCurrentInstructionTicksLeft == 0)
            {
                var increasePC = instance.Execute(this);

                programCounter = ProgramCounter;

                if (increasePC)
                {
                    programCounter++;
                }

                if (ExecutionSettings.ProfilingEnabled && (Mode != RunMode.Module || increasePC))
                {
                    instructionWord.IncreaseProfilingExecutionCount();
                }
            }
            else
            {
                programCounter = ProgramCounter;
            }

            if (programCounter > mMemory.MaxWordIndex)
            {
                ProgramCounter = mMemory.MaxWordIndex;
                ReportRuntimeError("Program counter overflow");
            }
            else
            {
                ProgramCounter = programCounter;
                if (Status == RunStatus.Running && IsBreakpointSet(programCounter))
                {
                    ReportBreakpointReached();
                }
            }
        }