Points of Required Attention™
Smaghetti, a new Super Mario Advance 4 editor, is currently in development! Check out the thread HERE!

Please chime in on a proposed restructuring of the ROM hacking sections.
Views: 88,320,183
Main | FAQ | Uploader | IRC chat | Radio | Memberlist | Active users | Latest posts | Calendar | Stats | Online users | Search 03-29-24 04:08 PM
Guest: Register | Login

0 users currently in ROM Hacking | 3 guests | 1 bot

Main - ROM Hacking - MMC3 Mapper Question New thread | New reply


RetroRain
Posted on 05-08-12 07:31 AM (rev. 3 of 05-08-12 07:58 AM) Link | Quote | ID: 150844


Fuzz Ball
Level: 66

Posts: 590/994
EXP: 2432595
Next: 29256

Since: 09-30-07

Last post: 1907 days
Last view: 929 days
Okay, two games that have MMC3, Super Mario Bros. 3 and Mega Man 3.

The length of both games is 0x6000F.

Taken from FireBug's Mapper Document, the Notes Section of MMC3:

"Two of the 8K ROM banks in the PRG area are switchable. The other two are "hard-wired" to the last two banks in the cart. The default setting is switchable banks at $8000 and $A000, with banks 0 and 1 being swapped in at reset. Through bit 6 of $8000, the hard-wiring can be made to affect $8000 and $E000 instead of $C000 and $E000. The switchable banks, whatever their addresses, can be swapped through commands 6 and 7."

Okay, so at the default setting, banks 0 and 1 are loaded into $8000 and $A000 respectively. I get that.

That means that at first, 0x10 - 0x400F is loaded into $8000, and 0x4010 - 800F is loaded into $A000.

What I don't get, is which banks are hardwired to $C000 and $E000?

I opened up Super Mario Bros. 3 and Megaman 3, and being that they are both 0x6000F in lengh, I've noticed that the very last bank $E000, 0x3E010 - 0x4000F is loaded in.

Now, being that the MMC3 mapper loads the PRG in 8k chunks (2000 bytes), if you divide 0x6000F by 0x2000, you get 0x30. Yet, the last bank that is hard-wired (0x3E010 - 0x4000F) is at 0x1F (divide 0x3E010 by 0x2000). It doesn't make sense to me, because I can't figure out the logic behind it. 0x3E010 is more than halfway through the ROM. What if a game is less than 6000F, like 4000F?

While I suppose it is possible, are the last two banks the ones that are two-thirds into the ROM?

What I'm getting at, is if a game uses a MMC3 mapper, which 8K PRG banks are thrown into the last two banks of the ROM? How do you determine those banks based on the size of the ROM?

____________________
My YouTube Channel

Kiokuffiib11
Posted on 05-09-12 07:09 AM Link | Quote | ID: 150853


Porcupo
Level: 40

Posts: 289/313
EXP: 406010
Next: 35299

Since: 07-10-09
From: Marquette, Michigan

Last post: 3284 days
Last view: 1907 days
I don't know if this will help,,, but have you tried opening the two files (One at a time) with fceux and then the rom and then looking at what it fills in that spot, then look through the rom, and see what it throws there?

____________________
セシル

never-obsolete
Posted on 05-09-12 01:12 PM Link | Quote | ID: 150857


Rat
Level: 24

Posts: 86/96
EXP: 74330
Next: 3795

Since: 02-22-07
From: Phoenix, AZ

Last post: 2568 days
Last view: 2568 days
SMB3 has 0x10 * 16K prg banks (based on byte4 of the header). The mmc3 maps prg banks 8K in size. The mmc3 always maps the last 8K of prg into $E000-$FFFF. So for SMB3, the math would be:

((2 * 0x10) - 1) * 8K
(0x1F) * 0x2000 = 0x3E000

0x3C000 will be mapped to $C000-$DFFF (mode0) or $8000-$9FFF (mode1).

On start-up, you can't really assume what prg bank mode the mapper will be set to or what will be mapped into $8000, $A000, or $C000. You'll want to point your vector to somewhere in $E000 and initialize the mapper from there.


RetroRain
Posted on 05-09-12 05:28 PM (rev. 5 of 05-09-12 07:23 PM) Link | Quote | ID: 150861


Fuzz Ball
Level: 66

Posts: 591/994
EXP: 2432595
Next: 29256

Since: 09-30-07

