Non-power-of-two ROM size

From NESdev Wiki
Revision as of 15:01, 23 June 2021 by Tepples (talk | contribs) (Canonical doubling algorithm)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Because of the cost of soldering multiple DIP chips to a board, it wasn't common to have more than one PRG ROM or more than one CHR ROM on an NES cartridge board. RTROM and STROM have two 8 KiB PRG ROMs, SMROM has two 128 KiB PRG ROMs, and Sunsoft-4 as used in After Burner has two 128 KiB CHR ROMs. Even then, because there were almost always two ROMs of the same size on the PRG or CHR side, the PRG ROM size and the CHR ROM size were each almost always a power of two. The most notable exception on NES is Action 52, which has four footprints for 512Kx8 (4 Mbit) PRG ROMs, of which three are populated totaling 12 Mbit (1.5 MiB).

Non-power-of-two ROM size became more common in the 16-bit era, when games contained only a PRG ROM. Games of size 10, 12, 20, 24, and 48 Mbit (1.25, 1.5, 2.5, 3, and 6 MiB) exist. In the memory space, the larger ROM is at a lower address, and the smaller ROM is mirrored to appear as large as the larger ROM. A 12 Mbit ROM usually shows up as one copy of the first 8 Mbit and two copies of the last 4 Mbit (ABCC). A 20 Mbit ROM is one copy of the first 16 Mbit and four copies of the last 4 Mbit (ABCDEEEE). This interpretation matches the checksum values in Super NES ROMs' internal header.

The following doubling algorithm should produce reasonable results for most ROMs with non-power-of-two sizes:

While ROM size is not a power of two:
    Find the place value of the least significant 1 bit in ROM size
    Double up that many bytes at the end

For example, 10 Mbit is 1310720 ($140000) bytes. Doubling the last $40000 bytes produces 12 Mbit, or 1572864 ($180000) bytes. Further doubling the last $80000 bytes of this produces 16 Mbit, or 2097152 ($200000) bytes.

For Action 52, this produces reasonable results from an emulation perspective. Though ROM slots 0, 1, and 3 are populated on the actual board (ABxC), this algorithm additionally populates slot 2 with a copy of slot 3's data (ABCC).