public static int Main(string[] args) { DateTime startTime = DateTime.Now; int returnCode = 0; DisplaySplash(); if (args.Length == 0) { DisplayHelp(); return 1; } string inputFile = null; string outputFile = null; string listingFile = null; string jsonFile = null; string pipe = null; string workingDirectory = Directory.GetCurrentDirectory(); bool bigEndian = true, quiet = false, verbose = false; Assembler assembler = new Assembler(); assembler.IncludePath = Environment.GetEnvironmentVariable("ORGINCLUDE"); if (string.IsNullOrEmpty(assembler.IncludePath)) assembler.IncludePath = ""; for (int i = 0; i < args.Length; i++) { string arg = args[i]; if (arg.StartsWith("-")) { try { switch (arg) { case "-h": case "-?": case "/h": case "/?": case "--help": DisplayHelp(); return 1; case "-o": case "--output": case "--output-file": outputFile = args[++i]; break; case "--input-file": inputFile = args[++i]; break; case "-e": case "--equate": ExpressionResult result = assembler.ParseExpression(args[i + 2]); if (!result.Successful) { Console.WriteLine("Error: " + ListEntry.GetFriendlyErrorMessage(ErrorCode.IllegalExpression)); return 1; } assembler.Values.Add(args[i + 1].ToLower(), result.Value); i += 2; break; case "-l": case "--listing": listingFile = args[++i]; break; case "--little-endian": bigEndian = false; break; case "--long-literals": assembler.ForceLongLiterals = true; break; case "--quiet": case "-q": quiet = true; break; case "--pipe": case "-p": pipe = args[++i]; break; case "--json": jsonFile = args[++i]; break; case "--include": case "-i": assembler.IncludePath = Environment.GetEnvironmentVariable("ORGINCLUDE") + ";" + args[++i]; break; case "--plugins": ListPlugins(assembler); return 0; case "--working-directory": case "-w": workingDirectory = args[++i]; break; case "--verbose": case "-v": verbose = true; break; case "--debug-mode": Console.ReadKey(); break; case "--install": assembler.InstallPlugin(args[++i]); return 0; case "--remove": assembler.RemovePlugin(args[++i]); return 0; case "--search": assembler.SearchPlugins(args[++i]); return 0; case "--info": assembler.GetInfo(args[++i]); return 0; default: HandleParameterEventArgs hpea = new HandleParameterEventArgs(arg); hpea.Arguments = args; hpea.Index = i; if (assembler.TryHandleParameter != null) assembler.TryHandleParameter(assembler, hpea); if (!hpea.Handled) { Console.WriteLine("Error: Invalid parameter: " + arg + "\nUse Organic.exe --help for usage information."); return 1; } else i = hpea.Index; if (hpea.StopProgram) return 0; break; } } catch (ArgumentOutOfRangeException) { Console.WriteLine("Error: Missing argument: " + arg + "\nUse Organic.exe --help for usage information."); return 1; } } else { if (inputFile == null) inputFile = arg; else if (outputFile == null) outputFile = arg; else { Console.WriteLine("Error: Invalid parameter: " + arg + "\nUse Organic.exe --help for usage information."); return 1; } } } if (inputFile == null && pipe == null) { Console.WriteLine("Error: No input file specified.\nUse Organic.exe --help for usage information."); return 1; } if (outputFile == null) outputFile = Path.GetFileNameWithoutExtension(inputFile) + ".bin"; if (!File.Exists(inputFile) && pipe == null && inputFile != "-") { Console.WriteLine("Error: File not found (" + inputFile + ")"); return 1; } string contents; if (pipe == null) { if (inputFile != "-") { StreamReader reader = new StreamReader(inputFile); contents = reader.ReadToEnd(); reader.Close(); } else contents = Console.In.ReadToEnd(); } else contents = pipe; List<ListEntry> output; string wdOld = Directory.GetCurrentDirectory(); Directory.SetCurrentDirectory(workingDirectory); if (pipe == null) output = assembler.Assemble(contents, inputFile); else output = assembler.Assemble(contents, "[piped input]"); Directory.SetCurrentDirectory(wdOld); if (assembler.AssemblyComplete != null) assembler.AssemblyComplete(assembler, new AssemblyCompleteEventArgs(output)); // Output errors if (!quiet) { foreach (var entry in output) { if (entry.ErrorCode != ErrorCode.Success) { Console.Error.WriteLine("Error " + entry.FileName + " (line " + entry.LineNumber + "): " + ListEntry.GetFriendlyErrorMessage(entry.ErrorCode)); returnCode = 1; } if (entry.WarningCode != WarningCode.None) Console.WriteLine("Warning " + entry.FileName + " (line " + entry.LineNumber + "): " + ListEntry.GetFriendlyWarningMessage(entry.WarningCode)); } } ushort currentAddress = 0; Stream binStream = null; if (outputFile != "-") { if (!string.IsNullOrEmpty(Path.GetDirectoryName(outputFile))) Directory.CreateDirectory(Path.GetDirectoryName(outputFile)); binStream = File.Open(outputFile, FileMode.Create); } foreach (var entry in output) { if (entry.Output != null) { foreach (ushort value in entry.Output) { currentAddress++; byte[] buffer = BitConverter.GetBytes(value); if (bigEndian) Array.Reverse(buffer); if (outputFile != "-") binStream.Write(buffer, 0, buffer.Length); else Console.Out.Write(Encoding.ASCII.GetString(buffer)); } } } string listing = ""; if (listingFile != null || verbose) listing = CreateListing(output); string json = ""; if (jsonFile != null) json = CreateJson(output); if (verbose) Console.Write(listing); if (listingFile != null) { if (!string.IsNullOrEmpty(Path.GetDirectoryName(listingFile))) Directory.CreateDirectory(Path.GetDirectoryName(listingFile)); var writer = new StreamWriter(listingFile); writer.Write(listing); writer.Close(); } if (jsonFile != null) { if (!string.IsNullOrEmpty(Path.GetDirectoryName(jsonFile))) Directory.CreateDirectory(Path.GetDirectoryName(jsonFile)); var writer = new StreamWriter(jsonFile); writer.Write(json); writer.Close(); } TimeSpan duration = DateTime.Now - startTime; Console.WriteLine("Organic build complete " + duration.TotalMilliseconds + "ms"); return returnCode; }
/// <summary> /// Given an expression, it will parse it and return the result as a nullable ushort /// </summary> /// <param name="value"></param> /// <returns></returns> public ExpressionResult ParseExpression(string value) { ExpressionResult expressionResult = new ExpressionResult(); expressionResult.Successful = true; expressionResult.References = new List <string>(); value = value.Trim(); if (HandleExpression != null) { HandleExpressionEventArgs heea = new HandleExpressionEventArgs(value); HandleExpression(this, heea); value = heea.Expression; } if (value.SafeContains('(')) { // Check for advanced expression handlers foreach (var item in ExpressionExtensions) { if (value.StartsWith(item.Key.ToLower() + "(")) { string expr = value.Substring(value.SafeIndexOf('(') + 1); expr = expr.Remove(expr.Length - 1); expressionResult.Value = item.Value(expr); return(expressionResult); } } return(EvaluateParenthesis(value)); } if (value.StartsWith("~")) { expressionResult = ParseExpression(value.Substring(1)); if (expressionResult.Successful) { expressionResult.Value = (ushort)~expressionResult.Value; } return(expressionResult); } if (!HasOperators(value)) { // Parse value ushort result; EvaluateValueEventArgs args = new EvaluateValueEventArgs(value); if (EvaluateExpressionValue != null) { EvaluateExpressionValue(this, args); } if (args.Handled) { expressionResult.Value = args.Result; return(expressionResult); } else if (value.StartsWith("0d")) { value = value.Substring(2); } if (value.StartsWith("'")) // Character { if (value.Length < 3) { expressionResult.Successful = false; return(expressionResult); } value = value.Substring(1, value.Length - 2).Unescape(); if (value == null) { expressionResult.Successful = false; return(expressionResult); } if (value.Length != 1) { expressionResult.Successful = false; return(expressionResult); } expressionResult.Value = (ushort)Encoding.ASCII.GetBytes(value)[0]; return(expressionResult); } else if (value.StartsWith("{") && value.EndsWith("}")) // instruction literal { string instruction = value.Substring(1, value.Length - 2); Assembler subAssembler = new Assembler(); List <ListEntry> assembly = subAssembler.Assemble(instruction); if (assembly.Count == 0) { expressionResult.Successful = false; return(expressionResult); } if (assembly[0].Output == null) { expressionResult.Successful = false; return(expressionResult); } if (assembly[0].Output.Length == 0) { expressionResult.Successful = false; return(expressionResult); } expressionResult.Value = assembly[0].Output[0]; return(expressionResult); } else if (value.StartsWith("0x")) // Hex { value = value.Substring(2); if (!ushort.TryParse(value.Replace("_", ""), NumberStyles.HexNumber, null, out result)) { expressionResult.Successful = false; return(expressionResult); } else { expressionResult.Value = result; return(expressionResult); } } else if (value.StartsWith("0b")) // Binary { value = value.Substring(2); ushort?binResult = ParseBinary(value.Replace("_", "")); if (binResult == null) { expressionResult.Successful = false; } else { expressionResult.Value = binResult.Value; } return(expressionResult); } else if (value.StartsWith("0o")) { value = value.Substring(2); try { expressionResult.Value = Convert.ToUInt16(value.Replace("_", ""), 8); return(expressionResult); } catch { expressionResult.Successful = false; return(expressionResult); } } else if (ushort.TryParse(value.Replace("_", ""), out result)) // Decimal { expressionResult.Value = result; return(expressionResult); } else if (value == "$") { if (LineNumbers.Count == 0) { expressionResult.Successful = false; return(expressionResult); } expressionResult.Value = currentAddress; return(expressionResult); } else if (value.StartsWith("$")) // Relative label { if (LineNumbers.Count == 0) { expressionResult.Successful = false; return(expressionResult); } value = value.Substring(1); int nextLabelIndex = -1; // Find the next relative label after the current line for (int i = 0; i < RelativeLabels.Count; i++) { if (RelativeLabels.ElementAt(i).Key > LineNumbers.Peek()) { nextLabelIndex = i; break; } } if (nextLabelIndex == -1) { nextLabelIndex = RelativeLabels.Count - 1; // If no such label is found, use the last one } bool initialPlus = true; // For each plus, increment that label index, and each minus decrements it foreach (char c in value) { if (c == '+') // The intial plus symbol is ignored { if (initialPlus) { nextLabelIndex++; } initialPlus = false; } else if (c == '-') { nextLabelIndex--; } } if (nextLabelIndex < 0) { expressionResult.Successful = false; return(expressionResult); } if (nextLabelIndex > RelativeLabels.Count - 1) { expressionResult.Successful = false; return(expressionResult); } expressionResult.Value = RelativeLabels.ElementAt(nextLabelIndex).Value; return(expressionResult); } else if (value.ToLower() == "true") { expressionResult.Value = 1; return(expressionResult); } else if (value.ToLower() == "false") { expressionResult.Value = 0; return(expressionResult); } else // Defined value or error { if (value.StartsWith(".")) { value = PriorGlobalLabel + "_" + value.Substring(1); } if (Values.ContainsKey(value)) { expressionResult.Value = Values[value]; } else if (LabelValues.ContainsKey(value)) { expressionResult.Relocate = true; expressionResult.Value = LabelValues.GetValue(value); } else { expressionResult.Successful = false; } expressionResult.References.Add(value); if (!ReferencedValues.Contains(value)) { ReferencedValues.Add(value); } return(expressionResult); } } // Parse expression string[] operands = GetOperands(value); if (operands == null) { expressionResult.Successful = false; return(expressionResult); } if (string.IsNullOrEmpty(operands[0]) && operands[1] == "-") { expressionResult = ParseExpression(operands[2]); expressionResult.Value = (ushort)-expressionResult.Value; return(expressionResult); } if (operands == null) { expressionResult.Successful = false; return(expressionResult); } ExpressionResult left = ParseExpression(operands[0]); ExpressionResult right = ParseExpression(operands[2]); expressionResult.References.AddRange(left.References.Concat(right.References)); if ((!left.Successful || !right.Successful) && operands[1] != "===" && operands[1] != "!==") { expressionResult.Successful = false; return(expressionResult); } switch (operands[1]) { case "*": expressionResult.Value = (ushort)(left.Value * right.Value); break; case "/": expressionResult.Value = (ushort)(left.Value / right.Value); break; case "+": expressionResult.Value = (ushort)(left.Value + right.Value); break; case "-": expressionResult.Value = (ushort)(left.Value - right.Value); break; case "<<": expressionResult.Value = (ushort)(left.Value << right.Value); break; case ">>": expressionResult.Value = (ushort)(left.Value >> right.Value); break; case "|": expressionResult.Value = (ushort)(left.Value | right.Value); break; case "^": expressionResult.Value = (ushort)(left.Value ^ right.Value); break; case "&": expressionResult.Value = (ushort)(left.Value & right.Value); break; case "%": expressionResult.Value = (ushort)(left.Value % right.Value); break; case "==": expressionResult.Value = (ushort)(left.Value == right.Value ? 1 : 0); break; case "!=": case "<>": expressionResult.Value = (ushort)(left.Value != right.Value ? 1 : 0); break; case "<": expressionResult.Value = (ushort)(left.Value < right.Value ? 1 : 0); break; case ">": expressionResult.Value = (ushort)(left.Value > right.Value ? 1 : 0); break; case "<=": expressionResult.Value = (ushort)(left.Value <= right.Value ? 1 : 0); break; case ">=": expressionResult.Value = (ushort)(left.Value >= right.Value ? 1 : 0); break; case "===": expressionResult.Value = (ushort)(operands[0].ToLower().Trim() == operands[2].ToLower().Trim() ? 1 : 0); break; case "!==": expressionResult.Value = (ushort)(operands[0].ToLower().Trim() != operands[2].ToLower().Trim() ? 1 : 0); break; case "&&": expressionResult.Value = (ushort)(left.Value > 0 && right.Value > 1 ? 1 : 0); break; case "||": expressionResult.Value = (ushort)(left.Value > 0 || right.Value > 1 ? 1 : 0); break; case "^^": expressionResult.Value = (ushort)(left.Value > 0 ^ right.Value > 1 ? 1 : 0); // between boolean operators, ^ is ^^ in C# break; default: expressionResult.Successful = false; return(expressionResult); } return(expressionResult); }
/// <summary> /// Given an expression, it will parse it and return the result as a nullable ushort /// </summary> /// <param name="value"></param> /// <returns></returns> public ExpressionResult ParseExpression(string value) { ExpressionResult expressionResult = new ExpressionResult(); expressionResult.Successful = true; expressionResult.References = new List<string>(); value = value.Trim(); if (HandleExpression != null) { HandleExpressionEventArgs heea = new HandleExpressionEventArgs(value); HandleExpression(this, heea); value = heea.Expression; } if (value.SafeContains('(')) { // Check for advanced expression handlers foreach (var item in ExpressionExtensions) { if (value.StartsWith(item.Key.ToLower() + "(")) { string expr = value.Substring(value.SafeIndexOf('(') + 1); expr = expr.Remove(expr.Length - 1); expressionResult.Value = item.Value(expr); return expressionResult; } } return EvaluateParenthesis(value); } if (value.StartsWith("~")) { expressionResult = ParseExpression(value.Substring(1)); if (expressionResult.Successful) expressionResult.Value = (ushort)~expressionResult.Value; return expressionResult; } if (!HasOperators(value)) { // Parse value ushort result; EvaluateValueEventArgs args = new EvaluateValueEventArgs(value); if (EvaluateExpressionValue != null) { EvaluateExpressionValue(this, args); } if (args.Handled) { expressionResult.Value = args.Result; return expressionResult; } else if (value.StartsWith("0d")) value = value.Substring(2); if (value.StartsWith("'")) // Character { if (value.Length < 3) { expressionResult.Successful = false; return expressionResult; } value = value.Substring(1, value.Length - 2).Unescape(); if (value == null) { expressionResult.Successful = false; return expressionResult; } if (value.Length != 1) { expressionResult.Successful = false; return expressionResult; } expressionResult.Value = (ushort)Encoding.ASCII.GetBytes(value)[0]; return expressionResult; } else if (value.StartsWith("{") && value.EndsWith("}")) // instruction literal { string instruction = value.Substring(1, value.Length - 2); Assembler subAssembler = new Assembler(); List<ListEntry> assembly = subAssembler.Assemble(instruction); if (assembly.Count == 0) { expressionResult.Successful = false; return expressionResult; } if (assembly[0].Output == null) { expressionResult.Successful = false; return expressionResult; } if (assembly[0].Output.Length == 0) { expressionResult.Successful = false; return expressionResult; } expressionResult.Value = assembly[0].Output[0]; return expressionResult; } else if (value.StartsWith("0x")) // Hex { value = value.Substring(2); if (!ushort.TryParse(value.Replace("_", ""), NumberStyles.HexNumber, null, out result)) { expressionResult.Successful = false; return expressionResult; } else { expressionResult.Value = result; return expressionResult; } } else if (value.StartsWith("0b")) // Binary { value = value.Substring(2); ushort? binResult = ParseBinary(value.Replace("_", "")); if (binResult == null) expressionResult.Successful = false; else expressionResult.Value = binResult.Value; return expressionResult; } else if (value.StartsWith("0o")) { value = value.Substring(2); try { expressionResult.Value = Convert.ToUInt16(value.Replace("_", ""), 8); return expressionResult; } catch { expressionResult.Successful = false; return expressionResult; } } else if (ushort.TryParse(value.Replace("_", ""), out result)) // Decimal { expressionResult.Value = result; return expressionResult; } else if (value == "$") { if (LineNumbers.Count == 0) { expressionResult.Successful = false; return expressionResult; } expressionResult.Value = currentAddress; return expressionResult; } else if (value.StartsWith("$")) // Relative label { if (LineNumbers.Count == 0) { expressionResult.Successful = false; return expressionResult; } value = value.Substring(1); int nextLabelIndex = -1; // Find the next relative label after the current line for (int i = 0; i < RelativeLabels.Count; i++) { if (RelativeLabels.ElementAt(i).Key > LineNumbers.Peek()) { nextLabelIndex = i; break; } } if (nextLabelIndex == -1) nextLabelIndex = RelativeLabels.Count - 1; // If no such label is found, use the last one bool initialPlus = true; // For each plus, increment that label index, and each minus decrements it foreach (char c in value) { if (c == '+') // The intial plus symbol is ignored { if (initialPlus) nextLabelIndex++; initialPlus = false; } else if (c == '-') nextLabelIndex--; } if (nextLabelIndex < 0) { expressionResult.Successful = false; return expressionResult; } if (nextLabelIndex > RelativeLabels.Count - 1) { expressionResult.Successful = false; return expressionResult; } expressionResult.Value = RelativeLabels.ElementAt(nextLabelIndex).Value; return expressionResult; } else if (value.ToLower() == "true") { expressionResult.Value = 1; return expressionResult; } else if (value.ToLower() == "false") { expressionResult.Value = 0; return expressionResult; } else // Defined value or error { if (value.StartsWith(".")) value = PriorGlobalLabel + "_" + value.Substring(1); if (Values.ContainsKey(value)) expressionResult.Value = Values[value]; else if (LabelValues.ContainsKey(value)) { expressionResult.Relocate = true; expressionResult.Value = LabelValues.GetValue(value); } else expressionResult.Successful = false; expressionResult.References.Add(value); if (!ReferencedValues.Contains(value)) ReferencedValues.Add(value); return expressionResult; } } // Parse expression string[] operands = GetOperands(value); if (operands == null) { expressionResult.Successful = false; return expressionResult; } if (string.IsNullOrEmpty(operands[0]) && operands[1] == "-") { expressionResult = ParseExpression(operands[2]); expressionResult.Value = (ushort)-expressionResult.Value; return expressionResult; } if (operands == null) { expressionResult.Successful = false; return expressionResult; } ExpressionResult left = ParseExpression(operands[0]); ExpressionResult right = ParseExpression(operands[2]); expressionResult.References.AddRange(left.References.Concat(right.References)); if ((!left.Successful || !right.Successful) && operands[1] != "===" && operands[1] != "!==") { expressionResult.Successful = false; return expressionResult; } switch (operands[1]) { case "*": expressionResult.Value = (ushort)(left.Value * right.Value); break; case "/": expressionResult.Value = (ushort)(left.Value / right.Value); break; case "+": expressionResult.Value = (ushort)(left.Value + right.Value); break; case "-": expressionResult.Value = (ushort)(left.Value - right.Value); break; case "<<": expressionResult.Value = (ushort)(left.Value << right.Value); break; case ">>": expressionResult.Value = (ushort)(left.Value >> right.Value); break; case "|": expressionResult.Value = (ushort)(left.Value | right.Value); break; case "^": expressionResult.Value = (ushort)(left.Value ^ right.Value); break; case "&": expressionResult.Value = (ushort)(left.Value & right.Value); break; case "%": expressionResult.Value = (ushort)(left.Value % right.Value); break; case "==": expressionResult.Value = (ushort)(left.Value == right.Value ? 1 : 0); break; case "!=": case "<>": expressionResult.Value = (ushort)(left.Value != right.Value ? 1 : 0); break; case "<": expressionResult.Value = (ushort)(left.Value < right.Value ? 1 : 0); break; case ">": expressionResult.Value = (ushort)(left.Value > right.Value ? 1 : 0); break; case "<=": expressionResult.Value = (ushort)(left.Value <= right.Value ? 1 : 0); break; case ">=": expressionResult.Value = (ushort)(left.Value >= right.Value ? 1 : 0); break; case "===": expressionResult.Value = (ushort)(operands[0].ToLower().Trim() == operands[2].ToLower().Trim() ? 1 : 0); break; case "!==": expressionResult.Value = (ushort)(operands[0].ToLower().Trim() != operands[2].ToLower().Trim() ? 1 : 0); break; case "&&": expressionResult.Value = (ushort)(left.Value > 0 && right.Value > 1 ? 1 : 0); break; case "||": expressionResult.Value = (ushort)(left.Value > 0 || right.Value > 1 ? 1 : 0); break; case "^^": expressionResult.Value = (ushort)(left.Value > 0 ^ right.Value > 1 ? 1 : 0); // between boolean operators, ^ is ^^ in C# break; default: expressionResult.Successful = false; return expressionResult; } return expressionResult; }
public static int Main(string[] args) { DateTime startTime = DateTime.Now; int returnCode = 0; DisplaySplash(); if (args.Length == 0) { DisplayHelp(); return(1); } string inputFile = null; string outputFile = null; string listingFile = null; string jsonFile = null; string pipe = null; string workingDirectory = Directory.GetCurrentDirectory(); bool bigEndian = true, quiet = false, verbose = false; Assembler assembler = new Assembler(); assembler.IncludePath = Environment.GetEnvironmentVariable("ORGINCLUDE"); if (string.IsNullOrEmpty(assembler.IncludePath)) { assembler.IncludePath = ""; } for (int i = 0; i < args.Length; i++) { string arg = args[i]; if (arg.StartsWith("-")) { try { switch (arg) { case "-h": case "-?": case "/h": case "/?": case "--help": DisplayHelp(); return(1); case "-o": case "--output": case "--output-file": outputFile = args[++i]; break; case "--input-file": inputFile = args[++i]; break; case "-e": case "--equate": ExpressionResult result = assembler.ParseExpression(args[i + 2]); if (!result.Successful) { Console.WriteLine("Error: " + ListEntry.GetFriendlyErrorMessage(ErrorCode.IllegalExpression)); return(1); } assembler.Values.Add(args[i + 1].ToLower(), result.Value); i += 2; break; case "-l": case "--listing": listingFile = args[++i]; break; case "--little-endian": bigEndian = false; break; case "--long-literals": assembler.ForceLongLiterals = true; break; case "--quiet": case "-q": quiet = true; break; case "--pipe": case "-p": pipe = args[++i]; break; case "--json": jsonFile = args[++i]; break; case "--include": case "-i": assembler.IncludePath = Environment.GetEnvironmentVariable("ORGINCLUDE") + ";" + args[++i]; break; case "--plugins": ListPlugins(assembler); return(0); case "--working-directory": case "-w": workingDirectory = args[++i]; break; case "--verbose": case "-v": verbose = true; break; case "--debug-mode": Console.ReadKey(); break; case "--install": assembler.InstallPlugin(args[++i]); return(0); case "--remove": assembler.RemovePlugin(args[++i]); return(0); case "--search": assembler.SearchPlugins(args[++i]); return(0); case "--info": assembler.GetInfo(args[++i]); return(0); default: HandleParameterEventArgs hpea = new HandleParameterEventArgs(arg); hpea.Arguments = args; hpea.Index = i; if (assembler.TryHandleParameter != null) { assembler.TryHandleParameter(assembler, hpea); } if (!hpea.Handled) { Console.WriteLine("Error: Invalid parameter: " + arg + "\nUse Organic.exe --help for usage information."); return(1); } else { i = hpea.Index; } if (hpea.StopProgram) { return(0); } break; } } catch (ArgumentOutOfRangeException) { Console.WriteLine("Error: Missing argument: " + arg + "\nUse Organic.exe --help for usage information."); return(1); } } else { if (inputFile == null) { inputFile = arg; } else if (outputFile == null) { outputFile = arg; } else { Console.WriteLine("Error: Invalid parameter: " + arg + "\nUse Organic.exe --help for usage information."); return(1); } } } if (inputFile == null && pipe == null) { Console.WriteLine("Error: No input file specified.\nUse Organic.exe --help for usage information."); return(1); } if (outputFile == null) { outputFile = Path.GetFileNameWithoutExtension(inputFile) + ".bin"; } if (!File.Exists(inputFile) && pipe == null && inputFile != "-") { Console.WriteLine("Error: File not found (" + inputFile + ")"); return(1); } string contents; if (pipe == null) { if (inputFile != "-") { StreamReader reader = new StreamReader(inputFile); contents = reader.ReadToEnd(); reader.Close(); } else { contents = Console.In.ReadToEnd(); } } else { contents = pipe; } List <ListEntry> output; string wdOld = Directory.GetCurrentDirectory(); Directory.SetCurrentDirectory(workingDirectory); if (pipe == null) { output = assembler.Assemble(contents, inputFile); } else { output = assembler.Assemble(contents, "[piped input]"); } Directory.SetCurrentDirectory(wdOld); if (assembler.AssemblyComplete != null) { assembler.AssemblyComplete(assembler, new AssemblyCompleteEventArgs(output)); } // Output errors if (!quiet) { foreach (var entry in output) { if (entry.ErrorCode != ErrorCode.Success) { Console.Error.WriteLine("Error " + entry.FileName + " (line " + entry.LineNumber + "): " + ListEntry.GetFriendlyErrorMessage(entry.ErrorCode)); returnCode = 1; } if (entry.WarningCode != WarningCode.None) { Console.WriteLine("Warning " + entry.FileName + " (line " + entry.LineNumber + "): " + ListEntry.GetFriendlyWarningMessage(entry.WarningCode)); } } } ushort currentAddress = 0; Stream binStream = null; if (outputFile != "-") { if (!string.IsNullOrEmpty(Path.GetDirectoryName(outputFile))) { Directory.CreateDirectory(Path.GetDirectoryName(outputFile)); } binStream = File.Open(outputFile, FileMode.Create); } foreach (var entry in output) { if (entry.Output != null) { foreach (ushort value in entry.Output) { currentAddress++; byte[] buffer = BitConverter.GetBytes(value); if (bigEndian) { Array.Reverse(buffer); } if (outputFile != "-") { binStream.Write(buffer, 0, buffer.Length); } else { Console.Out.Write(Encoding.ASCII.GetString(buffer)); } } } } string listing = ""; if (listingFile != null || verbose) { listing = CreateListing(output); } string json = ""; if (jsonFile != null) { json = CreateJson(output); } if (verbose) { Console.Write(listing); } if (listingFile != null) { if (!string.IsNullOrEmpty(Path.GetDirectoryName(listingFile))) { Directory.CreateDirectory(Path.GetDirectoryName(listingFile)); } var writer = new StreamWriter(listingFile); writer.Write(listing); writer.Close(); } if (jsonFile != null) { if (!string.IsNullOrEmpty(Path.GetDirectoryName(jsonFile))) { Directory.CreateDirectory(Path.GetDirectoryName(jsonFile)); } var writer = new StreamWriter(jsonFile); writer.Write(json); writer.Close(); } TimeSpan duration = DateTime.Now - startTime; Console.WriteLine("Organic build complete " + duration.TotalMilliseconds + "ms"); return(returnCode); }
static void Main(string[] args) { DateTime startupTime = DateTime.Now; // Parse arguments foreach (string arg in args) { if (arg.StartsWith("-")) { switch (arg) { case "--debug-mode": Console.ReadKey(true); break; case "--generate-reports": case "-r": generateReports = true; break; case "--little-endian": case "-l": bigEndian = false; break; default: Console.WriteLine("Invalid arguments."); return; } } } Console.WriteLine("0x42c Build Tool Copyright 0x42c Team 2012"); startupDirectory = Directory.GetCurrentDirectory(); // Clean up old build if (Directory.Exists("../bin")) Directory.Delete("../bin", true); Directory.CreateDirectory("../bin"); Directory.CreateDirectory("../bin/kernel"); Directory.CreateDirectory("../bin/bootloader"); Directory.CreateDirectory("../bin/userspace"); Directory.CreateDirectory("../bin/dump"); if (generateReports) { if (Directory.Exists("../reports")) Directory.Delete("../reports", true); Directory.CreateDirectory("../reports"); } // Build kernel Console.WriteLine("Building 0x42c-kernel..."); Directory.SetCurrentDirectory("../src/kernel"); Assembler kernelAssembler = new Assembler(); kernelAssembler.ForceLongLiterals = true; kernelAssembler.IncludePath = "../include"; using (StreamReader sr = new StreamReader("base.dasm")) { string code = sr.ReadToEnd(); Kernel = kernelAssembler.Assemble(code, "base.dasm"); } Directory.SetCurrentDirectory(startupDirectory); CreateOutput(Kernel, "../bin/kernel", "kernel"); // Build bootloader Console.WriteLine("Building 0x42c-bootloader..."); Directory.SetCurrentDirectory("../src/bootloader"); Assembler bootloaderAssembler = new Assembler(); kernelAssembler.ForceLongLiterals = true; bootloaderAssembler.IncludePath = "../include"; using (StreamReader sr = new StreamReader("base.dasm")) { string code = sr.ReadToEnd(); Bootloader = bootloaderAssembler.Assemble(code, "base.dasm"); } Directory.SetCurrentDirectory(startupDirectory); CreateOutput(Bootloader, "../bin/bootloader", "bootloader"); // Patch all files together Console.WriteLine("Creating memory dump..."); using (Stream dump = File.Open("../bin/dump/0x42c.bin", FileMode.Create)) { dump.Write(new byte[0xFFFF * 2], 0, 0xFFFF * 2); dump.Flush(); // Write kernel to dump dump.Seek(0, SeekOrigin.Begin); kernelSize = WriteToStream(Kernel, dump); // Write bootloader to dump dump.Seek(kernelAssembler.Values["os_bootloader"], SeekOrigin.Begin); bootloaderSize = WriteToStream(Bootloader, dump); } Console.WriteLine("Build complete " + (DateTime.Now - startupTime).TotalMilliseconds + "ms"); }