private static void BuildLibrary() { if (config.VerboseMode) { Console.WriteLine("Building external library..."); Console.WriteLine(); } int fileCount = 0; bool binaryMode = false; var files = Directory.GetFiles("library/", "*.asm", SearchOption.AllDirectories); string fullPath = Path.GetFullPath("library/"); repeat: foreach (var asmFile in files) { int start; int end; string baseFolder = Path.GetDirectoryName(asmFile) + "/"; string fileName = Path.GetFileName(asmFile); string fileNameExt = Path.GetFileNameWithoutExtension(asmFile); string fullFilePath = Path.GetFullPath(asmFile); string labelLevel = fullFilePath.Substring(fullPath.Length) .Replace(" ", "_").Replace("/", "_").Replace("\\", "_"); int s = labelLevel.LastIndexOf('.'); if (config.VerboseMode && binaryMode) { Console.WriteLine("Processing binary file '{0}':", fileName); } else if (config.VerboseMode) { Console.WriteLine("Processing file '{0}':", fileName); } if (s != -1) { labelLevel = labelLevel.Substring(0, s); } if (!binaryMode) { if (!CompileFile(File.ReadAllText(asmFile), baseFolder, fileName, "library", false, out start, out end, false, null)) { return; } } else { string baseAssembly = labelLevel + ":\r\nincbin \"" + fileName + "\"\r\n"; if (!CompileFile(baseAssembly, baseFolder, fileName, "library", false, out start, out end, false, null)) { return; } } if (config.VerboseMode) { Console.WriteLine(" Inserted at ${0:X6} (PC: 0x{1:x})", start, SNES.ToPCHeadered(start, rom.containsHeader)); Console.WriteLine(" Insert size: {0} (0x{0:X}) bytes", end - start + 8); } totalInsertSize += end - start + 8; var labels = Asar.getlabels().ToList(); int copyl = 0; for (int i = 0; i < labels.Count; ++i) { if (labels[i].Name != labelLevel) { var copy = labels[i]; copy.Name = labelLevel + "_" + copy.Name; labels[i] = copy; } if (labelList.Any(x => x.Name == labels[i].Name)) { Console.WriteLine(" {0} - error: label redefinition [{1}].", fileName, labels[i].Name); error = true; return; } if (!labels[i].Name.Contains(":")) { labelList.Add(labels[i]); copyl++; } if (labels[i].Location >= end || labels[i].Location < start) { labels.RemoveAt(i); --i; } } if (config.VerboseMode) { if (copyl == 1) { Console.WriteLine(" Processed one label."); } else { Console.WriteLine(" Processed {0} labels.", copyl); } } if (labels.Count == 0) { Console.WriteLine(" {0}: error: file contains no label within freespace area.", fileName); error = true; return; } if (!protPointerList.Contains(labels[0].Location)) { protPointerList.Add(labels[0].Location); } else { Console.WriteLine(" {0}: wtf error: Library included file is already protected.", fileName); error = true; return; } if (config.VerboseMode) { Console.WriteLine(); } fileCount++; } if (!binaryMode) { binaryMode = true; files = Directory.GetFiles("library/", "*.*", SearchOption.AllDirectories) .Where(x => !x.EndsWith(".asm", StringComparison.InvariantCultureIgnoreCase)).ToArray(); goto repeat; } if (fileCount == 0) { return; } if (fileCount == 1 && config.VerboseMode) { Console.WriteLine("Processed one library file."); } else if (config.VerboseMode) { Console.WriteLine("Processed {0} library files.", fileCount); } }
private static void BuildAsm(string asmPath, int maxItems, int mode, string initTable, string mainTable, string nmiTable, string loadTable) { if (error) { return; } int total = 0; if (config.VerboseMode) { Console.WriteLine("Building {0} ASM...", asmPath.ToUpper()[0] + asmPath.Substring(1)); Console.WriteLine(); } string baseFile = "asm/base/" + asmPath + ".asm"; string baseTempFile = "asm/work/" + asmPath + ".asm"; string baseFolder = asmPath + "/"; string assemblyData = File.ReadAllText(baseFile); StringBuilder initPointerList = new StringBuilder(); StringBuilder mainPointerList = new StringBuilder(); StringBuilder nmiPointerList = new StringBuilder(); StringBuilder loadPointerList = new StringBuilder(); for (int i = 0; i < maxItems; ++i) { initPointerList.Append("dl "); mainPointerList.Append("dl "); nmiPointerList.Append("dl "); loadPointerList.Append("dl "); if (config.FileASMList[mode][i] == null || config.FileASMList[mode][i].Length == 0) { initPointerList.Append("null_pointer"); mainPointerList.Append("null_pointer"); nmiPointerList.Append("null_pointer"); loadPointerList.Append("null_pointer"); } else { int nAsmInLevel = config.FileASMList[mode][i].Length; bool multiple = nAsmInLevel > 1; List <Code> codePaths = new List <Code>(); for (int j = 0; j < nAsmInLevel; j++) { codePaths.Add(config.CodeList[config.FileASMList[mode][i][j]]); } var code = codePaths[0]; string levelContents = null; if (!multiple) { try { levelContents = File.ReadAllText(baseFolder + code.Path); } catch (Exception ex) { Console.WriteLine("Error while reading file: " + ex.Message); error = true; return; } } if (config.VerboseMode) { Console.WriteLine("Processing file '{0}':", code.Path); } if (!code.Inserted) { if (!CompileFile(levelContents, baseFolder, code.Path, baseFolder, true, out int startPc, out int endPc, multiple, multiple ? codePaths.Select(x => x.Path) : null, loadTable != null)) { return; } if (endPc - startPc < 0) { Console.WriteLine(" {0}: error: Negative insert size. " + "Did you change program counter without pushpc/pullpc?", code.Path); error = true; return; } else if (endPc - startPc == 0) { Console.WriteLine(" {0}: error: Null (0 byte insert size) file.", code.Path); error = true; return; } if (config.VerboseMode) { Console.WriteLine(" Inserted at ${0:X6} (PC: 0x{1:x})", startPc, SNES.ToPCHeadered(startPc, rom.containsHeader)); Console.WriteLine(" Insert size: {0} (0x{0:X}) bytes", endPc - startPc + 8); } totalInsertSize += endPc - startPc + 8; var pointers = GetPointers(loadTable != null); if (pointers == null) { if (loadTable == null) { Console.WriteLine(" {0}: error: Missing init/main/nmi label.", code.Path); } else { Console.WriteLine(" {0}: error: Missing load/init/main/nmi label.", code.Path); } error = true; return; } int combo = 0; if (pointers[0] == -1) { initPointerList.Append("null_pointer"); } else if (pointers[0] >= endPc || pointers[0] < startPc) { Console.WriteLine(" {0}: error: INIT label outside free space range.", code.Path); error = true; return; } else { code.Init = pointers[0]; initPointerList.AppendFormat("${0:X6}", pointers[0]); combo |= 1; } if (pointers[1] == -1) { mainPointerList.Append("null_pointer"); } else if (pointers[1] >= endPc || pointers[1] < startPc) { Console.WriteLine(" {0}: error: MAIN label outside free space range.", code.Path); error = true; return; } else { code.Main = pointers[1]; mainPointerList.AppendFormat("${0:X6}", pointers[1]); combo |= 2; } if (pointers[3] == -1) { loadPointerList.Append("null_pointer"); } else if (pointers[3] >= endPc || pointers[3] < startPc) { Console.WriteLine(" {0}: error: LOAD label outside free space range.", code.Path); error = true; return; } else { code.Load = pointers[3]; loadPointerList.AppendFormat("${0:X6}", pointers[3]); combo |= 8; } if (pointers[2] == -1) { nmiPointerList.Append("null_pointer"); } else if (pointers[2] >= endPc || pointers[2] < startPc) { Console.WriteLine(" {0}: error: NMI label outside free space range.", code.Path); error = true; return; } else { code.Nmi = pointers[2]; nmiPointerList.AppendFormat("${0:X6}", pointers[2]); enableNmi[mode] = true; combo |= 4; } if (config.VerboseMode) { Console.Write($" INIT: {PrintPointer(code.Init)}"); if (combo >= 2) { Console.Write($" - MAIN: {PrintPointer(code.Main)}"); } if (combo >= 4) { Console.Write($" - NMI: {PrintPointer(code.Nmi)}"); } if (combo >= 8) { Console.Write($" - LOAD: {PrintPointer(code.Load)}"); } Console.WriteLine(); } code.Inserted = true; } else { if (code.Init == -1) { initPointerList.Append("null_pointer"); } else { initPointerList.AppendFormat("${0:X6}", code.Init); } if (code.Main == -1) { mainPointerList.Append("null_pointer"); } else { mainPointerList.AppendFormat("${0:X6}", code.Main); } if (code.Load == -1) { loadPointerList.Append("null_pointer"); } else { loadPointerList.AppendFormat("${0:X6}", code.Load); } if (code.Nmi == -1) { nmiPointerList.Append("null_pointer"); } else { nmiPointerList.AppendFormat("${0:X6}", code.Nmi); enableNmi[mode] = true; } if (config.VerboseMode) { Console.WriteLine(" Insert size: zero bytes"); } } if (config.VerboseMode) { Console.WriteLine(); } total++; } initPointerList.AppendLine(); mainPointerList.AppendLine(); nmiPointerList.AppendLine(); loadPointerList.AppendLine(); } InsertTable(ref assemblyData, initTable, initPointerList.ToString()); InsertTable(ref assemblyData, mainTable, mainPointerList.ToString()); if (loadTable != null) { InsertTable(ref assemblyData, loadTable, loadPointerList.ToString()); } if (enableNmi[mode]) { InsertTable(ref assemblyData, nmiTable, nmiPointerList.ToString()); } if (!FileUtils.ForceCreate(baseTempFile, assemblyData)) { Console.WriteLine(" Error: access denied while creating base temp file."); error = true; return; } if (config.VerboseMode) { if (total == 0) { return; } else if (total == 1) { Console.WriteLine("Total one file processed."); Console.WriteLine(); } else { Console.WriteLine("Total {0} files processed.", total); Console.WriteLine(); } } }