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); }
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); }