Page 1 of 1

[MMC3] Expanding the PRG

Posted: Fri Dec 04, 2009 4:33 pm
by Rid
I'm trying to expand a MMC3 game, and this is what I do :
1) count the number of 16kB PRG bank in the iNES header;
2) increment this number
3) copy the last 16kB PRG bank, and insert it at the offset (nbPRGBank*16*$400) + $10 (iNESHeader).

As the mapper used the two last 8kB PRG bank as fixed, I though my modification would be harmless, but it seems it isn't :s

Does someone knows what is going wrong with my expansion method?

--Edit : more information
Before the mod, the fourth byte into the iNES header was 8. Which means there was 8kB PRG banks. Thus, the PRG went from 0x0010 to 0x2000F.

After the mod, the fourth byte is 9. I made a byte copy from 0x1C010 to 0x2000F and I inserted it at 0x20010, increasing the size of my file of 16kB

Posted: Fri Dec 04, 2009 5:18 pm
by tokumaru
In this recent thread we had proof that the NES doesn't like ROMs with odd sizes. Although the iNES header allows all kinds of ROM sizes, the sizes of actual ROM chips are always powers of 2.

This means that if you want to extend the ROM (CHR or PRG) of a game, you can't just add another bank, you'll have to double it (if the there are 128KB or PRG-ROM, you must add another 128 for a total of 256), because the double is the next power of 2. And of course, you can only do this if the game doesn't already have the maximum size that the mapper allows (IIRC the MMC3 can take up to 512KB or PRG and 256KB of CHR).

When you read about the iNES header and mappers without knowing much about electronics, it sounds really simple, a byte tells how many banks there are. But this is not how the mappers actually work. Having the last bank fixed at the end of the addressing space is a matter of setting the upper bits of the address bus high when the top of the addressing space is accessed, and that only works if the size of the ROM is a power of 2. The mapper doesn't really know how many banks are there. So when you have ROMs that are not powers of 2 you screw up all the mapping.

Although having odd ROM sizes might work in some emulators (each emulator seems to handle this differently), you should remember that you are making a NES program, so you must make your ROM as close to an actual cart as possible, and an actual cart will only take powers of 2.

Posted: Fri Dec 04, 2009 5:36 pm
by tepples
You're more likely to "get away with" an odd-sized ROM for CHR than for PRG because CHR has no requirement for vectors to be in a valid bank.

If you're making an emulator: It's probably safest to treat "missing" banks in an odd-sized iNES ROM as mirrors of the last bank. At least that will get the vectors in the right place.

Posted: Fri Dec 04, 2009 5:53 pm
by tokumaru
tepples wrote:If you're making an emulator: It's probably safest to treat "missing" banks in an odd-sized iNES ROM as mirrors of the last bank. At least that will get the vectors in the right place.
Yeah, but people really shouldn't make these broken ROMs in the first place. People trying to make carts out of these kinds of ROMs will have a lot of trouble (because of the "replicating the last bank" thing). Ideally, the ROM files are exact replicas of the chips, and their sizes are always powers of 2. IMO emulators should refuse to run these broken ROMs.

Posted: Fri Dec 04, 2009 9:01 pm
by tepples
tokumaru wrote:people really shouldn't make these broken ROMs in the first place.
Then why do Super NES games have 10, 12, 20, or 24 Mbit ROMs? Are those replicated inside the mask ROM?

Posted: Fri Dec 04, 2009 9:19 pm
by tokumaru
tepples wrote:Then why do Super NES games have 10, 12, 20, or 24 Mbit ROMs? Are those replicated inside the mask ROM?
Don't ask me! I know someone recently mentioned this was common for SNES ROMs, and that there was a standard way to deal with that. Maybe the actual carts have more than 1 ROM inside? So when dumped they can add up to sizes that are not powers of 2, much like it happens when you put the PRG and the CHR in the same NES file, the final result isn't always a power of 2, but the individual chips are. If this isn't the case I wonder how the actual carts are.

Whatever the case is, we're talking about the NES here, and for it we can safely say that all games use chips whose sizes are powers of 2.

Posted: Fri Dec 04, 2009 9:29 pm
by tepples
tokumaru wrote:Whatever the case is, we're talking about the NES here, and for it we can safely say that all games use chips whose sizes are powers of 2.
So if someone makes a 1536 KiB PRG (using three chips) and 512 KiB CHR, does that make him a cheaterman?

Posted: Fri Dec 04, 2009 9:40 pm
by bunnyboy
tepples wrote:Then why do Super NES games have 10, 12, 20, or 24 Mbit ROMs? Are those replicated inside the mask ROM?
They use two different sized physical chips. Guess 16Mbit + 8Mbit is cheaper than 32Mbit.

Posted: Fri Dec 04, 2009 9:43 pm
by tokumaru
tepples wrote:cheaterman
I'm assuming this uses an obscure mapper that's aware of the existence of the 3 chips, but each one is still a power of 2 big.

MMC3 boards have 2 ROMs (or 1, if it uses CHR-RAM), each ones is a power of 2 big. MLT-ACTION52 boards have 4 ROMs, each one is a power of 2 big. He's working on a MMC3 game, so he'd better make the sizes of those ROMs powers of 2 if he expects it to work without problems anywhere.

Posted: Sat Dec 05, 2009 1:11 am
by Rid
tokumaru wrote:In this recent thread we had proof that the NES doesn't like ROMs with odd sizes. Although the iNES header allows all kinds of ROM sizes, the sizes of actual ROM chips are always powers of 2.
tokumaru wrote:This means that if you want to extend the ROM (CHR or PRG) of a game, you can't just add another bank, you'll have to double it (if the there are 128KB or PRG-ROM, you must add another 128 for a total of 256), because the double is the next power of 2. And of course, you can only do this if the game doesn't already have the maximum size that the mapper allows (IIRC the MMC3 can take up to 512KB or PRG and 256KB of CHR).
I didn't know that. I try to read (and understand) the most of threads that are written in this forum, but it is often very hard for me to understand all.
tokumaru wrote:When you read about the iNES header and mappers without knowing much about electronics, it sounds really simple, a byte tells how many banks there are. But this is not how the mappers actually work. Having the last bank fixed at the end of the addressing space is a matter of setting the upper bits of the address bus high when the top of the addressing space is accessed, and that only works if the size of the ROM is a power of 2. The mapper doesn't really know how many banks are there. So when you have ROMs that are not powers of 2 you screw up all the mapping.
I don't have understood this part. As the adressing space is only within $0000 and $FFFF, why does the size of the ROM chip has necessary to be power of 2?
tokumaru wrote:Although having odd ROM sizes might work in some emulators (each emulator seems to handle this differently), you should remember that you are making a NES program, so you must make your ROM as close to an actual cart as possible, and an actual cart will only take powers of 2.
As I intent to make a good and safe hack, I think I won't try to expand the game. To double its size (make it increase from a 128kB PRG chip to a 256kB, would be quite inappropriate...)

Posted: Sat Dec 05, 2009 1:37 am
by Rid
So, this what I've done.
Same configuration : 8 PRG banks from 0x0010 to 0x2000F.

I inserted 128kB at the ROM offset 0x20010 and I copied the last 16kB PRG bank to the ROM offset 0x3C010 (the other bytes are only 00). And finally, I filled with 00 the former last bank.
And it worked: FCEUX SP seemed to launch the game!

Well, now my ROM file has an increased size (passing from 257kB to 393kB).