/// <summary> /// Constructs a new instance of the 6502 assembler object. /// </summary> /// <param name="services">The shared <see cref="AssemblyServices"/> object.</param> public Asm6502(AssemblyServices services) : base(services) { Reserved.DefineType("IndIndeces", "s", "sp", "x"); Reserved.DefineType("IndicesInd", "y", "z"); Reserved.DefineType("Indeces", "s", "sp", "x", "y", "z"); Reserved.DefineType("Registers", "a", "s", "sp", "x", "y", "z"); Reserved.DefineType("Implieds", "brk", "clc", "cld", "cla", "cle", "cli", "clv", "clx", "cly", "csh", "dex", "dey", "dez", "inx", "iny", "inz", "jam", "map", "nop", "pha", "phb", "phd", "phk", "php", "phx", "phy", "phz", "pla", "plb", "pld", "plp", "plx", "ply", "plz", "rts", "rti", "rtl", "rtn", "say", "sec", "sed", "see", "sei", "set", "stp", "tax", "tay", "taz", "tcd", "tcs", "tdc", "tsc", "tsx", "tsy", "txa", "txs", "txy", "tya", "tys", "tyx", "tza", "wai", "wdm", "xba", "xce" ); Reserved.DefineType("Branches", "bcc", "bcs", "beq", "bmi", "bne", "bpl", "bra", "bvc", "bvs", "brl", "per", "blt", "bge", "bbr", "bbs" ); Reserved.DefineType("Branches16", "brl", "per", "blt", "bge" ); Reserved.AddWord("RelativeSecond", "bbr"); Reserved.AddWord("RelativeSecond", "bbs"); Reserved.AddWord("RelativeSecond", "rmb"); Reserved.AddWord("RelativeSecond", "smb"); Reserved.DefineType("MoveMemory16", "tai", "tdd", "tia", "tii", "tin" ); Reserved.DefineType("Jumps", "jmp", "jsr" ); Reserved.DefineType("JumpsLong", "jml", "jsl" ); Reserved.AddWord("SwapOperands", "mvn"); Reserved.AddWord("SwapOperands", "mvp"); Reserved.DefineType("LongShort", ".m16", ".m8", ".x16", ".x8", ".mx16", ".mx8" ); Reserved.DefineType("Autos", ".auto", ".manual"); Reserved.DefineType("PseudoBranches", "jcc", "jcs", "jeq", "jmi", "jne", "jpl", "jvc", "jvs"); Reserved.DefineType("RepSep", "rep", "sep" ); Reserved.DefineType("Mnemonics", "adc", "anc", "and", "ane", "arr", "asl", "asr", "asw", "bit", "bsr", "cmp", "cop", "cpx", "cpy", "cpz", "dcp", "dec", "dew", "dop", "eor", "inc", "inw", "isb", "jml", "jmp", "jsl", "jsr", "las", "lax", "lda", "ldx", "ldy", "ldz", "lsr", "neg", "ora", "pea", "pei", "phw", "rla", "rol", "ror", "row", "rra", "sax", "sbc", "sha", "shx", "shy", "slo", "sre", "st1", "st2", "sta", "stx", "sty", "stz", "tam", "tas", "tma", "top", "trb", "tsb", "tst", "adcq", "aslq", "andq", "cpq", "deq", "eom", "eorq", "inq", "ldq", "lsrq", "orq", "rolq", "rorq", "sbcq", "stq" ); // set architecture specific encodings Services.Encoding.SelectEncoding("\"petscii\""); Services.Encoding.Map("az", 'A'); Services.Encoding.Map("AZ", 0xc1); Services.Encoding.Map('£', '\\'); Services.Encoding.Map('↑', '^'); Services.Encoding.Map('←', '_'); Services.Encoding.Map('▌', 0xa1); Services.Encoding.Map('▄', 0xa2); Services.Encoding.Map('▔', 0xa3); Services.Encoding.Map('▁', 0xa4); Services.Encoding.Map('▏', 0xa5); Services.Encoding.Map('▒', 0xa6); Services.Encoding.Map('▕', 0xa7); Services.Encoding.Map('◤', 0xa9); Services.Encoding.Map('├', 0xab); Services.Encoding.Map('└', 0xad); Services.Encoding.Map('┐', 0xae); Services.Encoding.Map('▂', 0xaf); Services.Encoding.Map('┌', 0xb0); Services.Encoding.Map('┴', 0xb1); Services.Encoding.Map('┬', 0xb2); Services.Encoding.Map('┤', 0xb3); Services.Encoding.Map('▎', 0xb4); Services.Encoding.Map('▍', 0xb5); Services.Encoding.Map('▃', 0xb9); Services.Encoding.Map('✓', 0xba); Services.Encoding.Map('┘', 0xbd); Services.Encoding.Map('━', 0xc0); Services.Encoding.Map('♠', 0xc1); Services.Encoding.Map('│', 0xc2); Services.Encoding.Map('╮', 0xc9); Services.Encoding.Map('╰', 0xca); Services.Encoding.Map('╯', 0xcb); Services.Encoding.Map('╲', 0xcd); Services.Encoding.Map('╱', 0xce); Services.Encoding.Map('●', 0xd1); Services.Encoding.Map('♥', 0xd3); Services.Encoding.Map('╭', 0xd5); Services.Encoding.Map('╳', 0xd6); Services.Encoding.Map('○', 0xd7); Services.Encoding.Map('♣', 0xd8); Services.Encoding.Map('♦', 0xda); Services.Encoding.Map('┼', 0xdb); Services.Encoding.Map('π', 0xde); Services.Encoding.Map('◥', 0xdf); Services.Encoding.SelectEncoding("\"cbmscreen\""); Services.Encoding.Map("@Z", '\0'); Services.Encoding.Map("az", 'A'); Services.Encoding.Map('£', '\\'); Services.Encoding.Map('π', '^'); // π is $5e in unshifted Services.Encoding.Map('↑', '^'); // ↑ is $5e in shifted Services.Encoding.Map('←', '_'); Services.Encoding.Map('▌', '`'); Services.Encoding.Map('▄', 'a'); Services.Encoding.Map('▔', 'b'); Services.Encoding.Map('▁', 'c'); Services.Encoding.Map('▏', 'd'); Services.Encoding.Map('▒', 'e'); Services.Encoding.Map('▕', 'f'); Services.Encoding.Map('◤', 'i'); Services.Encoding.Map('├', 'k'); Services.Encoding.Map('└', 'm'); Services.Encoding.Map('┐', 'n'); Services.Encoding.Map('▂', 'o'); Services.Encoding.Map('┌', 'p'); Services.Encoding.Map('┴', 'q'); Services.Encoding.Map('┬', 'r'); Services.Encoding.Map('┤', 's'); Services.Encoding.Map('▎', 't'); Services.Encoding.Map('▍', 'u'); Services.Encoding.Map('▃', 'y'); Services.Encoding.Map('✓', 'z'); Services.Encoding.Map('┘', '}'); Services.Encoding.Map('━', '@'); Services.Encoding.Map('♠', 'A'); Services.Encoding.Map('│', 'B'); Services.Encoding.Map('╮', 'I'); Services.Encoding.Map('╰', 'J'); Services.Encoding.Map('╯', 'K'); Services.Encoding.Map('╲', 'M'); Services.Encoding.Map('╱', 'N'); Services.Encoding.Map('●', 'Q'); Services.Encoding.Map('♥', 'S'); Services.Encoding.Map('╭', 'U'); Services.Encoding.Map('╳', 'V'); Services.Encoding.Map('○', 'W'); Services.Encoding.Map('♣', 'X'); Services.Encoding.Map('♦', 'Z'); Services.Encoding.Map('┼', '['); Services.Encoding.Map('◥', '_'); Services.Encoding.SelectEncoding("\"atascreen\""); Services.Encoding.Map(" _", '\0'); Services.Encoding.SelectDefaultEncoding(); _autoOn = CPU.Equals("65816") && Services.Options.Autosize; _m16 = _x16 = false; }
public void AddSymbol(string symbol) => Reserved.AddWord("UserDefined", symbol);
IEnumerable <SourceLine> ProcessMacros(IEnumerable <SourceLine> uncommented) { var macroProcessed = new List <SourceLine>(); RandomAccessIterator <SourceLine> lineIterator = uncommented.GetIterator(); SourceLine line = null; while ((line = lineIterator.GetNext()) != null) { try { if (string.IsNullOrWhiteSpace(line.ParsedSource)) { macroProcessed.Add(line); continue; } if (line.InstructionName.Equals(".macro")) { if (string.IsNullOrEmpty(line.LabelName)) { Assembler.Log.LogEntry(line, line.Instruction, "Macro name not specified."); continue; } var macroName = "." + line.LabelName; if (_macros.ContainsKey(macroName)) { Assembler.Log.LogEntry(line, line.Label, $"Macro named \"{line.LabelName}\" already defined."); continue; } if (Assembler.IsReserved.Any(i => i.Invoke(macroName)) || !char.IsLetter(line.LabelName[0])) { Assembler.Log.LogEntry(line, line.Label, $"Macro name \"{line.LabelName}\" is not valid."); continue; } Reserved.AddWord("MacroNames", macroName); var compare = Assembler.Options.CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; var macro = new Macro(line.Operand, line.ParsedSource, compare); _macros[macroName] = macro; var instr = line; while ((line = lineIterator.GetNext()) != null && !line.InstructionName.Equals(".endmacro")) { if (macroName.Equals(line.InstructionName)) { Assembler.Log.LogEntry(line, line.Instruction, "Recursive macro call not allowed."); continue; } if (line.InstructionName.Equals(".macro")) { Assembler.Log.LogEntry(line, line.Instruction, "Nested macro definitions not allowed."); continue; } if (line.InstructionName.Equals(".include") || line.InstructionName.Equals(".binclude")) { var includes = ExpandInclude(line); foreach (var incl in includes) { if (macroName.Equals(incl.InstructionName)) { Assembler.Log.LogEntry(incl, incl.Instruction, "Recursive macro call not allowed."); continue; } macro.AddSource(incl); } } else { macro.AddSource(line); } } if (!string.IsNullOrEmpty(line.LabelName)) { if (line.OperandHasToken) { Assembler.Log.LogEntry(line, line.Operand, "Unexpected argument found for macro definition closure."); continue; } line.Instruction = null; line.ParsedSource = line.ParsedSource.Replace(".endmacro", string.Empty); macro.AddSource(line); } else if (line == null) { line = instr; Assembler.Log.LogEntry(instr, instr.Instruction, "Missing closure for macro definition."); continue; } } else if (line.InstructionName.Equals(".include") || line.InstructionName.Equals(".binclude")) { macroProcessed.AddRange(ExpandInclude(line)); } else if (_macros.ContainsKey(line.InstructionName)) { if (!string.IsNullOrEmpty(line.LabelName)) { SourceLine clone = line.Clone(); clone.Operand = clone.Instruction = null; clone.UnparsedSource = clone.ParsedSource = line.LabelName; macroProcessed.Add(clone); } Macro macro = _macros[line.InstructionName]; macroProcessed.AddRange(ProcessExpansion(macro.Expand(line.Operand))); } else if (line.InstructionName.Equals(".endmacro")) { Assembler.Log.LogEntry(line, line.Instruction, "Directive \".endmacro\" does not close a macro definition."); continue; } else { macroProcessed.Add(line); } } catch (ExpressionException ex) { Assembler.Log.LogEntry(line, ex.Position, ex.Message); } } return(macroProcessed); }