Beispiel #1
0
        /// <summary>
        /// Method for performing the NUM instruction
        /// </summary>
        public static bool ConvertToNumeric(ModuleBase module, MixInstruction.Instance instance)
        {
            decimal  num = 0M;
            Register rA  = module.Registers.RA;

            for (int i = 0; i < rA.ByteCount; i++)
            {
                num *= 10M;
                num += rA[i] % 10;
            }

            Register rX = module.Registers.RX;

            for (int j = 0; j < rX.ByteCount; j++)
            {
                num *= 10M;
                num += rX[j] % 10;
            }

            if (num > rA.MaxMagnitude)
            {
                module.ReportOverflow();
                num = num % rA.MaxMagnitude;
            }

            rA.MagnitudeLongValue = (long)num;

            return(true);
        }
Beispiel #2
0
        public static InstanceValidationError[] InstanceValid(MixInstruction.Instance instance)
        {
            int index = 0;

            InstanceValidationError[] errorArray = new InstanceValidationError[2];

            if (instance.Index > 6)
            {
                errorArray[index] = new InstanceValidationError(InstanceValidationError.Sources.Index, 0, 6);
                index++;
            }

            if (instance.FieldSpec.MixByteValue.ByteValue >= Devices.DeviceCount)
            {
                errorArray[index] = new InstanceValidationError(InstanceValidationError.Sources.FieldSpec, 0, 20);
                index++;
            }

            if (index == 1)
            {
                return new InstanceValidationError[] { errorArray[0] }
            }
            ;
            if (index == 2)
            {
                return(errorArray);
            }

            return(null);
        }
Beispiel #3
0
        /// <summary>
        /// Method for performing MUL instruction
        /// </summary>
        public static bool Multiply(ModuleBase module, MixInstruction.Instance instance)
        {
            var indexedAddress = InstructionHelpers.GetValidIndexedAddress(module, instance.AddressValue, instance.Index);

            if (indexedAddress == int.MinValue)
            {
                return(false);
            }

            Register rA = module.Registers.RA;
            Register rX = module.Registers.RX;

            long rAValue         = rA.LongValue;
            long memoryWordValue = WordField.LoadFromFullWord(instance.FieldSpec, module.Memory[indexedAddress]).LongValue;

            var result = decimal.Multiply(rAValue, memoryWordValue);

            rA.Sign = rX.Sign = result.GetSign();
            result  = result.GetMagnitude();

            var rXResultValue = (long)(result % ((long)1 << rX.BitCount));
            var rAResultValue = (long)decimal.Truncate(result / ((long)1 << rX.BitCount));

            rA.MagnitudeLongValue = rAResultValue;
            rX.MagnitudeLongValue = rXResultValue;

            return(true);
        }
Beispiel #4
0
        /// <summary>
        /// Method for performing the JRED instruction
        /// </summary>
        public static bool JumpIfReady(ModuleBase module, MixInstruction.Instance instance)
        {
            if (module.Devices == null)
            {
                module.ReportRuntimeError("Module does not provide devices");
                return(false);
            }

            var indexedAddress = InstructionHelpers.GetValidIndexedAddress(module, instance.AddressValue, instance.Index);

            if (indexedAddress == int.MinValue)
            {
                return(false);
            }

            int       deviceIndex = instance.FieldSpec.MixByteValue.ByteValue;
            MixDevice device      = module.Devices[deviceIndex];

            if (!device.Busy)
            {
                JumpInstructions.Jump(module, indexedAddress);
                return(false);
            }

            return(true);
        }
Beispiel #5
0
        /// <summary>
        /// Method for performing the OUT instruction
        /// </summary>
        public static bool Output(ModuleBase module, MixInstruction.Instance instance)
        {
            if (module.Devices == null)
            {
                module.ReportRuntimeError("Module does not provide devices");
                return(false);
            }

            var mValue = InstructionHelpers.GetValidIndexedAddress(module, instance.AddressValue, instance.Index);

            if (mValue == int.MinValue)
            {
                return(false);
            }

            int       deviceIndex = instance.FieldSpec.MixByteValue.ByteValue;
            MixDevice device      = module.Devices[deviceIndex];

            if (!device.SupportsOutput)
            {
                module.ReportRuntimeError("Device " + deviceIndex + " doesn't support output");
                return(false);
            }

            if (device.Busy)
            {
                return(false);
            }

            var field = WordField.LoadFromRegister(new FieldSpec(4, 5), module.Registers.RX);

            device.StartOutput(module.Memory, mValue, (int)field.LongValue, module is Mix && ((Mix)module).Mode == ModuleBase.RunMode.Control ? new InterruptQueueCallback(((Mix)module).QueueInterrupt) : null);

            return(true);
        }
