private static void AddTemporaryLabels() { List <int> addMe = new List <int>(); int pointer = 0; while (pointer < Data.GetROMSize()) { int length = GetLineByteLength(pointer); Data.FlagType flag = Data.GetFlag(pointer); if (unlabeled == FormatUnlabeled.ShowAll) { addMe.Add(Util.ConvertPCtoSNES(pointer)); } else if (unlabeled != FormatUnlabeled.ShowNone && (flag == Data.FlagType.Opcode || flag == Data.FlagType.Pointer16Bit || flag == Data.FlagType.Pointer24Bit || flag == Data.FlagType.Pointer32Bit)) { int ia = Util.GetIntermediateAddressOrPointer(pointer); if (ia >= 0 && Util.ConvertSNEStoPC(ia) >= 0) { addMe.Add(ia); } } pointer += length; } // TODO +/- labels for (int i = 0; i < addMe.Count; i++) { Data.AddLabel(addMe[i], Util.GetDefaultLabel(addMe[i]), false); } }
private static void AddTemporaryLabels() { List <int> addMe = new List <int>(); int pointer = 0; while (pointer < Data.GetROMSize()) { int length = GetLineByteLength(pointer); if (unlabeled == FormatUnlabeled.ShowAll) { addMe.Add(pointer); } else if (unlabeled != FormatUnlabeled.ShowNone) { int ea = Util.GetEffectiveAddressOrPointer(pointer); int pc = Util.ConvertSNEStoPC(ea); if (pc >= 0) { addMe.Add(pc); } } pointer += length; } // TODO +/- labels for (int i = 0; i < addMe.Count; i++) { Data.AddLabel(addMe[i], Util.GetDefaultLabel(addMe[i]), false); } }
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); }
private void GoToIntermediateAddress(int offset) { int ia = Util.GetIntermediateAddressOrPointer(offset); if (ia >= 0) { int pc = Util.ConvertSNEStoPC(ia); if (pc >= 0) { SelectOffset(pc, 1); } } }
private void GoToEffectiveAddress(int offset) { int ea = Util.GetEffectiveAddress(offset); if (ea >= 0) { int pc = Util.ConvertSNEStoPC(ea); if (pc >= 0) { SelectOffset(pc, 1); } } }
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); }
private void textROM_TextChanged(object sender, EventArgs e) { if (!updatingText) { updatingText = true; NumberStyles style = radioDec.Checked ? NumberStyles.Number : NumberStyles.HexNumber; Util.NumberBase noBase = radioDec.Checked ? Util.NumberBase.Decimal : Util.NumberBase.Hexadecimal; if (int.TryParse(textROM.Text, style, null, out int address)) { int pc = Util.ConvertSNEStoPC(address); if (pc >= 0 && pc < Data.GetROMSize()) { textPC.Text = Util.NumberToBaseString(pc, noBase, 0); } } updatingText = false; } }
private void textStart_TextChanged(object sender, EventArgs e) { if (!updatingText) { updatingText = true; NumberStyles style = radioDec.Checked ? NumberStyles.Number : NumberStyles.HexNumber; if (int.TryParse(textStart.Text, style, null, out int result)) { if (radioROM.Checked) { result = Util.ConvertSNEStoPC(result); } start = result; count = end - start; } UpdateText(textStart); } }
public Dictionary <int, string> GetGeneratedLabels() { Dictionary <int, string> labels = new Dictionary <int, string>(); for (int i = 0; i < checkboxes.GetLength(0); i++) { for (int j = 0; j < checkboxes.GetLength(1); j++) { if (checkboxes[i, j].Checked) { int index = offset + 15 + 0x10 * i + 2 * j; int val = data[index] + (data[index + 1] << 8); int pc = Util.ConvertSNEStoPC(val); if (pc >= 0 && pc < data.Length && !labels.ContainsKey(pc)) { labels.Add(pc, vectorNames[i, j]); } } } } return(labels); }
public static void MarkInOutPoints(int offset) { int opcode = Data.GetROMByte(offset); int iaOffsetPC = Util.ConvertSNEStoPC(Util.GetIntermediateAddress(offset, true)); // set read point on EA if (iaOffsetPC >= 0 && ( // these are all read/write/math instructions ((opcode & 0x04) != 0) || ((opcode & 0x0F) == 0x01) || ((opcode & 0x0F) == 0x03) || ((opcode & 0x1F) == 0x12) || ((opcode & 0x1F) == 0x19)) && (opcode != 0x45) && (opcode != 0x55) && (opcode != 0xF5) && (opcode != 0x4C) && (opcode != 0x5C) && (opcode != 0x6C) && (opcode != 0x7C) && (opcode != 0xDC) && (opcode != 0xFC) ) { Data.SetInOutPoint(iaOffsetPC, Data.InOutPoint.ReadPoint); } // set end point on offset if (opcode == 0x40 || opcode == 0x4C || opcode == 0x5C || opcode == 0x60 || // RTI JMP JML RTS opcode == 0x6B || opcode == 0x6C || opcode == 0x7C || opcode == 0x80 || // RTL JMP JMP BRA opcode == 0x82 || opcode == 0xDB || opcode == 0xDC // BRL STP JML ) { Data.SetInOutPoint(offset, Data.InOutPoint.EndPoint); } // set out point on offset // set in point on EA if (iaOffsetPC >= 0 && ( 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 opcode == 0x20 || opcode == 0x22)) // JSR JSL { Data.SetInOutPoint(offset, Data.InOutPoint.OutPoint); Data.SetInOutPoint(iaOffsetPC, Data.InOutPoint.InPoint); } }
private static string FormatOperandAddress(int offset, AddressMode mode) { int address = Util.GetIntermediateAddress(offset); if (address < 0) { return(""); } int pc = Util.ConvertSNEStoPC(address); if (pc >= 0 && Data.GetLabel(pc) != "") { return(Data.GetLabel(pc)); } int count = BytesToShow(mode); if (mode == AddressMode.RELATIVE_8 || mode == AddressMode.RELATIVE_16) { address = Util.GetROMWord(offset + 1); } address &= ~(-1 << (8 * count)); return(Util.NumberToBaseString(address, Util.NumberBase.Hexadecimal, 2 * count, true)); }
private static string GetLine(int offset, string special) { string line = ""; for (int i = 0; i < list.Count; i++) { if (list[i].Item2 == int.MaxValue) // string literal { line += list[i].Item1; } else if (special != null) // special parameter (replaces code & everything else = empty) { line += GetParameter(offset, "%" + (list[i].Item1 == "code" ? special : "empty"), list[i].Item2); } else // normal parameter { line += GetParameter(offset, list[i].Item1, list[i].Item2); } } if (special == null) { // throw out some errors if stuff looks fishy Data.FlagType flag = Data.GetFlag(offset), check = flag == Data.FlagType.Opcode ? Data.FlagType.Operand : flag; int step = flag == Data.FlagType.Opcode ? GetLineByteLength(offset) : Util.TypeStepSize(flag), size = Data.GetROMSize(); if (flag == Data.FlagType.Operand) { err.WriteLine("({0}) Offset 0x{1:X}: Bytes marked as operands formatted as data.", ++errorCount, offset); } else if (step > 1) { for (int i = 1; i < step; i++) { if (offset + i >= size) { err.WriteLine("({0}) Offset 0x{1:X}: {2} extends past the end of the ROM.", ++errorCount, offset, Util.TypeToString(check)); break; } else if (Data.GetFlag(offset + i) != check) { err.WriteLine("({0}) Offset 0x{1:X}: Expected {2}, but got {3} instead.", ++errorCount, offset + i, Util.TypeToString(check), Util.TypeToString(Data.GetFlag(offset + i))); break; } } } int ia = Util.GetIntermediateAddress(offset, true); if (ia >= 0 && flag == Data.FlagType.Opcode && Data.GetInOutPoint(offset) == Data.InOutPoint.OutPoint && Data.GetFlag(Util.ConvertSNEStoPC(ia)) != Data.FlagType.Opcode) { err.WriteLine("({0}) Offset 0x{1:X}: Branch or jump instruction to a non-instruction.", ++errorCount, offset); } } return(line); }
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 byte[] SaveVersion1() { int size = Data.GetROMSize(); byte[] romSettings = new byte[31]; romSettings[0] = (byte)Data.GetROMMapMode(); romSettings[1] = (byte)Data.GetROMSpeed(); Util.IntegerIntoByteArray(size, romSettings, 2); for (int i = 0; i < 0x15; i++) { romSettings[6 + i] = (byte)Data.GetROMByte(Util.ConvertSNEStoPC(0xFFC0 + i)); } for (int i = 0; i < 4; i++) { romSettings[27 + i] = (byte)Data.GetROMByte(Util.ConvertSNEStoPC(0xFFDC + i)); } // TODO put selected offset in save file List <byte> label = new List <byte>(), comment = new List <byte>(); Dictionary <int, string> all_labels = Data.GetAllLabels(), all_comments = Data.GetAllComments(); Util.IntegerIntoByteList(all_labels.Count, label); foreach (KeyValuePair <int, string> pair in all_labels) { Util.IntegerIntoByteList(pair.Key, label); for (int i = 0; i < pair.Value.Length; i++) { label.Add((byte)pair.Value[i]); } label.Add(0); } Util.IntegerIntoByteList(all_comments.Count, comment); foreach (KeyValuePair <int, string> pair in all_comments) { Util.IntegerIntoByteList(pair.Key, comment); for (int i = 0; i < pair.Value.Length; i++) { comment.Add((byte)pair.Value[i]); } comment.Add(0); } byte[] romLocation = Util.StringToByteArray(currentROMFile); byte[] data = new byte[romSettings.Length + romLocation.Length + 8 * size + label.Count + comment.Count]; romSettings.CopyTo(data, 0); for (int i = 0; i < romLocation.Length; i++) { data[romSettings.Length + i] = romLocation[i]; } for (int i = 0; i < size; i++) { data[romSettings.Length + romLocation.Length + i] = (byte)Data.GetDataBank(i); } for (int i = 0; i < size; i++) { data[romSettings.Length + romLocation.Length + size + i] = (byte)Data.GetDirectPage(i); } for (int i = 0; i < size; i++) { data[romSettings.Length + romLocation.Length + 2 * size + i] = (byte)(Data.GetDirectPage(i) >> 8); } for (int i = 0; i < size; i++) { data[romSettings.Length + romLocation.Length + 3 * size + i] = (byte)(Data.GetXFlag(i) ? 1 : 0); } for (int i = 0; i < size; i++) { data[romSettings.Length + romLocation.Length + 4 * size + i] = (byte)(Data.GetMFlag(i) ? 1 : 0); } for (int i = 0; i < size; i++) { data[romSettings.Length + romLocation.Length + 5 * size + i] = (byte)Data.GetFlag(i); } for (int i = 0; i < size; i++) { data[romSettings.Length + romLocation.Length + 6 * size + i] = (byte)Data.GetArchitechture(i); } for (int i = 0; i < size; i++) { data[romSettings.Length + romLocation.Length + 7 * size + i] = (byte)Data.GetInOutPoint(i); } // ??? label.CopyTo(data, romSettings.Length + romLocation.Length + 8 * size); comment.CopyTo(data, romSettings.Length + romLocation.Length + 8 * size + label.Count); // ??? return(data); }