Example #1
0
        // 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);
        }
Example #2
0
        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);
        }
Example #6
0
            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)));
            }
Example #7
0
            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));
            }
Example #8
0
        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);
        }
Example #9
0
        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);
            }
            }
        }
Example #10
0
 public static int GetBankSize(RomMapMode mode)
 {
     // todo
     return(mode == RomMapMode.LoRom ? 0x8000 : 0x10000);
 }
Example #11
0
        public static int ConvertSnesToPc(int address, RomMapMode mode, int size)
        {
            var index = ConvertSnesToPcRaw(address, mode, size);

            return(index < 0 ? -1 : index);
        }
Example #12
0
 public static RomSpeed GetRomSpeed(RomMapMode mode, IReadOnlyList <byte> romBytes) =>
 GetRomSpeed(GetRomSettingOffset(mode), romBytes);
Example #13
0
        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));
        }
Example #14
0
        public static Data PopulateFromRom(this Data data, ByteSource romByteSource, RomMapMode romMapMode, RomSpeed romSpeed)
        {
            var mapping = RomUtil.CreateRomMappingFromRomByteSource(romByteSource, romMapMode, romSpeed);

            return(PopulateFrom(data, mapping));
        }
Example #15
0
 public static void UpdateRomChecksum(IList <byte> romdata, RomMapMode mode, int size) =>
 AsarChecksumUtil.fixchecksum(romdata, mode, size);
Example #16
0
 public static bool IsRomChecksumValid(IList <byte> romdata, RomMapMode mode, int size) =>
 AsarChecksumUtil.goodchecksum(romdata, mode, size);