Exemple #1
0
        static void Main(string[] args)
        {
            bool ShowWarnings = true;
            bool ShowInfo     = true;
            bool ShowFile     = false;

            int desiredSize = 0;

            List <FileParserException> exceptionList = new List <FileParserException>();

            Console.WriteLine("--MiniSRC Assembler by Mitchell Waite--\n");
            Console.WriteLine("-- Updated for 2021 by Alex McKinnon --\n");

            if (args.Length == 0)
            {
                Console.Write("Usage: minisrc_asm.exe [file] [output] [length] [options]\n\n[file] is a relative or absolute path to a MiniSRC asm file\n[output] is the desired location for the generated MIF\n\n[length] is the desired MIF size length, in (32 bit) words of memory.\n\nOptions:\n-showfile : show the MIF output in the console window.\n-noinfo : supress informational messages\n-nowarn : supress warning messages\n\nUse an & symbol to specify a line with data items, separated by spaces or commas -> &0x5,0x6\nUse an @ symbol to specify a subroutine, on its own line.\n\n");
            }
            else if (!File.Exists(args[0]))
            {
                Console.Write("The file specified below does not exist.\n\n" + args[0]);
            }
            else if (!Int32.TryParse(args[2], out desiredSize))
            {
                Console.Write("The following integer is not valid for desired MIF size: " + args[2] + "\n\n");
            }
            else
            {
                Console.WriteLine("Input: " + args[0]);
                Console.WriteLine("Output: " + args[1]);
                Console.WriteLine("");

                if (args.Contains("-noinfo"))
                {
                    ShowInfo = false;
                }

                if (args.Contains("-nowarn"))
                {
                    ShowWarnings = false;
                }

                if (args.Contains("-showfile"))
                {
                    ShowFile = true;
                }

                try
                {
                    List <String> outList = FileParser.ParseFile(args[0], ref exceptionList, desiredSize);

                    File.WriteAllLines(args[1], outList);

                    if (ShowFile)
                    {
                        foreach (string s in outList)
                        {
                            Console.WriteLine(s);
                        }

                        Console.WriteLine();
                    }

                    if (exceptionList.Count > 0)
                    {
                        foreach (FileParserException ex in exceptionList)
                        {
                            StringBuilder s = new StringBuilder();

                            if (ex.ErrorType == 1 && ShowWarnings)
                            {
                                s.Append("Warning");
                            }
                            else if (ex.ErrorType == 2 && ShowInfo)
                            {
                                s.Append("Information");
                            }
                            else
                            {
                                s.Append("Error");
                            }

                            s.AppendFormat(" in file: {0}\nLine: {1}\nMessage: {2}\n\n", args[0], ex.LineNumber, ex.Message);
                            Console.Error.Write(s);
                        }
                    }
                }
                catch (Exception ex)
                {
                    StringBuilder s = new StringBuilder();
                    s.AppendFormat("There was an error processing the assembly file.\n\nError: {0}\nMessage: {1}\nStack: {2}\n", ex.GetType().ToString(), ex.Message, ex.StackTrace);
                    Console.Error.Write(s);
                }
            }

            Console.WriteLine("Assembler Finished. Press any key to continue.");
            Console.ReadKey();
        }
