コード例 #1
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);
        }
コード例 #2
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);
        }
コード例 #3
0
ファイル: StoreInstructions.cs プロジェクト: arlm/MixEmul
        /// <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);
        }
コード例 #4
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);
        }
コード例 #5
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);
        }
コード例 #6
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);
        }
コード例 #7
0
ファイル: StoreInstructions.cs プロジェクト: arlm/MixEmul
        /// <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);
        }
コード例 #8
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);
        }
コード例 #9
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);
        }
コード例 #10
0
ファイル: WValue.cs プロジェクト: arlm/MixEmul
        public static IValue ParseValue(string text, int sectionCharIndex, ParsingStatus status)
        {
            // split the text to parse in its W-value components
            var textParts    = text.Split(new char[] { ',' });
            int currentIndex = 0;

            var register = new FullWordRegister();
            var word     = new FullWord(0);

            // parse and apply each component to the word that contains the result
            foreach (string part in textParts)
            {
                // parse the address part...
                var braceIndex = part.IndexOf('(');
                var address    = ExpressionValue.ParseValue((braceIndex == -1) ? part : part.Substring(0, braceIndex), sectionCharIndex + currentIndex, status);
                if (address == null)
                {
                    return(null);
                }

                // ... and check if it is valid
                var addressSign      = address.GetSign(status.LocationCounter);
                var addressMagnitude = address.GetMagnitude(status.LocationCounter);
                if (addressMagnitude > register.MaxMagnitude)
                {
                    status.ReportParsingError(sectionCharIndex + currentIndex, (braceIndex == -1) ? part.Length : braceIndex, "W-value field value invalid");
                    return(null);
                }

                register.MagnitudeLongValue = addressMagnitude;
                register.Sign = addressSign;
                int fieldValue = FullWord.ByteCount;

                // if a fieldspec part is present...
                if (braceIndex >= 0)
                {
                    // ... parse its value...
                    var field = FPartValue.ParseValue(part.Substring(braceIndex), (sectionCharIndex + currentIndex) + braceIndex, status);
                    if (field == null)
                    {
                        return(null);
                    }

                    // ... and check if it is valid
                    if (field.GetValue(status.LocationCounter) != FPartValue.Default)
                    {
                        fieldValue = (int)field.GetValue(status.LocationCounter);
                    }
                }

                // use the fieldspec value to create and check an actual fieldspec
                var fieldSpec = new FieldSpec(fieldValue);
                if (!fieldSpec.IsValid)
                {
                    status.ReportParsingError((sectionCharIndex + currentIndex) + braceIndex, part.Length - braceIndex, "field must be a fieldspec");
                    return(null);
                }

                // apply the component to the word that will contain the end result
                WordField.LoadFromRegister(fieldSpec, register).ApplyToFullWord(word);
                currentIndex += part.Length + 1;
            }

            return(new NumberValue(word.Sign, word.MagnitudeLongValue));
        }