MMC1 versions, WRAM disabling, and save 'durability'

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
MMC1 versions, WRAM disabling, and save 'durability'
by on (#110432)
So I've found what appears to be conflicting data on this dang old 'R' WRAM enable bit that was implemented in later versions of the MMC1. What follows is a regurgitation of what I've seen in our various sources, and what I've found in experiment sorry if it's tough to read, but I don't know how to present it much better than what follows. Fair warning, the text below is a bit of me rambling on... :) If you go to the end you'll see where I'm looking for input from the community on the best solution on how to implement the various behaviors on a single design.

All sources I've found claim that the'R' bit exists on MMC1B and later. I have found that the MMC1 is much more 'durable' to abusive power cycling when this 'R' bit is in place while testing on by CPLD boards. The value of start up on MMC1B's is a separate debate, but I don't think it matters much. The value at start up doesn't seem to affect save 'durability' much. So it makes sense that Nintendo implemented this bit later in life.

Additionally I found that my saves were fairly susceptible I to data loss from abusive power cycling, measurably worse than the original carts even when I had this 'R' bit in place. I tried several things to improve my boards so they were at least comparable to Nintendo's. I deviated slightly from Nintendo's design and gave WRAM /WE signal to the mapper's control, vice directly wiring it to PRG R/W. So my design will take /WE high whenever the /CE pin is high, and only passes through PRG R/W to /WE when /CE is low. This appeared to significantly improve the save durability during abusive power cycling.

Note, I am working with SNROM and it's 'E' bits which are implemented on all SNROM boards AFAIK, even on early mmc1 versions without the 'R' bit. My E bits are internal to the CPLD since the SRAM I typically use only has a single chip enable (/CE).

The issue/surprising thing I found was when testing the game 'Sweet Home'. I don't have access to bootgod's DB at the moment, but from what I recall the cart there has a MMC1B2. Which according to all sources should have the 'R' bit implemented. But I found when playing this game is that the attribute tables appeared messed up after the opening title scene. I haven't gone as far as dissecting the ROM and probably should have, but it appears that this game is relying on the 'R' bit to not exist. And yes it works just fine with the 'E' bits fully operational.

So a few questions come to mind. Are there any emulators that implement the 'R' bit? I know most don't implement the 'E' bits. Does any one know of a game that relies on the later version of MMC1 with the 'R' bit? I'm guessing that most emulators don't even bother with the 'R' bit since there isn't much function other than to improve save durability from what I can tell.

So I've got a plan on how to implement things that is a sort of hybrid of early and late versions of the MMC1 and curious what people think about it. Since the 'R' bit does improve save durability I'd like to keep it in my design. While it is still decent without the 'R' bit, it only takes a min or two of heavy power cycling to loose a save slot or two on Zelda. But from what I've found some games apparently rely on this bit to not exist during operation. So I'm thinking about implementing the 'R' bit from start-up until the MMC1 is reset via 'PRG D7'. At which point the 'R' bit would cease to have any effect. In doing this I figure I'll have the most durable saves I can make (given the hardware limitations of my current design which I don't see reason to change), and also have the added compatibility since my small sampling of games only found titles that relied on the 'R' bit to not exist (I'm unaware of any titles that rely on it's existence).

Thoughts? Criticisms? Questions?

