Beispiel #1
0
        public static int ImportUsageMap(byte[] usageMap)
        {
            int  size      = Data.GetROMSize();
            bool unsaved   = false;
            int  modified  = 0;
            int  prevFlags = 0;

            for (int map = 0; map <= 0xFFFFFF; map++)
            {
                var i = Util.ConvertSNEStoPC(map);

                if (i == -1 || i >= size)
                {
                    // branch predictor may optimize this
                    continue;
                }

                var flags = (Data.BsnesPlusUsage)usageMap[map];

                if (flags == 0)
                {
                    // no information available
                    continue;
                }

                if (Data.GetFlag(i) != Data.FlagType.Unreached)
                {
                    // skip if there is something already set..
                    continue;
                }

                // opcode: 0x30, operand: 0x20
                if (flags.HasFlag(Data.BsnesPlusUsage.UsageExec))
                {
                    Data.SetFlag(i, Data.FlagType.Operand);

                    if (flags.HasFlag(Data.BsnesPlusUsage.UsageOpcode))
                    {
                        prevFlags = ((int)flags & 3) << 4;
                        Data.SetFlag(i, Data.FlagType.Opcode);
                    }

                    Data.SetMXFlags(i, prevFlags);
                    unsaved = true;
                    modified++;
                }
                else if (flags.HasFlag(Data.BsnesPlusUsage.UsageRead))
                {
                    Data.SetFlag(i, Data.FlagType.Data8Bit);
                    unsaved = true;
                    modified++;
                }
            }

            Project.unsavedChanges |= unsaved;
            return(modified);
        }
Beispiel #2
0
        public static int Mark(int offset, Data.FlagType type, int count)
        {
            Project.unsavedChanges = true;
            int i, size = Data.GetROMSize();

            for (i = 0; i < count && offset + i < size; i++)
            {
                Data.SetFlag(offset + i, type);
            }
            return(offset + i < size ? offset + i : size - 1);
        }
Beispiel #3
0
        public static int FixMisalignedFlags()
        {
            int count = 0, size = Data.GetROMSize();

            for (int i = 0; i < size; i++)
            {
                Data.FlagType flag = Data.GetFlag(i);

                if (flag == Data.FlagType.Opcode)
                {
                    int len = GetInstructionLength(i);
                    for (int j = 1; j < len && i + j < size; j++)
                    {
                        if (Data.GetFlag(i + j) != Data.FlagType.Operand)
                        {
                            Data.SetFlag(i + j, Data.FlagType.Operand);
                            count++;
                        }
                    }
                    i += len - 1;
                }
                else if (flag == Data.FlagType.Operand)
                {
                    Data.SetFlag(i, Data.FlagType.Opcode);
                    count++;
                    i--;
                }
                else if (Util.TypeStepSize(flag) > 1)
                {
                    int step = Util.TypeStepSize(flag);
                    for (int j = 1; j < step; j++)
                    {
                        if (Data.GetFlag(i + j) != flag)
                        {
                            Data.SetFlag(i + j, flag);
                            count++;
                        }
                    }
                    i += step - 1;
                }
            }

            if (count > 0)
            {
                Project.unsavedChanges = true;
            }

            return(count);
        }
Beispiel #4
0
        public static int ImportTraceLog(string[] lines)
        {
            // Must follow this format.
            // 028cde rep #$30               A:0004 X:0000 Y:0004 S:1fdd D:0000 DB:02 nvmxdiZC V:133 H: 654 F:36
            bool unsaved  = false;
            int  modified = 0;
            int  size     = Data.GetROMSize();

            foreach (var line in lines)
            {
                if (line.Length < 80)
                {
                    continue;
                }

                // TODO: error treatment
                // TODO: parse MX flags
                int directPageIndex = line.IndexOf("D:") + 2;
                int dataBankIndex   = line.IndexOf("DB:") + 3;

                int snesAddress = Convert.ToInt32(line.Substring(0, 6), 16);
                int directPage  = Convert.ToInt32(line.Substring(directPageIndex, 4), 16);
                int dataBank    = Convert.ToInt32(line.Substring(dataBankIndex, 2), 16);

                int pc = Util.ConvertSNEStoPC(snesAddress);

                if (pc == -1)
                {
                    continue;
                }

                Data.SetFlag(pc, Data.FlagType.Opcode);

                do
                {
                    Data.SetDataBank(pc, dataBank);
                    Data.SetDirectPage(pc, directPage);
                    pc++;
                    unsaved = true;
                    modified++;
                } while (pc < size && Data.GetFlag(pc) == Data.FlagType.Operand);
            }

            Project.unsavedChanges |= unsaved;
            return(modified);
        }
