/******************************************************************************* *** IFLITERALVALID FUNCTION *** ******************************************************************************** *** DESCRIPTION: This function takes in the linked list and test the *** *** literal to make sure that it is a valid literal *** ******************************************************************************** *** INPUT ARGS: Node_Lit list, string ex *** *** OUTPUT ARGS: N/A *** *** IN/OUT ARGS: N/A *** *** RETURN: string ERR_MSG *** ********************************************************************************/ public string IfLiteralValid(Node_Lit list, string ex) { //Search if previously defined if (search(list, ex) != null) { return("AD"); } //If the first character is not correct if (ex[0] != '=') { return(ERR_MSG_1); } //If the second character is not correct if (ex[1] != 'C' && ex[1] != 'c' && ex[1] != 'X' && ex[1] != 'x') { return(ERR_MSG_1); } //If the third and last character are ' if (ex[2] != (char)39 || ex[ex.Length - 1] != (char)39) { return(ERR_MSG_1); } if (ex[1] == 'X' || ex[1] == 'x') { ex = ex.TrimStart('X', 'x', '=', '\''); ex = ex.TrimEnd('\''); if (!isStringHex(ex)) { return(ERR_MSG_2); } } return(null); }
/******************************************************************************* *** SEARCH FUNCTION *** ******************************************************************************** *** DESCRIPTION: This function takes in the linked list and a literal and *** *** searches the linked list to see if the literal exsists *** ******************************************************************************** *** INPUT ARGS: Node_Lit list, string lit *** *** OUTPUT ARGS: N/A *** *** IN/OUT ARGS: N/A *** *** RETURN: null or list *** ********************************************************************************/ public Node_Lit search(Node_Lit list, string lit) { if (list == null) { return(null); } else if (list.name != lit) { return(search(list.next, lit)); } else { return(list); } }
/******************************************************************************* *** INSERT FUNCTION *** ******************************************************************************** *** DESCRIPTION: This function takes in a Literal Node and a string. This *** *** function runs a check function to test if the literal entered is valid *** *** and if valid, returns null, and populates the literal and return the *** *** linked list. *** ******************************************************************************** *** INPUT ARGS: Node_Lit list, string lit *** *** OUTPUT ARGS: N/A *** *** IN/OUT ARGS: N/A *** *** RETURN: Node_Lit newNode *** ********************************************************************************/ public Node_Lit insert(Node_Lit list, string lit, string add) { Node_Lit newNode = new Node_Lit(); newNode.ERR_MSG = IfLiteralValid(list, lit); if (newNode.ERR_MSG == "AD") { return(list); } newNode.head = newNode; newNode.next = list.head; newNode.address = add; newNode.name = lit; newNode.value = FindVal(lit); newNode.length = FindLen(lit); return(newNode); }
/******************************************************************************* *** VIEW FUNCTION *** ******************************************************************************** *** DESCRIPTION: This function takes in the linked list of literals. And *** *** prints each expression. If it has an error message, then it prints the *** *** error. *** ******************************************************************************** *** INPUT ARGS: Node_Lit list *** *** OUTPUT ARGS: N/A *** *** IN/OUT ARGS: N/A *** *** RETURN: null *** ********************************************************************************/ public Node_Lit view(Node_Lit list) { if (list != null) { if (list.ERR_MSG != null && list.ERR_MSG != "AD") { view(list.next); Console.WriteLine("{0,-10} {1,-30}", list.name, list.ERR_MSG); } else if (list.ERR_MSG == null) { view(list.next); Console.WriteLine("{0,-10} {1,-10} {2,-10} {3,-10}", list.name, list.value, list.length, list.address); } return(null); } else { return(null); } }
/******************************************************************************* *** 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); }