It is currently Sun Dec 10, 2017 9:03 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 12 posts ] 
Author Message
PostPosted: Mon Dec 04, 2017 6:31 pm 
Offline

Joined: Sun Jun 12, 2011 12:06 pm
Posts: 254
Location: Poland
While creating repro of Super Mario All Stars for MMC5, I had to implement MMC5 in FPGA. For some unknown reason, creators of this cartridge used the ability of MMC5 to supply diffrent CHR banks for sprites & background. Of course they also use the IRQ, so I come back into trouble of thinking how MMC5 scanline detector works.
Fortunately I have Just Breed MMC5 cartridge, so using KrzysioKazzo i was able to research MMC5 features with cycle acuracy
Image

Before I started any research, I rev'ed the board to confirm if the wiki data is correct. I found two bugs:
Image Image Image
1. pin 28 is PPU-!A13, not PPU-A13 as states wiki
2. one of the resistors in amplifier circuit is 6.8k (but it might vary from board to board I think)

I am also very curious about the unconnected pins. They are wired and cut out of edge from board, this is super crazy. Also, multimeter test shows internal connection. I think they might be related to the WRAM.
Image

----

Ok, now some research about the MMC5 itself:
0. Multiplier ($5205/$5206) -> after writing A and B, low(A*B) and high(A*B) can be read immediatelly on next cpu cycle (no need to wait 8 cycles like in mapper90). This means that the whole product is calculated as combinatorial function and it requires quite a lot of ASIC resources.
The 8 cycle delay in mapper 90 is because after every cycle, each succesive bit of B is multiplied by A and added to the result causing much less resource need.

1.Check if sequence of two PPU reads from same address at row will trigger MMC5's scanline detector
It won't
Code:
public byte[] cpu_read(long start_address, int bytes_to_read)
void cpu_write(long start_address, byte[] bytes_to_write);
public byte[] ppu_read(long start_address, int bytes_to_read);
public void ppu_write(long start_address, byte[] bytes_to_write);
public int read_irq(); //reads !IRQ line (0=irq asserted, 1=not asserted), this does not produce any cpu cycle
public void cpu_m2_constant_clocking(bool clocking_enabled); //if clocking_enabled=false -> there won't be any cpu/ppu cycles during idle time, if
 clocking_enabled=true, there will be CPU read at $0000 as idle cycle



cpu_m2_constant_clocking(false);
   cpu_read(0x5204, 1); //clear any interrupt if pending
   cpu_write(0x5203, new byte[] {10}); //generate irq at scanline 10

   string result = "";
   byte r0x5204;

   for (int i = 0; i < 20; ++i) {
      r0x5204 = cpu_read(0x5204, 1)[0];
      result += String.Format("{0:x2} ", r0x5204);

      ppu_read(1 << 13, 1);
      ppu_read(1 << 13, 1);
      ppu_read(0 << 13, 1);
   }
Output:
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


2.Check if sequence of three PPU reads from same address at row will trigger MMC5's scanline detector
It does
Code:
   string result = "";
   byte r0x5204;
   
   cpu_m2_constant_clocking(false);
   cpu_read(0x5204, 1); //clear any interrupt if pending
   cpu_write(0x5203, new byte[] {10}); //generate irq at scanline 10

   for (int i = 0; i < 20; ++i) {
      r0x5204 = cpu_read(0x5204, 1)[0];
      result += String.Format("{0:x2} ", r0x5204);

      ppu_read(1 << 13, 1);
      ppu_read(1 << 13, 1);
      ppu_read(1 << 13, 1);     <- this was added
      ppu_read(0 << 13, 1);
   }
Output:
   00 00 40 40 40 40 40 40 40 40 40 40 c0 40 40 40 40 40 40 40

---
03. Will 3 reads with A13=0 trigger it?
It won't
Code:
   string result = "";
   byte r0x5204;
   
   cpu_m2_constant_clocking(false);
   cpu_read(0x5204, 1); //clear any interrupt if pending
   cpu_write(0x5203, new byte[] {10}); //generate irq at scanline 10

   for (int i = 0; i < 20; ++i) {
      r0x5204 = cpu_read(0x5204, 1)[0];
      result += String.Format("{0:x2} ", r0x5204);

      ppu_read(0 << 13, 1);         <- change  was made here
      ppu_read(0 << 13, 1);         <- change  was made here
      ppu_read(0 << 13, 1);         <- change  was made here
      ppu_read(1 << 13, 1);         <- change  was made here
   }