Beispiel #6
0
        public static InstanceValidationError[] ValidateIndex(MixInstruction.Instance instance) =>
        instance.Index > 6 ? new InstanceValidationError[]
        {
            new InstanceValidationError(InstanceValidationError.Sources.Index, 0, 6)
        }

                                                                                                                                            : null;
        static bool DoIncrease(ModuleBase module, MixInstruction.Instance instance, int registerIndex, bool negateSign)
        {
            var      indexedAddress = module.Registers.GetIndexedAddress(instance.AddressValue, instance.Index);
            Register register       = module.Registers[registerIndex];
            long     longValue      = register.LongValue;

            if (negateSign)
            {
                indexedAddress = -indexedAddress;
            }

            longValue += indexedAddress;

            if (longValue != 0L)
            {
                register.Sign = longValue.GetSign();
                longValue     = longValue.GetMagnitude();
            }

            if (longValue > register.MaxMagnitude)
            {
                if (register is IndexRegister)
                {
                    module.ReportRuntimeError("Index register overflow");
                    return(false);
                }

                module.ReportOverflow();
                longValue &= register.MaxMagnitude;
            }

            register.MagnitudeLongValue = longValue;

            return(true);
        }
Beispiel #8
0
        public static InstanceValidationError[] ValidateIndexAndFieldSpec(MixInstruction.Instance instance)
        {
            int index = 0;

            InstanceValidationError[] errorArray = new InstanceValidationError[2];

            if (instance.Index > 6)
            {
                errorArray[index] = new InstanceValidationError(InstanceValidationError.Sources.Index, 0, 6);
                index++;
            }

            if (!instance.FieldSpec.IsValid)
            {
                errorArray[index] = new InstanceValidationError(InstanceValidationError.Sources.FieldSpec, "valid fieldspec required");
                index++;
            }

            if (index == 1)
            {
                return new InstanceValidationError[] { errorArray[0] }
            }
            ;
            if (index == 2)
            {
                return(errorArray);
            }

            return(null);
        }
    }
Beispiel #9
0
 public RuntimeValidationError(int programCounter, MixInstruction.Instance instance, string message, int validLowerBound, int validUpperBound, int actualValue)
     : base(message, validLowerBound, validUpperBound)
 {
     Instance       = instance;
     ProgramCounter = programCounter;
     ActualValue    = actualValue;
 }
Beispiel #10
0
        /// <summary>
        /// Method for performing the STZ instruction
        /// </summary>
        public static bool StoreZero(ModuleBase module, MixInstruction.Instance instance)
        {
            var indexedAddress = InstructionHelpers.GetValidIndexedAddress(module, instance.AddressValue, instance.Index);

            if (indexedAddress != int.MinValue)
            {
                var word = new FullWord();
                WordField.LoadFromFullWord(instance.FieldSpec, word).ApplyToFullWord(module.Memory[indexedAddress]);
            }

            return(true);
        }
Beispiel #11
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);
        }
