What's going on with the MMC5 counter?

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

Moderators: B00daW, Moderators

User avatar
qbradq
Posts: 951
Joined: Wed Oct 15, 2008 11:50 am

Post by qbradq » Fri Apr 15, 2011 3:20 pm

tepples wrote:MMC5 has to count horizontal fetches to tell sprite banks from background banks and figure out at what point on the scanline to vertically split.
Dang Tepples, that was totally lost on me! Thanks for pointing that out!

I was just thinking in the John that a more robust way of detecting scanlines is to look for the idle cycle at the end of one for synchronization, then just count the CHR /RD edges until you hit 336. If you see more than one idle PPU cycle you know rendering is disabled, and you can reset the state machine.

That should approximate the behavior we see. When you disable the PPU through a register write there are at least 2 PPU cycles between the end of the write and the execution of the next CPU instruction byte, during which time the PPU should be idle.

Drag
Posts: 1325
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Post by Drag » Fri Apr 15, 2011 7:29 pm

MMC5 test rom (Edit: Redownload, I forgot to properly initialize sprites)
This rom ought to test for the quirks I mentioned a while back. I don't have the means to put this on an actual MMC5 cart, so could someone here do it?

When the screen scrolls up, you should see a bunch of 0s at the top of the screen. That's attribute data being rendered as nametable data, by setting the Y scrolling to $FF. Underneath this is a row of down arrows, that's just to indicate the top of the nametable.

The PPU will incidentally make a duplicate read all on its own, when it goes to render the "tile" at 23FF (also happens at 27FF, 2BFF, and 2FFF), because it'll fetch 23FF as a tile, and then fetch 23FF as an attribute. If the scanline counter indeed looks for a duplicate fetch, then the ruler thing at the bottom of the screen should move when the invalid data scrolls onto the screen. It could:
  • Shift down 8 pixels
  • Shift up 8 pixels
  • Cover the screen
  • Do nothing at all
If the ruler moves at all, how it moves will determine what kind of duplicate read the MMC5 looks for.

If the ruler stays still the whole time, then we can't quite conclude anything.

Press start to pause/unpause the scrolling at any point, and use the left/right keys to scroll the screen left and right (this changes where the incidental double-read occurs). So, if the ruler doesn't immediately freak out when the invalid data scrolls on screen, try pausing it, and then moving the screen left and right.

User avatar
Bregalad
Posts: 7952
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Sat Apr 16, 2011 10:02 am

Well I said I'd help but I didn't expect to have to do it so soon. I think I only have one 256 kb Flash ROM and one 32kb permanant SRAM at the momment, I hope I'll be able to make a devcart using those next week so I could tell the result on a real MMC5.
Useless, lumbering half-wits don't scare us.

User avatar
qbradq
Posts: 951
Joined: Wed Oct 15, 2008 11:50 am

Post by qbradq » Sat Apr 16, 2011 10:52 am

I could also make a test cart, but I'd have to get some new ROM chips first. I got a Willem PCB5 and it is not working with the 29F020 chips I have.

Drag
Posts: 1325
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Post by Drag » Sat Apr 16, 2011 11:06 am

I put all of the code in a single 16k bank, so you can use whatever size rom you want, just mirror the data.

Drag
Posts: 1325
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Post by Drag » Thu May 05, 2011 9:42 pm

So has anyone had a chance to test this? I'm personally interested in whether or not any of the quirks I mentioned are happening.

User avatar
loopy
Posts: 396
Joined: Sun Sep 19, 2004 10:52 pm
Location: UT

Post by loopy » Tue Dec 13, 2011 6:01 am

I tried your test rom. The ruler does indeed move, if you scroll to the left a little bit. Interesting! Not what I was expecting.

http://youtu.be/dGhVxdFJVuY

User avatar
Zepper
Formerly Fx3
Posts: 3220
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Post by Zepper » Sun Feb 19, 2012 5:34 pm

Just tried this ROM, but something's strange. It has 16k of PRG ROM, but it writes $00 to $5100, setting the PRG mode to 32k. My emu crashes because there's no 32k page available.

tepples
Posts: 22055
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples » Sun Feb 19, 2012 6:42 pm

Mirror, mirror on the wall...

User avatar
Zepper
Formerly Fx3
Posts: 3220
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Post by Zepper » Sun Feb 19, 2012 7:18 pm

Non-standard settings. Why? I had to duplicate the 16k page in the file & change the iNES header for 2 of 0x4000 PRG banks. It worked.

Drag
Posts: 1325
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Post by Drag » Wed Feb 22, 2012 1:16 am

Sorry about that, I think I originally coded this to be 32k in size, but then I later changed it to 16k, probably without updating my code to explicitly set up a 16k + 16k bank setup. Then again, I was under the understanding that if your ROM chip is smaller than 32k, it'll always be mirrored to 32k because the ROM chip won't ever see the upper address lines from the NES.

Thank you so incredibly much for testing this, loopy! I'll need to reread my ramblings in this thread in order to figure out what my train of thought from 7 months ago was, but I think this confirms that the MMC5's scanline counter detects duplicate PPU fetches in order to count scanlines.

The reason I can conclude this is because of the trick I mentioned, where I'm giving the PPU an invalid Y-scroll value, and tricking it into reading $23FF twice consecutively (once as a tile and then again as an attribute byte). The MMC5 detects this duplicate read, and clocks the scanline counter on each scanline that the trick-tile occupies, which is why the ruler moves up when it scrolls onto the screen.

