Пример #1
0
        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);
            }
        }
Пример #2
0
        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();
                }
            }
        }