All though now that I put all of this to words, I'm realizing that I may have a better logic saving alternative which is kind of already in-place with the 'E' bits. If the 'R' bit improves the durability regardless of startup value, then why doesn't the 'E' bits themselves give me the same durability. Perhaps there's power in numbers and the combo of all 3 logic bits gives me better chances of keeping /CE high during undefined power cycling. One idea might be to just do away with the 'R' bit all together, and have the two separate E bits with the CHR in 4KB mode at s/u. My CPLD actually starts up in 8KB mode at the moment, so I've really only got the effect of one 'E' bit at power on. Although I can't control that the rom most likely uses 8KB mode leaving me with effectively only one 'E' bit at power down either way. I'd expect that saves are generally lost at power down and not power on.
Re: MMC1 versions, WRAM disabling, and save 'durability'
by on (#110435)
When a save is destroyed, how many bytes does it spray over?

Has anyone here managed to implement Reed-Solomon coding on a 6502?
Re: MMC1 versions, WRAM disabling, and save 'durability'
by on (#110437)
I seem to remember finding that the first few bytes of SRAM were most susceptible to corruption. I did some kind of hardware patch to my devcart to make basically unaffected by the most vigorous power on/off I could abuse it with. OK, looks like I put a 100 ohm resistor in parallel with the 10K resistor that goes from the SRAM's GND to pin 6 on the MMC1. I do remember experimenting with various values and abusing the power switch until I found one that was ironclad.
Re: MMC1 versions, WRAM disabling, and save 'durability'
by on (#110438)
infiniteneslives wrote:
I don't have access to bootgod's DB at the moment, but from what I recall the cart there has a MMC1B2
You recall correctly.
infiniteneslives wrote:
So a few questions come to mind. Are there any emulators that implement the 'R' bit?
Nestopia-1.4.0h does. I don't see the corruption you describe, though.
infiniteneslives wrote:
why doesn't the 'E' bits themselves give me the same durability
In an authentic MMC1, the E bit goes to the 6264's /CE pin, and the CHR bits are believed to be random on power up (and so there's a 50% chance of not being protected). Obviously you could do differently...
Re: MMC1 versions, WRAM disabling, and save 'durability'
by on (#110442)
Quote:
In an authentic MMC1, the E bit goes to the 6264's /CE pin, and the CHR bits are believed to be random on power up (and so there's a 50% chance of not being protected). Obviously you could do differently...

As already discussed in the SRAM initialisation thread, undefined and random are very different.
When powered up an uninitialized flip flot will randomly pick a '1' or a '0', but from personal experience I can tell the same flip flop will likely always pick the same value.

So your sentence would rather be : With a given MMC1 you have 50% of chances of being protected (always), and 50% of chances of not being protected (always).
However those probabilities are probably not 50% and 50%. This could be easily tested with a program that resides in main RAM and reads the data from various cartridges with MMC1s in them that are inserted (a very clever trick invented by Blargg).
Re: MMC1 versions, WRAM disabling, and save 'durability'
by on (#110458)
SNROM for me disabled WRAM on the PRG-register bit, not the CHR-bit? At least thats what I wrote my program to use...and that's what it reported. Disableable:Yes. It was an MMC1B2 from Open Golf.
Re: MMC1 versions, WRAM disabling, and save 'durability'
by on (#110462)
tepples wrote:
When a save is destroyed, how many bytes does it spray over?

Not sure, my testing was pretty simple. I just filled all three save slots of Zelda and power cycled repetitively. It seemed like the last slot was usually the first to go, then the second, then the first. I'm not sure if that's how they were arranged in actual addressing though.

blargg wrote:
OK, looks like I put a 100 ohm resistor in parallel with the 10K resistor that goes from the SRAM's GND to pin 6 on the MMC1.

Effectively a 100 ohm then, (10k & 100ohm in parallel = 99 ohms) I'm using a 10k because that's what Nintendo did and it's a nice large value that still works. 100 ohms is actually pretty small when the MMC1 outputs a high ~4.5v on your 99ohm pull down you're drawing (I = V/R, 4.5v/100ohm = ~45mA) That's quite a bit of current... It probably can't actually supply that much current because your stressing that line driver pretty hard only a matter of time before it gives out I'd guess. (I'd also guess the mmc1 gets warm to the touch) It would pull down a lot quicker though, and might be why you saw improved 'save' durability. A 10k gives you 0.5mA which is a lot safer current for a unknown digital IC driver.


lidnariq wrote:
infiniteneslives wrote:
So a few questions come to mind. Are there any emulators that implement the 'R' bit?
Nestopia-1.4.0h does. I don't see the corruption you describe, though.

Interesting, wonder if I have some other bug going on... I'll have to dissect the rom and try to figure out what's triggering the issue. I'm literally removing comments to select the 'R' (aka 'B' per kevtris) in my implementation and confirmed I can remove and re-insert the issue in sweet home, for anyone curious:
Code:
   //MMC1A has no B bit             
   //if ((prg_addr == 2'b11) & (prg_ce == 1) & (m2 == 1))               
   
   //MMC1B su low -> 0 enabled  'B'  (Deemed best saves surprisingly)
   if ((B == 0) & (prg_addr == 2'b11) & (prg_ce == 1) & (m2 == 1))      

   //MMC1C su low -> 0 disabled 'Bn' (probably just as good as B, hard to tell)
   //if ((Bn == 1) & (prg_addr == 2'b11) & (prg_ce == 1) & (m2 == 1))   
   begin //enabled
      //w_ce_n = 1'b0; //raw signal to WRAM on non-SNROM boards
      w_ce_int = 1;    //used for SNROM anding CHR A16 signal
      w_we = prg_rw;   //allows for PCB simplification and possibly better save protection
      end
   else

   begin //disabled
      //w_ce_n = 1'b1; //raw signal to WRAM on non-SNROM boards
      w_ce_int = 0;    //used for SNROM anding CHR A16 signal
      w_we =      1;
      end

...

always @ (w_ce_int) 
begin
    
   //combine w_ce signal and ca16 signal to create a single WRAM /CE output
   if ((w_ce_int == 1) & (ca16 == 0))  //    CE==1 and /CE==0
      begin //enabled
      w_ce_n = 0;      //my SRAM only has one chip enable
      end
   else
      begin //disabled
      w_ce_n = 1;
      end



Here's what I'm seeing:
Image

Image
The opening scene is fine, and the 'door' scene is good. Since Nestopia doesn't see the issue I'm guessing I have something else going on...


Quote:
infiniteneslives wrote:
why doesn't the 'E' bits themselves give me the same durability
In an authentic MMC1, the E bit goes to the 6264's /CE pin, and the CHR bits are believed to be random on power up (and so there's a 50% chance of not being protected). Obviously you could do differently...

Yeah that's what I'm thinking mine's defaulting to E bits enabled in 8KB. But I may try s/u E bits disabled and test each CHR mode although I'm guessing I won't be able to easily measure the difference by my current testing means.

Bregalad wrote:
So your sentence would rather be : With a given MMC1 you have 50% of chances of being protected (always), and 50% of chances of not being protected (always). However those probabilities are probably not 50% and 50%. This could be easily tested with a program that resides in main RAM and reads the data from various cartridges with MMC1s in them that are inserted (a very clever trick invented by Blargg).

Relying on the 50% is basically asking for failure... There's no need to measure the exact amount of failure ;) Either way I don't intend to exactly emulate the MMC1's and variants including it's random unknowns between one chip and another due to fabrication process variations. I can control register start up low or high in a CPLD, so I'm trying to use that to my advantage.

3gengames wrote:
SNROM for me disabled WRAM on the PRG-register bit, not the CHR-bit? At least thats what I wrote my program to use...and that's what it reported. Disableable:Yes. It was an MMC1B2 from Open Golf.

Indeed there are two separate enables for SNROM boards. MMC1 pin6 controls CE, address decoding of WRAM and the 'R' bit depending on the revision. On SNROM the CHR A16 line *always* controls the WRAM /CE for 'software disabling' of WRAM even on mmc1 variants without the 'R' bit.

So your test rom is only verifing one of the chip enables (/CE to be specific). You're getting what you expect though because BOTH chip enable pins must be enabled to activate the SRAM. So you're really only testing one disable method. If you additionally tested the 'R' bit separately then you'd determine whether or not the mmc1 was 'old' (without the 'R' bit) or 'new' (with the 'R' bit). Either way the CHR A16 enable bits 'E' exist, it's not an either/or situation.
Re: MMC1 versions, WRAM disabling, and save 'durability'
by on (#110464)
For curiosity's sake, I looked at an execution trace. Before it ever touches WRAM, Sweet Home writes the following registers: $A000←$00 $C000←$00 $8000←$0E $8000←$0E $E000←$0B $E000←$00 $E000←$0A $E000←$0A. So I'm hard pressed to see how it would be different from any other MMC1B game.
Re: MMC1 versions, WRAM disabling, and save 'durability'
by on (#110466)
Quote:
Relying on the 50% is basically asking for failure... There's no need to measure the exact amount of failure Either way I don't intend to exactly emulate the MMC1's and variants including it's random unknowns between one chip and another due to fabrication process variations. I can control register start up low or high in a CPLD, so I'm trying to use that to my advantage.


We can't know if we don't measure it. Pehaps those flip flops are made in a way so they always start in a "set" state, which means you'd always be protected.

Another option could be that Nintendo tests their chips, and chips with an initial "1" state would be soldered on SNROM carts while chips with an initial "0" state would be attributed to other carts... while for some reason I'm myself not very convinced with this theory...

I could write such a test (it would only work with SNROM boards and with MMC1 games with 128kb of CHR unfortunately) but I don't have loads of carts to test it on (5-6 at the very most). Someone that owns >30 of such games (such as bootgod) should do the test instead.
Re: MMC1 versions, WRAM disabling, and save 'durability'
by on (#110468)
Bregalad wrote:
Pehaps those flip flops are made in a way so they always start in a "set" state, which means you'd always be protected.

And that would actually be rather simple to do in NMOS - a flip-flop is just two cross-coupled inverters, and since NMOS inverters are just a pull-down transistor and a pull-up resistor, giving one of those resistors a lower resistance would cause that side to go high before the other one does, forcing a particular power-on state.
Re: MMC1 versions, WRAM disabling, and save 'durability'
by on (#110470)
Are the MMC1 made with NMOS or CMOS technology ?
Re: MMC1 versions, WRAM disabling, and save 'durability'
by on (#110680)
infiniteneslives wrote:
blargg wrote:
OK, looks like I put a 100 ohm resistor in parallel with the 10K resistor that goes from the SRAM's GND to pin 6 on the MMC1.

Effectively a 100 ohm then, (10k & 100ohm in parallel = 99 ohms) I'm using a 10k because that's what Nintendo did and it's a nice large value that still works. 100 ohms is actually pretty small when the MMC1 outputs a high ~4.5v on your 99ohm pull down you're drawing (I = V/R, 4.5v/100ohm = ~45mA) That's quite a bit of current... It probably can't actually supply that much current because your stressing that line driver pretty hard only a matter of time before it gives out I'd guess. (I'd also guess the mmc1 gets warm to the touch) It would pull down a lot quicker though, and might be why you saw improved 'save' durability. A 10k gives you 0.5mA which is a lot safer current for a unknown digital IC driver.

Looked at this on a scope and you're right; the CE to the SRAM only goes to about 2.1V. I'd have left just the 10K in there except the SRAM would get corrupt often. With the 100 ohm it works and doesn't get corrupt when powering off/on. MMC1 isn't hot. It's only driving this on SRAM accesses. Anyway, you're right, it is a hack, but might be useful for someone who wants to make the tradeoff.
Re: MMC1 versions, WRAM disabling, and save 'durability'
by on (#110681)
So it looks like the MMC1's capable of about 20mA max. Did you ever try something like a 500ohm resistor? That should still pull down quickly and put a 10ma load on the MMC1. A 1k with ~5ma sounds better, but might not be as quick to give you more durable saves.

I'm surprised you didn't get good saves with the 10k though. Nintendo used 10k's after all and there are no issues. Did you use your own diodes? Or were they already on the board? You NEED to use Schottky diodes. Standard rectifier diodes aren't fast enough, plus they have a larger foward biased voltage drop ~0.7v compared to ~0.2v. I tried a standard diode before for saves and it failed often, Schottky's are key.