This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

MMC1 questions

MMC1 questions
by on (#204529)
Originally, my next game was going to be an UNROM game, but my graphics artist insists on battery-backed save states instead of passwords, so I had to switch over to MMC1.

I did the Nerdy Nights chapter on MMC1 and read the corresponding wiki articles:
https://wiki.nesdev.com/w/index.php/MMC1
https://wiki.nesdev.com/w/index.php/Programming_MMC1

So far, everything works fine.

But I still have some questions about it:


1. About the fact that things like switching the bank need several consecutive writes, the wiki says:
Quote:
If an NMI or IRQ can interrupt a series of writes, it is not easy to know what state the serial register was in before the interruption.

I actually have such a situation: If the game logic is still in the middle of running and the NMI starts, it immediately stops again, but not before calling the sound library, so that the music doesn't lag. In this case, it sets the bank as well.

So, is there even a way to reset only one specific register? I thought that setting a 1 in the highest bit of $8000-$FFFF will reset the whole mapper.
Does that mean whenever I switch the bank, I also have to set the screen mirroring again?


2. What happens if writing to a register, for example $8000, is interrupted by the NMI and the NMI then writes to $E000? Do the writes to $8000 and $E000 clash with each other as well or can they be mixed?
I.e. if setting screen mirroring is interrupted by setting the bank, do I have to reset and try again the screen mirroring?


3. The wiki suggests that you should mirror the start of the reset function as well as the three vectors to all banks. Because there are some MMC1 revisions that don't guarantee that the last bank is indeed treated as the fixed bank at startup, so any bank could be the active bank at the beginning.

Is this really something I need to consider or can I just ensure that I use an MMC1 version where the last bank is always guaranteed to be active?
In how far can you rely on this and in how far is this more a thing that you should take care of regardless?

Can I simply declare that my game has to run on an MMC1 SNROM-05 board and that's it? Or getting a specific revision something that you shouldn't rely on?


4. I've read somewhere that you should disable battery support when values are not written to WRAM. Am I remembering this correctly or do I confuse something here?
Re: MMC1 questions
by on (#204530)
DRW wrote:
So, is there even a way to reset only one specific register? I thought that setting a 1 in the highest bit of $8000-$FFFF will reset the whole mapper.
Resetting the MMC1 seems to only set the 'PP' bits of the register at $8000. It definitely does not change the CHR registers and I'm about 90% certain it does not change the PRG bank. I don't remember whether the PRG RAM protect bit is changed.

Quote:
2. What happens if writing to a register, for example $8000, is interrupted by the NMI and the NMI then writes to $E000? Do the writes to $8000 and $E000 clash with each other as well or can they be mixed?
There is one 4-bit FIFO. On the 5th write, the register corresponding to the fifth write is what chooses where the value goes.
Re: MMC1 questions
by on (#204531)
None of the original UxROM boards had PRG-RAM, as far as I know, but there's nothing about the mapper that forbids it. Some emulators can provide the PRG-RAM for it, and you can make a board that supports it. (There's also UNROM 512, but it explicitly uses flash for saves, so I don't think battery backed PRG-RAM is an option for that.)


3. I think there are a few MMC1 boards that are using a 32k PRG and don't bother to connect the PRG banking, so those MMC1 games that don't need to have the reset stub because of that. I don't think there's versions of the MMC1 chip that initialize the PRG bank? (Not entirely sure.)

If you're building an MMC1 clone on a CPLD you could just make it power on with the high bank where you want it, though.


4. A lot of battery backed mappers had ways to protect it when not otherwise in use. I couldn't say how often you will get save corruption if you don't do this, but I do think this practice existed for good reason.
Re: MMC1 questions
by on (#204535)
rainwarrior wrote:
None of the original UxROM boards had PRG-RAM, as far as I know, but there's nothing about the mapper that forbids it. Some emulators can provide the PRG-RAM for it, and you can make a board that supports it.

The circuit for this functionality uses a 74HC20 and can be seen in Family BASIC.

rainwarrior wrote:
I think there are a few MMC1 boards that are using a 32k PRG and don't bother to connect the PRG banking, so those MMC1 games that don't need to have the reset stub because of that.

SEROM doesn't need reset code because the PRG ROM is mapped directly: A14 runs directly from the cart edge to PRG ROM A14. But the only MMC1 board with both WRAM and 32K PRG ROM (SIROM, Japan only) does use the MMC1's PRG A14 output.

rainwarrior wrote:
A lot of battery backed mappers had ways to protect it when not otherwise in use. I couldn't say how often you will get save corruption if you don't do this, but I do think this practice existed for good reason.

I think save corruption comes from stray writes as the CPU and decoder start to lose power. As far as I'm aware, the 74HC20 circuit provides no protection against this effect, so the player has to be diligent about holding Reset when turning off the power. Perhaps a protection circuit like the Mitsumi MM1026 used in MMC4 games might help.
Re: MMC1 questions
by on (#204536)
I thought for a long time that enabling the RAM write protection of MMC3 and MMC5 etc protected against stray writes when powering off. So that's why even MMC5 games like Just Breed asks the user to hold RESET when powering off.
Re: MMC1 questions
by on (#204541)
Have two bankswitch routines, one for the NMI, and one for the main game.
NMI's first bankswitch routine:
Reset the MMC1 (write anything 80-FF or whatever)
Do the 5 writes for the mapper
Set a flag to indicate that NMI has done mapper writes
Subsequent bankswitches don't need to reset the MMC1 first, but it's no problem if you do.

Game's bankswitch routine:
Do the 5 writes for the mapper
check the flag to see if NMI has done mapper writes
If it did, reset the mapper, then do the 5 mapper writes again.

For this, you need to have your bankswitch code live in the fixed bank, and have the final ROM bank be the fixed bank be at C000-FFFF. Just like UNROM.
Also, the mapper may begin in an unknown state, and on actual cartridges, you need a reset vector and small mapper reset code on every single 16K rom bank. Just a single mapper write and a jump to the real boot code, so it's tiny code.
Re: MMC1 questions
by on (#204548)
Or just ensure that your NMI routine never switches banks. Something that just sends OAM and VRAM updates and sets scroll should work.

To avoid music slowdown now that you've moved audio out of NMI, you can have the NMI routine increment the number of times the audio engine's update routine needs to be called, and then check that variable at multiple points during your main thread. This also handily avoids the thread safety problem where an NMI happens during jsr start_sound_effect, causing your audio engine's sound effect code to see an inconsistent state due to a partly initialized channel.
Re: MMC1 questions
by on (#204550)
tepples wrote:
Or just ensure that your NMI routine never switches banks. Something that just sends OAM and VRAM updates and sets scroll should work.

If you can do that, great, but there are many legitimate reasons for switching banks in the NMI handler besides audio updates (e.g. copying CHR data from ROM to VRAM), so it's good to know how to do that correctly.

Quote:
This also handily avoids the thread safety problem where an NMI happens during jsr start_sound_effect, causing your audio engine's sound effect code to see an inconsistent state due to a partly initialized channel.

Or you could leave the audio update/playback routine take care of actually initializing channels, with the main thread merely sending commands to the audio system through a queue, as opposed to directly manipulating its state.
Re: MMC1 questions
by on (#204551)
Just chiming in as I'm suprised it hasn't yet been mentioned. If the only thing motiviating the jump to mmc1 is saves slots, did you consider utilizing flash saves to PRG-ROM with a discrete mapper?

"UNROM-512" already has a defined and emulator supported PRG-ROM saving feature and has been utilized by multiple homebrews to date.

The cost of a CPLD, PRG-RAM, and battery circuit is significantly more than a single logic gate needed to unlock PRG-ROM saves.
Re: MMC1 questions
by on (#204552)
How does that work when one erase sector is bigger than the NES's entire RAM? Or would most saving be done on a blank screen using CHR RAM as work RAM?
Re: MMC1 questions
by on (#204553)
Other options:
- Don't hold total bytes of saves larger than you can keep in WRAM (There's nothing that says you have to use the entirety of the 4 KiB sector size.)
- Use two sectors, and swap which one holds the save back and forth.

Because of how flash works (converting bits from 1 to 0 can be done in any order at any time; converting bits back to 1 can only be done 32 kibit at a time) there may be more cleverness that takes advantage of this.
Re: MMC1 questions
by on (#204555)
Unlocking 32KB of CHR-RAM on mapper 2 is also relatively cheap/free. Plenty of scratch RAM to buffer sector data if needed. If one doesn't have 4-8KByte of PRG-ROM to spare doubling density is still significantly cheaper than ASIC mapper + PRG RAM + battery.

Don't get me wrong, managing flash saves is challenging in comparison. But several different developers and publishers are actively utilizing it.
Re: MMC1 questions
by on (#204556)
If only it were PowerPak supported...
Re: MMC1 questions
by on (#204561)
About the idea of using a custom mapper (UNROM with battery save etc.): I would never do this. Not only do I insist on only using mappers that existed back in the NES days, I also make sure that I only use common mappers. Which is why I even wanted to avoid using UNROM with 256 KB because that one was only used for two unimportant games while the 128 KB version was used for many times.

With MMC1, I don't have that problem anymore. MMC1 with 256 KB is common enough. And it was used in "Final Fantasy", one of the most popular NES games.


I mirrored the vectors and the reset start code now because I saw that even "The Legend of Zelda" does it, so obviously the most common board types also have that issue.

Dwedit wrote:
Have two bankswitch routines, one for the NMI, and one for the main game.

Instead of writing two switch functions, how about this:
You take a global variable. At the start of the function, you increment it and also save the new value to the stack.
At the end of the function, you check whether the variable still has the same value as the one on the stack. If not: Increment again, repeat.

This way, you can use the same function in all locations and you can have an arbitrary number of interrupts doing switches. Unless you try to do 256 bank switches at once, the function always knows whether it was interrupted by another bank switch because it doesn't have a "was interrupted" flag, but each call basically has its own ID that can be checked for changes. Since the absolute numerical value is not important (only the comparison with another value for equalness), the ID never gets decremented. It only gets incremented with every new bank switch call.

tepples wrote:
This also handily avoids the thread safety problem where an NMI happens during jsr start_sound_effect, causing your audio engine's sound effect code to see an inconsistent state due to a partly initialized channel.

That's a really good point that I haven't considered yet. (Fortunately, my previous game never lags, so this wasn't a problem there.)
Since I use FamiTone, there's no way I can ensure that this doesn't happen, since, as far as I'm concerned, FamiTone is a black box.

But how do you avoid the lagging of music? If I simply set a counter in every NMI for every intended music call, this only means that a game logic lag will skip a certain amount of sound, but it will still lag.

For example, let's take an extreme example: Let's say my game logic lags for five seconds in a certain situation.
Calling the sound outside of NMI and using a counter to check how often it has to update the APU doesn't mean that the music doesn't lag. It just means it lags for five seconds and then it skips five seconds worth of music all at once.
Unless I clutter all my code with nothing but music calls, but then I have the problem that music is already updated, even though later parts of the game logic intend to add sound effects etc.

I guess I simply swallow potential music lag. Lagging shouldn't happen that often anyway and if it happens, who cares that the music becomes a bit slower?


This should also completely eliminate my initial problem: Other than for the music, my NMI never switches banks since it only does the bare minimum, updating the PPU by reading some pre-prepared data from RAM and nothing else.
(Stuff like CHR updates are done when rendering is turned off.)

So, if no interrupt ever switches a bank or writes to any other MMC1 register, can I be sure that an NMI that triggers in the middle of the bank switch function doesn't corrupt the bank switch status? (Of course, given that the NMI always correctly saves A, X and Y to the stack when it starts and restores them when it ends.)


rainwarrior wrote:
4. A lot of battery backed mappers had ways to protect it when not otherwise in use. I couldn't say how often you will get save corruption if you don't do this, but I do think this practice existed for good reason.

Since I don't know anymore where I read this whole thing, I have to ask again:
What means are there in the MMC1 mapper to protect the battery data? How can I disable battery support and only enable it during writes? (If that is even a thing that can/should be done. As I said, I'm not quite sure what exactly I read there at all, I only vaguely remember something about protecting it by disabling it when not in use.)
Re: MMC1 questions
by on (#204563)
Quote:
I mirrored the vectors and the reset start code now because I saw that even "The Legend of Zelda" does it, so obviously the most common board types also have that issue.

It has nothing to do with the board, but rather MMC1 chip version. I think earlier versions had unknown state at poweron, but this was fixed for MMC1A, and all MMCB series chips, which are most commons. The older MMC1 is extremely rare. Legend of Zelda was one of the first games using the chip.

As for the matter, I do not think it is necessary to have two functions, unless you are really tight on NMI VBlank time.
Something like this is enough:
Code:
MMC1_switch:
   pha
   lda M2000
   and #$7f
   sta $2000
   pla
   sta $ffff
   lsr A
   sta $ffff
   lsr A
   sta $ffff
   lsr A$
   sta $ffff
   lsr A
   sta $ffff
   lda M2000
   sta $2000
   rts

M2000 is supposed to mirror the value last written to $2000. This prevent VBlank during the switching codes, and make it appen only after the switching is done. This can delay NMI, and as such, shorten VBlank time a little, but for 99% of the cases it'll do the trick. If full VBlank time is really needed, or if you're doing timed code synchronized directly from NMI this is unacceptable. Then you can either do what dwedit describes, or do something like that:

Code:
MMC1_switch:
   inc while_accessing_mmc1
   sta $ffff
   lsr A
   sta $ffff
   lsr A
   sta $ffff
   lsr A$
   sta $ffff
   lsr A
   sta $ffff
   dec while_accessing_mmc1
   rts

In the VBlank, do not switch any bank if the "while_accessing_mmc1" flag is true/nonzero. This means in very rare cases the music code will not run when lagging, but it will still run normally if the game engine lags and it is outside of this routine.

If you want to be extremely perfectionist you could go for the extreme solution : Before switching banks in NMI, you check the programm counter value saved on the stack and see if it is within the MMC1 writing routine, and act accordingly. This way you can fully use VBlank time *and* you are not required to reset the mapper by writing $80, which seems to have a side effect of changing PRG-ROM switching mode.
Re: MMC1 questions
by on (#204564)
O.k., so you're suggesting to mark the start of a bank switch and to skip the sound update in the rare cases when NMI actually entered while the bank switch was done.
This might be a solution.

Although, personally, I guess I'll just put the sound update inside the if NmiCanBeProcessed condition instead of out of it. Then I don't need to save any kind of status at all and can be sure that MMC1 writes are never interrupted by other MMC1 writes.
My game is supposed to be mostly lag-free anyway, so if it does lag for a short moment, then I don't care if the sound lags as well.
Re: MMC1 questions
by on (#204565)
Bregalad wrote:
Code:
MMC1_switch:
   pha
   lda M2000
   and #$7f
   sta $2000

Doesn't writing to $2000 mid-frame cause those glitchy scanlines that are common in SMB1? As far as I recall, the consensus was that we just shouldn't do it.
Re: MMC1 questions
by on (#204567)
DRW wrote:
But how do you avoid the lagging of music? If I simply set a counter in every NMI for every intended music call, this only means that a game logic lag will skip a certain amount of sound, but it will still lag.

Even Pokémon lags during blank-screen transitions, with the music skipping ahead to catch up to the tempo once the transition ends. This is better than what earlier Game Boy games like Tetris did, which was just to let music fall behind.

DRW wrote:
For example, let's take an extreme example: Let's say my game logic lags for five seconds in a certain situation.

If you can profile what function or combination thereof is eating 9 million cycles, call audio_update_if_needed() every so often during this task. The idea is that you try to call it at least once every 20,000 cycles (less than a frame), so that even if you mis-estimate and there ends up a 60,000 cycle (2 frame) gap, the player is unlikely to notice.

DRW wrote:
Unless I clutter all my code with nothing but music calls, but then I have the problem that music is already updated

In this case, audio_update_if_needed() will check the variable, see that nothing needs to be done, and do nothing. In C, it'd look like this:
Code:
extern unsigned char audio_lag_frames;

void audio_update_if_needed() {
  while (audio_lag_frames > 0) {
    audio_update();
    --audio_lag_frames;
  }
}


Or in assembly language:
Code:
.import _audio_lag_frames
.export _audio_update_if_needed

.proc _audio_update_if_needed
  lda _audio_lag_frames
  beq no_update_needed
  loop:
    jsr _audio_update
    dec _audio_lag_frames
    bne loop
  nope:
  rts
.endproc


DRW wrote:
So, if no interrupt ever switches a bank or writes to any other MMC1 register, can I be sure that an NMI that triggers in the middle of the bank switch function doesn't corrupt the bank switch status?

Correct.

DRW wrote:
What means are there in the MMC1 mapper to protect the battery data? How can I disable battery support and only enable it during writes?

In theory, there are two ways to disable the WRAM. On MMC1B and later, writing to $E000 (PRG bank) with bit 4 true causes the MMC1 not to raise WRAM +CE2 when WRAM is accessed. And on the SNROM board only, the mapper's CHR A16 output is connected to WRAM /CE1, which means writing to $A000 (CHR bank) with bit 4 true causes the MMC1 to hold /CE1 high. But in practice, if the MMC1 is itself losing power, it may lose the power to drive these signals. I'd need someone with a scope to confirm this for sure.
Re: MMC1 questions
by on (#204589)
I chose the following now, which is based on one of the suggestions from this thread:

Whenever the bank is switched, I set a flag.
Since there's only one bank switch in interrupts, the sound update in NMI, I check the flag before doing the sound update.
In the rare case where the NMI triggered in the middle of a bank switch, I skip the sound update and accept a sound lag of one frame (and don't try to catch up).
But if the NMI triggers during the game logic, but outside a bank switch, the music is continued normally.

This allows me to keep the bank switches simple, without that the whole "if it was interrupted, start the function again" stuff.


Another thing:
About the question "What happens when the NMI triggers while we're right in the middle of setting a sound effect?":

I don't know whether FamiTone can handle such a situation. But this question is moot anyway. Because we can also have the situation where two sound effects are played simultaneously in the same frame.

If the NMI triggers right between those two calls, we have an inconsistent sound status where one sound effect is already sent to the sound library and played, but another one from the same frame isn't.

That's why I will buffer all music and sound IDs in an array. And only in the end will I update all of them right after another.
And for this case, I will set the same flag as the one that I use for bank switches, so that the sound update doesn't start until all sound effects have been set.



I need to know one more thing:

Can MMC1 register writes to one register confuse the status of another register?
I.e., do I also have to set a "don't switch to the sound bank" flag when I switch the mirroring?

Or, in code form: Is the following a problem or does it work?
Code:
SetMmc1Config:
    STA $8000
    LSR
    STA $8000
    LSR
    STA $8000
    STA $E000 ; <-- Would this confuse the $8000 writes?
    LSR
    STA $8000
    LSR
    STA $8000
    RTS


tepples wrote:
In theory, there are two ways to disable the WRAM.

Now the question is: Should I do this?

Does disabling the WRAM mean that the whole 8 KB of battery-backed RAM are instantly deleted?
Because in this case, I'd rather not do this because it would delete all save states.

Or does it only mean that access to WRAM is impossible as long as it's disabled, so that powering off the console cannot produce any faulty writes to WRAM?
In this case, this might be useful, to enable it only when we write to it (or read from it at the start of the game), and then disable it again to protect it from corruption.

Which one is it?
Re: MMC1 questions
by on (#204591)
Quote:
Can MMC1 register writes to one register confuse the status of another register?
I.e., do I also have to set a "don't switch to the sound bank" flag when I switch the mirroring?

Absolutely. There's only one shift register in the MMC1, and only the last write determine which MMC1 register is actually written to. See the wiki for more info about this.

Quote:
Now the question is: Should I do this?

It's all up to you.

Quote:
Does disabling the WRAM mean that the whole 8 KB of battery-backed RAM are instantly deleted?

Of course not, it just makes WRAM inaccessible/open bus, but the data is still there intact (and that no matter whether the WRAM is battery backed or not).

Quote:
Or does it only mean that access to WRAM is impossible as long as it's disabled, so that powering off the console cannot produce any faulty writes to WRAM?
In this case, this might be useful, to enable it only when we write to it (or read from it at the start of the game), and then disable it again to protect it from corruption.

Exactly, I think that was the purpose of those disable bits in the 1st place. In practice, I suspect commercial games hardly ever used them, because most games with battery-backed WRAM also use the chip as extra general-purpose SRAM which is not related to saving games, and as such it's used all the time and isn't disabled. It should check some commercial games with FCEUX in order to see how they handle this.

tokumaru wrote:
Doesn't writing to $2000 mid-frame cause those glitchy scanlines that are common in SMB1? As far as I recall, the consensus was that we just shouldn't do it.

I don't think it's a major problem. I don't use MMC1 in my engine but also write to $2000 to disable NMI when initializing a sound effect pointer, so that the sound engine does never try to play a sound effect with a partially updated address (which can have almost catastrophic consequences).
Re: MMC1 questions
by on (#204592)
Bregalad wrote:
I don't think it's a major problem.

Well, I happen to find that glitch pretty annoying. I always noticed it as a kid when playing SMB at other peoples' houses and always wondered what that was, until someone here in the forums discovered the reason. I would never intentionally put glitches in my games if there were other options.

Quote:
I don't use MMC1 in my engine but also write to $2000 to disable NMI when initializing a sound effect pointer, so that the sound engine does never try to play a sound effect with a partially updated address (which can have almost catastrophic consequences).

Like I said before, you could simply put sound effect requests in a queue instead, and only process those requests in the NMI, right before calling the playback code.
Re: MMC1 questions
by on (#204601)
Bregalad wrote:
Exactly, I think that was the purpose of those disable bits in the 1st place. In practice, I suspect commercial games hardly ever used them, because most games with battery-backed WRAM also use the chip as extra general-purpose SRAM which is not related to saving games, and as such it's used all the time and isn't disabled.

I don't think I will need it as general RAM since the regular 2 KB are more than enough for me. (In fact, apart from larger arrays, I try to put all variables of my game into zeropage.)

So, if I disable and enable the WRAM access depending on the situation, is disabling it really an actual, "physical" protection from accidental random writes?

I.e. does disabling the WRAM mean that you don't have to do this whole "hold the Reset button when turning off the system" as long as you don't switch off the console in the middle of saving?
Re: MMC1 questions
by on (#204603)
Provided that the program keeps RAM writing disabled, and provided that the mapper can guarantee that disabling will continue even as the mapper is powering down, the user shouldn't have to hold Reset. But it may take an oscilloscope to prove that the mapper can guarantee that disabling will continue even as the mapper is powering down, as I imagine that in some situations, loss of power can cause the mapper to inadvertently generate enable signals.
Re: MMC1 questions
by on (#204607)
DRW wrote:
In the rare case where the NMI triggered in the middle of a bank switch, I skip the sound update and accept a sound lag of one frame (and don't try to catch up).
But if the NMI triggers during the game logic, but outside a bank switch, the music is continued normally.

It may be a rare case overall, but the distribution of stuff like this tends to be clustered.

Successive frames often do very similar stuff. The timing could easily be close enough from frame to frame to trigger this "rare" case 100 frames in a row, or continually until you move, etc.

The failure tends to look more like "the music hangs in this one room if I'm wearing the blue armour", a lot less subtle than just hanging for 1 frame at a time on rare occasions.


Same deal with tepples "count lag and catch up" suggestion, 1 frame of doubled music update probably doesn't sound that unusual, but doing it continually will. (And if you're not careful to cap it, you can get a runaway increase in workload as the extra updates cause even more lag on the next frame, cascading out of control.)


Solutions like that can be useful, but don't think of "rare" cases as being surrounded by a safety net of common cases. They come in bunches!
Re: MMC1 questions
by on (#204620)
DRW wrote:
I don't think I will need it as general RAM since the regular 2 KB are more than enough for me. (In fact, apart from larger arrays, I try to put all variables of my game into zeropage.)

In that case, using 80's economic logic, it makes almost no sense to use WRAM and battery, as it would make your game much more expensive than passwords. Heck, many mass-produced games which even used WRAM still used passwords instead of battery (Metroid, Kid Icarus) or nothing at all (SMB3) in order to be cheaper. Today it's entirely different, but I assume you're using 80's economic logic here, like I myself like to do (i.e. use only common mappers).

Quote:
I would never intentionally put glitches in my games if there were other options.

Well I never noticed glitches but if they ever become noticeable I'll probably change the approach and avoid writing to $2000 in dis-synchronization with the PPU. For me it has yet to cause any problems. Perhaps this is an NTSC-only and earlier revisions of PPU only thing, like the controller reading DMC glitch ?

Quote:
Same deal with tepples "count lag and catch up" suggestion, 1 frame of doubled music update probably doesn't sound that unusual, but doing it continually will. (And if you're not careful to cap it, you can get a runaway increase in workload as the extra updates cause even more lag on the next frame, cascading out of control.)

You don't have to catch up in the next NMI, you can catch up after the MMC1 switch is finished and it discovers it was interrupted by NMI.
Re: MMC1 questions
by on (#204621)
tepples wrote:
Provided that the program keeps RAM writing disabled, and provided that the mapper can guarantee that disabling will continue even as the mapper is powering down, the user shouldn't have to hold Reset.

Does "The Legend of Zelda" or "Final Fantasy" use that enable/disable feature anywhere?

rainwarrior wrote:
It may be a rare case overall, but the distribution of stuff like this tends to be clustered.

Well, the first thing that has to happen: The game has to lag at all. And of course, I'll try to avoid this as much as possible.

And even then, the ifs and elses that have to be gone through will be different in every frame. (When I enable intensity bits in PPUMASK to measure the time my code needs to run, the colored layer over the screen always jumps up and down.)
And bank switch and music update is a small piece of code in a huge ocean of code.

The last thing that is usually done in every frame is updating the sprites array ($0200) according to the meta sprites. In this case, we switch to the meta sprite bank once in the beginning. And then we iterate through all in-game characters to read their current meta sprite address.
If the game lags, it will probably lag in the middle of sprite updates where there's no further bank switch.

So, I would say that consecutive NMI hits during the same bank switch are very, very unlikely.

Bregalad wrote:
In that case, using 80's economic logic, it makes almost no sense to use WRAM and battery, as it would make your game much more expensive than passwords.

Yeah, I know. That's why I intended my game to be UNROM.
But my graphics artist absolutely hated the idea of passwords in a story-driven "Zelda"-like top down fantasy action adventure. So, to make her happy, I switched over to MMC1.

With the added bonus that I can now make her draw some huge character artworks for the game because with twice the memory, we will probably have enough room for this kind of excessive stuff.
And we don't have to be so cheap on in-game dialogs.

Oh yes, and since I like to hold code in the fixed bank (so the additional memory is good for game data, but the room for actual code is still the same), I got back 550 bytes by removing the "update the graphics row by row during vertical scrolling" feature since I can switch the mirroring, so vertical scrolling works just as easy as horizontal scrolling.

Does "The Legend of Zelda" even need the WRAM excessively? I mean, the game itself with its screen-by-screen logic surely gets along fine with the regular RAM. And as far as savestates are concerned: You need to save all the collected items, all burnt trees, all bombed walls. And what else? That should be pretty much it. I assume each savestate should need less than 100 bytes. So, isn't WRAM and a battery also a total waste here, but they still used it?
Re: MMC1 questions
by on (#204623)
Wouldn't battery backed CHR-RAM be an option here? You can put a battery in any CHR-RAM board to preserve the contents of the CHR-RAM chip, and "steal" a few tiles for the save data (8 tiles will give you 128 bytes). It's a little weird but really easy and cheap to implement.
Re: MMC1 questions
by on (#204625)
Is this something that was ever done in a licensed commercial game?
Re: MMC1 questions
by on (#204629)
I don't think so. Apparently only one unlicensed game did it (RacerMate Challenge II), but it's a thing, and it's supported by the NES 2.0 format. I figured you wouldn't be interested since this wasn't a common practice, but thought I'd mention it anyway.

Using CHR space for things other than tiles isn't so rare though. SMB and a bunch of CNROM games have data stored where tiles would normally be, so I guess developers weren't opposed to sacrificing a few tiles.
Re: MMC1 questions
by on (#204633)
Programming tricks like that are alright for me if it ever becomes necessary. But if the hardware wasn't used commonly back then, I will not create my game in this way.

Even though my cartridges will be built from all-new parts, I only do games that could be easily reproduces with donor cartridges of widely available games.

UNROM with 128 KB is fine since there are countless games like that.

UNROM with 256 KB would be out of the question or at least I would do this only very, very reluctantly. How many copies of "Paperboy 2" or "Best of the Best - Championship Karate" exist out there? 20? 30?

UNROM 512 would be totally disqualified since it didn't exist until it was manuafactured for homebrews.

MMC1 with 256 KB is already acceptable because of "Final Fantasy" alone, a hugely successful game, but I assume there are more games with this mapper and this ROM size.
Re: MMC1 questions
by on (#204634)
DRW wrote:
So, isn't WRAM and a battery also a total waste here, but they still used it?

The cartridge Zelda is an FDS conversion. FDS has that 8 KB extra RAM built in.
Re: MMC1 questions
by on (#204636)
Yeah, but when they converted it to cartridge form, they still opted for a battery and not for a password system like in "Metroid". And I'd like to know: Was it necessary because the additional 8 KB are really used extensively? Or could they have converted it to a password system, but they just said "Eh, screw it"?
Re: MMC1 questions
by on (#204639)
DRW wrote:
Even though my cartridges will be built from all-new parts, I only do games that could be easily reproduces with donor cartridges of widely available games.

Adding a battery without address decoding logic (as would be the case for CHR-RAM) is probably much easier than desoldering mask ROMs and replacing them them with rewired Flash/EPROMs, which people using donors would have to do anyway.

Quote:
UNROM with 256 KB would be out of the question or at least I would do this only very, very reluctantly. How many copies of "Paperboy 2" or "Best of the Best - Championship Karate" exist out there? 20? 30?

You don't need any of these "rare" games, since the UNROM 128 boards already have all the hardware to support 256KB, they just left one of the address lines disconnected. With a little rewiring, any UNROM 128 can become an UOROM. This was one of my first hardware projects (unfortunately the pics are gone, but I still have the board somewhere, so I could grab new ones): viewtopic.php?f=9&t=2849

So yeah, there's absolutely nothing hard or obscure about battery-backed CHR-RAM or UOROM, as these are some of the simplest mods one can do to donor cartridges, even simpler than the mandatory ROM replacement. If someone has the skill to swap ROMs, they can add a battery or connect the extra address line of UOROM just fine.

But if you're so hung up on using "popular" configurations from back in the day, that's fine. I'm just trying to debunk the myth that some of the less common configurations make the production of carts harder or more expensive. In fact, the games you often mention as examples of battery-backed MMC1 games are crazy expensive, and would never be used as donors, so I don't know how easy it is to come by a reasonable MMC1 donor, so modifying an UNROM might actually be easier/cheaper. IDK.
Re: MMC1 questions
by on (#204640)
It's more a thing that I do on principle: There were no battery-backed UNROM games or UNROM games with 512 KB, so I will not use them. It's not so much about actual practical doability since the games will be manufactured with new boards anyway.

When I create an NES game, I always imagine when this game would have come out if we were an actual 80s video game company in an alternate history.

"City Trouble" is supposed to be a game from 1986 that we worked on after discovering the NES in New York of 1985. I could have easily let my artist create modern-looking graphics, but I consciously opted for launch title aesthetics.

The new adventure game uses a gameplay similar to "Zelda", but with a real in-game story like in "Final Fantasy Adventure". So, I will not use anything that didn't exist in 1991/1992.

If I ever do my "A Nightmare on Elm Street" game based on the 1984 movie, it will be a simple game again.
(Since "City Trouble" is established to be our first game when we discovered the NES and it is already from 1986, I will probably create a backstory for the "Nightmare" game where we were working on an arcade game for another company in 1984, but the company went broke and the game never came out. So, after we set a foot in the market with "City Trouble", I ported my own, never-released arcade game to the NES.)

If I ever created an NES game based on "Django Unchained", I would be free to use modern mappers since the game would also be modern inside that fictitious history.
Re: MMC1 questions
by on (#204641)
tokumaru wrote:
In fact, the games you often mention as examples of battery-backed MMC1 games are crazy expensive

I don't know how you define crazy expensive, but "Final Fantasy" can be bought for $20-$40 on eBay. Surely not suited for mass-production, but still reasonable if the game is not available anymore and someone wants to get a reproduction of it.
Re: MMC1 questions
by on (#204642)
DRW wrote:
It's more a thing that I do on principle: There were no battery-backed UNROM games or UNROM games with 512 KB, so I will not use them. It's not so much about actual practical doability since the games will be manufactured with new boards anyway.

When I create an NES game, I always imagine when this game would have come out if we were an actual 80s video game company in an alternate history.

Ah, finally someone who understands me and have the same philosophy as I ! I've always come with that philosophy, make games as they were made back then, and I do not aim to push the system to its limit or invent new things. Whether this is feasible in hardware easily or not is a totally orthogonal question.

That's why I find it even weirder you don't insist more on passwords. Games with battery back up were really a small minority of games back then. I suspect that actually WRAM was not really more expensive as of 1988 or so, but batteries sill were expensive, and that up until the end of the console's life. The fact many games had to use CHR-RAM means Nintendo had to buy 8k SRAM chips in mass quantity anyway, so if games also used for PRG-RAM it doesn't make such a difference, just a minor cost increase. That's why it's common to see games that said "screw it" and added a 8k SRAM chip in the cartridge, probably it was only a minor cost addition to the cartridge, however only games that needed really complex saving system used battery backup.

That explains why CHR-RAM battery backup wasn't done; In theory it sounds nice, it's just a battery added to a normal game cartridge and does not require any extra chips (just extra discrete parts). But the problem is not the cost of the extra 8k SRAM chip, nor the extra PCB area, but the problem is indeed the cost of the battery which is very significant and cannot be reduced.

I suspect EEPROM saving was even more expensive, considering it was only used in a couple of games in Japan made by Bandai.

In addition to that, Passwords has the advantages you can write them down on a sheet and re-use them as many times as you'd like, unlike battery saves which are gone as soon as you overwrite them with another battery save. Even if you dedicate the whole 8k chip to saves you could have more save slots, but there's still a limited amount of them. Also loosing saves is a real problems. I've lost my saves regularly no matter whether I pressed RESET or not. When I did a whole playthrough of Final Fantasy 3 on real hardware, I usually saved to all 3 of the save slots to ensure at least one of them would remain on the next booting session. It was not rare than the first or the second save slot were randomly erased, only the 3rd one seemed more stable.

Quote:
Or could they have converted it to a password system, but they just said "Eh, screw it"?

To be honest, for me it's still a mystery to me why Zelda used battery saves when Metroid and Kid Icarus, using the same game engine, didn't. My wild guess is that selling Zelda more expensive was more acceptable because it came with a gold package (except some later revisions) and came with a walkthrough included.

Quote:
Does "The Legend of Zelda" or "Final Fantasy" use that enable/disable feature anywhere?

I can't comment on "The Legend of Zelda" (you should look it up using FCEUX), but I can guarantee you Final Fantasy does not use the WRAM disable bits, at least not directly. The CHR-banking regs are just written to with "00000" at startup, which enable SRAM. It's possible that it's disabled at power-on if the MMC1 internally initialize to "11111". All PRG bankswitching is done with the top bit at "0", which means again that SRAM is enabled (and again, it is likely that the MMC1 defaults to "1" effectively disabling SRAM at power-on).

Actually I'd be very interested to know if/which games ever used those bits other than setting them to "0" at start-up and never chanting them ever again.

Quote:
I don't know how you define crazy expensive, but "Final Fantasy" can be bought for $20-$40 on eBay.

Both "The Legend of Zelda" and "Final Fantasy" are well known because of their franchise. I'd expect SNROM games which aren't part of a well known franchise to be significantly cheaper (and also, in some cases, less shameful to destroy).

Quote:
Using CHR space for things other than tiles isn't so rare though. SMB and a bunch of CNROM games have data stored where tiles would normally be, so I guess developers weren't opposed to sacrificing a few tiles.

But this is with CHR-ROM, which is a completely different thing than CHR-RAM.
Re: MMC1 questions
by on (#204645)
Bregalad wrote:
But this is with CHR-ROM, which is a completely different thing than CHR-RAM.

Of course, these are totally different scenarios, but both involve the sacrifice of a few pattern table slots that can't be used for graphics anymore.
Re: MMC1 questions
by on (#204647)
DRW wrote:
UNROM with 128 KB is fine since there are countless games like that.

UNROM with 256 KB would be out of the question or at least I would do this only very, very reluctantly. How many copies of "Paperboy 2" or "Best of the Best - Championship Karate" exist out there? 20? 30?

Converting UNROM to UOROM isn't significantly more complicated than the rewiring needed to use UVEPROM or flash memory in the first place: three wires to route D3 through the '161 and the '32 to PRG ROM A17. But dead-bugging a WRAM onto a donor would be a job.

DRW wrote:
MMC1 with 256 KB is already acceptable because of "Final Fantasy" alone, a hugely successful game, but I assume there are more games with this mapper and this ROM size.

NesCartDB's list of 2 Mbit MMC1 games with 64 kbit CHR RAM and WRAM with battery shows about 50 games, mostly Japan-only, but including Destiny of an Emperor, Dragon Warrior II, Final Fantasy, Genghis Khan, AD&D: Hillsfar, Maniac Mansion, NES Open Tournament Golf, Nobunaga's Ambition, Romance of the Three Kingdoms, Shingen the Ruler, and three Ultima games. I've heard Ultima: Exodus in particular mentioned as a relatively common yet forgettable SNROM donor.

A few of these (Khan, Nobunaga, and Three Kingdoms) are SOROM, which differ from SNROM primarily in having two WRAMs, only one of which is connected to the battery. SOROM can protect save RAM from stray writes even if you're using WRAM as work RAM: load the extra fixed bank code into WRAM 0, which isn't battery-backed, and the save data into WRAM 2, which is.
Re: MMC1 questions
by on (#204652)
DRW, I can understand not using battery-backed CHR-RAM if you're trying to be period-accurate, since no matter how simple/cheap it is, this solution was never used by licensed games, but your "prejudice" against UOROM is exaggerated, considering that any UNROM board can support 256KB with the addition of just a few wires, and that a few licensed games did use that configuration.
Re: MMC1 questions
by on (#204661)
Bregalad wrote:
That's why I find it even weirder you don't insist more on passwords.

That wasn't my decision.
I don't work alone, I have a team of a graphics artist and a sound composer. And these are not some random strangers from the internet, these are my two best friends that I spend every lunch break with.

I wanted to do passwords, but my graphics designer is against it.
Why is she against it? Because we're not doing some simple little game like "Gauntlet", but a full-blown action adventure with 16 x 16 overworld screens, a good bunch of dungeons and a real plot where the story develops as you go along.
(Regarding the story, "Zelda" and "Final Fantasy" are even much simpler: You have an initial task and then you simply find a certain amount of a specific item and then you go to the final boss.
If you want to see what way of storytelling we will do, have a look at "Final Fantasy Adventure" for the Game Boy.)

And having passwords in such a JRPG-like top-down open-world plot-heavy adventure game is something she absolutely despises, especially since almost no NES adventure game does it.
O.k., "Willow", "Magic of Sheherazade", "Times of Lore" and "Robin Hood" do it.
Two of them are movie conversions (one of them quite crappy) and one is a western adventure game that originated on home computers.

But the real Japanese games from the action adventure and RPG genre: "Zelda", "Final Fantasy", "Dragon Warrior", "Destiny of an Emperor", "Faria", "Crystalis", "Star Tropics". They all use battery saves.

That's why I gave in and said: "O.k., fine, I'll change the game to MMC1."
You gotta have to make your team members happy.

By the way, if we did a side-scrolling adventure game like "Faxanadu", "Castlevania II" or "Battle of Olympus", she would have no problem with a password.

tokumaru wrote:
DRW, I can understand not using battery-backed CHR-RAM if you're trying to be period-accurate, since no matter how simple/cheap it is, this solution was never used by licensed games, but your "prejudice" against UOROM is exaggerated, considering that any UNROM board can support 256KB with the addition of just a few wires, and that a few licensed games did use that configuration.

Well, this isn't an issue anymore anyway. We do MMC1 now because of the battery save. So, I don't need to think about whether UOROM would be acceptable for me until I do the next game.
Re: MMC1 questions
by on (#204667)
Quote:
Well, this isn't an issue anymore anyway. We do MMC1 now because of the battery save. So, I don't need to think about whether UOROM would be acceptable for me until I do the next game.

Indeed, and UNROM/UOROM plus saved SRAM is almost out of question for both of us because it wasn't done back then (even if it shouldn't be that hard to do with hardware).

Quote:
That wasn't my decision.
I don't work alone, I have a team of a graphics artist and a sound composer. And these are not some random strangers from the internet, these are my two best friends that I spend every lunch break with.

Well you're lucky ! It remembers me 10 years ago... Now I'm alone and the advantage is that I do what I want, but the problem is that most of the cases I don't know what I want and I lack ideas/imagination like I had when I was younger. Also being alone makes being motivated much harder.

Quote:
But the real Japanese games from the action adventure and RPG genre: "Zelda", "Final Fantasy", "Dragon Warrior", "Destiny of an Emperor", "Faria", "Crystalis", "Star Tropics". They all use battery saves.

Dragon Quest I and II actually uses passwords. Only from Dragon Quest III and the american Dragon Warrior I (released almost simultaneously) they started to use battery saves.

Quote:
Why is she against it? Because we're not doing some simple little game like "Gauntlet", but a full-blown action adventure with 16 x 16 overworld screens, a good bunch of dungeons and a real plot where the story develops as you go along.
(Regarding the story, "Zelda" and "Final Fantasy" are even much simpler: You have an initial task and then you simply find a certain amount of a specific item and then you go to the final boss.
If you want to see what way of storytelling we will do, have a look at "Final Fantasy Adventure" for the Game Boy.)

Actually whether passwords is an acceptable system or not does not depend on the game genre at all, but rather the amount of data to be saved. But oh well, if your friends /colleagues really didn't want it I think I can't change their minds :p
Re: MMC1 questions
by on (#204669)
Bregalad wrote:
Dragon Quest I and II actually uses passwords.

Yeah, even in our hypothetical reality, we're still a German company and not Japanese developers, so she would still judge the situation based on western releases of the game.

Bregalad wrote:
Actually whether passwords is an acceptable system or not does not depend on the game genre at all, but rather the amount of data to be saved. But oh well, if your friends /colleagues really didn't want it I think I can't change their minds :p

I guess it has mostly to do with epicness: Entering a password makes the game feel like a simple little game. But having a battery save makes it feel like one of those huge Square RPGs.
Re: MMC1 questions
by on (#204671)
DRW wrote:
MMC1 with 256 KB is already acceptable because of "Final Fantasy" alone, a hugely successful game, but I assume there are more games with this mapper and this ROM size.

Bootgod's database has a search feature for answering that kind of question:

http://bootgod.dyndns.org:7777/search.php?romsize=256&&ines=1&battery=Yes
Re: MMC1 questions
by on (#204673)
DRW wrote:
Yeah, even in our hypothetical reality, we're still a German company and not Japanese developers, so she would still judge the situation based on western releases of the game.

Well, JRPGs in Europe were existant until the mid 1990s, outside the Zelda franchise. I could be wrong but don't think anyone here would even know the genre existed at all. Secret of Mana was the first JRPG-like game to be released here with a great success, but it's an A-RPG. Final Fantasy Adventure was released here before that, but I think it was largely unsuccessful (the translation is awful, too).
Final Fantasy franchise was unheard off here before 1997 and the release of Final Fantasy VII for the PS1 (ok, Final Fantasy Mystic Quest was released, but I think it sold very poorly and that nobody noticed it).

Rare was the only large NES game developer based in Europe. There was however also the company that made Asterix (based in spain) and the guys that made Elite, I think they were from France ? Also there is Software Creations, I think from the UK but only did a single NES game (Solstice), but at least it's a great game.
Re: MMC1 questions
by on (#204675)
Bregalad wrote:
Well, JRPGs in Europe were existant until the mid 1990s, outside the Zelda franchise. I could be wrong but don't think anyone here would even know the genre existed at all.

As a game company that develops NES games and who got into contact with the NES in New York in 1985, we of course have good connections to the American market. (Even "City Trouble" was programmed with NTSC in mind.) So, of course, we know about "Final Fantasy" and "Dragon Warrior". However, we only have a rudimentary knowledge of Japan-only Famicom games. That's why Katrin is aware of the battery saves in the JRPG games, but not that the Japanese version of "Dragon Quest" uses passwords. :wink:

Bregalad wrote:
Final Fantasy Adventure was released here before that, but I think it was largely unsuccessful (the translation is awful, too).

Whether successful or not, this game is the one that inspired us to do a story-driven game in the first place.
This time this is even true in the real world because I couldn't find an NES game with a real on-going story. Also, I even played this game in the 90s, so yeah, in reality and in our fictitious history, I knew of the game. (I even had "Final Fantasy - Mystic Quest".)

Bregalad wrote:
Rare was the only large NES game developer based in Europe. There was however also the company that made Asterix (based in spain) and the guys that made Elite, I think they were from France ? Also there is Software Creations, I think from the UK but only did a single NES game (Solstice), but at least it's a great game.

And Den Kat Games, from Germany. :mrgreen: Although I didn't decide yet whether we have been a licensed or an unlicensed developer.
Re: MMC1 questions
by on (#204679)
rainwarrior wrote:
Bootgod's database has a search feature for answering that kind of question:

http://bootgod.dyndns.org:7777/search.php?romsize=256&&ines=1&battery=Yes

That would appear to include SKROM games with 256 KiB PRG + 128 KiB CHR, which is why I added &vram=8 to my query a few posts up. Yet your results are the same as mine. I'm surprised that there aren't actually any 3 Mbit SKROM games.

DRW wrote:
Although I didn't decide yet whether we have been a licensed or an unlicensed developer.

Given how close to UNROM the Codemasters board behaves, I imagine an unlicensed developer would more likely have gone with a custom UOROM+WRAM board.
Re: MMC1 questions
by on (#204682)
tepples wrote:
...my query a few posts up.

Ah, whoops. Sorry for the redundancy, I probably thought I was at the end of the thread at the bottom of the second page when I hit reply. :P
Re: MMC1 questions
by on (#204684)
DRW wrote:
tokumaru wrote:
DRW, I can understand not using battery-backed CHR-RAM if you're trying to be period-accurate, since no matter how simple/cheap it is, this solution was never used by licensed games, but your "prejudice" against UOROM is exaggerated, considering that any UNROM board can support 256KB with the addition of just a few wires, and that a few licensed games did use that configuration.

Well, this isn't an issue anymore anyway. We do MMC1 now because of the battery save. So, I don't need to think about whether UOROM would be acceptable for me until I do the next game.

Sure, I know you've decided on the MMC1 for your current game, so I was indeed talking about UOROM for future projects.