Last post: 1907 days
Last view: 929 days
Posted by never-obsolete
The mmc3 always maps the last 8K of prg into $E000-$FFFF.
Since SMB3 is 0x6000F in length, wouldn't the last 8K bank that is loaded into $E000-$FFFF be 0x5E010 - 0x6000F? Instead it is 0x3E010 - 0x4000F. Unless of course that it is truly loading 0x5E010 - 0x6000F into the last bank, and then it is quickly switched. But I am lead to believe that the last two banks are hardwired the moment the game is turned on, so no switching in the hardwired banks is allowed.

Posted by never-obsolete
So for SMB3, the math would be:

((2 * 0x10) - 1) * 8K
(0x1F) * 0x2000 = 0x3E000

0x3C000 will be mapped to $C000-$DFFF (mode0) or $8000-$9FFF (mode1).
I understand the logic of the math, but why is it that we are multiplying 2 by 0x10 and then subtracting 1? And then multiplying that by 8K?

In other words, I did the math you put there in the calculator, and it worked out perfectly. But I'm trying to understand why it is that way, you know what I mean? Why multiply 2 and then subtract 1? I understand that the game has 0x10 in PRG banks, I'm just trying to figure out why that math is the way it is.

Posted by never-obsolete
On start-up, you can't really assume what prg bank mode the mapper will be set to or what will be mapped into $8000, $A000, or $C000. You'll want to point your vector to somewhere in $E000 and initialize the mapper from there.
Are you saying, that the "hardwiring" effect is not immediate on start-up because the mapper registers have to be set up via code? If so, then I guess that would answer my question, and I feel stupid for asking.

EDIT - Now another thing is bothering me.

SMB3 has 0x10 16K PRG ROM banks. If 2000 bytes is 8K, and 4000 bytes is 16K, then why is 0x10 * 4000 getting me 0x40000 and not 0x60000? SMB3 is definitely 0x6000F. Unless of course because 4000 is a little more than 16K.

This is one of those things I hate about numbers.

EDIT 2 - Duh, because it has CHR-ROM I forgot to acknowledge the CHR-ROM in the game. Damn. The game is really 0x40000 of PRG-ROM, and 0x20000 of CHR-ROM. That is what was throwing me off! How could I forget about that? I was counting every byte in the ROM file as PRG-ROM.

____________________
My YouTube Channel

never-obsolete
Posted on 05-09-12 10:54 PM Link | Quote | ID: 150864


Rat
Level: 24

Posts: 87/96
EXP: 74330
Next: 3795

Since: 02-22-07
From: Phoenix, AZ

Last post: 2568 days
Last view: 2568 days
Posted by RetroRain
I understand the logic of the math, but why is it that we are multiplying 2 by 0x10 and then subtracting 1? And then multiplying that by 8K?


The header tells you how many 16K prg banks there are. The mmc3 maps 8K prg banks, so you have to multiply the bank number by two. AxROM (mapper #7) maps 32K banks, so in that case you would divide your bank numbers by two. Subtracting one is because bank numbers start at zero.


bank #s
-------
8 1 3
K 6 2
K K rom

0 0 0 0x00000
1 0x02000
2 1 0x04000
3 0x06000
4 2 1 0x08000
5 0x0A000
6 3 0x0C000
7 0x0E000
8 4 2 0x10000
9 0x12000
A 5 0x14000
B 0x16000
C 6 3 0x18000
D 0x1A000
E 7 0x1C000
F 0x1E000


Posted by RetroRain
Are you saying, that the "hardwiring" effect is not immediate on start-up because the mapper registers have to be set up via code? If so, then I guess that would answer my question, and I feel stupid for asking.


The hard-wiring is immediate, but the state of the mapper is still unknown. That's why you jump to $E000-$FFFF first, since it will always be mapped to 0x3E000 (for SMB3). 0x3C000 will be mapped at either $8000 or $C000. $A000 and the bank not hard-wired to 0x3C000 could be mapped to any prg bank.

RetroRain
Posted on 05-10-12 08:08 PM Link | Quote | ID: 150875


Fuzz Ball
Level: 66

Posts: 592/994
EXP: 2432595
Next: 29256

Since: 09-30-07

Last post: 1907 days
Last view: 929 days
Thank you never-obsolete! I appreciate your help!

____________________
My YouTube Channel

Main - ROM Hacking - MMC3 Mapper Question New thread | New reply

Acmlmboard 2.1+4δ (2023-01-15)
© 2005-2023 Acmlm, blackhole89, Xkeeper et al.

Page rendered in 0.019 seconds. (342KB of memory used)
MySQL - queries: 62, rows: 88/88, time: 0.014 seconds.