private static void PostProcess(Data data) { Pad(data); var snesApi = data.GetSnesApi(); Debug.Assert(snesApi != null); // inject the game name into the bytes // This is a UTF8 string that needs to be converted to ShiftJIS (Ascii w/some japanese chars) encoding. snesApi.SetCartridgeTitle(GetSampleUtf8CartridgeTitle()); // initialize some SNES header stuff (this is not complete, feel free to add things that are useful) Debug.Assert(snesApi.RomMapMode == RomMapMode.LoRom); Debug.Assert(snesApi.RomSpeed == RomSpeed.FastRom); var romSettingsOffset = RomUtil.GetRomSettingOffset(RomMapMode.LoRom); const int loromAndFastRom = 0x30; data.RomBytes[romSettingsOffset].Rom = loromAndFastRom; // do this LAST after all modifications to the ROM bytes have been completed snesApi.FixChecksum(); // NORMALLY when a project is loaded, we have to open the ROM file on disk and read the bytes on disk into RomBytes // for this sample data, there is no ROM on disk, so we tell Diz we already took care of it data.RomBytesLoaded = true; }
public void TestRomDetectionGeneratedRom() { sampleDataFixture.Should().NotBeNull(); var detectRomMapMode = RomUtil.DetectRomMapMode(sampleDataFixture.SampleRomBytes, out var detectedValidRomMapType); detectedValidRomMapType.Should().Be(true); detectRomMapMode.Should().Be(RomMapMode.LoRom); }
public static void ConvertSnesToPcLoRom() { var romSize = RomUtil.GetBankSize(RomMapMode.LoRom) * 8; Assert.Equal(-1, RomUtil.ConvertSnesToPc(0x790000, RomMapMode.LoRom, romSize)); Assert.Equal(0x00, RomUtil.ConvertSnesToPc(0x808000, RomMapMode.LoRom, romSize)); }
public void TestRomDetectionHiRom() { var detectRomMapMode = RomUtil.DetectRomMapMode( fileReader.ReadRomFileBytes(CartNameData.ExampleHiRomFile), out var detectedValidRomMapType); detectedValidRomMapType.Should().Be(true); detectRomMapMode.Should().Be(RomMapMode.HiRom); }
public static void ConvertSnesToPcHiRom() { var romSize = RomUtil.GetBankSize(RomMapMode.HiRom) * 64; Assert.Equal(-1, RomUtil.ConvertSnesToPc(0x202000, RomMapMode.HiRom, romSize)); Assert.Equal(0x01FFFF, RomUtil.ConvertSnesToPc(0x41FFFF, RomMapMode.HiRom, romSize)); Assert.Equal(0x000123, RomUtil.ConvertSnesToPc(0xC00123, RomMapMode.HiRom, romSize)); Assert.Equal(0x3F0123, RomUtil.ConvertSnesToPc(0xFF0123, RomMapMode.HiRom, romSize)); Assert.Equal(-1, RomUtil.ConvertSnesToPc(0x10000000, RomMapMode.HiRom, romSize)); }
public int FixMisalignedFlags() { int count = 0, size = GetRomSize(); for (var i = 0; i < size; i++) { var flag = GetFlag(i); switch (flag) { case FlagType.Opcode: { int len = GetInstructionLength(i); for (var j = 1; j < len && i + j < size; j++) { if (GetFlag(i + j) != FlagType.Operand) { SetFlag(i + j, FlagType.Operand); count++; } } i += len - 1; break; } case FlagType.Operand: SetFlag(i, FlagType.Opcode); count++; i--; break; default: { if (RomUtil.GetByteLengthForFlag(flag) > 1) { int step = RomUtil.GetByteLengthForFlag(flag); for (int j = 1; j < step; j++) { if (GetFlag(i + j) == flag) { continue; } SetFlag(i + j, flag); count++; } i += step - 1; } break; } } } return(count); }
public Dictionary <int, Data.FlagType> GenerateHeaderFlags() { var flags = new Dictionary <int, Data.FlagType>(); if (ShouldCheckHeader) { RomUtil.GenerateHeaderFlags(RomSettingsOffset, flags, ImportSettings.RomBytes); } return(flags); }
protected virtual void Init() { InitOutput(); SetupParseList(); BankSize = RomUtil.GetBankSize(Data.RomMapMode); ErrorCount = 0; LabelsWeVisited = new List <int>(); GenerateAdditionalExtraLabels(); WriteGeneratedLabelsIntoUnderlyingData(); // MODIFIES DATA. MAKE SURE TO UNDO THIS. }
private static bool MatchCartTitle(RomToProjectAssociation container, Project?project, ValidationContext <RomToProjectAssociation> validationContext) { if (project?.Data == null) { return(false); } var gameNameFromRomBytes = RomUtil.GetCartridgeTitleFromRom(container.RomBytes, project.Data.RomSettingsOffset); var requiredGameNameMatch = project.InternalRomGameName; return(MatchCartTitle(requiredGameNameMatch, gameNameFromRomBytes, validationContext)); }
public static void TestTitleRead() { var fakeRom = Enumerable .Range(0, 0x7FC0) .Select(_ => (byte)0x00) .Concat(RawRomBytes) .ToArray(); RomUtil .GetCartridgeTitleFromRom( fakeRom, RomUtil.GetRomSettingOffset(RomMapMode.LoRom) ).Should().Be(ExpectedTitleStr); }
private void Mark(int offset) { if (!RomDataPresent()) { return; } ProjectController.MarkChanged(); var newOffset = Project.Data.MarkTypeFlag(offset, markFlag, RomUtil.GetByteLengthForFlag(markFlag)); SelectOffset(newOffset); UpdateUI_Tmp3(); }
private void Mark(int offset) { if (!RomDataPresent()) { return; } ProjectController.MarkChanged(); var newOffset = Project.Data.GetSnesApi().MarkTypeFlag(offset, markFlag, RomUtil.GetByteLengthForFlag(markFlag)); SelectOffset(newOffset, new ISnesNavigation.HistoryArgs { Description = "Mark (single)" }); UpdateUi_TimerAndPercent(); }
public void CreateSettingsFromRom(string filename) { var romBytes = RomUtil.ReadAllRomBytesFromFile(filename); ImportSettings = new ImportRomSettings { RomFilename = filename, RomBytes = romBytes, RomMapMode = RomUtil.DetectRomMapMode(romBytes, out var detectedMapModeSuccess) }; if (detectedMapModeSuccess) { DetectedMapMode = ImportSettings.RomMapMode; } OnSettingsCreated(); }
// Mark collected trace data for a RomByte (which should be an opcode) AND any of the operands that follow us. private void SetOpcodeAndOperandsFromTraceData( int snesAddress, int dataBank, int directPage, bool xflagSet, bool mflagSet, int opcodeLen = -1) { // extremely performance-intensive function. be really careful when adding stuff var currentIndex = 0; while (true) { if (!SetOneRomByteFromTraceData(snesAddress, dataBank, directPage, xflagSet, mflagSet, opcodeLen, currentIndex)) { break; } snesAddress = RomUtil.CalculateSnesOffsetWithWrap(snesAddress, 1); currentIndex++; } }
private static int GetNextSNESAddress(int modDataSnesAddress) { return(RomUtil.CalculateSnesOffsetWithWrap(modDataSnesAddress, 1)); }
private void buttonScan_Click(object sender, EventArgs e) { textLog.Text = ""; int found = 0, offset = 0; while (found < 500 && offset < Data.GetRomSize()) { FlagType flag = Data.GetFlag(offset), check = flag == FlagType.Opcode ? FlagType.Operand : flag; var step = flag == FlagType.Opcode ? Data.GetInstructionLength(offset) : RomUtil.GetByteLengthForFlag(flag); if (flag == FlagType.Operand) { found++; textLog.Text += $"{Util.NumberToBaseString(Data.ConvertPCtoSnes(offset), Util.NumberBase.Hexadecimal, 6, true)} (0x{Util.NumberToBaseString(offset, Util.NumberBase.Hexadecimal, 0)}): Operand without Opcode\r\n"; } else if (step > 1) { for (var i = 1; i < step; i++) { if (Data.GetFlag(offset + i) == check) { continue; } found++; textLog.Text += $"{Util.NumberToBaseString(Data.ConvertPCtoSnes(offset + i), Util.NumberBase.Hexadecimal, 6, true)} (0x{Util.NumberToBaseString(offset + i, Util.NumberBase.Hexadecimal, 0)}): {Util.GetEnumDescription(Data.GetFlag(offset + i))} is not {Util.GetEnumDescription(check)}\r\n"; } } offset += step; } if (found == 0) { textLog.Text = "No misaligned flags found!"; } }
private int GetByteLengthFollowing(int offset) { var flag = Data.GetFlag(offset); return(flag == Data.FlagType.Opcode ? GetLineByteLength(offset) : RomUtil.GetByteLengthForFlag(flag)); }
public override (Project project, string warning) Load(byte[] data) { if (!IsBinaryFileFormat(data)) { throw new InvalidDataException($"This is not a binary serialized project file!"); } byte version = data[0]; ValidateProjectFileVersion(version); var project = new Project { Data = new Data() }; // version 0 needs to convert PC to SNES for some addresses ByteUtil.AddressConverter converter = address => address; if (version == 0) { converter = project.Data.ConvertPCtoSnes; } // read mode, speed, size project.Data.RomMapMode = (RomMapMode)data[HeaderSize]; project.Data.RomSpeed = (RomSpeed)data[HeaderSize + 1]; var size = ByteUtil.ByteArrayToInt32(data, HeaderSize + 2); // read internal title var pointer = HeaderSize + 6; project.InternalRomGameName = RomUtil.ReadStringFromByteArray(data, RomUtil.LengthOfTitleName, pointer); pointer += RomUtil.LengthOfTitleName; // read checksums project.InternalCheckSum = ByteUtil.ByteArrayToInt32(data, pointer); pointer += 4; // read full filepath to the ROM .sfc file while (data[pointer] != 0) { project.AttachedRomFilename += (char)data[pointer++]; } pointer++; project.Data.RomBytes.Create(size); for (int i = 0; i < size; i++) { project.Data.SetDataBank(i, data[pointer + i]); } pointer++; for (int i = 0; i < size; i++) { project.Data.SetDirectPage(i, data[pointer + size + i] | (data[pointer + 1 * size + i] << 8)); } pointer += 2; for (int i = 0; i < size; i++) { project.Data.SetXFlag(i, data[pointer * size + i] != 0); } pointer++; for (int i = 0; i < size; i++) { project.Data.SetMFlag(i, data[pointer * size + i] != 0); } pointer++; for (int i = 0; i < size; i++) { project.Data.SetFlag(i, (Data.FlagType)data[pointer * size + i]); } pointer++; for (int i = 0; i < size; i++) { project.Data.SetArchitecture(i, (Data.Architecture)data[pointer * size + i]); } pointer++; for (int i = 0; i < size; i++) { project.Data.SetInOutPoint(i, (Data.InOutPoint)data[pointer * size + i]); } pointer++; //for (int i = 0; i < size; i++) project.Data.SetBaseAddr(i, (Data.InOutPoint)data[pointer * size + i]); pointer++; ReadLabels(project, data, ref pointer, converter, version >= 2); ReadComments(project, data, ref pointer, converter); project.UnsavedChanges = false; var warning = ""; if (version != LatestFileFormatVersion) { warning = "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."; } return(project, warning); }
public static Data PopulateFromRom(this Data data, ByteSource romByteSource, RomMapMode romMapMode, RomSpeed romSpeed) { var mapping = RomUtil.CreateRomMappingFromRomByteSource(romByteSource, romMapMode, romSpeed); return(PopulateFrom(data, mapping)); }
public int ConvertSnesToPc(int address) => RomUtil.ConvertSnesToPc(address, Data.RomMapMode, GetRomSize());
private void RegenerateSampleOutput() { var result = RomUtil.GetSampleAssemblyOutput(settings); textSample.Text = result.OutputStr; }
private int ConvertSnesToPc(int modDataSnesAddress) { // PERF: could use Data.ConvertSnesToPc(), but, by caching the two variables here, // we can save some locking and maybe speed things up. return(RomUtil.ConvertSnesToPc(modDataSnesAddress, romMapModeCached, romSizeCached)); }
private void table_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) { var row = e.RowIndex + ViewOffset; if (row >= Project.Data.GetRomSize()) { return; } switch (e.ColumnIndex) { case 0: e.Value = Project.Data.Labels.GetLabelName(Project.Data.ConvertPCtoSnes(row)); break; case 1: e.Value = Util.NumberToBaseString(Project.Data.ConvertPCtoSnes(row), Util.NumberBase.Hexadecimal, 6); break; case 2: e.Value = (char)Project.Data.GetRomByte(row); break; case 3: e.Value = Util.NumberToBaseString(Project.Data.GetRomByte(row) ?? 0x0, displayBase); break; case 4: e.Value = RomUtil.PointToString(Project.Data.GetSnesApi().GetInOutPoint(row)); break; case 5: var len = Project.Data.GetSnesApi().GetInstructionLength(row); e.Value = row + len <= Project.Data.GetRomSize() ? Project.Data.GetSnesApi().GetInstruction(row) : ""; break; case 6: var ia = Project.Data.GetSnesApi().GetIntermediateAddressOrPointer(row); e.Value = ia >= 0 ? Util.NumberToBaseString(ia, Util.NumberBase.Hexadecimal, 6) : ""; break; case 7: e.Value = Util.GetEnumDescription(Project.Data.GetSnesApi().GetFlag(row)); break; case 8: e.Value = Util.NumberToBaseString(Project.Data.GetSnesApi().GetDataBank(row), Util.NumberBase.Hexadecimal, 2); break; case 9: e.Value = Util.NumberToBaseString(Project.Data.GetSnesApi().GetDirectPage(row), Util.NumberBase.Hexadecimal, 4); break; case 10: e.Value = RomUtil.BoolToSize(Project.Data.GetSnesApi().GetMFlag(row)); break; case 11: e.Value = RomUtil.BoolToSize(Project.Data.GetSnesApi().GetXFlag(row)); break; case 12: e.Value = Project.Data.GetCommentText(Project.Data.ConvertPCtoSnes(row)); break; } }
public int ConvertPCtoSnes(int offset) { return(RomUtil.ConvertPCtoSnes(offset, RomMapMode, RomSpeed)); }
public int ConvertPCtoSnes(int offset) => RomUtil.ConvertPCtoSnes(offset, Data.RomMapMode, Data.RomSpeed);
public static Data PopulateFrom(this Data data, IReadOnlyCollection <byte> actualRomBytes, RomMapMode romMapMode, RomSpeed romSpeed) { var mapping = RomUtil.CreateRomMappingFromRomRawBytes(actualRomBytes, romMapMode, romSpeed); return(PopulateFrom(data, mapping)); }
private Dictionary <int, Label> GenerateVectorLabels() => RomUtil.GenerateVectorLabels( VectorTableEntriesEnabled, RomSettingsOffset, ImportSettings.RomBytes, ImportSettings.RomMapMode);
public int GetBankSize() => RomUtil.GetBankSize(Data.RomMapMode);
public int GetBankSize() { return(RomUtil.GetBankSize(RomMapMode)); }
public void PaintCell(int offset, DataGridViewCellStyle style, int column_index, int selOffset, DataGridViewCellPaintingEventArgs cell) { // editable cells show up green string column = ColumnName(column_index); if (column == "label" || column == "base" || column == "db" || column == "dp" || column == "ia" || column == "comment") { style.SelectionBackColor = Color.Chartreuse; } bool diff = Project.Data.GetLabelName(Project.Data.ConvertPCtoSnes(offset)) == "" && (offset > 0 && Project.Data.GetFlag(offset - 1) == Project.Data.GetFlag(offset)); Data.InOutPoint point = Project.Data.GetInOutPoint(offset); Data.FlagType flag = Project.Data.GetFlag(offset); Data.ConstantType constant = Project.Data.GetConstantType(offset); switch (flag) { case Data.FlagType.Unreached: style.BackColor = Color.LightGray; style.ForeColor = Color.DarkSlateGray; break; case Data.FlagType.Opcode: int opcode = Project.Data.GetRomByte(offset); switch (column) { case "points": int r = 255, g = 255, b = 255; if ((point & (Data.InOutPoint.EndPoint | Data.InOutPoint.OutPoint)) != 0) { g -= 50; } if ((point & (Data.InOutPoint.InPoint)) != 0) { r -= 50; } if ((point & (Data.InOutPoint.ReadPoint)) != 0) { b -= 50; } style.BackColor = Color.FromArgb(r, g, b); break; case "instruction": 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 ) { style.BackColor = Color.Yellow; } if (constant != Data.ConstantType.Hexadecimal) { style.BackColor = Color.FromArgb(50 - (int)constant, 100 - (int)constant, 255 - ((int)constant * 20)); style.ForeColor = Color.White; } break; case "db": if (opcode == 0xAB || opcode == 0x44 || opcode == 0x54) // PLB MVP MVN { style.BackColor = Color.OrangeRed; } else if (opcode == 0x8B) // PHB { style.BackColor = Color.Yellow; } break; case "dp": if (opcode == 0x2B || opcode == 0x5B) // PLD TCD { style.BackColor = Color.OrangeRed; } if (opcode == 0x0B || opcode == 0x7B) // PHD TDC { style.BackColor = Color.Yellow; } break; case "m": case "x": int mask = column == "m" ? 0x20 : 0x10; if (opcode == 0x28 || ((opcode == 0xC2 || opcode == 0xE2) && // PLP SEP REP (Project.Data.GetRomByte(offset + 1) & mask) != 0)) // relevant bit set { style.BackColor = Color.OrangeRed; } if (opcode == 0x08) // PHP { style.BackColor = Color.Yellow; } break; } switch (opcode) { case 0x4C: case 0x5C: case 0x6C: case 0x7C: case 0xDC: style.BackColor = Color.WhiteSmoke; break; case 0x60: case 0x6B: style.BackColor = Color.LightGreen; break; } break; case Data.FlagType.Operand: style.ForeColor = Color.LightGray; break; case Data.FlagType.Graphics: style.BackColor = Color.LightPink; break; case Data.FlagType.Music: style.BackColor = Color.PowderBlue; break; case Data.FlagType.Data8Bit: case Data.FlagType.Data16Bit: case Data.FlagType.Data24Bit: case Data.FlagType.Data32Bit: style.BackColor = Color.NavajoWhite; if (column == "ia" && Project.Data.GetConstantType(offset) == Data.ConstantType.Color && (point & Data.InOutPoint.ReadPoint) > 0) { if (flag == Data.FlagType.Data16Bit) { style.BackColor = Util.ColorRGB555(Project.Data.GetRomWord(offset)); } else if (flag == Data.FlagType.Data24Bit) { style.BackColor = Color.FromArgb(Project.Data.GetRomByte(offset + 2), Project.Data.GetRomByte(offset + 1), Project.Data.GetRomByte(offset)); } } if (RomUtil.GetByteLengthForFlag(flag) > 1 && (point & Data.InOutPoint.ReadPoint) == 0) { style.ForeColor = Color.DarkGray; } break; case Data.FlagType.Pointer16Bit: case Data.FlagType.Pointer24Bit: case Data.FlagType.Pointer32Bit: style.BackColor = Color.Orchid; if ((point & (Data.InOutPoint.ReadPoint | Data.InOutPoint.EndPoint)) == 0) { style.ForeColor = Color.DarkMagenta; } break; case Data.FlagType.Text: style.BackColor = Color.Aquamarine; if (diff) { style.ForeColor = Color.DarkGray; } break; case Data.FlagType.Empty: style.BackColor = Color.DarkSlateGray; style.ForeColor = Color.LightGray; break; case Data.FlagType.Binary: style.BackColor = Color.Aqua; break; } int ia = Project.Data.ConvertSnesToPc(Project.Data.GetIntermediateAddressOrPointer(offset)); int sia = Project.Data.ConvertSnesToPc(Project.Data.GetIntermediateAddressOrPointer(selOffset)); if (selOffset >= 0 && selOffset < Project.Data.GetRomSize()) { if ((column == "pc" && sia >= 0 && sia == offset) || (column == "ia" && ia >= 0 && ia == selOffset)) { style.BackColor = Color.DeepPink; } } switch (column) { case "label": style.ForeColor = Project.Data.GetLabelName(Project.Data.ConvertPCtoSnes(offset)) == "" ? Color.LightGray : style.ForeColor; break; case "base": style.ForeColor = Project.Data.GetBaseAddr(offset) > 0 /*&& Project.Data.GetFlag(offset) != Data.FlagType.Operand*/ ? Color.DarkBlue : Color.LightGray; break; case "ia": if (Project.Data.GetIndirectAddr(offset) > 0 /*&& Project.Data.GetFlag(offset) != Data.FlagType.Operand*/) { style.ForeColor = Color.Red; } break; case "constant": if (constant != Data.ConstantType.Hexadecimal) { style.BackColor = Color.FromArgb(50 - (int)constant, 100 - (int)constant, 255 - ((int)constant * 20)); style.ForeColor = Color.White; } break; case "comment": if (Project.Data.GetComment(Project.Data.ConvertPCtoSnes(offset)) == "") { style.ForeColor = Color.LightGray; } break; } cell.PaintBackground(cell.CellBounds, true); if (sia >= 0) { if (column == "pc" && ((sia > selOffset && offset < sia && offset > selOffset) || (sia < selOffset && offset > sia && offset <= selOffset))) { cell.Graphics.DrawLine(new Pen(Color.DeepPink, 2F), cell.CellBounds.Right - 2, cell.CellBounds.Top, cell.CellBounds.Right - 2, cell.CellBounds.Bottom); } if (((sia >= 0 && selOffset == offset - 1) || (ia >= 0 && ia == offset)) && column_index > ColumnIndex("pc") && column_index <= ColumnIndex("ia")) { cell.Graphics.DrawLine(Pens.DeepPink, cell.CellBounds.Left, cell.CellBounds.Top, cell.CellBounds.Right, cell.CellBounds.Top); } } cell.Paint(cell.ClipBounds, DataGridViewPaintParts.ContentForeground); cell.Handled = true; }