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 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); }
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); }
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); }
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); }
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!"); } }
// 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!"); } }
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); }