Add a new bank in MMC1 and use the new space

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Timaeus
Posts: 12
Joined: Wed Jul 13, 2022 1:06 pm

Add a new bank in MMC1 and use the new space

Post by Timaeus »

Hello there. I have been coding more complex bosses for my current Megaman 1 hack, which is using the original mapper which is UNROM (Mapper 2, MMC1), with PRG-ROM size of 8 x 16kb and CHR-ROM size of 0 x 8kb, which means I did not expanded anything on it yet and have been working with the original game size until now.

The problem is that, in order to code my bosses, I need more free space than the game gives, and I think one more bank of free space will be enough. At first, I wanted the double of the size, but it feels like it makes jumping from one location to another and bankswapping much more difficult, so now I want just 4000 hex of free space only, to keep things simple perhaps. I have a hex editor that does allow me to insert the amount of bytes in, and I am already aware that bank switching will probably be necessary, and it is possible to expand the rom too.

I have a written disassembly document of the game that have the codes and locations of everything. I can link it up if needed. Normally, the game uses this code to change banks:

A9 05 lda #$05
85 42 sta CurrentBank
8D 05 C0 sta $C005
...

$C005 is the location of a table with numbers from 0 to 7, which is necessary for the swap to work.

the game also uses this code for a specific swap


08 php
48 pha
8A txa
48 pha
A5 31 lda CurrentStage

C9 06 cmp #$06 ; bank=(stage%6)
90 02 bcc +
E9 06 sbc #$06
+
AA tax
85 42 sta CurrentBank
9D 00 C0 sta $C000,x
68 pla
AA tax
68 pla
28 plp
60 rts

I believe this one is for stages id or something, since CurrentStage is always used to that, and stage 6 is the Wily stage 1, so I believe this one will not be necessary to touch.

The new bank will be from 1C010 until 20010. How do I make the game reads the new space? I think normal pointers will not make it without bankswapping, since the new space will probably out of range. I did made the game have the double of size and made it load thanks to adding byte 10 in address 00004, but I also dont know which byte to write there for one new bank only.

I have a bank swap code sample ready too, which nis the follows (I hope it is right :p)

A9 07 ;load byte 7 (which will represent bank 7)
85 42 ;start CurrentBank
8D 07 C0 ;read byte 07 at c007 (byte from the table I mentioned)
4C 00 80 ;jumps to the new location (free space location in 1c010)

this code worked but by changing to AC 01 80 makes it go to 1C110 instead of 1C011. Maybe if I use only one new bank, the math will be simpler. I am aware that I will need to swap it back to the original mapper the game used in the place the code was activated, and that I will probably need to do it for every jump I may need, which will be alot.

Thank you very much~
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: Add a new bank in MMC1 and use the new space

Post by lidnariq »

You cannot add "only" one bank. Behavior is only well-defined for a power of two.

Also, UxROM extends arbitrarily big up to a maximum of 4MiB (256×16KiB), and the simpler mapper is probably better than MMC1 for your purposes, unless you are specifically changing nametable arrangement dynamically.
Timaeus
Posts: 12
Joined: Wed Jul 13, 2022 1:06 pm

Re: Add a new bank in MMC1 and use the new space

Post by Timaeus »

I only need space for bosses patterns, nothing else. Ok, Ill keep the doubled sized rom. How should I make it jump to where I need? I am a newbie in bank swaps. I just got to know that each bank in this mapper is $4000 size :p
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: Add a new bank in MMC1 and use the new space

Post by lidnariq »

For UNROM, you'll need to double the "bus conflict prevention table" to include the new banks you'll use.

If the current code uses only banks 0-6, then you can insert the padding between the first 7 banks and the last bank, and won't have to update anything.

If it uses something other than 0-6, the patch will be enough more involved that I can't simply summarize the differences.

If you're switching it to MMC1 you don't need the "bus conflict prevention table", but you need the MMC1 update routines and that's probably bigger. (And slower...)
Timaeus
Posts: 12
Joined: Wed Jul 13, 2022 1:06 pm

Re: Add a new bank in MMC1 and use the new space

Post by Timaeus »

I believe this table you said is the one in $C000, that have numbers from 00 until 07 (8 bytes). I do pretend to keep using the UNROM mapper as well. I believe I have to make the Hex location divided by 4000 (bank size) to figure it out the bank numbers, right? So 1c010 is one, 20010 is another, 24010 is another, etc. Also, since I will have to include a new table with the double of the size for bank switching, can I add it in $C000-FFFF (which is not at 3c010)? I have some unused space there that will work nicely for it (I know I will have to change the pointers to go to the new location too)
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: Add a new bank in MMC1 and use the new space

Post by lidnariq »

Timaeus wrote: Fri Jul 22, 2022 3:12 pm I believe this table you said is the one in $C000, that have numbers from 00 until 07 (8 bytes). I do [in]tend to keep using the UNROM mapper as well. [...] Also, since I will have to include a new table with the double of the size for bank switching, can I add it in $C000-FFFF (which is not at 3c010)? I have some unused space there that will work nicely for it (I know I will have to change the pointers to go to the new location too)
You only have to include a number for each bank that you'll use, so if you indeed only need one more bank, you only need 0 through 8. If you don't put the replacement table in the last 16KiB, you'll have to put a copy in every other bank.
I believe I have to make the Hex location divided by 4000 (bank size) to figure it out the bank numbers, right? So 1c010 is one, 20010 is another, 24010 is another, etc.
Because iNES header, subtract 0x10, then divide by 0x4000, correct.
User avatar
Memblers
Site Admin
Posts: 4044
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: Add a new bank in MMC1 and use the new space