Beispiel #12
0
        /// <summary>
        /// Method for performing CMPx instructions
        /// </summary>
        public static bool Compare(ModuleBase module, MixInstruction.Instance instance)
        {
            var indexedAddress = InstructionHelpers.GetValidIndexedAddress(module, instance.AddressValue, instance.Index);

            if (indexedAddress == int.MinValue)
            {
                return(false);
            }

            int      registerIndex = instance.MixInstruction.Opcode - opcodeBase;
            Register register      = module.Registers[registerIndex];

            module.Registers.CompareIndicator = WordField.LoadFromFullWord(instance.FieldSpec, register.FullWordValue).CompareTo(module.Memory[indexedAddress]).ToCompValue();

            return(true);
        }
        static bool DoEnter(ModuleBase module, MixInstruction.Instance instance, int registerIndex, bool negateSign)
        {
            var      indexedAddress = module.Registers.GetIndexedAddress(instance.AddressValue, instance.Index);
            Register register       = module.Registers[registerIndex];

            if (negateSign)
            {
                indexedAddress = -indexedAddress;
            }

            register.LongValue = indexedAddress;

            if (indexedAddress == 0)
            {
                register.Sign = instance.Sign;
            }

            return(true);
        }
Beispiel #14
0
        /// <summary>
        /// Method for performing DIV instruction
        /// </summary>
        public static bool Divide(ModuleBase module, MixInstruction.Instance instance)
        {
            var indexedAddress = InstructionHelpers.GetValidIndexedAddress(module, instance.AddressValue, instance.Index);

            if (indexedAddress == int.MinValue)
            {
                return(false);
            }

            long memoryWordValue = WordField.LoadFromFullWord(instance.FieldSpec, module.Memory[indexedAddress]).LongValue;

            if (memoryWordValue == 0L)
            {
                module.ReportOverflow();
                return(true);
            }

            Register rA = module.Registers.RA;
            Register rX = module.Registers.RX;

            long rAValue = rA.LongValue;
            long rXValue = rX.LongValue;

            decimal rAXValue = (decimal)rAValue * ((long)1 << rX.BitCount) + rXValue;
            decimal divider  = rAXValue / memoryWordValue;

            rX.Sign = rA.Sign;
            rA.Sign = divider.GetSign();
            divider = divider.GetMagnitude();

            if (divider > rA.MaxMagnitude)
            {
                module.ReportOverflow();
                return(true);
            }

            decimal remainder = rAXValue % memoryWordValue;

            rA.MagnitudeLongValue = (long)divider;
            rX.MagnitudeLongValue = (long)remainder;

            return(true);
        }
Beispiel #15
0
        /// <summary>
        /// Method for performing SLB and SRB instructions
        /// </summary>
        public static bool ShiftAXBinary(ModuleBase module, MixInstruction.Instance instance)
        {
            var indexedAddress = module.Registers.GetIndexedAddress(instance.AddressValue, instance.Index);

            if (indexedAddress < 0)
            {
                module.ReportRuntimeError("Indexed value must be nonnegative: " + indexedAddress);
                return(false);
            }

            Register rA = module.Registers.RA;
            Register rX = module.Registers.RX;

            int registerBitCount = FullWordRegister.RegisterByteCount * MixByte.BitCount;
            int shiftCount       = indexedAddress % (registerBitCount * 2);

            if (shiftCount == 0)
            {
                return(true);
            }

            long rAlongValue = rA.MagnitudeLongValue;
            long rXlongValue = rX.MagnitudeLongValue;

            switch (instance.MixInstruction.FieldSpec.MixByteValue.ByteValue)
            {
            case slbField:
                rA.MagnitudeLongValue = ((rAlongValue << shiftCount) & rA.MaxMagnitude) | (rXlongValue >> (rX.BitCount - shiftCount));
                rX.MagnitudeLongValue = (rXlongValue << shiftCount) & rX.MaxMagnitude;

                break;

            case srbField:

                rA.MagnitudeLongValue = rAlongValue >> shiftCount;
                rX.MagnitudeLongValue = (rXlongValue >> shiftCount) | (rAlongValue << (rX.BitCount - shiftCount));

                break;
            }

            return(true);
        }
Beispiel #16
0
        static bool DoLoad(ModuleBase module, MixInstruction.Instance instance, int registerIndex, bool negateSign)
        {
            var indexedAddress = InstructionHelpers.GetValidIndexedAddress(module, instance.AddressValue, instance.Index);

            if (indexedAddress == int.MinValue)
            {
                return(false);
            }

            var memoryField = WordField.LoadFromFullWord(instance.FieldSpec, module.Memory[indexedAddress]);

            if (negateSign)
            {
                memoryField.InvertSign();
            }

            memoryField.ApplyToRegister(module.Registers[registerIndex]);

            return(true);
        }
