示例#1
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);
        }
示例#2
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);
        }
示例#3
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);
        }
示例#4
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));
        }