Classroom Public page

Lab 5.2: Boot a SNES ROM in bsnes-plus and Locate the Header

893 words

~90 minutes. Download a SNES homebrew ROM; boot it in bsnes-plus; locate the SNES header (LoROM or HiROM); decode the key fields.


Goal: complete the third-platform tour. The SNES adds complexity (two possible header locations); your job is to find which one your ROM uses.

Estimated time: 90 minutes

Prerequisites: bsnes-plus installed; week 5 lecture and lab 5.1 complete

Steps

Step 1: Download a SNES homebrew ROM (20 minutes)

Visit one of:

  • https://itch.io/games/tag-snes (filter to free / homebrew)
  • https://www.snesdev.com/ (community resource)
  • https://nesdev.org/snesdev (some entries link from NESdev as crossover content)

Pick a small SNES homebrew ROM. Save to ~/spk-101/roms/snes/. The file extension should be .sfc (Super Famicom; the technically-correct extension) or .smc (Super Nintendo; older convention used by some dumpers; sometimes has an extra 512-byte SMC header that throws off offsets, see step 5 if so).

Step 2: Boot the ROM in bsnes-plus (15 minutes)

Launch bsnes-plus. File → Load Cartridge → Super Famicom (or "Load ROM", UI varies slightly). Load your downloaded ROM. The game should boot.

Play for ~5 minutes. Take a screenshot.

Step 3: Find the header (LoROM vs HiROM) (20 minutes)

The SNES header is 32 bytes long but lives at ONE of two possible offsets, depending on the ROM's memory-mapping scheme:

  • LoROM: header at offset 0x7FB0 (immediately after the 32-KB region used for low memory)
  • HiROM: header at offset 0xFFB0 (immediately after the 64-KB region used for high memory)

You need to figure out which one your ROM uses. Two ways:

Way A: read the cart-type byte at each location. Open the ROM in your hex editor.

  • Check byte 0x7FD5 (the LoROM "Map mode" byte). If it equals 0x20 or 0x30, your ROM is LoROM
  • Check byte 0xFFD5 (the HiROM "Map mode" byte). If it equals 0x21 or 0x31, your ROM is HiROM

The one that matches is your ROM's header location.

Way B: scan both candidate locations for readable text. SNES headers contain a 21-byte game title in ASCII. The location where you can read recognizable text is the actual header.

Write down: "My ROM is ___ (LoROM / HiROM). The header lives at offset 0x____."

Step 4: Decode the header fields (25 minutes)

Once you have located the header, decode its fields. The 32-byte SNES header layout (starting at the offset you found):

Offset within header Length Field Meaning
0x00 21 Game title ASCII, space-padded
0x15 1 Map mode 0x20 = LoROM, 0x21 = HiROM, 0x30 = FastROM LoROM, 0x31 = FastROM HiROM
0x16 1 Cart type 0x00 = ROM only; 0x01 = ROM + RAM; 0x02 = ROM + RAM + battery; higher values for special chips like SA-1, DSP-1, SuperFX
0x17 1 ROM size 0x09 = 4 Mbit; 0x0A = 8 Mbit; 0x0B = 16 Mbit; etc. (encoded as log2 of size in KB)
0x18 1 RAM size 0x00 = none; 0x03 = 8 KB; 0x04 = 16 KB; etc.
0x19 1 Destination code 0x00 = Japan; 0x01 = North America; 0x02 = Europe; etc.
0x1A 1 Old licensee (Pre-1996) publisher code
0x1B 1 Mask ROM version Usually 0x00
0x1C 2 Inverted checksum The 16-bit complement of the global checksum
0x1E 2 Checksum A 16-bit sum of all bytes in the ROM (modulo 16 bits)

Walk through each field. Write down values.

Step 5: SMC header check (5 minutes)

Some SNES dumps have an extra 512-byte SMC header prefix before the actual ROM content. This is a copier-tool artifact, not part of the game. If your ROM file size is exactly 512 bytes larger than a power-of-2 (e.g., 4 MB + 512 bytes), you might have an SMC header.

To check: open your ROM in your hex editor. Look at the first 16 bytes. If they look like 16 zero bytes or have an obvious "header-y" structure, you have an SMC header. In that case, your offset calculations from step 4 need to be shifted by +512 (so LoROM is at 0x7FB0 + 0x200 = 0x81B0).

Most modern SNES homebrew releases do NOT have SMC headers. If your byte at 0x7FD5 or 0xFFD5 matches an expected map-mode value, you do not have an SMC header.

Step 6: Journal (10 minutes)

Open ~/spk-101/journal/lab-5-2-notes.md. Write:

  • The ROM you used (title, source)
  • LoROM or HiROM (and how you determined it)
  • Each header field's value
  • A reflection: the SNES designers gave themselves TWO header locations. Why? What is the engineering trade-off they were making?

Expected output

  • SNES homebrew ROM bootable in bsnes-plus
  • Confirmed LoROM or HiROM
  • Decoded SNES header (all 10 main fields)
  • Journal entry

Common pitfalls

  • Picking the wrong header location: if the bytes at 0x7FD5 and 0xFFD5 BOTH look plausible, decode both and see which one makes sense (e.g., which one has a readable title)
  • SMC header throwing off offsets: see step 5
  • Mistaking RAM size for ROM size: bytes 0x17 and 0x18 of the header are both sizes; one is ROM, one is RAM. Do not confuse them
  • bsnes-plus doesn't load some old SNES ROMs cleanly: try a different SNES homebrew. Modern homebrew is well-tested; older dumps sometimes have format issues

Stretch (optional)

  • Find both a LoROM and a HiROM example in your collection. Compare the headers
  • Modify the ASCII title byte. Stay within 21 characters. Reload in bsnes-plus. See if the title appears anywhere in the game's display
  • Read the SNES technical reference at https://wiki.superfamicom.org/internal-rom-header for the full header field list, including the interrupt vectors at 0x1F-0x2F

Lab 5.2 v0.1. The complete tour: NES → Game Boy → SNES. Same skills; three different chips.