Beispiel #17
0
        /// <summary>
        /// Method for performing the CHAR instruction
        /// </summary>
        public static bool ConvertToChar(ModuleBase module, MixInstruction.Instance instance)
        {
            Register rA = module.Registers.RA;
            long     magnitudeLongValue = rA.MagnitudeLongValue;
            Register rX = module.Registers.RX;

            for (int i = rX.ByteCount - 1; i >= 0; i--)
            {
                rX[i] = zeroCharValue + ((byte)(magnitudeLongValue % 10L));
                magnitudeLongValue /= 10L;
            }

            for (int i = rA.ByteCount - 1; i >= 0; i--)
            {
                rA[i] = zeroCharValue + ((byte)(magnitudeLongValue % 10L));
                magnitudeLongValue /= 10L;
            }

            return(true);
        }
Beispiel #18
0
        /// <summary>
        /// Method for performing SLA and SRA instructions
        /// </summary>
        public static bool ShiftA(ModuleBase module, MixInstruction.Instance instance)
        {
            var indexedAddress = module.Registers.GetIndexedAddress(instance.AddressValue, instance.Index);

            if (indexedAddress < 0)
            {
                module.ReportRuntimeError("Indexed value must be nonnegative: " + indexedAddress);
                return(false);
            }

            Register rA         = module.Registers.RA;
            int      shiftCount = indexedAddress % rA.ByteCount;

            if (shiftCount != 0)
            {
                switch (instance.MixInstruction.FieldSpec.MixByteValue.ByteValue)
                {
                case slaField:
                    ShiftWordLeft(rA, shiftCount);

                    for (int i = rA.ByteCount - shiftCount; i < rA.ByteCount; i++)
                    {
                        rA[i] = 0;
                    }

                    break;

                case sraField:
                    ShiftWordRight(rA, shiftCount);

                    for (int j = shiftCount - 1; j >= 0; j--)
                    {
                        rA[j] = 0;
                    }

                    break;
                }
            }
            return(true);
        }
Beispiel #19
0
        /// <summary>
        /// Method for performing STx instructions
        /// </summary>
        public static bool StoreRegister(ModuleBase module, MixInstruction.Instance instance)
        {
            var indexedAddress = InstructionHelpers.GetValidIndexedAddress(module, instance.AddressValue, instance.Index);

            if (indexedAddress != int.MinValue)
            {
                Register sourceRegister;

                if (instance.MixInstruction.Opcode == storeJOpcode)
                {
                    sourceRegister = module.Registers.RJ;
                }
                else
                {
                    sourceRegister = module.Registers[instance.MixInstruction.Opcode - storeOpcodeBase];
                }

                WordField.LoadFromRegister(instance.FieldSpec, sourceRegister).ApplyToFullWord(module.Memory[indexedAddress]);
            }

            return(true);
        }
Beispiel #20
0
        /// <summary>
        /// Method for performing the IOC instruction
        /// </summary>
        public static bool IOControl(ModuleBase module, MixInstruction.Instance instance)
        {
            if (module.Devices == null)
            {
                module.ReportRuntimeError("Module does not provide devices");
                return(false);
            }

            var       indexedAddress = module.Registers.GetIndexedAddress(instance.AddressValue, instance.Index);
            int       deviceIndex    = instance.FieldSpec.MixByteValue.ByteValue;
            MixDevice device         = module.Devices[deviceIndex];

            if (device.Busy)
            {
                return(false);
            }

            var field = WordField.LoadFromRegister(new FieldSpec(4, 5), module.Registers.RX);

            device.StartIoc(indexedAddress, (int)field.LongValue, module is Mix && ((Mix)module).Mode == ModuleBase.RunMode.Control ? new InterruptQueueCallback(((Mix)module).QueueInterrupt) : null);

            return(true);
        }
Beispiel #21
0
        /// <summary>
        /// Method for performing ADD and SUB instructions
        /// </summary>
        public static bool AddSubstract(ModuleBase module, MixInstruction.Instance instance)
        {
            var indexedAddress = InstructionHelpers.GetValidIndexedAddress(module, instance.AddressValue, instance.Index);

            if (indexedAddress == int.MinValue)
            {
                return(false);
            }

            Register rA              = module.Registers.RA;
            long     rALongValue     = rA.LongValue;
            long     memoryWordValue = WordField.LoadFromFullWord(instance.FieldSpec, module.Memory[indexedAddress]).LongValue;

            if (instance.MixInstruction.Opcode == substractOpcode)
            {
                memoryWordValue = -memoryWordValue;
            }

            long sumValue = rALongValue + memoryWordValue;

            if (sumValue != 0L)
            {
                rA.Sign  = sumValue.GetSign();
                sumValue = sumValue.GetMagnitude();
            }

            if (sumValue > rA.MaxMagnitude)
            {
                module.ReportOverflow();
                sumValue &= rA.MaxMagnitude;
            }

            rA.MagnitudeLongValue = sumValue;

            return(true);
        }
Beispiel #22
0
 public RuntimeValidationError(int programCounter, MixInstruction.Instance instance, int validLowerBound, int validUpperBound, int actualValue)
     : this(programCounter, instance, null, validLowerBound, validUpperBound, actualValue)
 {
 }
Beispiel #23
0
 public RuntimeValidationError(int programCounter, MixInstruction.Instance instance, string message)
     : this(programCounter, instance, message, int.MinValue, int.MinValue, int.MinValue)
 {
 }
Beispiel #24
0
 public InstructionText(MixInstruction.Instance instance)
 {
     mInstance = instance;
 }
Beispiel #25
0
        /// <summary>
        /// Method for performing JxN, JxZ, JxP, JxNN, JxNZ, JxNP, JxE and JxO instructions
        /// </summary>
        public static bool RegJump(ModuleBase module, MixInstruction.Instance instance)
        {
            var indexedAddress = InstructionHelpers.GetValidIndexedAddress(module, instance.AddressValue, instance.Index);

            if (indexedAddress == int.MinValue)
            {
                return(false);
            }

            int  registerIndex = instance.MixInstruction.Opcode - regJumpOpcodeBase;
            long longValue     = module.Registers[registerIndex].LongValue;

            switch (instance.MixInstruction.FieldSpec.MixByteValue.ByteValue)
            {
            case regJumpNegField:
                if (longValue >= 0L)
                {
                    break;
                }

                Jump(module, indexedAddress);
                return(false);

            case regJumpZeroField:
                if (longValue != 0L)
                {
                    break;
                }

                Jump(module, indexedAddress);
                return(false);

            case regJumpPosField:
                if (longValue <= 0L)
                {
                    break;
                }

                Jump(module, indexedAddress);
                return(false);

            case regJumpNonNegField:
                if (longValue < 0L)
                {
                    break;
                }

                Jump(module, indexedAddress);
                return(false);

            case regJumpNonZeroField:
                if (longValue == 0L)
                {
                    break;
                }

                Jump(module, indexedAddress);

                return(false);

            case regJumpNonPosField:
                if (longValue > 0L)
                {
                    break;
                }

                Jump(module, indexedAddress);
                return(false);

            case regJumpEvenField:
                if (longValue % 2 != 0)
                {
                    break;
                }

                Jump(module, indexedAddress);
                return(false);

            case regJumpOddField:
                if (longValue % 2 == 0)
                {
                    break;
                }

                Jump(module, indexedAddress);
                return(false);
            }

            return(true);
        }
 /// <summary>
 /// Method for performing INCx instructions
 /// </summary>
 public static bool Increase(ModuleBase module, MixInstruction.Instance instance) =>
 DoIncrease(module, instance, instance.MixInstruction.Opcode - opcodeBase, false);
 /// <summary>
 /// Method for performing ENNx instructions
 /// </summary>
 public static bool EnterNegative(ModuleBase module, MixInstruction.Instance instance) =>
 DoEnter(module, instance, instance.MixInstruction.Opcode - opcodeBase, true);
