public override void CalculateHashes(byte[] rom, IHashWorkManager worker, float startProgress, float endProgress) { iNesHeader header = null; if (rom.Length > 0x10) { header = new iNesHeader(rom, 0); } if (SNES.HasExternalHeader(rom)) // Headered { worker.AddHashes(rom, 0, rom.Length, () => worker.AbortPending, RomHash.AllHashAlgorithms, HashFlags.FileHash); // Calculate headerless hashes int ROMSize = rom.Length - SNES.ExternalHeaderSize; ROMSize = Math.Min(ROMSize, rom.Length - SNES.ExternalHeaderSize); worker.AddHashes(rom, SNES.ExternalHeaderSize, ROMSize, () => worker.AbortPending, RomHash.AllHashAlgorithms, HashFlags.RomHash); } else { // Unheadered (file hash IS rom hash) worker.AddHashes(rom, 0, rom.Length, () => worker.AbortPending, RomHash.AllHashAlgorithms, HashFlags.FileHash, HashFlags.RomHash); } }
public override bool IsPlatformMatch(byte[] rom) { if (rom.Length < 0x2000) { return(false); } if (rom.Length < 4200000 && rom.Length >= 0x8000) // Too slow for massive ROMS { var checksum = SNES.CalculateChecksum(rom); if (checksum != 0 && checksum == SNES.GetInternalChecksum(rom)) { return(true); } } if (SNES.HasGoodSmcHeader(rom)) { return(true); } if (SNES.HasGoodSwcHeader(rom)) { return(true); } return(false); }
internal override void InitRomData(RomData data, byte[] rom) { base.InitRomData(data, rom); int romOffset = SNES.HasExternalHeader(rom) ? SNES.ExternalHeaderSize : 0; if (rom.Length - romOffset >= SnesHeader.MinimumRomSize) { SnesHeader snesheader = new SnesHeader(rom, romOffset); data.MiscData.Add(DataTags.DecodedHeader, snesheader); } }
protected override void AddPlatformExtendedData(RomExDataBuilder builder, byte[] rom, RomData data) { var checksum = SNES.CalculateChecksum(rom); int romOffset = SNES.HasExternalHeader(rom) ? SNES.ExternalHeaderSize : 0; string header = RomExDataBuilder.HeaderCat; object o_snesheader; SnesHeader snesheader; if (data.MiscData.TryGetValue(DataTags.DecodedHeader, out o_snesheader)) { //if (snesheader != null) { snesheader = o_snesheader as SnesHeader; builder.AddData(RomExDataBuilder.GeneralCat, "Checksum valid", (checksum == snesheader.Checksum) ? "Yes" : "No"); builder.AddData(header, "Mapping", snesheader.Mapping.ToString()); //builder.AddData(header,"Name", GetAscii } }
public static Ram GetLayoutAnnotated() { var ram = new Ram(); // I think this is map layout (when to read a block of sea or something or when to read map data) // see debug log: trying to find water 02 // code start: c04923 // code end: c04a43 // code never hits: c049b3 (does hit when loading cave map) // $ed8a00 - $ed9be2 var layoutSource = Rom.ByteArray(0xed8a00); var output = ram.WordArray(0x7f0000); var outputf3c6 = ram.ByteArray(0x7ff3c6); //c04923 php //c04924 %setAXYto16bit() //c04926 pha //c04927 phx //c04928 phy //c04929 sta $1c //c0492b stx $20 //c0492d stz $18 //c0492f stz $1a //c04931 lda #$03be //c04934 sta $1e //c04936 stz $22 //c04938 ldx #$0000 //c0493b stz $f3c6,x //c0493e inx //c0493f inx //c04940 cpx #$0400 //c04943 bcc $493b //c04945 ldy #$0000 //c04948 tya //c04949 %setAto8bit() // c04929 ushort x18x19 = 0; int x1c = 0x1000; // comes from outside (A) int x1e = 0x03BE; byte x1a = 0; byte x1b = 0; int x20 = 0; // comes from outside (X) byte x22 = 0; // don't have initial values? byte x24 = 0; byte x25 = 0; // $c04945 var y = 0; // A => 8bit // .Branch_c0494b -- top while (true) { //c0494b lsr $19 //c0494d ror $18 x18x19 = (ushort)(x18x19 >> 1); //c0494f lda $19 //c04951 lsr //c04952 bcs .Branch_c0495b if ((x18x19 & 0x0100) == 0) { //c04954 lda [$00],y //c04956 iny //c04957 sta $18 //c04959 dec $19 x18x19 = (ushort)((x18x19 - 0x0100 & 0xff00) + layoutSource[y]); y++; } //.Branch_c0495b //c0495b lda $18 //c0495d lsr //c0495e bcc .Branch_c049b4 if ((x18x19 & 0x0001) != 0) { //c04960 lda $22 //c04962 lsr //c04963 bcs .Branch_c0497e if ((x22 & 0x01) == 0) { //c04965 lda [$00],y //c04967 iny //c04968 sta $24 //c0496a ldx $1e //c0496c sta $f3c6,x x24 = layoutSource[y]; outputf3c6[x1e] = layoutSource[y]; y++; //c0496f inc $1e //c04971 bne .Branch_c0497a //c04973 lda $1f //c04975 inc //c04976 and #$03 //c04978 sta $1f //.Branch_c0497a x1e++; x1e &= 0x03ff; //c0497a inc $22 x22++; //c0497c bra .Branch_c0494b // back to top continue; } //.Branch_c0497e //c0497e lda [$00],y //c04980 iny //c04981 sta $25 //c04983 ldx $1e //c04985 sta $f3c6,x x25 = layoutSource[y]; outputf3c6[x1e] = layoutSource[y]; y++; //c04988 inc $1e //c0498a bne .Branch_c04993 //c0498c lda $1f //c0498e inc //c0498f and #$03 //c04991 sta $1f //.Branch_c04993 //c04993 inc $22 x1e++; x1e &= 0x03ff; x22++; //c04995 rep #$20 // ---------------------------------A => 16bit //c04997 ldx $20 //c04999 lda $24 //c0499b sta $0000,x //c0499e inx //c0499f inx //c049a0 stx $20 output[x20] = (ushort)(x24 + (x25 << 8)); x20 += 2; //c049a2 dec $1c x1c--; //c049a4 beq .Branch_c049ad if (x1c != 0) { //c049a6 lda #$0000 //c049a9 sep #$20 // ---------------------------------A => 8bit //c049ab bra .Branch_c0494b // back to top continue; } else { //.Branch_c049ad //c049ad %setAXYto16bit() //c049af ply //c049b0 plx //c049b1 pla //c049b2 plp //c049b3 rtl return(ram); // EXIT } } //.Branch_c049b4 // carry will be clear //c049b4 lda [$00],y //c049b6 iny //c049b7 sta $1a x1a = layoutSource[y]; y++; //c049b9 lda [$00],y //c049bb rol //c049bc rol //c049bd rol //c049be and #$03 //c049c0 sta $1b x1b = (byte)(layoutSource[y] >> 6 & 0x03); //c049c2 lda [$00],y //c049c4 iny //c049c5 and #$3f //c049c7 clc //c049c8 adc #$03 //c049ca phy //c049cb tay byte counter = (byte)((layoutSource[y] & 0x3f) + 3); y++; //.Branch_c049cc while (true) { //c049cc dey counter--; //c049cd bmi .Branch_c04a3a if (SNES.IsNegative16(counter)) { break; } //c049cf lda $22 //c049d1 lsr //c049d2 bcs .Branch_c049fc if ((x22 & 0x01) == 0) { //c049d4 ldx $1a //c049d6 lda $f3c6,x //c049d9 sta $24 //c049db inc $1a x24 = outputf3c6[x1a]; // TODO: Wrong, needs to be 16bit x1a x1a++; //c049dd bne .Branch_c049e8 if (x1a == 0) { //c049df lda $1b //c049e1 inc //c049e2 and #$03 //c049e4 sta $1b x1b++; x1b &= 0x03; //c049e6 lda $24 } //.Branch_c049e8 //c049e8 ldx $1e //c049ea sta $f3c6,x outputf3c6[x1e] = x24; //c049ed inc $1e //c049ef bne .Branch_c049f8 //c049f1 lda $1f //c049f3 inc //c049f4 and #$03 //c049f6 sta $1f //.Branch_c049f8 x1e++; x1e &= 0x03ff; //c049f8 inc $22 x22++; //c049fa bra .Branch_c049cc } else { //.Branch_c049fc //c049fc ldx $1a //c049fe lda $f3c6,x //c04a01 sta $25 x25 = outputf3c6[x1a]; // TODO: Wrong, needs to be 16bit x1a //c04a03 inc $1a x1a++; //c04a05 bne .Branch_c04a10 if (x1a == 0) { //c04a07 lda $1b //c04a09 inc //c04a0a and #$03 //c04a0c sta $1b x1b++; x1b &= 0x03; //c04a0e lda $25 } //.Branch_c04a10 //c04a10 ldx $1e //c04a12 sta $f3c6,x outputf3c6[x1e] = x25; //c04a15 inc $1e //c04a17 bne .Branch_c04a20 //c04a19 lda $1f //c04a1b inc //c04a1c and #$03 //c04a1e sta $1f //.Branch_c04a20 x1e++; x1e &= 0x03ff; //c04a20 inc $22 x22++; //c04a22 rep #$20 //---------------------------------- A=> 16bit //c04a24 ldx $20 //c04a26 lda $24 //c04a28 sta $0000,x //c04a2b inx //c04a2c inx //c04a2d stx $20 output[x20] = (ushort)(x24 + (x25 << 8)); x20 += 2; //c04a2f dec $1c x1c--; //c04a31 beq .Branch_c04a3e if (x1c == 0) { return(ram); // EXIT } //c04a33 lda #$0000 //c04a36 sep #$20 // ---------------------------------A => 8bit //c04a38 bra .Branch_c049cc } } //.Branch_c04a3a //c04a3a ply //c04a3b jmp Jump_c0494b // back to top } // end of while //.Branch_c04a3e -- EXIT //c04a3e ply //c04a3f ply //c04a40 plx //c04a41 pla //c04a42 plp //c04a43 rtl }
public override bool?HasHeader(byte[] rom) { return(SNES.HasExternalHeader(rom)); }
public override string GetRomFormatName(byte[] rom) { return(SNES.HasExternalHeader(rom) ? "Super Magicom" : "SNES rom image"); }
public override int GetRomSize(byte[] rom) { return(SNES.HasExternalHeader(rom) ? rom.Length - SNES.ExternalHeaderSize : rom.Length); }