Beispiel #5
0
        public static int Step(int offset, bool branch, bool force, int prevOffset)
        {
            int  opcode = Data.GetROMByte(offset);
            int  prevDirectPage = Data.GetDirectPage(offset);
            int  prevDataBank = Data.GetDataBank(offset);
            bool prevX = Data.GetXFlag(offset), prevM = Data.GetMFlag(offset);

            while (prevOffset >= 0 && Data.GetFlag(prevOffset) == Data.FlagType.Operand)
            {
                prevOffset--;
            }
            if (prevOffset >= 0 && Data.GetFlag(prevOffset) == Data.FlagType.Opcode)
            {
                prevDirectPage = Data.GetDirectPage(prevOffset);
                prevDataBank   = Data.GetDataBank(prevOffset);
                prevX          = Data.GetXFlag(prevOffset);
                prevM          = Data.GetMFlag(prevOffset);
            }

            if (opcode == 0xC2 || opcode == 0xE2) // REP SEP
            {
                prevX = (Data.GetROMByte(offset + 1) & 0x10) != 0 ? opcode == 0xE2 : prevX;
                prevM = (Data.GetROMByte(offset + 1) & 0x20) != 0 ? opcode == 0xE2 : prevM;
            }

            // set first byte first, so the instruction length is correct
            Data.SetFlag(offset, Data.FlagType.Opcode);
            Data.SetDataBank(offset, prevDataBank);
            Data.SetDirectPage(offset, prevDirectPage);
            Data.SetXFlag(offset, prevX);
            Data.SetMFlag(offset, prevM);

            int length = GetInstructionLength(offset);

            for (int i = 1; i < length; i++)
            {
                Data.SetFlag(offset + i, Data.FlagType.Operand);
                Data.SetDataBank(offset + i, prevDataBank);
                Data.SetDirectPage(offset + i, prevDirectPage);
                Data.SetXFlag(offset + i, prevX);
                Data.SetMFlag(offset + i, prevM);
            }

            MarkInOutPoints(offset);

            int nextOffset = offset + length;

            if (!force && (opcode == 0x4C || opcode == 0x5C || opcode == 0x80 || opcode == 0x82 || // JMP JML BRA BRL
                           (branch && (opcode == 0x10 || opcode == 0x30 || opcode == 0x50 || // BPL BMI BVC
                                       opcode == 0x70 || opcode == 0x90 || opcode == 0xB0 || opcode == 0xD0 || // BVS BCC BCS BNE
                                       opcode == 0xF0 || opcode == 0x20 || opcode == 0x22)))) // BEQ JSR JSL
            {
                int iaNextOffsetPC = Util.ConvertSNEStoPC(Util.GetIntermediateAddress(offset, true));
                if (iaNextOffsetPC >= 0)
                {
                    nextOffset = iaNextOffsetPC;
                }
            }

            return(nextOffset);
        }
