MMC5 Hacking Adventures

Discuss hardware-related topics, such as development cartridges, CopyNES, PowerPak, EPROMs, or whatever.

Moderator: Moderators

User avatar
Ben Boldt
Posts: 1148
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: MMC5 Hacking Adventures

Post by Ben Boldt »

Early findings but I found very clear correlations with a few registers that do and do not exist:
Register Existence.png
In this scope shot, a lower delta-I means a higher current draw by the MMC5. About 200 nsec after the rising edge of M2, something else has a small current spike. This current spike is large with registers $5000 and $5002 and small with registers $5020 and $5001. Comparing $5020 directly to $5001, they are the same. The scope shot compares $5020 ("valid address" signal high: invalid) to $5002 (valid address signal low: valid). Valid address is just an extra pin I am setting on the dsPIC. Also seen in the screenshot is CPU A1, demonstrating acceptable pull-up on address bus now that I changed that to 1k pull-ups today. The screenshot is a 512 sample average. I am triggering on my valid address signal. To verify that this difference is not an artifact of averaging or triggering somehow, I inverted the valid address signal, and spike still followed the valid address, i.e. the spike was present when valid address was high in that case.

This looks promising so far, will continue experimenting this evening.



Update:
This IS a highly effective way to see what registers are writable! I have found these registers to be writable:

5000
NOT 5001 (Confirms what we suspected, no pulse sweep unit)
5002
5003
5004
NOT 5005 (Confirms what we suspected, no pulse sweep unit)
5006
5007
5010
5011
5015
Unfortunately, nothing else until $5100 :(

5100
5101
5102
5103
5104
5105
5106
5107

NOT 5110-5112 (Confirms what we suspected)
5113
5114
5115
5116
5117

5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
512A
512B
NOT 512C-512F (Formally ending any remaining suspicion from my buggy tests from before)

5130

5200
5201
5202
5203
5204
5205
5206
5207 (Confirming this unknown register very likely exists)
5208
5209
520A


To do this, I set my scope in 8-sample average mode, running. I ran the same test with the invalid address and the valid address, but I added an I2C command that could change the valid address. In the GUI on my computer, I added a text box and button that would send a new address. The address auto-incremented after clicking the button. So I was able to keep clicking the button and watching the scope to test series of addresses efficiently. I found it best to set 1 horizontal cursor to the bottom of that magic dip on an invalid address and the other cursor to the flat spot right before it. Because the whole waveform shifts up and down slightly depending on the address, I would visually compare the distance between the cursors to the waveform. Anything larger than the cursors is writable. Addresses with only 1 or 2 writable bits had smaller but still detectable dips.

I tested all addresses in the range $5000 - 5250. I also tested these ranges and found nothing:
$5300-5310
$5400-5410

I tested $5800-5812 and they all DID have activity, similar to register $5204 with only 1 bit, for example. I then tested $5A00, it also behaved this way. I then tested $5C00, and it TOO behaved this way. This seems to suggest that RAM could exist in the entire range $5800-5FFF.

Next, I will experiment with the data written. Right now, I am alternating between writing $FF and $00. I will see if I can toggle just 1 bit at a time and see if I can tell which specific bits are writable.


Edit:
I am not able to tell any difference for individual bits. It seems that the current spike does not depend on the data written, only the number of writable bits. I will measure the deflections for each known register to get a rough idea how many bits are writable, but it won't tell us "which" bits. Also, some registers have a great big disturbance when written, presumably I trigger a bankswitch that changes lots of outputs or something. I recorded great big disturbances from writing to these registers:

5101
5105
5116
512B
5205
5206

I may be able to just always write the same value though instead of alternating $00 to $FF, and it may prevent this from happening. Will try it.


Edit:
There is not a strong correlation between number of writable bits and deflection when writing only $00 (9 bits being used to show "unknown"):
deflection chart.png
Reviewing this data, it suggests that $5208 (CL3 / SL3 Status) is in fact writable. That is fairly interesting.

$5207 (the unknown one) draws a healthy amount of current, I would speculate that it is more than just a 1 or 2 bit register. $5003 and $5007 drew a lot, presumably they are starting pulse channels. $5209 drew a lot, it is starting the timer.

Code: Select all

Reg	Known Bits	mV
5020	0	7.6
5000	8	9.16
5002	8	9.08
5003	8	14.08
5004	8	9
5006	8	8.88
5007	8	14.16
5010	2	8.56
5011	8	8.96
5015	2	8.6
5100	2	8.44
5101	2	8.24
5102	2	8.36
5103	2	8.28
5104	2	8.44
5105	8	8.64
5106	8	8.52
5107	2	8.16
5113	4	8.52
5114	8	8.6
5115	8	8.6
5116	8	8.76
5117	7	9.44
5120	8	9.52
5121	8	9.52
5122	8	9.48
5123	8	9.44
5124	8	9.44
5125	8	9.44
5126	8	9.36
5127	8	9.52
5128	8	9.04
5129	8	9.04
512A	8	8.92
512B	8	9.24
5130	2	8.52
5200	7	9.52
5201	8	9
5202	8	8.92
5203	8	8.72
5204	1	8.4
5205	8	8.84
5206	8	8.84
5207	9	9.32
5208	9	8.6
5209	8	11.64
520A	8	9.84
Edit:
New findings!
Writing random data to $5207 makes CL2 and SL2 outputs and toggling around. :D Will try to define exactly what is happening.

Edit:
==== CL3 / SL3 Data Direction and Output Data ($5207 write only) ====

Code: Select all

7  bit  0
 ---- ----
 ABxx xxCD
 ||     ||
 ||     |+- SL3 Output Data
 ||     +-- CL3 Output Data
 |+-------- SL3 Data Direction (0 = output, 1 = input)
 +--------- CL3 Data Direction (0 = output, 1 = input)

Edit:
There is more to this. When I set $5207 bits 0 and 1 to both = 0, then write randomly to $5208, SL3/CL3 dance around. More to be done here.

Edit:
I updated the wiki:

CL3 / SL3 Data Direction and Output Data ($5207 write only)

Code: Select all

7  bit  0
---- ----
ABxx xxCD  MMC5A default power-on write value = 11xx xxxx
||     ||
||     |+- MMC5.97 (CL3) Output Data (0 = output $5208.6 value written, 1 = output 1)
||     +-- MMC5.98 (SL3) Output Data (0 = output $5208.7 value written, 1 = output 1)
|+-------- MMC5.97 (CL3) Data Direction (0 = output, 1 = input)
+--------- MMC5.98 (SL3) Data Direction (0 = output, 1 = input)
CL3 / SL3 Status ($5208 read/write)
Write

Code: Select all

7  bit  0
---- ----
ABxx xxxx  MMC5A default power-on write value = 00xx xxxx
||
|+-------- Value to be output on MMC5.97 pin (CL3) if/when $5207.0 = 0 and $5207.6 = 0
+--------- Value to be output on MMC5.98 pin (SL3) if/when $5207.1 = 0 and $5207.7 = 0
Read

Code: Select all

7  bit  0
---- ----
ABxx xxxx
||
|+-------- Input value of MMC5.97 pin (CL3)
+--------- Input value of MMC5.98 pin (SL3)
That is probably all for tonight. Fun stuff! I wonder what this was for? Just 2 random GPIO pins? I suppose you could bit-bang an I2C EEPROM with this.
lidnariq
Posts: 11430
Joined: Sun Apr 13, 2008 11:12 am

Re: MMC5 Hacking Adventures

Post by lidnariq »

Any chance there's two different pull-up strengths between the value in [$5208]&$C0 and [$5207]&3 ?
User avatar
Ben Boldt
Posts: 1148
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: MMC5 Hacking Adventures

Post by Ben Boldt »

lidnariq wrote:Any chance there's two different pull-up strengths between the value in [$5208]&$C0 and [$5207]&3 ?
I tested lots of combinations, and any time each pin was high, I tried a 10k pull-down, and any time it was low, I tried a 10k pull-up. The signal didn't ever budge unless it was an input, in which case it went from high to low when I applied the pull-down. From what I have seen, it has 3 output states: drive high, drive low, or input.

It seems interesting that $5207 lets you override the output to a 1. That seems like it would be useful if it was used for a chip select, to force it unselected. Or maybe it isn't really overriding to 1, maybe it is changing the source of the data to something else, which happens to be 1. I tried brushing a gnd across my PPU address lines with $5207 = $03, it didn't do anything to SL3/CL3 though.

I looked at each of the remaining unknown pins when writing random data to $5207 and $5208. I found no activity on any of those pins.
User avatar
krzysiobal
Posts: 1036
Joined: Sun Jun 12, 2011 12:06 pm
Location: Poland
Contact:

Re: MMC5 Hacking Adventures

Post by krzysiobal »

I cannot repeat your experiment with forcing pins 97/98 to output 0. All I can do is that:
* When you write ANYTHING to $5207, both pins 97/98 start driving lines with 1 (that's for sure, cause when I pull them to GND with 1k resistor, the voltage drops to 4.5V). M2 must be cycling, otherwise it takes no effect.
* Writing then anything to $5208 does not change their values and they cannot be set to undrive the 1 any more (the only way to bring them back as inputs is is to stop cycling M2).
* Starting cycling M2 again will not change anything (they're still inputs until next write to $5207)

Either my MMC5 configuration is different (it is on the Just Breed PCB), MMC5 version differs or you write something more to other regs.
I need to take look on behaviour of SL4/SL5/SL6 pins, matbe it will be helpful.
User avatar
Ben Boldt
Posts: 1148
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: MMC5 Hacking Adventures

Post by Ben Boldt »

Okay, very interesting. Here is some more info about my setup for this test:
  • Still using my original MMC5A from a Just Breed cart (not using my letterless L'Empereur MMC5s)
  • M2 period is precisely 8 usec
  • I am doing dummy reads from CPU address $0000 when idle
  • All of my PPU address and data lines are floating, i.e. I am not driving them.

I began the test this way, which may have initialized or unlocked or something:
  • Writing a random value to $5207, then a random value to $5208, with no idle reads in between.
  • Then lots of idle reads from $0000
  • Then another pair of randoms, infinite loop like that, watching SL3/CL3 with my scope.
  • Once triggered, I did not power cycle the MMC5. I then began poking at individual bits. I may never have had any gap in M2 toggling during this transition.
Edit:
Actually, come to think of it, I did power cycle everything for a few seconds in order to determine the default power-on states of these registers. Both pins did revert to inputs, floated high when I did this, and no randomness or special sequence was involved when writing after that. I believe that PPU /RD and /WR would have been driven high or low and not changing during all of this testing.
User avatar
krzysiobal
Posts: 1036
Joined: Sun Jun 12, 2011 12:06 pm
Location: Poland
Contact:

Re: MMC5 Hacking Adventures

Post by krzysiobal »

Also my MMC5 might got damaged when I played with the registers by writing random things when SL3 & CL3 were shorted by the jumper on PCB.
Unfortunatelly I don't have second cartridge with it.
User avatar
Ben Boldt
Posts: 1148
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: MMC5 Hacking Adventures

Post by Ben Boldt »

krzysiobal wrote:Also my MMC5 might got damaged when I played with the registers by writing random things when SL3 & CL3 were shorted by the jumper on PCB.
Unfortunatelly I don't have second cartridge with it.
:( That's a bummer, but I don't think all hope is lost. We have very different test setups. You may very well have found a different function that we don't understand yet.

How are you powering your setup, what is your current limit? I use a bench supply and I dial down the current until it enters current limit mode, then dial it slightly back up until it is just above current limit mode. I can tell if a test has a bus conflict because I start entering current limit mode again. My bench supply can probably still dump loads of current from its output caps for a moment, not sure how much this could really save anything.

A Just Breed or Japanese L'Empereur cart can usually be had for about $10-15 USD if you keep an eye out on eBay. USA L'Empereurs cost a fortune, not sure why that is a desirable game. But we don't want those anyway because audio wouldn't be hooked up.
User avatar
krzysiobal
Posts: 1036
Joined: Sun Jun 12, 2011 12:06 pm
Location: Poland
Contact:

Re: MMC5 Hacking Adventures

Post by krzysiobal »

I am powering it from USB. I've just measured the current consumption of MMC5 (alll ROMs are removed):
* Powerup, when CPU/PPU = $0000, m2 not cycling: **2.5 mA**
* Powerup, when CPU/PPU = $0000, m2 cycling: **2.9 mA**
* Powerup, when CPU/PPU = $2000 m2 cycling: **7.2 mA**
* $5105 was written with 00, CPU/PPU = $2000, m2 cycling and **3.0 mA**
//excessive current consumption happens when MMC5 uses Fill Mode Nametables (which takes place on powerup for $2000-$2FFF). So probably internal MMC5 PPU data bus drivers for that mode are active for $2000-$2FFF even if the PPU !RD is high.

If I write anything to $5207 and $80/40/$c0/00 to $5208, no current drop happens so maybe it is not faulty, just that feature was not implemented?

Anyway, I've just ordered Famicom Emperarur from EBAY for something around 20$ shipped, never knew they are so cheap.
User avatar
Ben Boldt
Posts: 1148
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: MMC5 Hacking Adventures

Post by Ben Boldt »

We have the exact same chip though, MMC5A from Just Breed. I think we would either both have the feature or both not have it. When you say that no current drop happens when writing to $5208, what to you mean? How do you measure that? Were you repeating my test method? I can provide more details and source code that I wrote for it.

Nice to hear you found a reasonable price for a Japanese L'Empereur. I am not sure if this would be useful to you since you have a nice setup already but here is the breakout board that I got:

https://www.ebay.com/itm/171251434430

That seems so strange to hook those 2 pins together. So literally, you can write something to 2 registers and self-detonate those pins? That seems a little silly. I am not sure I quite buy that yet, you might well be triggering or disabling a feature somehow. I will play with it a bit more tonight and see if I can find anything. We believe them to have some function/purpose related to the PPU based on SL/CL mode description on the pinout page from kevtris, but nobody seems to know how he originally got that information.
Last edited by Ben Boldt on Thu Dec 06, 2018 5:20 pm, edited 1 time in total.
lidnariq
Posts: 11430
Joined: Sun Apr 13, 2008 11:12 am

Re: MMC5 Hacking Adventures

Post by lidnariq »

Ben Boldt wrote:That seems so strange to hook those 2 pins together. So literally, you can write something to 2 registers and self-detonate those pins? That seems a little silly.
Even if one did blow up two pins, that should only blow up the pull-up on one and the pull-down on the other...
User avatar
Ben Boldt
Posts: 1148
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: MMC5 Hacking Adventures

Post by Ben Boldt »

You are able to still drive high though right? Maybe first pin A drove high and B drove low, and blew up the low of B. Then later B drove high and A drove low, and blew up the low of A. This blown up pins theory is becoming more of a stretch the more we think about it though.

Edit:
oops sorry I didn't realize that was you lidnariq.

Edit 2:
It is absolutely not doing it for me now. Both pins are always inputs now. I highly doubt that I blew my pins up. I may have unknowingly unlocked something when testing the write registers. I have a lot of cap on my VCC, it may not have fully died when I removed power for a few seconds last night. Will keep poking at it.

Edit 3:
Okay, I DID get it to do it again. When I wrote values directly, it didn't work. When I went back to my random data writer to $5207 and $5208, it didn't work at first because I had disabled $5207 writes in that test. When I re-enabled, the 2 pins dance around. Whew. I will remove power for a while and do manual writes again and try to get more info about this.

Edit 4:
Now when I apply power, I can write $03 to $5207 and immediately both signals shift up, driving high. That was not the case in Edit 2 moments ago. Hmmmmm. I will leave VCC shorted to GND for a few minutes and try again.

Edit 5:
Okay, you're not going to believe this but the AVCC has to get powered at the same time as DVCC or else this function gets locked out. Coincidentally, that was the problem with my dsPIC33FJ64GS608, I had not connected the AVCC...

If I let my random write test keep running, and connect and disconnect AVCC, it will sometimes work and sometimes not work. Always when I disconnect AVCC, it stops working (turns back to inputs).

Edit 6:
Random write test:
tek00040.png
Edit 7:
If I change the AVCC voltage, it has no effect on any of the 3 voltages of SL3/CL3.

Edit 8:
With AVCC connected and SL3/CL3 latched as inputs, if I momentarily disconnect M2 and reconnect it (i.e. trigger reset detection), SL3/CL3 unlock and start toggling again. Could it be that the MMC5, in general, gets held in reset mode by AVCC?

Edit 9:
Yes, theory in Edit 8 correct. PRG RAM +CE (the signal as pointed out by krzysiobal that reflects reset state) does reflect the latching of CL3/SL3.

Edit 10:
So, you are seeing where it can drive high or be an input, but it can not drive low. And once driven high, it can not be turned back into an input again until you cause a reset. The fact that you can drive high pretty much proves that it isn't a reset causing the problem like it was for me. But the fact that it gets stuck as an output, is different, and doesn't particularly sound broken if reset can still turn it back to an input. I like what you are saying about potential things going on with the PCB, that seems like the biggest difference between us at the moment.

Edit 11:
Something I didn't notice before, there are lots of little glitches where it drives low for a very short time in the scope shot, and it is always followed by driving high. I wonder what that is about?? I will zoom in on it tomorrow and also look at the glitch in comparison to M2 and CPU R/W, etc. The scope shot is actually triggered on one of the glitches. :lol:
lidnariq
Posts: 11430
Joined: Sun Apr 13, 2008 11:12 am

Re: MMC5 Hacking Adventures

Post by lidnariq »

Quick question unrelated to the current bits: does /ROMCE additionally require that R/W be high? Or does it just pay attention to what banks are RAM vs ROM?

(I'm hoping to make a self-flashable cart)
User avatar
krzysiobal
Posts: 1036
Joined: Sun Jun 12, 2011 12:06 pm
Location: Poland
Contact:

Re: MMC5 Hacking Adventures

Post by krzysiobal »

MMC5-/ROMCE = CPU-/ROMSEL or CPU-R/W
MMC5-/ROMCE = 0 when CPU-/ROMSEL = 0 and CPU-R/W= 0 and ROM is selected in current prg mode for current cpu address

If you want to make flash-cart:
* bend ROM-!CS pin 22 (which is tied to GND on MMC5 PCBs) and connect it to CPU-/ROMSEL (cart 44 pin)
* ROM-!OE pin 31 is already connected to MMC5-/ROMCE
* connect the /WE of Flash-ROM to CPU-R/W (cart 14 pin), so you gets:

Code: Select all

action               | ROM-!CS | ROM-!OE | ROM-!WE
write @ $8000-$ffff: |    0    |    1    |    0
read  @ $8000-$ffff: |    0    |    0    |    1
outside $8000-$ffff: |    1    |    x    |    x
---

When you say that no current drop happens when writing to $5208, what to you mean? How do you measure that? Were you repeating my test method?
I write something (*) do $5207/$5208 and then just toggle M2 and measure the static average DC current supplied to MMC5
(*) something = for example $0/1/2/3/$40/$80/$c0 to $5207 and $00/$40/$80/$c0 to $5208. If there was internal short in the chip then it would drain lot more current when pin 97 and 98 are set to output different values, but for every of the combinations the current consumption is the same.
If outputs were broken, it would still allow me to bring them back as inputs by writing to $5207. I rather think the whole $5207 register is broken or my MMC5 does not have this functionality (maybe that's why no official game used it). PCB difference is rather irrelevant, without any chips, without battery and with the SL/CL jumper cut-out it is pretty same as yours.
User avatar
Ben Boldt
Posts: 1148
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: MMC5 Hacking Adventures

Post by Ben Boldt »

I just found something very interesting CL3 that we have not seen before. In certain conditions, I have made CL3 = !(M2):
tek00046.png
I will narrow this down more but here are all of the conditions that I currently have (not sure which ones are relevant):
  • Write a random byte to a random selection from this list of addresses:
    $5000, $5002, $5003, $5004, $5006, $5007, $5010, $5015, $5100, $5101, $5102, $5103, $5104, $5105, $5106, $5107, $5113, $5114, $5115, $5116, $5117, $5120, $5121, $5122, $5123, $5124, $5125, $5126, $5127, $5128, $5129, $512A, $512B, $5130, $5200, $5201, $5202, $5203, $5204, $5205, $5206, $5207, $5208, $5209, $520A, $5800
  • Exceptions: 1. Not including $5011. 2. If the address is $5800, always write $55
  • Then after that, do 4 sequential reads from address $5800, which is where this CL3 behavior occurs.
  • During the 4 reads, CL3 is the inverse of M2.
I still need to test:
  • Read other addresses. What addresses can cause this? Shown in the scope shot is a read from $0000, which does not cause this, so it does seem to be address dependent.
  • What values had been written to $5207 and $5208?
  • Will I get this behavior from SL3 instead of CL3 if I write $AA instead of $55?
  • Note that scope shot shows a write to $5207 just before this behavior.
Edit:
CL3 = !(M2) whenever reading from addresses in the range $5800-5BFF. Values checked: 57FF, 5800, 5801, 5A00, 5BFF, 5C00, D800, DBFF.
I found also that SL3 = !(M2) whenever writing to $5800. Will verify range of SL3 writes and also try to figure out which values in $5207/5208 can cause this.
lidnariq
Posts: 11430
Joined: Sun Apr 13, 2008 11:12 am

Re: MMC5 Hacking Adventures

Post by lidnariq »

Ben Boldt wrote:[*]Then after that, do 4 sequential reads from address $5800, which is where this CL3 behavior occurs.
[*]During the 4 reads, CL3 is the inverse of M2.
That sure sounds like it became a chip enable...
Post Reply