private static void InstructionHandler(Match lineReg) { string opcode = lineReg.Groups["opcode"].Value; string operands = lineReg.Groups["operands"].Value; if (macros.ContainsKey(opcode)) { Match macroReg = Regex.Match($"{opcode} {operands}", CPUDef.macroReg); CallMacroHandler(macroReg); return; } string label = lineReg.Groups["label"].Value; ushort opcodeAddr = currentAddr; opcode = lineReg.Groups["opcode"].Value.ToUpper(); if (!string.IsNullOrWhiteSpace(label)) { Symbol lSymb = new Symbol { Type = SymbolType.WORD, Value = currentAddr }; AddSymbol(label, lSymb); } Byte[] addrModesValues = CPUDef.OPC_TABLE[opcode]; CPUDef.AddrModes addrMode = CPUDef.AddrModes.NO; List <byte> instBytes = new List <byte>(); CPUDef.InstructionInfo instInfo = new CPUDef.InstructionInfo(); bool syntaxError = true; if (string.IsNullOrWhiteSpace(operands)) { syntaxError = false; // 1 byte opcode if (Array.Exists(CPUDef.ACC_OPC, opc => opc.Equals(opcode))) { addrMode = CPUDef.AddrModes.ACC; } else { addrMode = CPUDef.AddrModes.IMP; } instInfo = new CPUDef.InstructionInfo { addrMode = addrMode, nbrBytes = 1 }; instBytes.Add(addrModesValues[(int)addrMode]); } else { string expr = string.Empty; // 2 bytes opcode if (Array.Exists(CPUDef.REL_OPC, opc => opc.Equals(opcode))) { syntaxError = false; expr = operands; instInfo = new CPUDef.InstructionInfo { addrMode = CPUDef.AddrModes.REL, nbrBytes = 2 }; } else { instInfo = CPUDef.GetInstructionInfo(operands); syntaxError = false; expr = instInfo.expr; } if (syntaxError) { AddError(Errors.OPERANDS); } else { addrMode = instInfo.addrMode; ExprResult exprRes = ResolveExpr(expr, addrMode); if (exprRes.undefinedSymbs.Count == 0) { // convert to zero page if symbol is a single byte if (CPUDef.isAbsoluteAddr(addrMode) && exprRes.Type == SymbolType.BYTE) { addrMode = addrMode + 3; instInfo.nbrBytes = 2; } instBytes.Add(addrModesValues[(int)addrMode]); if (instInfo.nbrBytes == 2) { instBytes.Add((byte)exprRes.Result); } else { instBytes.AddRange(GetWordBytes((ushort)exprRes.Result)); } } else { instBytes.Add(addrModesValues[(int)addrMode]); SymbolType typeExpr; if (instInfo.nbrBytes == 2) { instBytes.AddRange(new byte[1] { 0 }); typeExpr = SymbolType.BYTE; } else // 3 bytes instr { instBytes.AddRange(new byte[2] { 0, 0 }); typeExpr = SymbolType.WORD; } ushort position = (ushort)(opcodeAddr - originAddr + 1); UnresolvedExpr exprObj = new UnresolvedExpr { Position = position, Type = typeExpr, addrMode = addrMode, NbrUndefinedSymb = exprRes.undefinedSymbs.Count, Expr = expr }; unsolvedExprList.Add(position, exprObj); foreach (string symb in exprRes.undefinedSymbs) { UnresolvedSymbol unResSymb = new UnresolvedSymbol(); unResSymb.DependingList = new List <string>(); unResSymb.ExprList = new List <ushort>(); unResSymb.ExprList.Add(position); AddUnsolvedSymbol(symb, unResSymb); } } } } if (!syntaxError) { currentAddr += instInfo.nbrBytes; fileOutMemory.AddRange(instBytes.ToArray()); MainConsole.WriteLine($"{opcode} mode {addrMode.ToString()}"); } }