Beispiel #6
0
        private static void OpenVersion1(byte[] unzipped, OpenFileDialog open)
        {
            Data.ROMMapMode mode = (Data.ROMMapMode)unzipped[HEADER_SIZE];
            Data.ROMSpeed   speed = (Data.ROMSpeed)unzipped[HEADER_SIZE + 1];
            int             size = Util.ByteArrayToInteger(unzipped, HEADER_SIZE + 2);
            string          romName = "", romLocation = "";

            byte[] rom;

            int pointer = HEADER_SIZE + 6;

            for (int i = 0; i < 0x15; i++)
            {
                romName += (char)unzipped[pointer++];
            }
            int checksums = Util.ByteArrayToInteger(unzipped, pointer);

            pointer += 4;
            while (unzipped[pointer] != 0)
            {
                romLocation += (char)unzipped[pointer++];
            }
            pointer++;

            if (ValidateROM(romLocation, romName, checksums, mode, out rom, open))
            {
                Data.Initiate(rom, mode, speed);

                for (int i = 0; i < size; i++)
                {
                    Data.SetDataBank(i, unzipped[pointer + i]);
                }
                for (int i = 0; i < size; i++)
                {
                    Data.SetDirectPage(i, unzipped[pointer + size + i] | (unzipped[pointer + 2 * size + i] << 8));
                }
                for (int i = 0; i < size; i++)
                {
                    Data.SetXFlag(i, unzipped[pointer + 3 * size + i] != 0);
                }
                for (int i = 0; i < size; i++)
                {
                    Data.SetMFlag(i, unzipped[pointer + 4 * size + i] != 0);
                }
                for (int i = 0; i < size; i++)
                {
                    Data.SetFlag(i, (Data.FlagType)unzipped[pointer + 5 * size + i]);
                }
                for (int i = 0; i < size; i++)
                {
                    Data.SetArchitechture(i, (Data.Architechture)unzipped[pointer + 6 * size + i]);
                }
                for (int i = 0; i < size; i++)
                {
                    Data.SetInOutPoint(i, (Data.InOutPoint)unzipped[pointer + 7 * size + i]);
                }

                pointer += 8 * size;
                int label_count = Util.ByteArrayToInteger(unzipped, pointer);
                pointer += 4;

                AliasList.me.Reset();
                for (int i = 0; i < label_count; i++)
                {
                    int offset = Util.ByteArrayToInteger(unzipped, pointer);
                    pointer += 4;

                    string label = "";
                    while (unzipped[pointer] != 0)
                    {
                        label += (char)unzipped[pointer++];
                    }
                    pointer++;

                    Data.AddLabel(offset, label, true);
                }

                int comment_count = Util.ByteArrayToInteger(unzipped, pointer);
                pointer += 4;

                for (int i = 0; i < comment_count; i++)
                {
                    int offset = Util.ByteArrayToInteger(unzipped, pointer);
                    pointer += 4;

                    string comment = "";
                    while (unzipped[pointer] != 0)
                    {
                        comment += (char)unzipped[pointer++];
                    }
                    pointer++;

                    Data.AddComment(offset, comment, true);
                }
            }
            else
            {
                throw new Exception("Couldn't open the ROM file!");
            }
        }
