예제 #1
0
        Tuple <OperandFormat, Instruction> GetFormatAndOpcode(SourceLine line)
        {
            var           instruction = line.Instruction.ToLower();
            string        expression1 = string.Empty, expression2 = string.Empty;
            long          eval1 = long.MinValue, eval2 = long.MinValue;
            StringBuilder formatBuilder = new StringBuilder();

            formatBuilder.AppendFormat("{0}", instruction);

            bool impliedA = line.Operand.Equals("a", Controller.Options.StringComparison);

            if (impliedA &&
                !(Reserved.IsOneOf("ImpliedAccumulator", instruction) ||
                  (Reserved.IsOneOf("ImpliedAC02", instruction) && !_cpu.Equals("6502"))
                  )
                )
            {
                throw new Exception();
            }

            string      finalFormat;
            Instruction opcode;

            if (string.IsNullOrEmpty(line.Operand) || impliedA)
            {
                finalFormat = formatBuilder.ToString();
                if (!_filteredOpcodes.TryGetValue(finalFormat, out opcode))
                {
                    return(new Tuple <OperandFormat, Instruction>(null, null));
                }
            }
            else
            {
                formatBuilder.Append(' ');
                int expSize = 1;

                string operand = line.Operand;

                if (operand[0] == '[')
                {
                    // differentiate between 'and [16]' and 'and [16] 16'
                    var firstBracket       = operand.FirstParenEnclosure(useBracket: true);
                    var firstBracketLength = firstBracket.Length;
                    if (operand.Length > firstBracketLength)
                    {
                        var delim = operand.Substring(firstBracketLength).First(c => !char.IsWhiteSpace(c));
                        if (delim != ',')
                        {
                            if (!char.IsWhiteSpace(operand[firstBracketLength]))
                            {
                                throw new Exception(ErrorStrings.None);
                            }
                            expSize = Convert.ToInt32(Controller.Evaluator.Eval(firstBracket.Substring(1, firstBracketLength - 2)));
                            if (expSize != 16 && expSize != 24)
                            {
                                throw new Exception(ErrorStrings.None);
                            }
                            expSize /= 8;
                            operand  = operand.Substring(firstBracketLength + 1);
                        }
                    }
                }
                if (operand[0] == '#')
                {
                    if (operand.Length < 2 || char.IsWhiteSpace(operand[1]))
                    {
                        throw new ExpressionException(operand);
                    }
                    expression1 = operand.Substring(1);
                    eval1       = Controller.Evaluator.Eval(expression1);
                    expSize     = eval1.Size();
                    formatBuilder.Append("#${0:x" + expSize * 2 + "}");
                }
                else
                {
                    IEnumerable <string> commasep;
                    if (line.Operand[0] == '[')
                    {
                        commasep = operand.CommaSeparate('[', ']');
                    }
                    else
                    {
                        commasep = operand.CommaSeparate();
                    }
                    if (commasep.Count() > 2)
                    {
                        throw new Exception(ErrorStrings.None);
                    }


                    string outerexpression = string.Empty;
                    if (commasep.Count() > 1)
                    {
                        if (Reserved.IsOneOf("MoveMemory", instruction))
                        {
                            outerexpression = "${1:x2}";
                            expression2     = commasep.Last();
                            eval2           = Controller.Evaluator.Eval(expression2.Trim());
                        }
                        else
                        {
                            outerexpression = commasep.Last();
                        }
                    }

                    var param1 = commasep.First();
                    if (param1[0] == '(' && param1.Last() == ')' &&
                        param1.FirstParenEnclosure().Equals(param1) &&
                        (commasep.Count() == 1 || commasep.Last().Equals("y", Controller.Options.StringComparison)))
                    {
                        eval1       = ParseSubExpression(param1, '(', ')', formatBuilder, instruction.Equals("jmp"));
                        expression1 = eval1.ToString();
                    }
                    else if (param1[0] == '[')
                    {
                        eval1       = ParseSubExpression(param1, '[', ']', formatBuilder, instruction.Equals("jmp"));
                        expression1 = eval1.ToString();
                    }
                    else
                    {
                        expression1 = param1.TrimEnd();
                        eval1       = Controller.Evaluator.Eval(expression1);
                        if (expSize == 1)
                        {
                            if (Reserved.IsOneOf("Branches16", instruction))
                            {
                                // we have to check this too in case the user does a brl $10ffff
                                expSize++;
                            }
                            else
                            {
                                expSize = eval1.Size();
                            }
                        }
                        formatBuilder.Append("${0:x" + expSize * 2 + "}");
                    }

                    if (commasep.Count() > 1)
                    {
                        formatBuilder.AppendFormat(",{0}", outerexpression);
                    }
                }
                finalFormat = formatBuilder.ToString();

                while (!_filteredOpcodes.TryGetValue(finalFormat, out opcode))
                {
                    // some instructions the size is bigger than the expression comes out to, so
                    // make the expression size larger
                    if (expSize > 3)
                    {
                        return(new Tuple <OperandFormat, Instruction>(null, null)); // we didn't find it
                    }
                    finalFormat = finalFormat.Replace("x" + (expSize++) * 2, "x" + expSize * 2);
                }
            }
            var fmt = new OperandFormat
            {
                FormatString = finalFormat,
                Eval1        = eval1,
                Eval2        = eval2
            };

            return(new Tuple <OperandFormat, Instruction>(fmt, opcode));
        }
 /// <summary>
 ///     Construct from a mnemonic and list of operand types.
 /// </summary>
 public InstructionFormat([NotNull] string mnemonic, [NotNull] params Type[] operand_types)
 {
     Mnemonic      = mnemonic;
     OperandFormat = new OperandFormat(operand_types);
 }
예제 #3
0
        // Constructors ///////////////////////////////////////////////////////

        /// <summary>
        ///     Construct from mnemonic, operand formats, and mappings.
        /// </summary>
        public NativeInstructionDefinition([NotNull] string mnemonic, [NotNull] OperandFormat operand_format,
                                           [NotNull] InstructionFieldMappingBuilder.InstructionFieldMapping mapping)
        {
            Format        = new InstructionFormat(mnemonic, operand_format);
            field_mapping = mapping;
        }
        // Constructors ///////////////////////////////////////////////////////

        /// <summary>
        ///     Construct from a mnemonic and operand format.
        /// </summary>
        public InstructionFormat([NotNull] string mnemonic, [NotNull] OperandFormat operand_format)
        {
            Mnemonic      = mnemonic;
            OperandFormat = operand_format;
        }