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 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()}"); } }