Beispiel #7
0
        // differences between version 0 and version 1:
        // version 0: addresses for aliases and comments were stored in PC offset format.
        //            tables: B, D lo, D hi, X, M, flag, arch, inoutpoint
        //            lists: alias, comment
        // version 1: addresses for aliases and comments are stored in SNES address format.
        //            tables: B, D lo, D hi, X, M, flag, arch, inoutpoint, ???
        //            lists: alias, comment, ???
        private static void OpenVersion0(byte[] unzipped, OpenFileDialog open)
        {
            MessageBox.Show(
                "This project file is in an older format.\n" +
                "You may want to back up your work or 'Save As' in case the conversion goes wrong.\n" +
                "The project file will be untouched until it is saved again.",
                "Project File Out of Date", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

            Data.ROMMapMode mode = (Data.ROMMapMode)unzipped[HEADER_SIZE];
            Data.ROMSpeed   speed = (Data.ROMSpeed)unzipped[HEADER_SIZE + 1];
            int             size = Util.ByteArrayToInteger(unzipped, HEADER_SIZE + 2);
            string          romName = "", romLocation = "";

            byte[] rom;

            int pointer = HEADER_SIZE + 6;

            for (int i = 0; i < 0x15; i++)
            {
                romName += (char)unzipped[pointer++];
            }
            int checksums = Util.ByteArrayToInteger(unzipped, pointer);

            pointer += 4;
            while (unzipped[pointer] != 0)
            {
                romLocation += (char)unzipped[pointer++];
            }
            pointer++;

            if (ValidateROM(romLocation, romName, checksums, mode, out rom, open))
            {
                Data.Initiate(rom, mode, speed);

                for (int i = 0; i < size; i++)
                {
                    Data.SetDataBank(i, unzipped[pointer + i]);
                }
                for (int i = 0; i < size; i++)
                {
                    Data.SetDirectPage(i, unzipped[pointer + size + i] | (unzipped[pointer + 2 * size + i] << 8));
                }
                for (int i = 0; i < size; i++)
                {
                    Data.SetXFlag(i, unzipped[pointer + 3 * size + i] != 0);
                }
                for (int i = 0; i < size; i++)
                {
                    Data.SetMFlag(i, unzipped[pointer + 4 * size + i] != 0);
                }
                for (int i = 0; i < size; i++)
                {
                    Data.SetFlag(i, (Data.FlagType)unzipped[pointer + 5 * size + i]);
                }
                for (int i = 0; i < size; i++)
                {
                    Data.SetArchitechture(i, (Data.Architechture)unzipped[pointer + 6 * size + i]);
                }
                for (int i = 0; i < size; i++)
                {
                    Data.SetInOutPoint(i, (Data.InOutPoint)unzipped[pointer + 7 * size + i]);
                }

                pointer += 8 * size;
                int label_count = Util.ByteArrayToInteger(unzipped, pointer);
                pointer += 4;

                AliasList.me.Reset();
                for (int i = 0; i < label_count; i++)
                {
                    int offset = Util.ConvertPCtoSNES(Util.ByteArrayToInteger(unzipped, pointer)); // pc -> snes
                    pointer += 4;

                    string label = "";
                    while (unzipped[pointer] != 0)
                    {
                        label += (char)unzipped[pointer++];
                    }
                    pointer++;

                    Data.AddLabel(offset, label, true);
                }

                int comment_count = Util.ByteArrayToInteger(unzipped, pointer);
                pointer += 4;

                for (int i = 0; i < comment_count; i++)
                {
                    int offset = Util.ConvertPCtoSNES(Util.ByteArrayToInteger(unzipped, pointer)); // pc -> snes
                    pointer += 4;

                    string comment = "";
                    while (unzipped[pointer] != 0)
                    {
                        comment += (char)unzipped[pointer++];
                    }
                    pointer++;

                    Data.AddComment(offset, comment, true);
                }
            }
            else
            {
                throw new Exception("Couldn't open the ROM file!");
            }
        }
Beispiel #8
0
        public static bool NewProject(string filename)
        {
            try
            {
                byte[] smc = File.ReadAllBytes(filename);
                byte[] rom = new byte[smc.Length & 0x7FFFFC00];

                if ((smc.Length & 0x3FF) == 0x200)
                {
                    for (int i = 0; i < rom.Length; i++)
                    {
                        rom[i] = smc[i + 0x200];
                    }
                }
                else if ((smc.Length & 0x3FF) != 0)
                {
                    throw new Exception("This ROM has an unusual size. It can't be opened.");
                }
                else
                {
                    rom = smc;
                }

                if (rom.Length < 0x8000)
                {
                    throw new Exception("This ROM is too small. It can't be opened.");
                }

                currentROMFile = filename;

                ImportROMDialog import = new ImportROMDialog(rom);
                DialogResult    result = import.ShowDialog();
                if (result == DialogResult.OK)
                {
                    Data.Initiate(rom, import.GetROMMapMode(), import.GetROMSpeed());
                    unsavedChanges = false;
                    currentFile    = null;

                    AliasList.me.Reset();
                    Dictionary <int, string> generatedLabels = import.GetGeneratedLabels();
                    if (generatedLabels.Count > 0)
                    {
                        foreach (KeyValuePair <int, string> pair in generatedLabels)
                        {
                            Data.AddLabel(pair.Key, pair.Value, true);
                        }
                        unsavedChanges = true;
                    }

                    Dictionary <int, Data.FlagType> generatedFlags = import.GetHeaderFlags();
                    if (generatedFlags.Count > 0)
                    {
                        foreach (KeyValuePair <int, Data.FlagType> pair in generatedFlags)
                        {
                            Data.SetFlag(pair.Key, pair.Value);
                        }
                        unsavedChanges = true;
                    }

                    return(true);
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            return(false);
        }