/******************************************************************************* *** INSERT FUNCTION *** ******************************************************************************** *** DESCRIPTION: This function takes in a symbol table and a string. Runs a *** *** function that return an error message if an invalid expression. If null *** *** then the Expression node is created and populated and returned. *** ******************************************************************************** *** INPUT ARGS: Node_Sym table, string ex *** *** OUTPUT ARGS: N/A *** *** IN/OUT ARGS: N/A *** *** RETURN: Node_Exp newNode *** ********************************************************************************/ public Node_Exp insert(Node_Sym table, string ex) { Node_Exp Expression = new Node_Exp(); Expression.expression = ex; if (ex[0] != '=') { Expression.ERR_MSG = IfExpressionValid(table, ex); if (Expression.ERR_MSG == null) { Expression.relocatable = retRel(table, ex); Expression.value = retVal(table, ex); if (ex[0] == '@') { Expression.N_bit = true; } else if (ex[0] == '#') { Expression.I_bit = true; } else if (ex[ex.Length - 2] == ',' && ex[ex.Length - 1] == 'X') { Expression.X_bit = true; } else { Expression.N_bit = true; Expression.I_bit = true; } } else { Console.WriteLine(Expression.ERR_MSG); } } else { Expression.N_bit = true; Expression.I_bit = true; Expression.X_bit = false; } return(Expression); }
/******************************************************************************* *** PASSDUO function *** ******************************************************************************** *** DESCRIPTION: This Pass 2 funciton takes in information from the .tmp *** *** file and outputs the Object Code for each line that applies, and then *** *** creates the object program to the assembly code that was given intially. *** ******************************************************************************** *** INPUT ARGS: List<Node_Op> ops, Node_Sym table, Node_Lit lit, string file *** *** OUTPUT ARGS: N/A *** *** IN/OUT ARGS: N/A *** *** RETURN: Node_P2 p2 *** ********************************************************************************/ public Node_P2 PassDuo(List <Node_Op> ops, Node_Sym table, Node_Lit lit, string file) { Node_P2 p2 = new Node_P2(); Node_Op op = new Node_Op(); NIXBPE nixbpe = new NIXBPE(); Node_Sym sym = new Node_Sym(); Node_Exp ex = new Node_Exp(); Registers reg = new Registers(); Literal_Table litTab = new Literal_Table(); Expressions Exp = new Expressions(); OpCodes opCode = new OpCodes(); Symbol_Table syTab = new Symbol_Table(); List <string> codes = new List <string>(); List <string> mrec = new List <string>(); string[] Prog = File.ReadAllLines(file); int lnum; string counter; string label = null; string operation; string operand = null; string rrec = null; string drec = null; string prog_len = "00000"; string prog_start = "00000"; string prog_name = "00000"; string Obj_Code = null; string[] splitLine; string tmpStr; string tmpFmt = null; bool Base_bit = false; string Base_Label = null; foreach (string line in Prog) { splitLine = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (splitLine.Length != 1) { //SETS LINE NUMBER if (Int32.TryParse(splitLine[0], out lnum)) { } ; //SETS LOAD COUNTER counter = splitLine[1]; //SETS LABEL if (splitLine.Length == 5) { label = splitLine[2].ToUpper(); splitLine = splitLine.Where(w => w != splitLine[0]).ToArray(); } else { tmpStr = splitLine[2]; if (tmpStr[0] != '+' && opCode.search(ops, tmpStr) == null) { label = tmpStr.ToUpper(); splitLine = splitLine.Where(w => w != splitLine[2]).ToArray(); } } //SETS OPERATION operation = splitLine[2].ToUpper(); //SETS OPERAND if (splitLine.Length > 3) { operand = splitLine[3]; } if (label == Base_Label && int.Parse(counter, System.Globalization.NumberStyles.HexNumber) > int.Parse("7FF", System.Globalization.NumberStyles.HexNumber)) { syTab.search(table, label).value = SubHex(counter, "7FF").TrimStart('0').PadLeft(5, '0'); } else { if (operation == "START") { prog_start = splitLine[3]; //FOR THE HEADER prog_name = label; //FOR THE HEADER } else if (operation != "END") { //FORMAT 4 CHECK if (operation[0] != '+') { op = opCode.search(ops, operation); } else { tmpStr = operation.TrimStart('+'); op = opCode.search(ops, tmpStr); tmpFmt = "4"; } if (op == null) { if (operation == "BASE") { Base_Label = operand; } else if (operation == "BYTE") { if (operand[0] == 'X') { Obj_Code = operand.TrimStart('X', '\'').TrimEnd('\'').PadLeft(6, '0'); } else { Obj_Code = BitConverter.ToString(Encoding.Default.GetBytes(operand.TrimStart('\'', 'C', 'c').TrimEnd('\''))).Replace("-", "").PadLeft(6, '0'); } } else if (operation == "EQU") { } else if (operation == "EXTDEF") { foreach (string n in operand.Split(',')) { drec = drec + "^" + n + "^" + syTab.search(table, TrimOp(n)).value; } } else if (operation == "EXTREF") { foreach (string n in operand.Split(',')) { rrec = rrec + "^" + n; } } else if (operation == "RESB") { } else if (operation == "RESW") { } else if (operation == "WORD") { Obj_Code = int.Parse(operand, System.Globalization.NumberStyles.HexNumber).ToString("X").PadLeft(6, '0'); if (operand.Contains('+') || operand.Contains('-')) { mrec.Add("M^" + AddHex(counter.PadLeft(6, '0'), "1") + "^06^"); } } } else if (tmpFmt != null) { nixbpe = setNIXBPE(table, operation, operand, Base_bit); if (operand[0] == '#') { Obj_Code = ObjPtOne(op.code, nixbpe) + counter; } else if (operand[0] == '@') { Obj_Code = ObjPtOne(op.code, nixbpe) + Exp.insert(table, operand).value; } else { Obj_Code = ObjPtOne(op.code, nixbpe) + Exp.insert(table, operand).value; } mrec.Add("M^" + AddHex(counter, "1").PadLeft(6, '0') + "^05^+" + operand.TrimStart('@', '#').TrimEnd(',', 'X')); } else { if (op.format == "1") { Obj_Code = op.code; } else if (op.format == "2") { Obj_Code = op.code + fmt2(operand); } else if (op.format == "3") { nixbpe = setNIXBPE(table, operation, operand, Base_bit); if (nixbpe.n == true && nixbpe.i == false && nixbpe.x == false) //IF INDIRECT '@' { Obj_Code = ObjPtOne(op.code, nixbpe) + SubHex(Exp.insert(table, operand).value, getNext(op, counter)).TrimStart('0').PadLeft(3, '0'); } else if (nixbpe.n == false && nixbpe.i == true && nixbpe.x == false) //IF IMMEDIATE '#' { Obj_Code = ObjPtOne(op.code, nixbpe) + Exp.insert(table, operand).value.TrimStart('0').PadLeft(3, '0'); } else if (nixbpe.n == false && nixbpe.i == false && nixbpe.x == true) //IF INDEXED ',X' { Obj_Code = ObjPtOne(op.code, nixbpe) + SubHex(Exp.insert(table, operand).value, getNext(op, counter)).TrimStart('0').PadLeft(3, '0'); } else { if (operand[0] == '=') { Obj_Code = ObjPtOne(op.code, nixbpe) + SubHex(litTab.search(lit, operand).address, getNext(op, counter)).TrimStart('0').PadLeft(3, '0'); } else { Obj_Code = ObjPtOne(op.code, nixbpe) + SubHex(Exp.insert(table, operand).value, getNext(op, counter)).TrimStart('0').PadLeft(3, '0'); } } } } } } if (operation == "*") { Obj_Code = litTab.search(lit, operand).value; } } else { prog_len = splitLine[0]; } //ADD THE OBJ CODE TO THE P2 NODE if (splitLine.Length != 1) { p2.prog.Add(line + string.Format("{0,-10}", Obj_Code)); } if (Obj_Code != null) { codes.Add(Obj_Code); } //SET VARIABLES BACK TO NULL tmpFmt = null; tmpStr = null; label = null; Obj_Code = null; } p2.obj_prog.Add("H^" + prog_name + "^" + prog_start.PadLeft(5, '0') + "^" + prog_len.PadLeft(5, '0')); if (drec != null) { p2.obj_prog.Add("D" + drec); } if (rrec != null) { p2.obj_prog.Add("R" + rrec); } p2.obj_prog = T_Records(p2.obj_prog, codes); foreach (string m in mrec) { p2.obj_prog.Add(m); } p2.obj_prog.Add("E^" + prog_start.PadLeft(6, '0')); return(p2); }
/******************************************************************************* *** PASSUNO function *** ******************************************************************************** *** DESCRIPTION: This Pass 1 funciton takes in information from the file *** *** passed in. In the file contains assembly instructions and pass one *** *** produces line numbers and load counters. Pass 1 also stores the labels *** *** as symbols and also store literals in the literal table. *** ******************************************************************************** *** INPUT ARGS: string program, List<Node_Op> OpCodes *** *** OUTPUT ARGS: N/A *** *** IN/OUT ARGS: N/A *** *** RETURN: Node_P1 p1 *** ********************************************************************************/ public Node_P1 PassUno(string program, List <Node_Op> OpCodes) { Node_P1 passOne = new Node_P1(); PassTwo p2 = new PassTwo(); List <string> theFile = new List <string>(); List <int> valLits = new List <int>(); OpCodes opCode = new OpCodes(); Symbol_Table SymTab = new Symbol_Table(); Expressions Exp = new Expressions(); Literal_Table LitTable = new Literal_Table(); Node_Lit lit = new Node_Lit(); Node_Sym table = new Node_Sym(); Node_Op op = new Node_Op(); Node_Exp ex = new Node_Exp(); List <string> Literals = new List <string>(); string[] Prog = File.ReadAllLines(program); string[] splitLine; string str_Count = null; string tmpCounter = null; string label = null; string operation = null; string operand = null; int l = 0; string Counter = "00000"; string EquCount = null; string tmpStr; int val; int tmp; bool r = true; foreach (string line in Prog) { //HANDLE IF EMPTY LINE if (line != null) { //COMMMENT HANDLING if (line[0] != '.') { tmpStr = line; //SPLITS THE LINE splitLine = tmpStr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); //SETS LABEL if (splitLine.Length >= 3) { label = splitLine[0].ToUpper(); splitLine = splitLine.Where(w => w != splitLine[0]).ToArray(); } else { tmpStr = splitLine[0]; if (tmpStr[0] != '+' && opCode.search(OpCodes, tmpStr) == null && tmpStr != "BASE" && tmpStr != "BYTE" && tmpStr != "END" && tmpStr != "EQU" && tmpStr != "EXTDEF" && tmpStr != "EXTREF" && tmpStr != "RESB" && tmpStr != "RESW" && tmpStr != "START" && tmpStr != "WORD") { label = splitLine[0].ToUpper(); splitLine = splitLine.Where(w => w != splitLine[0]).ToArray(); } } //SETS OPERTATION operation = splitLine[0].ToUpper(); //SETS OPERAND if (splitLine.Length > 1) { operand = splitLine[1]; } //SETS LINE NUMBER l++; if (operation != "EQU") { tmpCounter = Counter; } //IF START, THEN START; IF NOT END, THEN DO STUFF if (operation == "START") { Counter = operand.PadLeft(5, '0'); str_Count = Counter; } else if (operation != "END") { //FORMAT 4 CHECK if (operation[0] != '+') { op = opCode.search(OpCodes, operation); } else { tmpStr = operation.TrimStart('+'); op = opCode.search(OpCodes, tmpStr); op.format = "4"; } if (op == null) { if (operation == "WORD") { val = int.Parse(Counter, System.Globalization.NumberStyles.HexNumber) + 3; Counter = val.ToString("X").PadLeft(5, '0'); } else if (operation == "RESW") { if (int.TryParse(operand, out tmp)) { val = int.Parse(Counter, System.Globalization.NumberStyles.HexNumber) + (tmp * 3); Counter = val.ToString("X").PadLeft(5, '0'); } } else if (operation == "RESB") { if (int.TryParse(operand, out tmp)) { val = int.Parse(Counter, System.Globalization.NumberStyles.HexNumber) + tmp; Counter = val.ToString("X").PadLeft(5, '0'); } } else if (operation == "BYTE") { tmpStr = operand; if (tmpStr[0] == 'C') { tmpStr = tmpStr.TrimStart('C', '\''); tmpStr = tmpStr.TrimEnd('\''); tmp = tmpStr.Length; } else { tmpStr = tmpStr.TrimStart('X', '\''); tmpStr = tmpStr.TrimEnd('\''); tmp = tmpStr.Length / 2; } val = int.Parse(Counter, System.Globalization.NumberStyles.HexNumber) + tmp; Counter = val.ToString("X").PadLeft(5, '0'); } else if (operation == "BASE") { } else if (operation == "EQU") { if (operand == "*") { EquCount = Counter; } //IF OPERAND IS A DECIMAL VALUE else if (int.TryParse(operand, out tmp)) { EquCount = tmp.ToString("X").PadLeft(5, '0'); r = false; } //IF OPERAND IS AN EXPRESSION else { ex = Exp.insert(table, operand); if (int.TryParse(ex.value, out tmp)) { EquCount = tmp.ToString("X").PadLeft(5, '0'); r = ex.relocatable; } } } else if (operation == "EXTDEF") { r = false; } else if (operation == "EXTREF") { r = false; } } else { if (operation[0] != '+') { if (int.TryParse(op.format, out tmp)) { val = int.Parse(Counter, System.Globalization.NumberStyles.HexNumber) + tmp; Counter = val.ToString("X").PadLeft(5, '0'); } } else { val = int.Parse(Counter, System.Globalization.NumberStyles.HexNumber) + 4; Counter = val.ToString("X").PadLeft(5, '0'); } } } if (operand != null) { if (operand[0] == '=') { Literals.Add(operand); } } if (EquCount == null) { theFile.Add(string.Format("{0,-4} {1,-10} {2,-10} {3,-10} {4,-15}", l, tmpCounter, label, operation, operand)); if (label != null) { table = SymTab.insert(table, label, tmpCounter, r); } } else { theFile.Add(string.Format("{0,-4} {1,-10} {2,-10} {3,-10} {4,-15}", l, EquCount, label, operation, operand)); if (label != null) { table = SymTab.insert(table, label, EquCount, r); } } EquCount = null; r = true; label = null; operand = null; } } } if (Literals != null) { foreach (string oper in Literals) { l++; tmpCounter = Counter; lit = LitTable.insert(lit, oper, Counter); val = int.Parse(Counter, System.Globalization.NumberStyles.HexNumber) + lit.length; Counter = val.ToString("X").PadLeft(5, '0'); valLits.Add(lit.length); theFile.Add(string.Format("{0,-4} {1,-10} {2,-10} {3,-10} {4,-15}", l, tmpCounter, "*", oper, "")); } } passOne.length = p2.SubHex(Counter, str_Count); theFile.Add(passOne.length); passOne.table = table; passOne.lit = lit; passOne.prog = theFile; return(passOne); }