Output:
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


-------------------------------------------------------------------------------------------------
04. Does the PPU address matter or only A13 is checked?
There must be three consecutive fetches of the same address with A13=1 (all bits are checked)
Code:
   string result = "";
   byte r0x5204;
   
   cpu_m2_constant_clocking(false);
   cpu_read(0x5204, 1); //clear any interrupt if pending
   cpu_write(0x5203, new byte[] {10}); //generate irq at scanline 10

   for (int b = 0; b < 14; ++b) {
      for (int i = 0; i < 20; ++i) {
         r0x5204 = cpu_read(0x5204, 1)[0];
         result += String.Format("{0:x2} ", r0x5204);

         ppu_read((1 << 13) | (1 << b), 1);         <- change  was made here
         ppu_read(1 << 13, 1);
         ppu_read(1 << 13, 1);
         ppu_read(0 << 13, 1);
      }
      result += "\r\n";
   }
Output:
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   00 00 40 40 40 40 40 40 40 40 40 40 c0 40 40 40 40 40 40 40


-------------------------------------------------------------------------------------------------
05. What if there are more than 3 fetches per row?
Interrupt was generated earlier.
Code:
   string result = "";
   byte r0x5204;
   
   cpu_m2_constant_clocking(false);
   cpu_read(0x5204, 1); //clear any interrupt if pending
   cpu_write(0x5203, new byte[] {10}); //generate irq at scanline 10

   for (int i = 0; i < 20; ++i) {
      r0x5204 = cpu_read(0x5204, 1)[0];
      result += String.Format("{0:x2} ", r0x5204);
      
      ppu_read(1 << 13, 1);
      ppu_read(1 << 13, 1);
      ppu_read(1 << 13, 1);
   }
   
Output:
   00 00 40 40 40 c0 40 40 40 40 40 40 40 40 40 40 40 40 40 40


06. I found it by accident, but if I add one additional CPU read cycle before reading 0x5204 or after writing 0x5203,
the output will be:
00 40 40 40 40 40 40 40 40 40 40 c0 40 40 40 40 40 40 40 40
instead of:
00 00 40 40 40 40 40 40 40 40 40 40 c0 40 40 40 40 40 40 40
so the scanline detector starts working one scanline earlier.

06. What makes MMC5 think that frame rendering has ended
CPU read from from $fffa? -> yes
CPU read from from $fffb? -> yes
CPU write at $fffa/$fffb? -> no
CPU write $00 at $2001 -> no

If there are 3 or more CPU reads between which are no PPU read, MMC5 starts thinking PPU rendering has ended.ppu read
cpu read
cpu read
cpu read <- at beginning of this cycle, mmc5 sets in-frame to 0 (so if this read would be from $5204, it will return 0)

PPU writes does not matter, the following sequence will still set in-frame to 0:
ppu read
cpu read
ppu write
cpu read
cpu read <- at beginning of this cycle, m2 sets in-frame to 0 (so if this read would be from $5204, it will return 0)

---

Later I will check the memory protection bits, because I roughly tested it few days ago and I think that when M2 stops toggling, these bits are automatically set (like if reset happened). No idea how MMC5 checks without help of external detector that this happened.


Top
 Profile  
 
PostPosted: Mon Dec 04, 2017 8:43 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6503
Location: Seattle
krzysiobal wrote:
I am also very curious about the unconnected pins. They are wired and cut out of edge from board, this is super crazy. Also, multimeter test shows internal connection. I think they might be related to the WRAM.
I assume they're all some sort of validation, but it'd be interesting to figure out what all the bonus pins are. Certainly all the pins actually come out of the package and go to traces (that then fall off the PCB)

I wouldn't be surprised if pins 73 and 75 were "PRG RAM /CE" and "PRG RAM A15". And if one of 29 or 30 were "PPU A13 OR PPU /RD". But that leaves a number of pins.


Top
 Profile  
 
PostPosted: Tue Dec 05, 2017 2:36 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7312
Location: Chexbres, VD, Switzerland
Quote:
I am also very curious about the unconnected pins. They are wired and cut out of edge from board, this is super crazy.

The vast majority of Nintendo-made boards have those, this is nothing MMC5 specific.


Top
 Profile  
 
PostPosted: Tue Dec 05, 2017 5:33 am 
Online
User avatar

Joined: Mon Apr 04, 2011 11:49 am
Posts: 1931
Location: WhereverIparkIt, USA
Old PCBs often have areas where several traces meet together and then appear to have been drilled through that crossing to electrically disconnect them.

