예제 #1
0
        /// <summary>
        /// Translates the second argument to the machine code.
        /// The resulting value contains the argument encoding in the right
        /// position within the word, and zeroes in locations intended for the
        /// OPCode (mnemonic) and the other argument.
        /// </summary>
        /// <remarks>
        /// Because there is no third argument for I/O instructions, the second
        /// argument uses additional four bits.
        ///
        /// If the argument is a constant, it is stored in the lowest 7 bits,
        /// while the 8th has the value 0 to indicate a constant.
        ///
        /// If 3-bit addressing is used, the 5th to 8th bits have value 1000b,
        /// while the address is stored in the 3 lowest bits. The 4th lowest
        /// bit indicates if direct (0) or indirect (1) addressing is used.
        /// </remarks>
        /// <returns>A value containing the translation of the argument</returns>
        protected ushort TranslateArgument2()
        {
            if (Argument2.Type == ArgumentType.None)
            {
                return(1);                                                 // This argument is optional.
            }
            int value;

            Argument2.LookUpValue(Assembler, out value);

            if (Argument2.Type == ArgumentType.Constant || Argument2.Type == ArgumentType.SymbolConstant)
            {
                ushort constant = (ushort)value;
                // No shifting is required, and the constant range [0..127] garanties that
                // only the first 7 low bits can be set.
                return(constant);
            }
            else
            {
                // Write address to the lowest 3 bits
                ushort result = (ushort)value;
                if (Argument2.Type == ArgumentType.Indirect)
                {
                    // Indirect addressing is indicated by setting the 4th lowest bit.
                    result |= 0x8;
                }
                // The 3-bit address and the (in)direct addresing indicator are already in place.
                // It is only necessary to write the 1000b marker to the second argument position.
                result |= 0x8 << 4;
                return(result);
            }
        }
예제 #2
0
        /// <summary>
        /// Checks if the second argument is valid.
        /// </summary>
        /// <remarks>
        /// The second argument can be either a constant, or a direct or indirect 3-bit addressing.
        ///
        /// If the argument is a constant, it's value can be between [-32768..32767]
        /// </remarks>
        /// <returns>A value indicating if Argument2 is valid</returns>
        protected bool CheckArgument2()
        {
            int value;

            if (!Argument2.LookUpValue(Assembler, out value))
            {
                return(false);
            }

            if (Argument2.Type == ArgumentType.Direct || Argument2.Type == ArgumentType.Indirect)
            {
                if (value < 0 || value > 7)
                {
                    Error             = new Error();
                    Error.ID          = 3;
                    Error.Description = string.Format(Messages.E0003, Argument2.Text, 0, 7);
                    Error.Line        = Line;
                    Error.Column      = Argument2.Column;
                    return(false);
                }
            }
            else
            {
                if (value < short.MinValue || value > short.MaxValue)
                {
                    Error             = new Error();
                    Error.ID          = 2;
                    Error.Description = string.Format(Messages.E0002, Argument2.Text);
                    Error.Line        = Line;
                    Error.Column      = Argument2.Column;
                    return(false);
                }
            }
            return(true);
        }
예제 #3
0
        /// <summary>
        /// Translates the second argument to the machine code.
        /// The resulting value contains the argument encoding in the right
        /// position within the word, and zeroes in locations intended for the
        /// OPCode (mnemonic) or other arguments.
        /// </summary>
        /// <param name="constantSet">used to indicate that the argument is a consant, otherwise unchanged</param>
        /// <param name="constant">used to store the constant, if any, otherwise unchanged</param>
        /// <returns>A value containing the translation of the argument</returns>
        protected ushort TranslateArgument2(ref bool constantSet, ref ushort constant)
        {
            int value;

            Argument2.LookUpValue(Assembler, out value);

            if (Argument2.Type == ArgumentType.Constant || Argument2.Type == ArgumentType.SymbolConstant)
            {
                constant    = (ushort)value;
                constantSet = true;
                // The argument field content is not defined if it is a constant.
                return(0);
            }
            else
            {
                // Write address to the lowest 3 bits
                ushort result = (ushort)value;
                if (Argument2.Type == ArgumentType.Indirect)
                {
                    // Indirect addressing is indicated by setting the 4th lowest bit.
                    result |= 0x8;
                }
                // Move the argument to the right position : 00000000aaaa0000
                result <<= 4;
                return(result);
            }
        }