Since it's detecting my trick duplicate read, that means it must also be detecting the duplicate read that occurs at the end of each scanline (cycles 336-339), and since it clocks the scanline counter when it detects these duplicate reads, that must be how it's counting scanlines.

So, that's one MMC5 mystery solved. :D

User avatar
infiniteneslives
Posts: 2100
Joined: Mon Apr 04, 2011 11:49 am
Location: WhereverIparkIt, USA
Contact:

Post by infiniteneslives » Wed Feb 22, 2012 5:12 am

Drag wrote:The reason I can conclude this is because of the trick I mentioned, where I'm giving the PPU an invalid Y-scroll value, and tricking it into reading $23FF twice consecutively (once as a tile and then again as an attribute byte). The MMC5 detects this duplicate read, and clocks the scanline counter on each scanline that the trick-tile occupies, which is why the ruler moves up when it scrolls onto the screen.

Since it's detecting my trick duplicate read, that means it must also be detecting the duplicate read that occurs at the end of each scanline (cycles 336-339), and since it clocks the scanline counter when it detects these duplicate reads, that must be how it's counting scanlines.

So, that's one MMC5 mystery solved. :D
NICE! Nifty little way to get inside and figure out how it's detecting what's going on. So the logic involved here seems pretty simple for detecting this. The only costly thing is the number of I/O, but that's needed for the EXRAM anyways.

User avatar
Bregalad
Posts: 7952
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Wed Feb 22, 2012 5:30 am

Yahooooo !
Let's toast on this !


I think those extra unnecessarly fetches at the end of each scanlines are really weird/undocumented. I didn't even know it was a duplicate fetch.
This also explains/confirms why the MMC5's counter doesn't work on clones at all, clones which obviously have another fetching sequence.

What sucks, though, is that you can't intentionally display the attribute table as a nametable on the MMC5 while using the SL counter, as it will be clocked twice in that part (apparently). Displaying the attribute table as a nametable is the only way to fully use the ExGraphix mode without any waste, as you can get a 32x32 tilemap with every tile having single color.
Not a big issue though, since to do that you'd only need to trigger an IRQ after displaying the last true nametable row ($23a0-$23bf) to force the counter to $23c0, so after this line the IRQ counter is not necessary any longer.

Is there any other "mysteries" in the MMC5 left ? Like how it detects forced blanking, how exactly the ExRAM is accessed (dual port), how fast is the multiplier, etc...
Useless, lumbering half-wits don't scare us.

Drag
Posts: 1325
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Post by Drag » Wed Feb 22, 2012 10:30 am

An interesting thing with this video is that the effect doesn't start until the trick tile is actually the third tile on the scanline (from the left). As in, the ruler didn't move until there were 3 columns of dots on the screen.

The reason this is interesting is due to the fetches the PPU makes to render a scanline, which there's a handy reference for here.

The first two tiles of a scanline are fetched at the end of the PREVIOUS scanline, just before the duplicate read. However, when the trick tile is within the first two columns of the screen (when there are only 2 columns of dots in the video), the ruler is unaffected.

With one column of dots on the screen, the fetches should look something like this:

23FF -- First tile for next scanline --
23FF <- Trick duplicate read
0000
0008
23E0 -- Second tile for next scanline --
23F8
0000
0008
23E1 -- The end-of-scanline duplicate read, MMC5 detects this --
23E1
-- Idle Cycle --
23E1 -- Beginning of next scanline, third tile for this scanline --
23F8
0000
0008

However, the MMC5 doesn't seem to be recognizing this. Same for when there are two columns of dots on the screen:

23FE -- First tile for next scanline --
23FF
0000
0008
23FF -- Second tile for next scanline --
23FF <- Trick duplicate read
0000
0008
23E0 -- The end-of-scanline duplicate read, MMC5 detects this --
23E0
-- Idle Cycle --
23E0 -- Beginning of next scanline, third tile for this scanline --
23F8
0000
0008

but with three columns of dots on the screen, the MMC5 detects the trick and clocks the scanline counter one extra time.

23FD -- First tile for next scanline --
23FF
0000
0008
23FE -- Second tile for next scanline --
23FF
0000
0008
23FF -- The end-of-scanline duplicate read, MMC5 detects this --
23FF
-- Idle Cycle --
23FF -- Beginning of next scanline, third tile for this scanline --
23FF <- Trick duplicate read
0000
0008

I don't know what happens when the tile is on other parts of the scanline, but why does this trick only work when the tile is on the third column of the screen?

User avatar
loopy
Posts: 396
Joined: Sun Sep 19, 2004 10:52 pm
Location: UT

Post by loopy » Wed Feb 22, 2012 11:00 am

Because it's looking for *3* reads, not 2.

1 column:

Code: Select all

23FF
23FF
0000 
0008 

23E0
23F8 
0000 
0008 

23E1 \
23E1  \ 1
      /
23E1 /
23F8 
0000 
0008 

2 columns:

Code: Select all

23FE
23FF 
0000 
0008
 
23FF
23FF
0000 
0008 

23E0 \
23E0  \ 1
      /
23E0 /
23F8
0000 
0008 
3 columns:

Code: Select all

23FD
23FF 
0000 
0008
 
23FE
23FF 
0000 
0008 

23FF \
23FF  \ 1 \
      /    \ 2
23FF /     /
23FF      /
0000 
0008
That's how I've implemented it on the Powerpak anyway, and the results look the same.
Last edited by loopy on Wed Feb 22, 2012 3:15 pm, edited 1 time in total.

Post Reply