Just a guess, but I think these "crazy" routings allowed for PCB continuity testing prior to drilling step that breaks all the testing connections. Perhaps the traces that run off the edge of the board connected to a testing header of sorts.

_________________
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers


Top
 Profile  
 
PostPosted: Tue Dec 05, 2017 7:54 am 
Offline

Joined: Sun Jun 12, 2011 12:06 pm
Posts: 254
Location: Poland
What about this one?
Image

You really think there has been test pads in the place where there is hole now?
I rather suspect that this is some copy-protection policy. Nintendo ordered big PCB sheets containing more small PCB cartridges on them, with some fake tracks and connections between those small carts and later, they cutted and milled them on their own or in another factory to minimize posibility of leakage.


Top
 Profile  
 
PostPosted: Tue Dec 05, 2017 8:33 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7312
Location: Chexbres, VD, Switzerland
krzysiobal wrote:
What about this one?
I rather suspect that this is some copy-protection policy.

Hahaha ! I like how every single time something is not understood in reverse-engineering, someone comes and claims "this is a form of copy protection".

Quote:
0. Multiplier ($5205/$5206) -> after writing A and B, low(A*B) and high(A*B) can be read immediatelly on next cpu cycle (no need to wait 8 cycles like in mapper90). This means that the whole product is calculated as combinatorial function and it requires quite a lot of ASIC resources.

Could be, but not necessarily. There is a 4 cycle gap between an STA $abs and an immediately following LDA $abs instruction, so the MMC5 might take advantage of it for its multiplier.


Top
 Profile  
 
PostPosted: Tue Dec 05, 2017 10:05 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6503
Location: Seattle
krzysiobal wrote:
You really think there has been test pads in the place where there is hole now?
Another possibility is that their EDA software wouldn't let them have a trace that didn't go anywhere, so to silence it they sent it to a connector that they then milled out.


Top
 Profile  
 
PostPosted: Tue Dec 05, 2017 10:27 am 
Online
User avatar

Joined: Mon Apr 04, 2011 11:49 am
Posts: 1931
Location: WhereverIparkIt, USA
That's an example of where they all shorted together like I mentioned. Perhaps that massive shorting of signals provided continuity checks at the header that would be off the edge. I'm saying the signals that went off the edge of the board is where the header may have been. This is all just a theory though. I find it hard to believe it's copy protection and Nintendo did post manufacturing. I've wondered if lidnariq's theory might be the case as well, some artifact of early design tools.

_________________
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers


Top
 Profile  
 
PostPosted: Fri Dec 08, 2017 11:36 am 
Offline
User avatar

Joined: Sat Oct 29, 2005 2:09 am
Posts: 502
Location: Indianapolis
krzysiobal wrote:
I am also very curious about the unconnected pins. They are wired and cut out of edge from board, this is super crazy. Also, multimeter test shows internal connection. I think they might be related to the WRAM.
Image




Nah the answer is a lot more pedestrian. It's because they need to short all the lines together that they wish to gold plate. There's a shorting bar on the card edge where it plugs into the system, and then more shorting bars around the edges of the board. These cartridge boards use hard gold (vs. ENIG) and this is a plating process, so everything you wish to have gold on needs to be electrically connected.

The boards are plated, then the shorting bars are routed off, breaking all the connections into their separate circuits. You'll find that most if not all of the connections that run off the top/sides of the board are all internal" connections- i.e. signals from the MMC5 to the ROMs or WRAM and signals that do not actually make it back to the card edge. This is found on nearly all (if not all) nintendo-made cartridge boards.

_________________
/* this is a comment */


Top
 Profile  
 
PostPosted: Fri Dec 08, 2017 11:44 am 
Online
User avatar

Joined: Mon Apr 04, 2011 11:49 am
Posts: 1931
Location: WhereverIparkIt, USA
Ahh that makes a lot more sense. Guess I was right about intentional shorting and off board connection, but for the wrong reasons... Thanks kevtris!

_________________
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers


Top
 Profile  
 
PostPosted: Fri Dec 08, 2017 2:20 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6503
Location: Seattle
But why would you need to plate any signals that don't go to the card edge?


Top
 Profile  
 
PostPosted: Fri Dec 08, 2017 5:57 pm 
Offline

Joined: Sun Jun 12, 2011 12:06 pm
Posts: 254
Location: Poland
All vias are gold plated.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: Google Adsense [Bot] and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group