// Translates pseudoinstructions public ASMTranslatePseudoResult TranslatePseudo(string[] lines, uint startPC, bool skipLabelAssertion = false) { _errorTextBuilder.Length = 0; ASMTranslatePseudoResult result = new ASMTranslatePseudoResult(); List <EncodeLine> resultLines = new List <EncodeLine>(); int index = 0; uint pc = startPC; foreach (string line in lines) { if (string.IsNullOrEmpty(line)) { continue; } string processLine = ASMStringHelper.RemoveLeadingBracketBlock(line); processLine = ASMStringHelper.RemoveLeadingSpaces(processLine); processLine = ASMStringHelper.RemoveComment(processLine).ToLower(); processLine = ASMStringHelper.ConvertBracketBlocks(processLine); string[] parts = ASMStringHelper.SplitLine(processLine); parts = ASMStringHelper.RemoveLabel(parts); //pc = ASMPCHelper.ProcessOrg(pc, parts); ASMProcessPCResult processPCResult = ASMPCHelper.ProcessOrg(pc, parts, false); pc = processPCResult.PC; _errorTextBuilder.Append(processPCResult.ErrorMessage); // If this is an ASM command, pass off line to translating routine EncodingFormat encodingOrNull = FormatHelper.FindFormatByCommand(parts[0]); if (encodingOrNull != null) { // DEBUG 1/16 try { EncodingFormat encoding = encodingOrNull; EncodeLine[] encodeLines = TranslatePseudoSingle(encoding, parts, index, pc, skipLabelAssertion); foreach (EncodeLine encodeLine in encodeLines) { resultLines.Add(encodeLine); pc += 4; } } catch (Exception ex) { //result.errorMessage = "Error translating pseudoinstruction: " + line; _errorTextBuilder.Append("Error translating pseudoinstruction: " + line + " (" + ex.Message + ")\r\n"); //result.lines = null; //return result; } index++; } } result.lines = resultLines.ToArray(); result.errorMessage = _errorTextBuilder.ToString(); return(result); }
public static uint ProcessStartPC(string asm, uint pc) { // If the ASM starts with a .org statement, use that address as the PC string[] lines = asm.Split('\n'); lines = ASMStringHelper.RemoveFromLines(lines, "\r"); foreach (string line in lines) { if (!string.IsNullOrEmpty(line)) { string processLine = ASMStringHelper.RemoveComment(line).ToLower(); string[] parts = ASMStringHelper.SplitLine(processLine); ASMProcessPCResult processPCResult = ASMPCHelper.ProcessOrg(pc, parts); pc = processPCResult.PC; break; } } return(pc); }
public ASMFindLabelsResult FindLabels(string[] lines, EncodeLine[] encodeLines, uint pc) { ASMFindLabelsResult result = new ASMFindLabelsResult(); result.ErrorCode = 0; _errorTextBuilder.Length = 0; //LabelDict.Clear(); ClearLabelDict(); //int pc = ProcessPC(0, txt_StartPC.Text); int lineIndex = 0; int encodeLineIndex = 0; foreach (string line in lines) { if (string.IsNullOrEmpty(line)) { continue; } string processLine = ASMStringHelper.RemoveLeadingBracketBlock(line); processLine = ASMStringHelper.RemoveLeadingSpaces(processLine); processLine = ASMStringHelper.RemoveComment(processLine).ToLower(); string[] parts = ASMStringHelper.SplitLine(processLine); //pc = ASMPCHelper.ProcessOrg(pc, parts); ASMProcessPCResult processPCResult = ASMPCHelper.ProcessOrg(pc, parts, false); pc = processPCResult.PC; _errorTextBuilder.Append(processPCResult.ErrorMessage); ASMAddLabelResult processLabelResult = ProcessLabelStatement(parts); if (processLabelResult != null) { if (processLabelResult.ErrorCode > 0) { result.ErrorCode = 1; _errorTextBuilder.Append(processLabelResult.ErrorMessage); } } EncodingFormat encodingOrNull = FormatHelper.FindFormatByCommand(parts[0]); if (encodingOrNull != null) { EncodeLine eLine = new EncodeLine(); if ((encodeLines.Length > 0) && (encodeLineIndex < encodeLines.Length)) { eLine = encodeLines[encodeLineIndex]; } while ((eLine.LineIndex == lineIndex) && (encodeLineIndex < encodeLines.Length)) { pc += 4; encodeLineIndex++; if (encodeLineIndex < encodeLines.Length) { eLine = encodeLines[encodeLineIndex]; } } lineIndex++; } else { ASMAddLabelResult addLabelResult = AddLabel(pc, parts); if (addLabelResult.ErrorCode == 0) { pc = addLabelResult.PC; } else { _errorTextBuilder.Append(addLabelResult.ErrorMessage); result.ErrorCode = 1; } } } result.ErrorMessage = _errorTextBuilder.ToString(); return(result); }
public ASMEncoderResult EncodeASM(string asm, uint pc, string spacePadding, bool includeAddress, bool littleEndian, bool clearErrorText) { if (clearErrorText) { ClearErrorText(); } string[] lines = asm.Split('\n'); lines = ASMStringHelper.RemoveFromLines(lines, "\r"); string[] processLines = AddLabelLines(lines); string oldErrorText = _errorTextBuilder.ToString(); EncodeLine[] encodeLines = PreprocessLines(processLines, pc); int encodeLineIndex = 0; int lineIndex = 0; StringBuilder newTextASMBuilder = new StringBuilder(); StringBuilder newTextASMLineBuilder = new StringBuilder(); StringBuilder encodedASMBuilder = new StringBuilder(); List <byte> byteList = new List <byte>(); if (oldErrorText != _errorTextBuilder.ToString()) { return(new ASMEncoderResult(encodedASMBuilder.ToString(), byteList.ToArray(), asm, _errorTextBuilder.ToString())); } foreach (string line in lines) { if (string.IsNullOrEmpty(line)) { newTextASMBuilder.AppendLine(); continue; } newTextASMLineBuilder.Length = 0; string modLine = ASMStringHelper.RemoveLeadingBracketBlock(line); string processLine = ASMStringHelper.RemoveLeadingSpaces(modLine); processLine = ASMStringHelper.RemoveComment(processLine).ToLower(); string[] parts = ASMStringHelper.SplitLine(processLine); //pc = ASMPCHelper.ProcessOrg(pc, parts); ASMProcessPCResult processPCResult = ASMPCHelper.ProcessOrg(pc, parts); pc = processPCResult.PC; _errorTextBuilder.Append(processPCResult.ErrorMessage); parts = ASMStringHelper.RemoveLabel(parts); // If this is an ASM command, pass off line to encoding routine EncodingFormat encodingOrNull = FormatHelper.FindFormatByCommand(parts[0]); if (encodingOrNull != null) { if (includeAddress) { newTextASMLineBuilder.Append("[0x"); newTextASMLineBuilder.Append(ASMValueHelper.UnsignedToHex_WithLength(pc, 8)); newTextASMLineBuilder.Append("] "); } newTextASMLineBuilder.AppendLine(modLine); EncodeLine eLine = new EncodeLine(); if (encodeLines.Length > 0) { eLine = encodeLines[encodeLineIndex]; } while ((eLine.LineIndex == lineIndex) && (encodeLineIndex < encodeLines.Length)) { encodingOrNull = FormatHelper.FindFormatByCommand(eLine.LineParts[0]); EncodingFormat encoding = encodingOrNull; ASMSingleEncodeResult singleEncodeResult = TryEncodeSingle(eLine.LineParts, encoding, pc, modLine, littleEndian); encodedASMBuilder.Append(spacePadding); encodedASMBuilder.Append(singleEncodeResult.ASMText); encodedASMBuilder.AppendLine(); //encodedASMBuilder.Append("\r\n"); byteList.AddRange(singleEncodeResult.Bytes); encodeLineIndex++; pc += 4; if (encodeLineIndex < encodeLines.Length) { eLine = encodeLines[encodeLineIndex]; } } lineIndex++; } else { if (!string.IsNullOrEmpty(parts[0])) { if ((parts[0] != ".org") && (parts[0] != ".label") && (parts[0] != ".eqv") && (!parts[0].EndsWith(":"))) { _errorTextBuilder.AppendLine("WARNING: Ignoring unknown command \"" + parts[0] + "\"."); } } } if (string.IsNullOrEmpty(newTextASMLineBuilder.ToString())) { newTextASMLineBuilder.AppendLine(modLine); } newTextASMBuilder.Append(newTextASMLineBuilder.ToString()); } string newTextASM = newTextASMBuilder.ToString(); if (newTextASM.EndsWith("\r\n")) { newTextASMBuilder.Length -= 2; } else if (newTextASM.EndsWith("\n")) { newTextASMBuilder.Length -= 1; } newTextASM = newTextASMBuilder.ToString(); return(new ASMEncoderResult(encodedASMBuilder.ToString(), byteList.ToArray(), newTextASM, _errorTextBuilder.ToString())); }
// Translates pseudoinstructions public ASMTranslatePseudoResult TranslatePseudo(string[] lines, uint startPC, bool skipLabelAssertion = false) { _errorTextBuilder.Length = 0; bool reportErrors = !skipLabelAssertion; ASMTranslatePseudoResult result = new ASMTranslatePseudoResult(); List <EncodeLine> resultLines = new List <EncodeLine>(); int index = 0; uint pc = startPC; List <bool> isSkippingLine = new List <bool>() { false }; int ifNestLevel = 0; foreach (string line in lines) { if (string.IsNullOrEmpty(line)) { continue; } string processLine = ASMStringHelper.RemoveLeadingBracketBlock(line); processLine = ASMStringHelper.RemoveLeadingSpaces(processLine); processLine = ASMStringHelper.RemoveComment(processLine).ToLower(); processLine = ASMStringHelper.ConvertBracketBlocks(processLine); string[] parts = ASMStringHelper.SplitLine(processLine); parts = ASMStringHelper.RemoveLabel(parts); //pc = ASMPCHelper.ProcessOrg(pc, parts); ASMProcessPCResult processPCResult = ASMPCHelper.ProcessOrg(pc, parts, false); pc = processPCResult.PC; _errorTextBuilder.Append(processPCResult.ErrorMessage); string firstPart = parts[0].ToLower().Trim(); if (firstPart == ".endif") { if (ifNestLevel == 0) { if (reportErrors) { _errorTextBuilder.AppendLine("WARNING: No matching .if statement for .endif statement at address 0x" + ASMValueHelper.UnsignedToHex_WithLength(pc, 8)); } } else { isSkippingLine.RemoveAt(isSkippingLine.Count - 1); ifNestLevel--; } } else if (firstPart == ".else") { if (ifNestLevel == 0) { if (reportErrors) { _errorTextBuilder.AppendLine("WARNING: No matching .if statement for .else statement at address 0x" + ASMValueHelper.UnsignedToHex_WithLength(pc, 8)); } } else if (!isSkippingLine[ifNestLevel - 1]) { isSkippingLine[ifNestLevel] = !isSkippingLine[ifNestLevel]; } } else if (firstPart == ".if") { try { string[] innerParts = parts[1].Split(','); if (!parts[1].Contains(",")) { if (reportErrors) { _errorTextBuilder.AppendLine("WARNING: Unreachable code at address 0x" + ASMValueHelper.UnsignedToHex_WithLength(pc, 8) + " inside .if statement with bad argument list (no commas): \"" + parts[1] + "\""); } isSkippingLine.Add(true); ifNestLevel++; } else if (innerParts.Length < 2) { if (reportErrors) { _errorTextBuilder.AppendLine("WARNING: Unreachable code at address 0x" + ASMValueHelper.UnsignedToHex_WithLength(pc, 8) + " inside .if statement with bad argument list (less than 2 arguments): \"" + parts[1] + "\""); } isSkippingLine.Add(true); ifNestLevel++; } else if (isSkippingLine[ifNestLevel]) { isSkippingLine.Add(true); ifNestLevel++; } else { string operation = string.Empty; string eqvKey, eqvValue; if (innerParts.Length >= 3) { operation = ASMStringHelper.RemoveSpaces(innerParts[0]); eqvKey = ASMStringHelper.RemoveSpaces(innerParts[1]); eqvValue = ASMStringHelper.RemoveSpaces(innerParts[2]); } else { operation = "="; eqvKey = ASMStringHelper.RemoveSpaces(innerParts[0]); eqvValue = ASMStringHelper.RemoveSpaces(innerParts[1]); } int intKey = 0; int intValue = 0; bool isKeyInt = int.TryParse(eqvKey, out intKey); bool isValueInt = int.TryParse(eqvValue, out intValue); bool isIntCompare = isKeyInt && isValueInt; bool isPass = false; switch (operation) { case "=": case "==": isPass = eqvKey.Equals(eqvValue); break; case "!=": case "<>": isPass = !eqvKey.Equals(eqvValue); break; case "<": isPass = isIntCompare && (intKey < intValue); break; case ">": isPass = isIntCompare && (intKey > intValue); break; case "<=": isPass = isIntCompare && (intKey <= intValue); break; case ">=": isPass = isIntCompare && (intKey >= intValue); break; default: break; } isSkippingLine.Add(!isPass); ifNestLevel++; } } catch (Exception ex) { if (reportErrors) { _errorTextBuilder.AppendLine("Error on .if statement: " + ex.Message + "\r\n"); } } } else { // If this is an ASM command, pass off line to translating routine EncodingFormat encodingOrNull = FormatHelper.FindFormatByCommand(parts[0]); if (encodingOrNull != null) { try { if (!isSkippingLine[ifNestLevel]) { EncodingFormat encoding = encodingOrNull; EncodeLine[] encodeLines = TranslatePseudoSingle(encoding, parts, index, pc, skipLabelAssertion); foreach (EncodeLine encodeLine in encodeLines) { resultLines.Add(encodeLine); pc += 4; } //index++; } } catch (Exception ex) { if (reportErrors) { //result.errorMessage = "Error translating pseudoinstruction: " + line; _errorTextBuilder.Append("Error translating pseudoinstruction: " + line + " (" + ex.Message + ")\r\n"); } //result.lines = null; //return result; //index++; } index++; } } } result.lines = resultLines.ToArray(); result.errorMessage = _errorTextBuilder.ToString(); return(result); }