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 AutoStep(int offset, bool harsh, int amount)
        {
            Project.unsavedChanges = true;
            int newOffset = offset, prevOffset = offset - 1, nextOffset = offset;

            if (harsh)
            {
                while (newOffset < offset + amount)
                {
                    nextOffset = Step(newOffset, false, true, prevOffset);
                    prevOffset = newOffset;
                    newOffset  = nextOffset;
                }
            }
            else
            {
                Stack <int> stack        = new Stack <int>();
                List <int>  seenBranches = new List <int>();
                bool        keepGoing    = true;

                while (keepGoing)
                {
                    switch (Data.GetArchitechture(newOffset))
                    {
                    case Data.Architechture.CPU65C816:
                        if (seenBranches.Contains(newOffset))
                        {
                            keepGoing = false;
                            break;
                        }

                        int opcode = Data.GetROMByte(newOffset);

                        nextOffset = Step(newOffset, false, false, prevOffset);
                        int jumpOffset = Step(newOffset, true, false, prevOffset);

                        if (opcode == 0x40 || opcode == 0xCB || opcode == 0xDB || opcode == 0xF8 ||  // RTI WAI STP SED
                            opcode == 0xFB || opcode == 0x00 || opcode == 0x02 || opcode == 0x42 ||     // XCE BRK COP WDM
                            opcode == 0x6C || opcode == 0x7C || opcode == 0xDC || opcode == 0xFC        // JMP JMP JML JSR
                            )
                        {
                            keepGoing = false;
                        }

                        if (opcode == 0x4C || opcode == 0x5C || opcode == 0x80 || opcode == 0x82 ||  // JMP JML BRA BRL
                            opcode == 0x10 || opcode == 0x30 || opcode == 0x50 || opcode == 0x70 ||     // BPL BMI BVC BVS
                            opcode == 0x90 || opcode == 0xB0 || opcode == 0xD0 || opcode == 0xF0        // BCC BCS BNE BEQ
                            )
                        {
                            seenBranches.Add(newOffset);
                        }

                        if (opcode == 0x08)     // PHP
                        {
                            stack.Push(Data.GetMXFlags(newOffset));
                        }
                        else if (opcode == 0x28)       // PLP
                        {
                            if (stack.Count == 0)
                            {
                                keepGoing = false; break;
                            }
                            else
                            {
                                Data.SetMXFlags(newOffset, stack.Pop());
                            }
                        }

                        if (opcode == 0x60 || opcode == 0x6B)     // RTS RTL
                        {
                            if (stack.Count == 0)
                            {
                                keepGoing = false;
                                break;
                            }
                            else
                            {
                                prevOffset = newOffset;
                                newOffset  = stack.Pop();
                            }
                        }
                        else if (opcode == 0x20 || opcode == 0x22)       // JSR JSL
                        {
                            stack.Push(nextOffset);
                            prevOffset = newOffset;
                            newOffset  = jumpOffset;
                        }
                        else
                        {
                            prevOffset = newOffset;
                            newOffset  = nextOffset;
                        }
                        break;

                    case Data.Architechture.APUSPC700:
                    case Data.Architechture.GPUSuperFX:
                        nextOffset = Step(newOffset, false, true, prevOffset);
                        prevOffset = newOffset;
                        newOffset  = nextOffset;
                        break;
                    }

                    Data.FlagType flag = Data.GetFlag(newOffset);
                    if (!(flag == Data.FlagType.Unreached || flag == Data.FlagType.Opcode || flag == Data.FlagType.Operand))
                    {
                        keepGoing = false;
                    }
                }
            }
            return(newOffset);
        }