Exemple #2
0
        public SRCInstruction ParseInstruction(string inst)
        {
            SRCInstruction tmpInst = new SRCInstruction();

            tmpInst.originalInstructionString   = inst;
            tmpInst.outputInstructionString     = "";
            tmpInst.replaceImmediateWithAddress = false;

            string instruction = inst.ToLower();

            if (instruction == "nop")
            {
                tmpInst.outputInstructionString = "C8000000";
                return(tmpInst); //opcode for NOP
            }
            else if (instruction == "halt")
            {
                tmpInst.outputInstructionString = "D0000000"; //opcode for HALT!
                return(tmpInst);
            }
            else //not a single word no operand instruction
            {
                string[]      wsplit = inst.ToLower().Split(' ');
                StringBuilder s      = new StringBuilder();
                s.Append(opcodeDictionary[wsplit[0]]);

                try
                {
                    switch (wsplit[0])
                    {
                    case "ld":
                    case "ldi":
                    {
                        string regString;

                        if (wsplit.Length > 2)
                        {
                            regString = (wsplit[1] + wsplit[2]);

                            if (wsplit.Length > 3)
                            {
                                //dump warning
                            }
                        }
                        else
                        {
                            regString = wsplit[1];
                        }

                        Regex idx = new Regex(@"(([rR][0-9]*),\s*[$|0x|0X|-]*[0-9]+\(([rR][0-9]+)\))\s*");
                        Regex reg = new Regex(@"([rR][0-9]*),\s*[$|0x|0X|-]*[0-9]+\s*");
                        Regex sub = new Regex(@"([rR][0-9]*),\s*[\@][a-zA-Z0-9]+\s*");         //will match an @ declaration.... this should be good

                        if (idx.IsMatch(regString))
                        {
                            string[] dirString = regString.Split(',');
                            string[] addString = dirString[1].Split('(');

                            s.AppendFormat("{0}", RxToBin(FileParser.TrimWhiteSpace(dirString[0])));
                            s.AppendFormat("{0}", RxToBin(FileParser.TrimWhiteSpace(addString[1].TrimEnd(')'))));


                            string immString   = FileParser.TrimWhiteSpace(addString[0]);
                            int    c_sx        = 0;
                            string c_sx_string = "";

                            if (immString.StartsWith("$"))
                            {
                                immString = immString.Remove(0, 1);
                                c_sx      = Convert.ToInt32(immString, 16);
                            }
                            else if (immString.ToLower().StartsWith("0x"))
                            {
                                c_sx = Convert.ToInt32(immString, 16);
                            }
                            else
                            {
                                c_sx = Convert.ToInt32(immString);
                            }

                            if (c_sx < -524288 || c_sx > 524287)
                            {
                                throw new ArgumentOutOfRangeException("Immediate Value out of range.");
                            }
                            else
                            {
                                c_sx_string = String.Format(Convert.ToString(c_sx, 2)).PadLeft(19, '0');
                                if (c_sx_string.Length > 19)        //remove erroneous 1s
                                {
                                    c_sx_string = c_sx_string.Substring(c_sx_string.Length - 19, 19);
                                }
                            }

                            s.AppendFormat("{0}", c_sx_string);

                            tmpInst.outputInstructionString = Convert.ToUInt32(s.ToString(), 2).ToString("X");
                            return(tmpInst);
                        }
                        else if (reg.IsMatch(regString))
                        {
                            string[] dirString = regString.Split(',');
                            s.AppendFormat("{0}0000", RxToBin(FileParser.TrimWhiteSpace(dirString[0])));

                            string immString   = FileParser.TrimWhiteSpace(dirString[1]);
                            int    c_sx        = 0;
                            string c_sx_string = "";

                            if (immString.StartsWith("$"))
                            {
                                immString = immString.Remove(0, 1);
                                c_sx      = Convert.ToInt32(immString, 16);
                            }
                            else if (immString.ToLower().StartsWith("0x"))
                            {
                                c_sx = Convert.ToInt32(immString, 16);
                            }
                            else
                            {
                                c_sx = Convert.ToInt32(immString);
                            }

                            if (c_sx < -524288 || c_sx > 524287)
                            {
                                throw new ArgumentOutOfRangeException("Immediate Value out of range.");
                            }
                            else
                            {
                                c_sx_string = String.Format(Convert.ToString(c_sx, 2)).PadLeft(19, '0');
                                if (c_sx_string.Length > 19)         //remove erroneous 1s
                                {
                                    c_sx_string = c_sx_string.Substring(c_sx_string.Length - 19, 19);
                                }
                            }

                            s.AppendFormat("{0}", c_sx_string);

                            tmpInst.outputInstructionString = Convert.ToUInt32(s.ToString(), 2).ToString("X");
                            return(tmpInst);
                        }
                        else if (sub.IsMatch(regString))
                        {
                            //we're matching a subroutine. save this for later.
                            string[] dirString = regString.Split(',');
                            tmpInst.immediateToReplace          = dirString[1];
                            tmpInst.replaceImmediateWithAddress = true;
                            return(tmpInst);
                        }
                        else
                        {
                            throw new ArgumentException("Syntax Error in '" + inst + "' : invalid instruction format.");
                        }
                    }

                    case "st":
                    {
                        string regString;

                        if (wsplit.Length > 2)
                        {
                            regString = (wsplit[1] + wsplit[2]);

                            if (wsplit.Length > 3)
                            {
                                //dump warning
                            }
                        }
                        else
                        {
                            regString = wsplit[1];
                        }

                        Regex idx = new Regex(@"[$|0x|0X|-]([0-9]*[a-f|A-F]*)*\([rR][0-9]+\)\s*,\s*[rR][0-9]+");
                        Regex reg = new Regex(@"[$|0x|0X|-]*[0-9]+\s*,\s*[rR][0-9]+\s*");

                        if (idx.IsMatch(regString))
                        {
                            string[] dirString = regString.Split(',');
                            string[] addString = dirString[0].Split('(');

                            s.AppendFormat("{0}", RxToBin(FileParser.TrimWhiteSpace(dirString[1])));
                            s.AppendFormat("{0}", RxToBin(FileParser.TrimWhiteSpace(addString[1].TrimEnd(')'))));


                            string immString   = FileParser.TrimWhiteSpace(addString[0]);
                            int    c_sx        = 0;
                            string c_sx_string = "";

                            if (immString.StartsWith("$"))
                            {
                                immString = immString.Remove(0, 1);
                                c_sx      = Convert.ToInt32(immString, 16);
                            }
                            else if (immString.ToLower().StartsWith("0x"))
                            {
                                c_sx = Convert.ToInt32(immString, 16);
                            }
                            else
                            {
                                c_sx = Convert.ToInt32(immString);
                            }

                            if (c_sx < -524288 || c_sx > 524287)
                            {
                                throw new ArgumentOutOfRangeException("Immediate Value out of range.");
                            }
                            else
                            {
                                c_sx_string = String.Format(Convert.ToString(c_sx, 2)).PadLeft(19, '0');
                                if (c_sx_string.Length > 19)         //remove erroneous 1s
                                {
                                    c_sx_string = c_sx_string.Substring(c_sx_string.Length - 19, 19);
                                }
                            }

                            s.AppendFormat("{0}", c_sx_string);

                            tmpInst.outputInstructionString = Convert.ToUInt32(s.ToString(), 2).ToString("X");
                            return(tmpInst);
                        }
                        else if (reg.IsMatch(regString))
                        {
                            string[] dirString = regString.Split(',');
                            s.AppendFormat("{0}0000", RxToBin(FileParser.TrimWhiteSpace(dirString[1])));

                            string immString = FileParser.TrimWhiteSpace(dirString[0]);
                            int    c_sx      = 0;

                            string c_sx_string = "";

                            if (immString.StartsWith("$"))
                            {
                                immString = immString.Remove(0, 1);
                                c_sx      = Convert.ToInt32(immString, 16);
                            }
                            else if (immString.ToLower().StartsWith("0x"))
                            {
                                c_sx = Convert.ToInt32(immString, 16);
                            }
                            else
                            {
                                c_sx = Convert.ToInt32(immString);
                            }

                            if (c_sx < -524288 || c_sx > 524287)
                            {
                                throw new ArgumentOutOfRangeException("Immediate Value out of range.");
                            }
                            else
                            {
                                c_sx_string = String.Format(Convert.ToString(c_sx, 2)).PadLeft(19, '0');
                                if (c_sx_string.Length > 19)         //remove erroneous 1s
                                {
                                    c_sx_string = c_sx_string.Substring(c_sx_string.Length - 19, 19);
                                }
                            }

                            s.AppendFormat("{0}", c_sx_string);

                            tmpInst.outputInstructionString = Convert.ToUInt32(s.ToString(), 2).ToString("X");
                            return(tmpInst);
                        }
                        else
                        {
                            throw new ArgumentException("Syntax Error in '" + inst + "' : invalid instruction format.");
                        }
                    }


                    //operation,register instructions
                    case "jal":
                    case "jr":
                    case "mflo":
                    case "mfhi":
                    case "in":
                    case "out":
                    {
                        if (wsplit.Length > 2)
                        {
                            //dump warning here
                        }

                        s.Append(RxToBin(wsplit[1]));
                        tmpInst.outputInstructionString = Convert.ToUInt32(s.ToString().PadRight(32, '0'), 2).ToString("X");
                        return(tmpInst);
                    }

                    //operation, three registers, no immediate value
                    case "add":
                    case "sub":
                    case "and":
                    case "or":
                    case "shr":
                    case "shl":
                    case "ror":
                    case "rol":
                    {
                        string[] regString;

                        if (wsplit.Length > 3)
                        {
                            regString = (wsplit[1] + wsplit[2] + wsplit[3]).Split(',');

                            if (wsplit.Length > 4)
                            {
                                //dump warning
                            }
                        }
                        else if (wsplit.Length > 2)
                        {
                            regString = (wsplit[1] + wsplit[2]).Split(',');
                        }
                        else
                        {
                            regString = wsplit[1].Split(',');
                        }

                        s.AppendFormat("{0}{1}{2}", RxToBin(FileParser.TrimWhiteSpace(regString[0])), RxToBin(FileParser.TrimWhiteSpace(regString[1])), RxToBin(FileParser.TrimWhiteSpace(regString[2])));

                        tmpInst.outputInstructionString = Convert.ToUInt32(s.ToString().PadRight(32, '0'), 2).ToString("X");
                        return(tmpInst);
                    }

                    //operation, two registers, immediate value
                    case "addi":
                    case "andi":
                    case "ori":
                    {
                        string[] regString;

                        if (wsplit.Length > 3)
                        {
                            regString = (wsplit[1] + wsplit[2] + wsplit[3]).Split(',');

                            if (wsplit.Length > 4)
                            {
                                //dump warning
                            }
                        }
                        else if (wsplit.Length > 2)
                        {
                            regString = (wsplit[1] + wsplit[2]).Split(',');
                        }
                        else
                        {
                            regString = wsplit[1].Split(',');
                        }

                        s.AppendFormat("{0}{1}", RxToBin(FileParser.TrimWhiteSpace(regString[0])), RxToBin(FileParser.TrimWhiteSpace(regString[1])));

                        string immString = FileParser.TrimWhiteSpace(regString[2]);
                        int    c_sx      = 0;

                        string c_sx_string = "";

                        if (immString.StartsWith("$"))
                        {
                            immString = immString.Remove(0, 1);
                            c_sx      = Convert.ToInt32(immString, 16);
                        }
                        else if (immString.ToLower().StartsWith("0x"))
                        {
                            c_sx = Convert.ToInt32(immString, 16);
                        }
                        else
                        {
                            c_sx = Convert.ToInt32(immString);
                        }

                        if (c_sx < -524288 || c_sx > 524287)
                        {
                            throw new ArgumentOutOfRangeException("Immediate Value out of range.");
                        }
                        else
                        {
                            c_sx_string = String.Format(Convert.ToString(c_sx, 2)).PadLeft(19, '0');
                            if (c_sx_string.Length > 19)         //remove erroneous 1s
                            {
                                c_sx_string = c_sx_string.Substring(c_sx_string.Length - 19, 19);
                            }
                        }

                        s.AppendFormat("{0}", c_sx_string);

                        tmpInst.outputInstructionString = Convert.ToUInt32(s.ToString(), 2).ToString("X");
                        return(tmpInst);
                    }

                    //operation, two registers, nothing else
                    case "not":
                    case "neg":
                    case "div":
                    case "mul":
                    {
                        string[] regString;

                        if (wsplit.Length > 2)
                        {
                            regString = (wsplit[1] + wsplit[2]).Split(',');

                            if (wsplit.Length > 3)
                            {
                                //dump warning
                            }
                        }
                        else
                        {
                            regString = wsplit[1].Split(',');
                        }

                        s.AppendFormat("{0}{1}", RxToBin(FileParser.TrimWhiteSpace(regString[0])), RxToBin(FileParser.TrimWhiteSpace(regString[1])));

                        tmpInst.outputInstructionString = Convert.ToUInt32(s.ToString().PadRight(32, '0'), 2).ToString("X");
                        return(tmpInst);
                    }

                    //branches
                    case "brzr":
                    case "brnz":
                    case "brpl":
                    case "brmi":
                    {
                        string[] regString;

                        if (wsplit.Length > 2)
                        {
                            regString = (wsplit[1] + wsplit[2]).Split(',');

                            if (wsplit.Length > 3)
                            {
                                //dump warning
                            }
                        }
                        else
                        {
                            regString = wsplit[1].Split(',');
                        }

                        s.AppendFormat("{0}{1}", RxToBin(FileParser.TrimWhiteSpace(regString[0])), "00");

                        s.Append(branchSuffix[wsplit[0]]);


                        // Constant added to end
                        string immString = FileParser.TrimWhiteSpace(regString[1]);
                        int    c_sx      = 0;

                        string c_sx_string = "";

                        if (immString.StartsWith("$"))
                        {
                            immString = immString.Remove(0, 1);
                            c_sx      = Convert.ToInt32(immString, 16);
                        }
                        else if (immString.ToLower().StartsWith("0x"))
                        {
                            c_sx = Convert.ToInt32(immString, 16);
                        }
                        else
                        {
                            c_sx = Convert.ToInt32(immString);
                        }

                        if (c_sx < -524288 || c_sx > 524287)
                        {
                            throw new ArgumentOutOfRangeException("Immediate Value out of range.");
                        }
                        else
                        {
                            c_sx_string = String.Format(Convert.ToString(c_sx, 2)).PadLeft(19, '0');
                            if (c_sx_string.Length > 19)         //remove erroneous 1s
                            {
                                c_sx_string = c_sx_string.Substring(c_sx_string.Length - 19, 19);
                            }
                        }

                        s.AppendFormat("{0}", c_sx_string);



                        tmpInst.outputInstructionString = Convert.ToUInt32(s.ToString(), 2).ToString("X");
                        return(tmpInst);
                    }

                    default:
                    {
                        throw new ArgumentException("Unknown instruction: " + wsplit[0]);
                    }
                    }
                }
                catch (IndexOutOfRangeException)
                {
                    throw new ArgumentException("Syntax Error, argument(s) are missing from '" + inst + "'");
                }
            }
        }