Register | Login
Views: 19364387
Main | Memberlist | Active users | ACS | Commons | Calendar | Online users
Ranks | FAQ | Color Chart | Photo album | IRC Chat
11-02-05 12:59 PM
1 user currently in Rom Hacking: hukka | 2 guests
Acmlm's Board - I2 Archive - Rom Hacking - Mapper Information | |
Add to favorites | "RSS" Feed | Next newer thread | Next older thread
User Post
Rockman

Flurry
Level: 26

Posts: 182/250
EXP: 96387
For next: 5888

Since: 03-17-04

Since last post: 18 days
Last activity: 16 days
Posted on 04-13-05 02:57 AM Link | Quote
I sent Disch a PM, asking about how to add a new mapper, and he gave me a lot of useful information. I hope you find it useful as well!

Originally sent by Rockman

If I wanted to add a new mapper to Mega Man, MMC3, how would I go about doing that? This may sound stupid, but is it just a change of a byte to change the mapper? Offset 5 I think. I could be wrong. Is any heavy code involved in adding the new mapper, and if I did, how could I benefit from that. I know MMC3 is the mapper used in the later NES games, and seems to be pretty good.



Disch:

When changing mappers there are things you have to consider. The mapper you want to change to has to have all the same capabilities as the mapper the game currently uses. So -- it's important to know the basic capabilities of each mapper. If you don't have it already, pick up a copy of Firebug's mapper doc:

http://nesdev.parodius.com/mappers.zip

