private static void ConstantHandler(Match lineReg) { string label = lineReg.Groups["label"].Value; string value = lineReg.Groups["value"].Value; ExprResult res = ResolveExpr(value); if (res.undefinedSymbs.Count == 0) { Symbol symb = new Symbol() { Value = res.Result, Type = res.Type }; AddSymbol(label, symb); } else { UnresolvedSymbol unResSymb = new UnresolvedSymbol(); unResSymb.NbrUndefinedSymb = res.undefinedSymbs.Count; unResSymb.DependingList = new List <string>(); unResSymb.Expr = value; unResSymb.ExprList = new List <ushort>(); foreach (string symb in res.undefinedSymbs) { AddDependingSymb(symb, label); } AddUnsolvedSymbol(label, unResSymb); } }
private static void GenerateExprBytes(UnresolvedExpr expr, ExprResult exprRes) { byte[] bytes = null; switch (expr.Type) { case SymbolType.WORD: if (exprRes.Type == SymbolType.BYTE && !CPUDef.isAbsoluteAddr(expr.addrMode) && (expr.addrMode != CPUDef.AddrModes.IND)) { bytes = new byte[1] { (byte)exprRes.Result }; } else { if (expr.addrMode == CPUDef.AddrModes.REL) { int delta = (ushort)exprRes.Result - (expr.Position + originAddr); byte res; if (delta > 127 || delta < -128) { AddError(Errors.REL_JUMP); } else { if (delta < 0) { res = (byte)(255 + delta); } else { res = (byte)(delta - 1); } bytes = new byte[1] { res }; } } else { bytes = GetWordBytes((ushort)exprRes.Result); } } break; case SymbolType.BYTE: bytes = new byte[1] { (byte)exprRes.Result }; break; } if (bytes != null) { fileOutMemory.RemoveRange(expr.Position, bytes.Length); fileOutMemory.InsertRange(expr.Position, bytes); } }
private static void DataByteHandler(string bytesIn) { string[] bytes = bytesIn.Split(','); foreach (string db in bytes) { string data = db.Trim(); if (CPUDef.isString(data)) // handle strings { data = data.Substring(1, data.Length - 2); foreach (char c in data) { fileOutMemory.Add(Convert.ToByte(c)); currentAddr++; } } else { ExprResult res = ResolveExpr(data); if (res.undefinedSymbs.Count == 0) { fileOutMemory.Add((byte)res.Result); } else { fileOutMemory.Add(0); ushort position = (ushort)(currentAddr - originAddr); UnresolvedExpr expr = new UnresolvedExpr { Position = position, Type = SymbolType.BYTE, addrMode = CPUDef.AddrModes.NO, NbrUndefinedSymb = res.undefinedSymbs.Count, Expr = data }; unsolvedExprList.Add(position, expr); foreach (string symb in res.undefinedSymbs) { UnresolvedSymbol unResSymb = new UnresolvedSymbol(); unResSymb.DependingList = new List <string>(); unResSymb.ExprList = new List <ushort>(); unResSymb.ExprList.Add(position); AddUnsolvedSymbol(symb, unResSymb); } } currentAddr++; } } }
private static void IfHandler(string value) { if (cAsm.inCondition) { AddError(Errors.NESTED_CONDITIONAL_ASSEMBLY); return; } ExprResult res = ResolveExpr(value.Trim(), CPUDef.AddrModes.NO, true); if (res.undefinedSymbs.Count > 0) { AddError(Errors.UNDEFINED_SYMBOL); } else { cAsm.inCondition = true; cAsm.val = (bool)res.Result; } }
private static void MemResHandler(Match lineReg) { string label = lineReg.Groups["label"].Value; string value = lineReg.Groups["value"].Value; ExprResult res = ResolveExpr(value); if (res.undefinedSymbs.Count == 0) { MemArea ma; Dictionary <string, Symbol> symbTable; if (localScope.isLocalScope) { ma = localScope.memArea; symbTable = localScope.symbolTable; } else { ma = memArea; symbTable = symbolTable; } Symbol variable = new Symbol() { Type = ma.type, Value = ma.val }; if (!symbTable.ContainsKey(label)) { AddSymbol(label, variable); ma.val += res.Result; ma.type = ma.val <= 255 ? SymbolType.BYTE : SymbolType.WORD; MainConsole.WriteLine($"{label} {variable.Value.ToString("x")}"); } else { AddError(Errors.LABEL_EXISTS); } } else { AddError(Errors.UNDEFINED_SYMBOL); } }
private static void ResolveSymbolDepsAndExprs(UnresolvedSymbol unresSymb) { Dictionary <string, UnresolvedSymbol> unsolvedSymbs; if (localScope.isLocalScope) { unsolvedSymbs = localScope.unsolvedSymbols; } else { unsolvedSymbs = unsolvedSymbols; } // resolve depending symbols foreach (string dep in unresSymb.DependingList) { UnresolvedSymbol unresDep = unsolvedSymbs[dep]; unresDep.NbrUndefinedSymb--; if (unresDep.NbrUndefinedSymb <= 0) { ExprResult res = ResolveExpr(unresDep.Expr); AddSymbol(dep, new Symbol() { Value = res.Result, Type = res.Type }); } } // resolve expressions foreach (ushort expr in unresSymb.ExprList) { UnresolvedExpr unresExp = unsolvedExprList[expr]; unresExp.NbrUndefinedSymb--; if (unresExp.NbrUndefinedSymb <= 0) { ExprResult res = ResolveExpr(unresExp.Expr, unresExp.addrMode); GenerateExprBytes(unresExp, res); unsolvedExprList.Remove(expr); } } }
private static void DataWordHandler(string wordsIn) { string[] words = wordsIn.Split(','); foreach (string dw in words) { string data = dw.Trim(); ExprResult res = ResolveExpr(data); if (res.undefinedSymbs.Count == 0) { fileOutMemory.AddRange(GetWordBytes((ushort)res.Result)); } else { fileOutMemory.AddRange(new byte[2] { 0, 0 }); ushort position = (ushort)(currentAddr - originAddr); UnresolvedExpr expr = new UnresolvedExpr { Position = position, Type = SymbolType.WORD, addrMode = CPUDef.AddrModes.NO, NbrUndefinedSymb = res.undefinedSymbs.Count, Expr = data }; unsolvedExprList.Add(position, expr); foreach (string symb in res.undefinedSymbs) { UnresolvedSymbol unResSymb = new UnresolvedSymbol(); unResSymb.DependingList = new List <string>(); unResSymb.ExprList = new List <ushort>(); unResSymb.ExprList.Add(position); AddUnsolvedSymbol(symb, unResSymb); } } currentAddr += 2; } }
private static void MemAreaHandler(string value) { MemArea ma; if (!localScope.isLocalScope) { ma = memArea; } else { ma = localScope.memArea; } ExprResult res = ResolveExpr(value); if (res.undefinedSymbs.Count == 0) { ma.val = res.Result; ma.type = res.Type; } else { AddError(Errors.UNDEFINED_SYMBOL); } }
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()}"); } }
private static ExprResult ResolveExpr(string exprIn, CPUDef.AddrModes addrMode = CPUDef.AddrModes.NO, bool isLogical = false) { List <Token> tokens = Tokenizer.Tokenize(exprIn); string expr = string.Empty; Symbol symb; ExprResult exprRes = new ExprResult(); exprRes.undefinedSymbs = new List <string>(); foreach (Token token in tokens) { switch (token.Type) { case "HB": expr = $"{expr} {Byte.Parse(token.Value, NumberStyles.HexNumber)}"; break; case "HW": expr = $"{expr} {ushort.Parse(token.Value, NumberStyles.HexNumber)}"; break; case "binByte": expr = $"{expr} {Convert.ToByte(token.Value, 2)}"; break; case "DEC": int val = int.Parse(token.Value); if (val <= 255) { expr = $"{expr} {(byte)val}"; } else { expr = $"{expr} {(ushort)val}"; } break; case "label": symb = GetSymbolValue(token.Value); if (symb != null) { expr = $"{expr} {symb.Value}"; } else { exprRes.undefinedSymbs.Add(token.Value); } break; case "loLabel": symb = GetSymbolValue(token.Value); if (symb != null) { expr = $"{expr} {GetLowByte((ushort)symb.Value)}"; } else { exprRes.undefinedSymbs.Add(token.Value); } break; case "hiLabel": symb = GetSymbolValue(token.Value); if (symb != null) { expr = $"{expr} {GetHighByte((ushort)symb.Value)}"; } else { exprRes.undefinedSymbs.Add(token.Value); } break; case "loHW": expr = $"{expr} {GetLowByte(ushort.Parse(token.Value, NumberStyles.HexNumber))}"; break; case "hiHW": expr = $"{expr} {GetHighByte(ushort.Parse(token.Value, NumberStyles.HexNumber))}"; break; default: expr = $"{expr} {token.Value}"; break; } } if (exprRes.undefinedSymbs.Count == 0) { if (isLogical) { exprRes.Result = EvaluateLogicalExpression(expr); } else { DataTable dt = new DataTable(); exprRes.Result = dt.Compute(expr, ""); exprRes.Type = exprRes.Result <= 255 ? SymbolType.BYTE : SymbolType.WORD; if (addrMode == CPUDef.AddrModes.REL && exprRes.Type == SymbolType.WORD) { int delta = (ushort)exprRes.Result - (currentAddr + 1); byte res; if (delta > 127 || delta < -128) { AddError(Errors.REL_JUMP); } else { if (delta < 0) { res = (byte)(255 + delta); } else { res = (byte)(delta - 1); } exprRes.Result = res; exprRes.Type = SymbolType.BYTE; } } } } return(exprRes); }