예제 #4
0
        /// <summary>
        /// Checks if the second argument is valid.
        /// </summary>
        /// <remarks>
        /// The second argument can be either a constant, or a direct or indirect 3-bit addressing.
        ///
        /// If the argument is a constant, its value must be between [0..127] because there are
        /// 7 bits reserved for storing the constant.
        /// These instructions have a maximum of two arguments, so the second argument is stored in eight
        /// instead of the usual four bits.
        ///
        /// If the argument is a 3-bit address, the value must be between [0..7]
        /// </remarks>
        /// <returns>A value indicating if Argument2 is valid</returns>
        protected bool CheckArgument2()
        {
            // If there is no second argumnt, then there is no argument here. See what I did there? :P
            if (Argument2.Type == ArgumentType.None)
            {
                return(true);
            }

            int value;

            if (!Argument2.LookUpValue(Assembler, out value))
            {
                return(false);
            }

            if (Argument2.Type == ArgumentType.Direct || Argument2.Type == ArgumentType.Indirect)
            {
                if (value < 0 || value > 7)
                {
                    Error             = new Error();
                    Error.ID          = 3;
                    Error.Description = string.Format(Messages.E0003, Argument2.Text, 0, 7);
                    Error.Line        = Line;
                    Error.Column      = Argument2.Column;
                    return(false);
                }
            }
            else
            {
                if (value < 0 || value > 127)
                {
                    Error             = new Error();
                    Error.ID          = 5;
                    Error.Description = Messages.E0005;
                    Error.Line        = Line;
                    Error.Column      = Argument2.Column;
                    return(false);
                }
            }
            return(true);
        }
예제 #5
0
        /// <summary>
        /// Checks if the second argument is valid.
        /// </summary>
        /// <remarks>
        /// The second argument can be either a constant, or a direct or indirect 3-bit addressing.
        ///
        /// If the argument is a constant, it's value can be between [-32768..32767]
        ///
        /// If the argument is a 3-bit address, the value can be between [0..7] only if
        /// the third argument is NOT a constant. Otherwise, it is between [1..7].
        /// This is due to fact that the constant argument is encoded as 0 and it
        /// would be imposible to differentiate it from the 0 address.
        /// (The constant is stored in the second word of the instruction and only one
        /// argument can be a constant.)
        /// </remarks>
        /// <returns>A value indicating if Argument2 is valid</returns>
        protected bool CheckArgument2()
        {
            int value;

            if (!Argument2.LookUpValue(Assembler, out value))
            {
                return(false);
            }

            if (Argument2.Type == ArgumentType.Direct || Argument2.Type == ArgumentType.Indirect)
            {
                // Techically, an indirect addressing of the zero address would not be a problem, because the encoded
                // argument would be 1000b, not 0000b like a constant, but pCAS (the original assembler) does not allow this.
                // For compatibility, neither does Messy Lab.
                int min = Argument3.Type == ArgumentType.Constant || Argument3.Type == ArgumentType.SymbolConstant ? 1 : 0;
                if (value < min || value > 7)
                {
                    Error             = new Error();
                    Error.ID          = 3;
                    Error.Description = string.Format(Messages.E0003, Argument2.Text, min, 7);
                    Error.Line        = Line;
                    Error.Column      = Argument2.Column;
                    return(false);
                }
            }
            else
            {
                if (value < short.MinValue || value > short.MaxValue)
                {
                    Error             = new Error();
                    Error.ID          = 2;
                    Error.Description = string.Format(Messages.E0002, Argument2.Text);
                    Error.Line        = Line;
                    Error.Column      = Argument2.Column;
                    return(false);
                }
            }
            return(true);
        }