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); }
// 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; }