Post by Memblers »

Since you're only adding one one (used) bank, if it's any easier (depending on how it's already set up I guess), it's also possible to do bus conflict safe write without a table, like this:

Code: Select all

; anywhere in $C000-$FFFF
here: 
 lda #17
 sta here+1
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Add a new bank in MMC1 and use the new space

Post by Dwedit »

If it's MMC1, there shouldn't be any bus conflicts?
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Add a new bank in MMC1 and use the new space

Post by Quietust »

Dwedit wrote: Fri Jul 22, 2022 6:14 pm If it's MMC1, there shouldn't be any bus conflicts?
As noted above, rather than switching from UNROM to MMC1, the poster has decided to instead switch to UOROM (which obviously still suffers from bus conflicts),
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
Timaeus
Posts: 12
Joined: Wed Jul 13, 2022 1:06 pm

Re: Add a new bank in MMC1 and use the new space

Post by Timaeus »

Yeah, I decided to just expand the UNROM raw game instead. Ok so,thanks to someone, I managed to make a bank switch and also made it reach the location I need. The code is this one:

SwitchBankCstm:

08 php ; Push processor status to Stack so we can pull it back later
48 pha ; Push Accumulator to Stack so we can pull it back later
A9 07 lda #$07 ; Accumulator = $07
85 42 sta CurrentBank ; $0042 = Accumulator
8D 07 C0 sta $C007 ; $C007 = Accumulator
68 pla ; Pull Accumulator from Stack
28 plp ; Pull processor status from Stack
60 rts ;

I added it in 3E428 ($E418) and it worked. I also was suggested to do this with it:

3DC7F: 20 00 FF jsr $FF00 ; Jump to SwitchBankCstm
3DC82: 20 00 80 jsr $8000 ; Jump to where the boss code will start
3DC85: 20 B3 C3 jsr $C3B3 ; Jump to SwitchBank05 (a code to swtich back to bank 05, using the exact same bates as the one above)

However, my boss codes needs rts to switch to the next one. For example, the jump code is split in two parts, and for the first one to access the second, two hex bytes are required to add a new balue or increment the value of the function that calls the strategies, then rts.

I though about making a JMP (4C), but the game crashes obviously. when the rts is reach, the bank 5 swap function happens and the game become unable to make the boss jump, because the second code need routines from bank 5. How can I fix this issue?
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Add a new bank in MMC1 and use the new space

Post by Dwedit »

Here's a crazy idea, add 8K WRAM (6000-7FFF) to the game and put your code there. Now you don't have any worry to whether your code is conflicting with the game's code.
You'd just need to load in your expansion code at boot time, then it's ready to jump to whenever you need it.

Note that in order to run on a real cartridge, WRAM requires MMC1 or MM3 (or other such mappers), UxROM will not work.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
Memblers
Site Admin
Posts: 4044
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: Add a new bank in MMC1 and use the new space

Post by Memblers »

Dwedit wrote: Sat Jul 23, 2022 8:55 pm Here's a crazy idea, add 8K WRAM (6000-7FFF) to the game and put your code there. Now you don't have any worry to whether your code is conflicting with the game's code.
You'd just need to load in your expansion code at boot time, then it's ready to jump to whenever you need it.
Also, if it's small enough, you can do that with the stack page in RAM. Lots of games erase it at reset, but then never touch (most of) it again.
kuja killer
Posts: 130
Joined: Mon May 25, 2009 2:20 pm

Re: Add a new bank in MMC1 and use the new space

Post by kuja killer »

oh that's a good idea actually about using the 6000-7FFF area. not having to deal with those crazy formats with that mapper or anything. no bankswap or anything either assuming your only just using that 1 page.

I actually put code in the 6000-7FFF area on my game, megaman odyssey quite often, and runninig from there. But....i cant use the "1st page" because it's already all in use by storing an entire level's level data (6300-7FFF) ..and the other 300 bytes is all "save game" related stuff.
Puresabe did this also with Rockman 4 Minus Infinity. (mmc5)

So i have to actually do real bankswapping to switch to "page 2" for 6000-7FFF for when i want to run code from there. Since i use the mmc5 mapper

But yea that sucks that it's not supported on that UNROM though
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Add a new bank in MMC1 and use the new space

Post by Dwedit »

Do Everdrives/Powerpaks give 8K of WRAM to mappers which don't support it? I know that older emulators usually provide 8K of WRAM to all games (breaking Low G Man, which expects to read open bus).
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
calima
Posts: 1745
Joined: Tue Oct 06, 2015 10:16 am

Re: Add a new bank in MMC1 and use the new space

Post by calima »

Be careful though, there's been at least one hack before that just expected the SRAM contents to be pre-supplied. It didn't write them itself, and didn't work otherwise (IIRC it crashed late in the game or similar).
Post Reply