Skip to content

Instantly share code, notes, and snippets.

@anpage
Last active October 8, 2017 10:32
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anpage/c1085055db0242ea3c7558dab56712a5 to your computer and use it in GitHub Desktop.
Save anpage/c1085055db0242ea3c7558dab56712a5 to your computer and use it in GitHub Desktop.
Description of the headers used in the SNES Classic ROM files (.sfrom)

Header

Start Size Description Notes
0x00 0x4 0x00000100
0x04 0x4 File size Includes the header and footer
0x08 0x4 Location of ROM Always 0x00000030 in official files
0x0C 0x4 Location of PCM samples Comes after end of ROM in official files
0x10 0x4 Location of PCM footer Equals file size if PCM data missing
0x14 0x4 Location of footer (below) Same as New 3DS's SNES VC header starting from 0x30
0x18 0x4 Location of S-DD1 data offset Footer location + 0x2C
0x1C 0x4 0x00000000
0x20 0x4 Unknown Footer location + 0x1B. Some kind of a flag?
0x24 0x8 Wii U Virtual Console Game ID WUP-J**X, X — title region (E = USA, J = Japan, P = EUR)
0x2C 0x4 0x00000000

Footer

Start Size Description Notes
0x00 0x1 Emulation speed in FPS 0x3C == 60
0x01 0x4 ROM Size
0x05 0x4 Size of PCM samples 0 if missing
0x09 0x4 Size of PCM footer 0 if missing
0x0D 0x2 Game preset ID Varies between games
0x0F 0x1 # of players? Usually 0x02. Setting to 0x0 disables the second controller
0x10 0x1 Sound volume
0x11 0x1 ROM Type 0x15 for HiROM and 0x14 for LoROM
0x12 0x1 Super-FX flag? 0x0C if the game uses SFX Chip, 0x00 otherwise
0x13 0x7 0x00000000000000
0x1A 0x4? Unknown Usually 0x00000100
0x1E 0x4? Unknown Always 0x00000100
@anpage
Copy link
Author

anpage commented Oct 2, 2017

Taken from this pastebin from @Cluster_M, cleaned up with my own findings added in.

The pastebin was originally written by pcm720 on the GBAtemp forums.

@pcm720
Copy link

pcm720 commented Oct 2, 2017

By the way, I think that you got header offsets 0x20 and 0x18 mixed up.
Header offset 0x20 in SFROM always points to footer offset 0x1B, not 0x18.
If there is some pointer for S-DD1 data, it's probably header offset 0x18 since it always points to the end of file.

@anpage
Copy link
Author

anpage commented Oct 3, 2017

That's entirely possible. I kept getting two of them mixed up in my own notes and it was probably those two. I'll double check when I get the chance.

@pcm720
Copy link

pcm720 commented Oct 3, 2017

Okay, can confirm.

Take a look at Street Fighter Alpha 2 from Wii U VC (it uses the S-DD1 chip):
Header:
0x000000: 00 01 00 00 B2 6F A7 00 30 00 00 00 30 00 40 00
0x000010: 10 EE 5B 00 50 F0 5B 00 70 F0 5B 00 00 00 00 00
0x000020: 63 F0 5B 00 57 55 50 2D 4A 43 47 45 00 00 00 00

Footer:
0x5BF050: 3C 00 00 40 00 E0 ED 1B 00 40 02 00 00 DF 10 02
0x5BF060: A5 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00
0x5BF070: 80 F0 5B 00 00 00 00 00 00 00 00 00 00 00 00 00

Header offset 0x20 points to footer offset 0x13, and 0x18 points to footer offset 0x20.
At 0x5BF080, there's some kind of ROM data, 0x4B7F40 bytes in size. I'm pretty sure that this is data for the S-DD1.
So, it looks like 0x20 points to footer offset 0x20 that contains the location of S-DD1 data.

By the way, this ROM doesn't work on SNES Mini.

@anpage
Copy link
Author

anpage commented Oct 3, 2017

You're totally correct. I've updated the table. It's interesting that it has the first 0x01 byte at 0x13 in the footer, whereas every SNEC-C ROM I've examined so far has it at 0x1B. I wonder what they're even for.

Something interesting to note is that Super Mario RPG has this:

Header

          00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0x000000: 00 01 00 00 C0 81 4D 00 30 00 00 00 30 00 40 00
0x000010: 70 74 4D 00 84 81 4D 00 B0 81 4D 00 00 00 00 00
0x000020: 9F 81 4D 00 57 55 50 2D 4A 41 42 45 00 00 00 00

Footer

          00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0x4D8180: XX XX XX XX 3C 00 00 40 00 40 74 0D 00 14 0D 00
0x4D8190: 00 9C 10 02 32 14 00 00 00 00 00 00 00 00 00 01
0x4D81A0: 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00
0x4D81B0: C0 81 4D 00 00 00 00 00 00 00 00 00 00 00 00 00

The file is 0x4D81C0 bytes long, so that address in 0x4D81B0 is just the EOF. Also, this offset is located at footer + 0x2C rather than footer + 0x20 like in your example.

@pcm720
Copy link

pcm720 commented Oct 3, 2017

Who knows...
The footer structure is very inconsistent. That value at 0x4D81B0 does nothing, the game will boot anyway.
You can even set 0x18 to C0 81 4D and 0x4D81B0 to 00 00 00, and there will be no difference.

I wish we'd know more about their preset IDs. I had no luck with S-DD1, and SA1 is really weird.
Some games work with one preset, some games work with other, some display garbled graphics, and some refuse to boot at all...

@anpage
Copy link
Author

anpage commented Oct 3, 2017

Another thing I just noticed is that the ROM type at 0x11 in your SF2A footer is 0x00

@anpage
Copy link
Author

anpage commented Oct 3, 2017

I set 0x18 and 0x20 to 0x0 in the header and everything but ROM size and type in the footer to 0x0 for Super Mario All-Stars and it still works. It doesn't seem like the emulator cares about a lot of these values.

@anpage
Copy link
Author

anpage commented Oct 3, 2017

It looks like using this header with a combined footer (like the 3DS VC) works just fine for Super Mario All-Stars. If this format works for all ROMs, it would greatly simplify my conversion script.

      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0x00: 00 01 00 00 60 00 28 00 50 00 00 00 00 00 00 00
0x10: 00 00 00 00 30 00 00 00 00 00 00 00 00 00 00 00
0x20: 00 00 00 00 57 55 50 2D 4A 44 49 45 00 00 00 00
0x30: 00 00 00 28 00 00 00 00 00 00 00 00 00 00 00 00
0x40: 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00

EDIT: Confirmed working with Final Fantasy Mystic Quest as well.
Mega Man X2 works with this header and a preset ID of 0x113D, except there's graphical corruption whenever the Cx4 chip is used.
The preset ID 0x1117 (MMX2 on Wii U VC) works fine.

@pcm720
Copy link

pcm720 commented Oct 4, 2017

That's interesting. I can't see any reason why it won't work since we directly point emulator to a footer.

So, preset IDs are incompatible? That's very disappointing. It looks like they rely on emulation profiles instead of emulating the SNES properly...
At least DSP-1 and SuperFX games work fine with a single preset ID (or do they?)

@codex785
Copy link

codex785 commented Oct 8, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment