// verify the data in the provided ROM bytes matches the data we expect it to have. // returns error message if it's not identical, or null if everything is OK. public static string IsThisRomIsIdenticalToUs(byte[] rom, RomMapMode mode, string requiredGameNameMatch, int requiredRomChecksumMatch) { var romSettingsOffset = GetRomSettingOffset(mode); if (rom.Length <= romSettingsOffset + 10) { return("The linked ROM is too small. It can't be opened."); } var internalGameNameToVerify = GetRomTitleName(rom, romSettingsOffset); var checksumToVerify = ByteUtil.ByteArrayToInt32(rom, romSettingsOffset + 7); if (internalGameNameToVerify != requiredGameNameMatch) { return($"The linked ROM's internal name '{internalGameNameToVerify}' doesn't " + $"match the project's internal name of '{requiredGameNameMatch}'."); } if (checksumToVerify != requiredRomChecksumMatch) { return($"The linked ROM's checksums '{checksumToVerify:X8}' " + $"don't match the project's checksums of '{requiredRomChecksumMatch:X8}'."); } return(null); }
public BsnesTraceLogImporter(Data data) { this.data = data; romSizeCached = data.GetRomSize(); romMapModeCached = data.RomMapMode; InitStats(); InitObjectPool(); }
public BsnesTraceLogImporter(Data data) { this.data = data; romSizeCached = data?.GetRomSize() ?? 0; romMapModeCached = data?.RomMapMode ?? default; InitStats(); InitObjectPool(); }
public void TestRomDetectionFastRom() { var analyzer = new SnesRomAnalyzer(); analyzer.Analyze(CartNameData.ExampleHiRomFile); analyzer.Filename.Should().Be(CartNameData.ExampleHiRomFile); analyzer.AnalysisResults!.RomMapMode.Should().Be(RomMapMode.HiRom); analyzer.AnalysisResults.RomSpeed.Should().Be(RomSpeed.FastRom); analyzer.RomBytes.Should().HaveCount(0x400000); analyzer.RomSettingsOffset.Should().Be(RomUtil.HiromSettingOffset); }
public static Data InitializeEmptyRomMapping(this Data data, int size, RomMapMode mode, RomSpeed speed) { var romByteSource = new ByteSource { Bytes = new StorageList <ByteEntry>(size), Name = "Snes ROM" }; PopulateFromRom(data, romByteSource, mode, speed); return(data); }
internal static bool goodchecksum(IList <byte> romdata, RomMapMode mode, int size) { int snestopc(int snesAddress) => RomUtil.ConvertSnesToPc(snesAddress, mode, size); var checksum = (int)getchecksum(romdata); return(((romdata[snestopc(0x00FFDE)] ^ romdata[snestopc(0x00FFDC)]) == 0xFF) && ((romdata[snestopc(0x00FFDF)] ^ romdata[snestopc(0x00FFDD)]) == 0xFF) && ((romdata[snestopc(0x00FFDE)] & 0xFF) == (checksum & 0xFF)) && ((romdata[snestopc(0x00FFDF)] & 0xFF) == ((checksum >> 8) & 0xFF))); }
internal static void fixchecksum(IList <byte> romdata, RomMapMode mode, int size) { int snestopc(int snesAddress) => RomUtil.ConvertSnesToPc(snesAddress, mode, size); // randomdude999: clear out checksum bytes before recalculating checksum, this should make it correct on roms that don't have a checksum yet romdata.writeromdata(snestopc(0x00FFDC), 0xFFFF0000); var checksum = getchecksum(romdata); romdata.writeromdata_byte(snestopc(0x00FFDE), (byte)(checksum & 255)); romdata.writeromdata_byte(snestopc(0x00FFDF), (byte)((checksum >> 8) & 255)); romdata.writeromdata_byte(snestopc(0x00FFDC), (byte)((checksum & 255) ^ 255)); romdata.writeromdata_byte(snestopc(0x00FFDD), (byte)(((checksum >> 8) & 255) ^ 255)); }
public static int ConvertPCtoSnes(int offset, RomMapMode romMapMode, RomSpeed romSpeed) { switch (romMapMode) { case RomMapMode.LoRom: offset = ((offset & 0x3F8000) << 1) | 0x8000 | (offset & 0x7FFF); if (romSpeed == RomSpeed.FastRom || offset >= 0x7E0000) { offset |= 0x800000; } return(offset); case RomMapMode.HiRom: offset |= 0x400000; if (romSpeed == RomSpeed.FastRom || offset >= 0x7E0000) { offset |= 0x800000; } return(offset); case RomMapMode.ExHiRom when offset < 0x40000: offset |= 0xC00000; return(offset); case RomMapMode.ExHiRom: if (offset >= 0x7E0000) { offset &= 0x3FFFFF; } return(offset); case RomMapMode.ExSa1Rom when offset >= 0x400000: offset += 0x800000; return(offset); } offset = ((offset & 0x3F8000) << 1) | 0x8000 | (offset & 0x7FFF); if (offset >= 0x400000) { offset += 0x400000; } return(offset); }
public static int ConvertSnesToPc(int address, RomMapMode mode, int size) { if (address < 0) { return(-1); } int UnmirroredOffset(int offset) => RomUtil.UnmirroredOffset(offset, size); // WRAM is N/A to PC addressing if ((address & 0xFE0000) == 0x7E0000) { return(-1); } // WRAM mirror & PPU regs are N/A to PC addressing if (((address & 0x400000) == 0) && ((address & 0x8000) == 0)) { return(-1); } switch (mode) { case RomMapMode.LoRom: { // SRAM is N/A to PC addressing if (((address & 0x700000) == 0x700000) && ((address & 0x8000) == 0)) { return(-1); } return(UnmirroredOffset(((address & 0x7F0000) >> 1) | (address & 0x7FFF))); } case RomMapMode.HiRom: { return(UnmirroredOffset(address & 0x3FFFFF)); } case RomMapMode.SuperMmc: { return(UnmirroredOffset(address & 0x3FFFFF)); // todo, treated as hirom atm } case RomMapMode.Sa1Rom: case RomMapMode.ExSa1Rom: { // BW-RAM is N/A to PC addressing if (address >= 0x400000 && address <= 0x7FFFFF) { return(-1); } if (address >= 0xC00000) { return(mode == RomMapMode.ExSa1Rom ? UnmirroredOffset(address & 0x7FFFFF) : UnmirroredOffset(address & 0x3FFFFF)); } if (address >= 0x800000) { address -= 0x400000; } // SRAM is N/A to PC addressing if (((address & 0x8000) == 0)) { return(-1); } return(UnmirroredOffset(((address & 0x7F0000) >> 1) | (address & 0x7FFF))); } case RomMapMode.SuperFx: { // BW-RAM is N/A to PC addressing if (address >= 0x600000 && address <= 0x7FFFFF) { return(-1); } if (address < 0x400000) { return(UnmirroredOffset(((address & 0x7F0000) >> 1) | (address & 0x7FFF))); } if (address < 0x600000) { return(UnmirroredOffset(address & 0x3FFFFF)); } if (address < 0xC00000) { return(0x200000 + UnmirroredOffset(((address & 0x7F0000) >> 1) | (address & 0x7FFF))); } return(0x400000 + UnmirroredOffset(address & 0x3FFFFF)); } case RomMapMode.ExHiRom: { return(UnmirroredOffset(((~address & 0x800000) >> 1) | (address & 0x3FFFFF))); } case RomMapMode.ExLoRom: { // SRAM is N/A to PC addressing if (((address & 0x700000) == 0x700000) && ((address & 0x8000) == 0)) { return(-1); } return(UnmirroredOffset((((address ^ 0x800000) & 0xFF0000) >> 1) | (address & 0x7FFF))); } default: { return(-1); } } }
public static int GetBankSize(RomMapMode mode) { // todo return(mode == RomMapMode.LoRom ? 0x8000 : 0x10000); }
public static int ConvertSnesToPc(int address, RomMapMode mode, int size) { var index = ConvertSnesToPcRaw(address, mode, size); return(index < 0 ? -1 : index); }
public static RomSpeed GetRomSpeed(RomMapMode mode, IReadOnlyList <byte> romBytes) => GetRomSpeed(GetRomSettingOffset(mode), romBytes);
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)); }
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 static void UpdateRomChecksum(IList <byte> romdata, RomMapMode mode, int size) => AsarChecksumUtil.fixchecksum(romdata, mode, size);
public static bool IsRomChecksumValid(IList <byte> romdata, RomMapMode mode, int size) => AsarChecksumUtil.goodchecksum(romdata, mode, size);