Beispiel #28
0
        /// <summary>
        /// Method for performing JMP, JSJ, JOV, JNOV, JL, JE, JG, JGE, JNE and JLE instructions
        /// </summary>
        public static bool NonRegJump(ModuleBase module, MixInstruction.Instance instance)
        {
            var indexedAddress = InstructionHelpers.GetValidIndexedAddress(module, instance.AddressValue, instance.Index);

            if (indexedAddress == int.MinValue)
            {
                return(false);
            }

            switch (instance.MixInstruction.FieldSpec.MixByteValue.ByteValue)
            {
            case jmpField:
                Jump(module, indexedAddress);
                return(false);

            case jsjField:
                DoJump(module, indexedAddress, true);
                return(false);

            case jovField:
                if (!module.Registers.OverflowIndicator)
                {
                    module.Registers.OverflowIndicator = false;
                    break;
                }

                Jump(module, indexedAddress);
                return(false);

            case jnovField:
                if (module.Registers.OverflowIndicator)
                {
                    module.Registers.OverflowIndicator = false;
                    break;
                }

                Jump(module, indexedAddress);
                return(false);

            case jlField:
                if (module.Registers.CompareIndicator != Registers.CompValues.Less)
                {
                    break;
                }

                Jump(module, indexedAddress);
                return(false);

            case jeField:
                if (module.Registers.CompareIndicator != Registers.CompValues.Equal)
                {
                    break;
                }

                Jump(module, indexedAddress);
                return(false);

            case jgField:
                if (module.Registers.CompareIndicator != Registers.CompValues.Greater)
                {
                    break;
                }

                Jump(module, indexedAddress);
                return(false);

            case jgeField:
                if (module.Registers.CompareIndicator != Registers.CompValues.Greater && module.Registers.CompareIndicator != Registers.CompValues.Equal)
                {
                    break;
                }

                Jump(module, indexedAddress);
                return(false);

            case jneField:
                if (module.Registers.CompareIndicator == Registers.CompValues.Equal)
                {
                    break;
                }

                Jump(module, indexedAddress);

                return(false);

            case jleField:
                if (module.Registers.CompareIndicator != Registers.CompValues.Less && module.Registers.CompareIndicator != Registers.CompValues.Equal)
                {
                    break;
                }

                Jump(module, indexedAddress);
                return(false);
            }

            return(true);
        }
        public static bool DoFloatingPoint(ModuleBase module, MixInstruction.Instance instance)
        {
            if (!(module is Mix))
            {
                module.ReportRuntimeError(string.Format("Floating point instruction {0} is only available within Mix", instance.Instruction.Mnemonic));
                return(false);
            }

            var mix = (Mix)module;

            FloatingPointModule floatingPointModule = mix.FloatingPointModule;

            if (floatingPointModule == null)
            {
                module.ReportRuntimeError(string.Format("Instruction {0} requires floating point module to be enabled", instance.Instruction.Mnemonic));
                return(false);
            }

            if (mExecutionStatus != null && mExecutionStatus.ProgramCounter != module.ProgramCounter)
            {
                mExecutionStatus = null;
            }

            if (mExecutionStatus == null)
            {
                mExecutionStatus = new ExecutionStatus(module.Mode, module.ProgramCounter, instance.Instruction.Mnemonic);
            }

            if (mExecutionStatus.CurrentStep == ExecutionStatus.Step.Initialize)
            {
                mExecutionStatus.RAValue = module.Registers.RA.FullWordValue;

                bool prenormInstruction = Array.IndexOf(mPrenormOpcodes, instance.MixInstruction.Opcode) != -1;
                bool fcmpInstruction    = !prenormInstruction && instance.MixInstruction.Opcode == fcmpOpcode;

                if (prenormInstruction || fcmpInstruction)
                {
                    var indexedAddress = InstructionHelpers.GetValidIndexedAddress(module, instance.AddressValue, instance.Index);
                    if (indexedAddress == int.MinValue)
                    {
                        mExecutionStatus = null;
                        return(false);
                    }

                    mExecutionStatus.ParameterValue = module.Memory[indexedAddress];
                }

                module.Registers.SaveToMemory(floatingPointModule.FullMemory, ModuleSettings.FloatingPointMemoryWordCount, 0);

                if (!floatingPointModule.ValidateCall(mExecutionStatus.Mnemonic))
                {
                    module.ReportRuntimeError("Unable to initialize floating point module");
                    mExecutionStatus = null;

                    return(false);
                }

                module.Mode = ModuleBase.RunMode.Module;

                if (prenormInstruction)
                {
                    mExecutionStatus.CurrentStep = ExecutionStatus.Step.PrenormRA;

                    if (floatingPointModule.PreparePrenorm(mExecutionStatus.RAValue))
                    {
                        module.ReportBreakpointReached();
                        return(false);
                    }
                }
                else
                {
                    mExecutionStatus.CurrentStep = ExecutionStatus.Step.ExecuteInstruction;

                    if (fcmpInstruction
                                                ? floatingPointModule.PrepareCall(mExecutionStatus.Mnemonic, mExecutionStatus.RAValue, mExecutionStatus.ParameterValue)
                                                : floatingPointModule.PrepareCall(mExecutionStatus.Mnemonic, mExecutionStatus.RAValue))
                    {
                        module.ReportBreakpointReached();
                        return(false);
                    }
                }
            }

            mExecutionStatus.OverflowDetected |= floatingPointModule.Tick();

            switch (floatingPointModule.Status)
            {
            case ModuleBase.RunStatus.Idle:

                switch (mExecutionStatus.CurrentStep)
                {
                case ExecutionStatus.Step.PrenormRA:
                    mExecutionStatus.RAValue     = floatingPointModule.Registers.RA.FullWordValue;
                    mExecutionStatus.CurrentStep = ExecutionStatus.Step.PrenormParameter;

                    if (floatingPointModule.PreparePrenorm(mExecutionStatus.ParameterValue))
                    {
                        module.ReportBreakpointReached();
                        return(false);
                    }

                    break;

                case ExecutionStatus.Step.PrenormParameter:
                    mExecutionStatus.ParameterValue = floatingPointModule.Registers.RA.FullWordValue;
                    mExecutionStatus.CurrentStep    = ExecutionStatus.Step.ExecuteInstruction;

                    if (floatingPointModule.PrepareCall(mExecutionStatus.Mnemonic, mExecutionStatus.RAValue, mExecutionStatus.ParameterValue))
                    {
                        module.ReportBreakpointReached();
                        return(false);
                    }

                    break;

                case ExecutionStatus.Step.ExecuteInstruction:
                    mExecutionStatus.RAValue = floatingPointModule.Registers.RA.FullWordValue;
                    Registers.CompValues comparatorValue = floatingPointModule.Registers.CompareIndicator;
                    module.Registers.LoadFromMemory(floatingPointModule.FullMemory, ModuleSettings.FloatingPointMemoryWordCount);
                    module.Registers.OverflowIndicator = mExecutionStatus.OverflowDetected;

                    if (mExecutionStatus.Mnemonic == FcmpMnemonic)
                    {
                        module.Registers.CompareIndicator = comparatorValue;
                    }
                    else
                    {
                        module.Registers.RA.Magnitude = mExecutionStatus.RAValue.Magnitude;
                        module.Registers.RA.Sign      = mExecutionStatus.RAValue.Sign;
                    }

                    module.Mode = ModuleBase.RunMode.Normal;

                    mExecutionStatus = null;

                    return(true);
                }

                break;

            case ModuleBase.RunStatus.BreakpointReached:
                module.ReportBreakpointReached();

                break;

            case ModuleBase.RunStatus.InvalidInstruction:
            case ModuleBase.RunStatus.RuntimeError:
                module.ReportRuntimeError(string.Format("Floating point module failed to execute instruction {0}", mExecutionStatus.Mnemonic));
                module.Mode = mExecutionStatus.Mode;

                mExecutionStatus = null;

                break;
            }

            return(false);
        }
Beispiel #30
0
        /// <summary>
        /// Method for performing LDxN instructions
        /// </summary>
        public static bool LoadNegative(ModuleBase module, MixInstruction.Instance instance)
        {
            int registerIndex = instance.MixInstruction.Opcode - loadNegOpcodeBase;

            return(DoLoad(module, instance, registerIndex, true));
        }