Rename the mappers.nfo file to mappers.txt and toss/ignore the exe that comes with it (it's stupid) That doc gives a good general outline of several mappers -- although it's a little outdated and inaccurate at times (but it's good enough to get you going). For more accurate info, you might want to check Kevtris' mapper pages (the page was having trouble loading when I typed this, but that's the link):

http://www.tripoint.org/kevtris/mappers/mappers.html

Anyway... Megaman currently uses mapper 2 (UNROM). So to briefly look at what mapper 2 can do:

- 8k CHR RAM
- 16k PRG swapping @ $8000-$BFFF

And what mapper 4 (MMC3) can do:

- 8k CHR RAM or up to 512k (I think? maybe 256k?) CHR-ROM
- 8k PRG swapping @ $8000-$9FFF or $C000-$DFFF (but not both)
- 8k PRG swapping @ $A000-$BFFF
- (mapper has other features, but these are the only ones we're interested in for now)

So... can Mapper 4 do everything mapper 2 can? If not we've got a problem and the mapper conversion might not be possible without extremely heavy code changes to the game. But, comparing the above capabilties:

- UNROM does CHR-RAM --- MMC3 can do CHR-RAM (good!)
- UNROM can swap out $8000-$BFFF -- so can MMC3, but with a higher res (good!)

So a conversion IS possible.

So how do you convert? Well... changing the mapper number in the iNES header is part of it (high 4 bits of offset $00006 --- mapper 2 will be $2x, mapper 4 would be $4x). If you do just that -- the game will crash and burn when you play it! All that does it tell the emulator to use a different mapper -- the game itself will still be swapping and doing stuff with the old mapper's regs. So what you'll have to do is change ALL the code in the game that interacts with the mapper. You'll have to rewrite all mapper-specific routines so that they perform the same job, but with the new mapper.

In complex mappers this can be a big task, but with UNROM it's likely pretty simple. The only feature UNROM really provides is PRG swapping -- and the game probably has a single subroutine it JSRs to when it wants to swap banks ... so to change that routine, you'll have to find it and replace it with the MMC3 equivilant.

An UNROM game might swap a bank like so:

LDA #$04 ; it's going to select page 4
JSR swap_routine ; jump to our swap routine

; elsewhere in the game

swap_routine:

TAX ; move desired page to X reg
STA page_reference_table, X ;write to swapping reg
RTS ;return


page_reference_table is probably near the end of the ROM... and has a bunch of values that 'count up':

00 01 02 03 04 05 06 07 08 09 ...

UNROM swaps banks on any write to anywhere within the $8000-$FFFF range -- however due to bus conflicts, the value it writes must match the value read from that address. If you don't understand this, don't worry -- MMC3 does not have bus conflicts so you don't have to do anything like this -- just know that the game probably does something similar to the above. Basically, after the write to $8000-$FFFF, a new 16k will be swapped into $8000-$BFFF.

So for MMC3, you'll have to find that 'swap_routine' and rewrite it to something that does the same job -- but using MMC3's registers. It might look like the following;


swap_routine:

ASL A ;double our page number (make it an 8k page instead of 16k)
TAX ; save it in X

LDA #$06
STA $8000 ;set MMC3 to "swap 8k @ $8000" mode

TXA ; get the page number back from X
STA $8001 ;actually swap out the page

LDA #$07
STA $8000 ; set MMC3 to "swap 8k @ $A000" mode

INX ;increment the page number
TXA ; get the incremented page number from X
STA $8001 ; swap out the page

RTS ;exit


As you can see the MMC3 code is much larger -- this cannot be helped. You might have trouble with a lack of free space... but you'll just have to find some free space to fit the routine in. Note this space should remain in the "hardwired" bank (the last 16k PRG page in the ROM) so that the swap routine is always avaialable -- regardless of which bank is swapped in.


But that's not all!

The MMC3 should probably be prepped on power-up as well. UNROM doesn't really need any prepping, but MMC3 might. However, I wouldn't worry so much about this, since emulators will probably play the game fine even without prepping. In fact I wouldn't even worry about it for now -- but it's something you should keep in the back of your mind.

Anyway -- hope that's helpful and I hope I made sense. I can try to clarify more if you'd like.
EverdredReturns

Micro-Goomba
Level: 7

Posts: 4/19
EXP: 1376
For next: 72

Since: 01-30-05

Since last post: 2 days
Last activity: 2 days
Posted on 04-13-05 04:07 AM Link | Quote
I'm working on a Castlevania hack, which is mapper 2 as well, so this info is pretty interesting...Dunno if I'd go all the way to changing the mapper on my hack (as Castlevania seems to have a decent amount of empty space in places so I have no need to expand the ROM size, plus I don't want to mess with too many ASM changes).

I also know that in Castlevania, there are values that "count up" at the beginning of most of the PRG banks (all except the 5th I think) that go 00h to 07h.

Thanks for posting this!
Dish

Spiny
Level: 38

Posts: 337/596
EXP: 355646
For next: 14801

Since: 03-15-04
From: Disch

Since last post: 18 days
Last activity: 18 days
Posted on 04-13-05 04:41 AM Link | Quote
I just realized my MMC3 example code was a little inefficient. This code would have a smaller size:



swap_routine:

ASL A ; double page number (16k index becomes 8k index)
TAX ; stuff in X

LDY #$06 ;this uses Y, alternatively you could use A here
STY $8000
STX $8001 ; for some reason I forgot STX existed when I wrote that other code

INX
INY ; if using A, you'll need to do LDA #$07 instead
STY $8000
STX $8001

RTS



That code does the same thing as the above listed code but uses 19 bytes (20 if you use A instead of Y). The old code used 23 bytes.
dan

Snap Dragon
Level: 43

Posts: 518/782
EXP: 534516
For next: 30530

Since: 03-15-04

Since last post: 20 hours
Last activity: 14 hours
Posted on 04-13-05 03:17 PM Link | Quote
The only problem I have with changing mappers is that if you do it to add CHR-ROM, or add extra PRG banks, you are left with very few legal ways to distribute the damn thing. (An IPS patch will contain a ton of the original ROM)

There are also a few things I noted from converting ROMs from UNROM to MMC3 that threw me off. First, if you plan on using WRAM, you need to initialise it (some register can do it). Certain emulators allow you to use it without initialising it (FCEU comes to mind), but the more accurate ones don't (NEStopia). If you plan on converting everything to CHR-ROM (a very tedious task, trust me, I did it using a custom program I wrote to rip pattern tables out of FCEU savestates, otherwise it would have taken forever), when loading stuff into the sprite table, it seems to be that the CHR bank number must be a multiple of 2. This didn't seem to be covered in Firebug's documents.
DahrkDaiz

Red Super Koopa

Acmlm's Mosts 2005
Best ROM Hacker

Level: 45

Posts: 606/885
EXP: 643520
For next: 16644

Since: 03-15-04
From: K-Town

Since last post: 4 hours
Last activity: 4 hours
Posted on 04-13-05 10:22 PM Link | Quote
Not to mention, changing a mapper for expanding a ROM generally "breaks" any editors that are used for it, since some offsets will be changed. I had to manually hack SMB3 Workshop in a hex editor to have it load graphics corectly for my hack, but lucky, it has no error checking for loading levels outside of the original ROM size, but other editors might not be so lucky.

As for MMC3's CHR-ROM/PRG-ROM size, I've found (atleast from the emulators I've tried) that PRG-ROM size must be 128, 256 or 512Kb and CHR-ROM must be 64, 128 or 256KB. I'm sure other mappers have similiar limitations (MMC5 can have up to a MB of each I think, but I'm sure Disch will come by ahd thwart me on this.)
Dish

Spiny
Level: 38

Posts: 338/596
EXP: 355646
For next: 14801

Since: 03-15-04
From: Disch

Since last post: 18 days
Last activity: 18 days
Posted on 04-13-05 10:36 PM Link | Quote
Originally posted by dan
it seems to be that the CHR bank number must be a multiple of 2. This didn't seem to be covered in Firebug's documents.


Kind of.

MMC3 doesn't have eight 1k CHR banks... instead it has four 1k banks, and two 2k banks. The oddity is... when swapping in the 2k banks you give a 1k bank number (or 2x the 2k bank number) -- and the low bit of the written value is ignored.

So specifying $04 for the 2k bank at $0000, would have the same as specifying $04 for the 1k bank at $0000 and $05 for the 1k bank at $0400. Specifying $05 for the 2k bank would have the exact same effect as specifying $04 (low bit unused on 2k page selection).

This behavior exists on many/most/all mappers which have multiple bank sizes. Only one I can think of which has variable bank sizes and doesn't exhibit this behavior is CHR swapping on MMC5 (although PRG swapping does exhibit it).

Also: note that you cannot 'trick' the MMC3 to try to get eight 1k banks. A lot of people see the 'XOR CHR address' bit in the $8000 reg and think they can use it to get a higher swapping res -- but MMC3 does not work that way. Same for the PRG swapping mode bit in $8000 -- you can only swap $8000 or $C000 -- you cannot manipulate $8000.6 to swap both... it won't work.

EDIT:

As for what DD was talking about -- yes, when expanding a ROM, you should keep all PRG/CHR sizes a nice, even, power-of-two value (64k, 128k, 256k, 512k, 1M). I'm unsure of MMC3's maximum... according to Kevtris' doc the largest MMC3 boards (TK-ROM, TS-ROM) are 512k PRG, 256k CHR -- so those are likely your limit.

And yeah... I think the max for MMC5 is 1MB of each (along with a whopping 64k of WRAM!).


(edited by Disch on 04-13-05 05:45 AM)
BMF98567
BLACK HAS BUILT A SILLY DICE-MAZE!
GO!

Current list of BURNING FURY >8( recipients:
- Yiffy Kitten (x2)
- Xkeeper
Level: 53

Posts: 774/1261
EXP: 1094149
For next: 62970

Since: 03-15-04
From: Blobaria
Special Move: Rising Meatloaf Backhand Combo

Since last post: 21 hours
Last activity: 1 hour
Posted on 04-14-05 01:58 AM Link | Quote
An alternative to ROM expansion or mid-game bank swapping:

If the original game doesn't use it, or doesn't use all of it (highly likely), you can use WRAM ($6000-$7FFF) to hold extra ASM routines or temporary data. You've got 8,192 bytes to work with, or the equivalent of an MMC3 ROM bank! This can come in very handy if there's very little space in the ROM bank your code needs to reside in, since WRAM is always loaded and always accessible. As long as there's a ROM bank in the game that has enough space to hold your code, you can hack the game's startup routine to temporarily swap it in, copy the code into WRAM, and then swap back. You can then jump to this code at any time during the game.

Another "less kosher" method would be to include a .SAV file with your hack that already contains the necessary routines. Emulators would then load this into WRAM (WRAM and SRAM are the same thing, SRAM's just battery-backed) and you wouldn't have to bother with copying the code in the first place. The problems with this method are a) there's extra work involved on the part of the end user, having to copy the .SAV file to the proper folder for the emulator to recognize it, b) it could become corrupted by a game/emulator crash, requiring the user to restore the original file, and c) playing the hack on a real NES would be impossible, unless you soldered an EPROM with the code in place of the cart's WRAM. (However, I believe "The Jetsons" was configured in just such a way during development, since part of the debug code jumps to $6000, even though the game never writes anything there...)

There *might* be other limitations I'm not aware of that would prevent this from working, but it doesn't seem likely, as many NES games already execute code from ordinary RAM.
Dish

Spiny
Level: 38

Posts: 339/596
EXP: 355646
For next: 14801

Since: 03-15-04
From: Disch

Since last post: 18 days
Last activity: 18 days
Posted on 04-14-05 03:54 AM Link | Quote
This would only be legit on mappers which have WRAM/SRAM. Mapper 2 (to my knowledge) does not -- which is one reason why the FF2 translation hack which changes mappers to mapper 2 is taboo.

Emulators probably don't really care -- and probably put WRAM at $6000-$7FFF regardless (for example my emu puts RAM there for pretty much every mapper -- except mapper 0)
Add to favorites | "RSS" Feed | Next newer thread | Next older thread
Acmlm's Board - I2 Archive - Rom Hacking - Mapper Information | |


ABII


AcmlmBoard vl.ol (11-01-05)
© 2000-2005 Acmlm, Emuz, et al



Page rendered in 0.015 seconds.