static int LoadAndLink(List <string> files, string executableName) { if (files.Count < 1 || executableName == "") { Chronicler.WriteLine("Error, user must pass an output file name and at least one file to load!", Chronicler.OutputOptions.ERR); return(1); } //remove quotes from fileNames for (int i = 0; i < files.Count; i++) { files[i] = files[i].Trim().Trim('"').Trim(); } foreach (string fileName in files) { string path = "../../../" + fileName; string text = File.ReadAllText(path); PassOne(text); } PassTwo(); return(0); }
private static void parseModR(string v) { string instLoc = v.Substring(0, 6); string instLength = v.Remove(0, 6).Substring(0, 2); char sign = v[8]; string symbol = v.Remove(0, 9).Trim(); if (symRefs.Contains(symbol) || symDefs.Contains(symbol)) { int writeAddress = int.Parse(instLoc, System.Globalization.NumberStyles.HexNumber); int mFactor = sign == '+' ? 1 : -1; if (enableDebugging) { Chronicler.WriteLine("(" + sign + " : " + mFactor + ")", Chronicler.OutputOptions.DETAIL); } int length = int.Parse(instLength, System.Globalization.NumberStyles.HexNumber); MREC tmp; tmp.address = writeAddress + FileStartAdress; tmp.nibbleCount = length; tmp.arithmaticSign = mFactor; tmp.symbolName = symbol; mRecords.Add(tmp); } else { Chronicler.WriteLine("Error: MRecord not defined or exposed by reference!", Chronicler.OutputOptions.ERR); } }
static void dumpMemory(string filePath = "") { int curLineAddr = loadAdress; Chronicler.WriteLine("ADDRESS 0 1 2 3 4 5 6 7 8 9 A B C D E F"); for (int i = 0; i < memoryTable.Count; i++) { if (i % 32 == 0) { Chronicler.Write(curLineAddr.ToString("X6") + " "); } if (i % 2 == 0) { curLineAddr++; Chronicler.Write(" " + memoryTable[i]); } else { Chronicler.Write(memoryTable[i].ToString()); } if (i % 32 == 31) { Chronicler.Write("\n"); } } Chronicler.WriteLine("First executable adress: " + firstExecutableInstruction); if (filePath != "") { StreamWriter streamWriter = new StreamWriter(filePath, false); streamWriter.WriteLine("ADDRESS 0 1 2 3 4 5 6 7 8 9 A B C D E F"); for (int i = 0; i < memoryTable.Count; i++) { if (i % 32 == 0) { streamWriter.Write(curLineAddr.ToString("X6") + " "); } if (i % 2 == 0) { curLineAddr++; streamWriter.Write(" " + memoryTable[i]); } else { streamWriter.Write(memoryTable[i].ToString()); } if (i % 32 == 31) { streamWriter.Write("\n"); } } streamWriter.WriteLine("First executable adress: " + firstExecutableInstruction); streamWriter.Close(); } }
private static void parseDefR(string v) { string buffer = v; while (buffer != "") { string symbolName = buffer.Substring(0, 6).Trim(); buffer = buffer.Remove(0, 6).Trim(); int symbolLoc = int.Parse(buffer.Substring(0, 6).Trim(), System.Globalization.NumberStyles.HexNumber) + (FileStartAdress - loadAdress); Chronicler.WriteLine(symbolLoc.ToString("X6"), Chronicler.OutputOptions.DETAIL); buffer = buffer.Remove(0, 6).Trim(); externalSymbolTable.Add(symbolName, symbolLoc); symDefs.Add(symbolName); } }
static void PassTwo() { string ops = ""; foreach (MREC mREC in mRecords) { //calculate bounds int offsetAdress = mREC.address - loadAdress; int indexedAddress = mREC.nibbleCount % 2 == 0 ? (offsetAdress * 2): (offsetAdress * 2) + 1; //read substring string buffer = ""; for (int i = indexedAddress; i < indexedAddress + mREC.nibbleCount; i++) { buffer += memoryTable[i]; } //create cached value int value = int.Parse(buffer, System.Globalization.NumberStyles.HexNumber); ops += "Starting(" + offsetAdress.ToString("X6") + " : " + value.ToString($"X{mREC.nibbleCount}") + ")\t"; int mRecVal; //perform lookup if (externalSymbolTable.TryGetValue(mREC.symbolName, out mRecVal) == false) { Chronicler.WriteLine("Error: " + mREC.symbolName + " is not in the external symbol table!\nPlease check the input data and files being passed!\n", Chronicler.OutputOptions.ERR); } ops += "Found(" + mREC.symbolName + " : " + mRecVal.ToString($"X{mREC.nibbleCount}") + ")\t"; //apply modification mRecVal *= mREC.arithmaticSign; value += mRecVal; ops += "Result(" + value.ToString($"X{mREC.nibbleCount}") + ")\t"; //format string for writeback string replacementStr = value.ToString($"X{mREC.nibbleCount}"); ops += "Replacement(" + replacementStr + ")\n"; //perform write back for (int i = indexedAddress; i < indexedAddress + mREC.nibbleCount; i++) { memoryTable[i] = replacementStr[i - indexedAddress]; } } Chronicler.WriteLine(ops, Chronicler.OutputOptions.DETAIL); }
static int PassOne(string input) { string[] inputLines = input.Split('\n', '\r', StringSplitOptions.RemoveEmptyEntries); int errorLevel = 0; foreach (string line in inputLines) { if (line != null && line != "") { switch (line[0]) { case 'H': parseHeader(line.Remove(0, 1)); break; case 'T': parseTextR(line.Remove(0, 1)); break; case 'M': parseModR(line.Remove(0, 1)); break; case 'R': parseRefR(line.Remove(0, 1)); break; case 'D': parseDefR(line.Remove(0, 1)); break; case 'E': parseEndR(line.Remove(0, 1)); break; default: Chronicler.WriteLine("Error, did not understand '" + line[0] + "' record!", Chronicler.OutputOptions.ERR); return(1); } } } return(errorLevel); }