/// <summary> /// Translates the first or 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="argument">the argument for translation</param> /// <param name="argumentNumber">the argument number (either 1 or 2)</param> /// <returns>A value containing the translation of the argument</returns> protected ushort TranslateArgument12(Argument argument, int argumentNumber) { int value; argument.LookUpValue(Assembler, out value); // This is valid for 3-bit adressing and for the constants, because // zero is the only valid constant. // The value fits in the lowest 3 bits. ushort result = (ushort)value; if (argument.Type == ArgumentType.Indirect) { // Indirect addressing is indicated by setting the 4th lowest bit. result |= 0x8; } // Move the argument to the right position // Argument1: 0000aaaa00000000 // Argument2: 00000000aaaa0000 result <<= (3 - argumentNumber) * 4; return result; }
/// <summary> /// Checks if the first or second argument is valid. /// </summary> /// <remarks> /// The argument can be either a constant, or a direct or indirect 3-bit addressing. /// /// If the argument is a constant, it's value must be zero (encoded as 0000b in the /// address field, without an additional word). /// /// If the argument is a 3-bit address, the value can be between [0..7] for the /// indirect addressing or between [1..7] for direct addressing. /// This is due to fact that the constant argument would be indistinguishable from /// direct addressing the zero address (0000b). /// </remarks> /// <param name="argument">an argument to check (either the first of the second)</param> /// <returns>A value indicating if the argument is valid</returns> protected bool CheckArgument12(Argument argument) { int value; if (!argument.LookUpValue(Assembler, out value)) return false; if (argument.Type == ArgumentType.Constant) { if (value != 0) { Error = new Error(); Error.ID = 4; Error.Description = Messages.E0004; Error.Line = Line; Error.Column = argument.Column; return false; } } else { // Zero address is allowed for indirect addressing, because // it does not conflict with the zero constant. int min = (argument.Type == ArgumentType.Indirect) ? 0 : 1; if (value < min || value > 7) { Error = new Error(); Error.ID = 3; Error.Description = string.Format(Messages.E0003, argument.Text, min, 7); Error.Line = Line; Error.Column = argument.Column; return false; } } return true; }
/// <summary> /// Translates the 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="argument">the argument for translation</param> /// <param name="argumentNumber">the argument number</param> /// <returns>A value containing the translation of the argument</returns> protected ushort TranslateArgument(Argument argument, int argumentNumber) { if (argument.Type == ArgumentType.None) return 0; int value; argument.LookUpValue(Assembler, out value); // Write address to the lowest 3 bits ushort result = (ushort)value; if (argument.Type == ArgumentType.Indirect) { // Indirect addressing is indicated by setting the 4th lowest bit. result |= 0x8; } // Move the argument to the right position // Argument1 : 0000aaaa00000000 // Argument2 : 00000000aaaa0000 // Argument3 : 000000000000aaaa result <<= (3 - argumentNumber) * 4; return result; }
/// <summary> /// Translates the second or third 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="argument">the argument for translation</param> /// <param name="argumentNumber">the argument number (either 2 or 3)</param> /// <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 TranslateArgument23(Argument argument, int argumentNumber, ref bool constantSet, ref ushort constant) { int value; argument.LookUpValue(Assembler, out value); if (argument.Type == ArgumentType.Constant || argument.Type == ArgumentType.SymbolConstant) { constant = (ushort)value; constantSet = true; // A constant is encoded as 0000b in the Argument field. return 0; } else { // Write address to the lowest 3 bits ushort result = (ushort)value; if (argument.Type == ArgumentType.Indirect) { // Indirect addressing is indicated by setting the 4th lowest bit. result |= 0x8; } // Move the argument to the right position // Argument2: 00000000aaaa0000 // Argument3: 000000000000aaaa result <<= (3 - argumentNumber) * 4; return result; } }
/// <summary> /// Creates and populates an Argument object. /// </summary> /// <param name="node">Argument parser node</param> /// <param name="type">Argument type</param> /// <returns>Created Argument</returns> protected Argument ArgumentFromNode(Production node, ArgumentType type) { ArrayList values = GetChildValues(node); Argument a = new Argument(); a.Column = node.StartColumn; a.Text = values[0].ToString(); a.Type = type; return a; }