MMC3 clocking and palettes, what are the details?

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Alyosha_TAS
Posts: 173
Joined: Wed Jun 15, 2016 11:49 am

MMC3 clocking and palettes, what are the details?

Post by Alyosha_TAS »

I have something wrong with my implementation of mmc3 clocking when the palette is being read / written to, but I can't seem to figure out what it is. Specifically I am getting an error on the ending screen of Where's Waldo, where the game does some palette operations and expects different irq timing as a result.

I looked around but can't seem to find a thorough enough explanation to point me in the right direction.

Does anyone know the details that can explain what I should be doing? I'd really appreciate any insights.
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: MMC3 clocking and palettes, what are the details?

Post by Fiskbit »

Hopefully someone can go into further detail if needed, but the gist is that the PPU address bus contains the value of v when rendering is disabled, and so the cartridge can see that palette RAM is being targeted, it just can't see the writes. MMC3 is only looking for toggles on PPU A12, independent of the /rd and /wr signals, so when that bit is set in v from targeting palette RAM, it'll see that as a rising edge. It then won't see rising edges again until PPU A12 has been low for 3 M2 clock edges.

I might be able to help further if you can get more specific.
Alyosha_TAS
Posts: 173
Joined: Wed Jun 15, 2016 11:49 am

Re: MMC3 clocking and palettes, what are the details?

Post by Alyosha_TAS »

What is v in this case?

For example Where's Waldo does the following during vblank (changes one palette entry):

Code: Select all

E361:  A9 3F     LDA #$3F        A:C0  X:0D  Y:41  SP:F7  P:E5  NVTbdIzC  Cy:290774616  PPU-Cy:0
E363:  8D 06 20  STA $2006       A:3F  X:0D  Y:41  SP:F7  P:65  nVTbdIzC  Cy:290774618  PPU-Cy:0
E366:  A9 11     LDA #$11        A:3F  X:0D  Y:41  SP:F7  P:65  nVTbdIzC  Cy:290774622  PPU-Cy:0
E368:  8D 06 20  STA $2006       A:11  X:0D  Y:41  SP:F7  P:65  nVTbdIzC  Cy:290774624  PPU-Cy:0
E36B:  A5 55     LDA $55         A:11  X:0D  Y:41  SP:F7  P:65  nVTbdIzC  Cy:290774628  PPU-Cy:0
E36D:  8D 07 20  STA $2007       A:0D  X:0D  Y:41  SP:F7  P:65  nVTbdIzC  Cy:290774631  PPU-Cy:0
E370:  A9 00     LDA #$00        A:0D  X:0D  Y:41  SP:F7  P:65  nVTbdIzC  Cy:290774635  PPU-Cy:0
So what should the MMc3 see?

Thanks for the help!
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: MMC3 clocking and palettes, what are the details?

Post by Fiskbit »

v is one of the PPU's internal registers. See this wiki page. In short, writes to $2005 and $2006 update a sort-of staging register t, and the 2nd write to $2006 transfers the contents of t to v. t and v are also used during rendering, but for accessing VRAM outside of rendering, t is just a buffer for v and v is the current address on the PPU bus.

In your example, the two $2006 writes set t to $3F11, and the second write transfers t to v, setting v to $3F11 (with no intermediate value). The address bus then updates to the value of v, so the cartridge sees it change to $3F11. After the first write to $2007, an increment occurs, so the cart sees the incremented value ($3F12 or $3F31, depending on increment mode), but A12 is unchanged, so it doesn't affect anything.

I'm not well-versed in the specifics of the PPU address bus. I don't know what the delay is between v updating and the address bus changing, nor the delay between the 2nd $2006 write and v getting its new value. It's not relevant here, but because the lower bits have to be latched, I'm also not sure if those bits change at the same time as the upper bits or on the next PPU cycle.

Note that there's another detail that may matter to you regarding MMC3 IRQ. The 'idle cycle', dot 0 of each rendering scanline, actually starts a memory fetch, the same one that is done later on cycle 5. This read never actually happens, but the because the address is put on the bus on the first cycle of a two-cycle fetch, the cartridge sees the address change on cycle 0. This matters because if sprites are on the $0000 table and BG on the $1000 table, then the gap here would cause extra clocks were it not for cycle 0 resetting the M2 filter. However, when the skipped dot occurs, which technically skips the last dot on the prerender scanline, the memory fetch that would have finished on that skipped dot instead finishes on dot 0 of scanline 0, preventing this aborted fetch from starting, so the cycle 5 address does not make it onto the bus in this case, which can produce an extra clock. This happens sometimes in Wario's Woods, causing the last visible scanline to flicker because rendering gets disabled a scanline early (starting gameplay should settle into an alignment where it always either does or doesn't flicker).
Alyosha_TAS
Posts: 173
Joined: Wed Jun 15, 2016 11:49 am

Re: MMC3 clocking and palettes, what are the details?

Post by Alyosha_TAS »

Very interesting, thanks for the detailed reply.

one more question: after rendering is complete, what happens to v?
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: MMC3 clocking and palettes, what are the details?

Post by Fiskbit »

While the meaning of v changes depending on whether the PPU is rendering, the value does not. v keeps its value when rendering starts, v gets mutated over time by the PPU as part of the rendering process, and v keeps that mutated value when rendering ends. In fact, the low 14 bits of v can be left after rendering with a value that points into palette RAM, and this results in the PPU drawing the color at that address just as if you had manually set v to a palette RAM address.

During rendering, the value on the PPU address bus doesn't come directly from v; rather, it's whatever the PPU needs to fetch based on the information in v. However, when rendering ends, the PPU address bus is again automatically set to the value in the low 14 bits of v.
Alyosha_TAS
Posts: 173
Joined: Wed Jun 15, 2016 11:49 am

Re: MMC3 clocking and palettes, what are the details?

Post by Alyosha_TAS »

Ok, so I fixed Where's Waldo, but now I have a problem in Recca.

It seems the game expects one extra clock compared to what my emulator produces, but I'm not sure where it should come from.

The game does a bunch of palette writes during VBlank, and then it does the following:

Code: Select all

E286:  A9 3F     LDA #$3F        A:01  X:81  Y:0F  SP:99  P:24  nvTbdIzc  Cy:61405898  PPU-Cy:0
E288:  8D 06 20  STA $2006       A:3F  X:81  Y:0F  SP:99  P:24  nvTbdIzc  Cy:61405900  PPU-Cy:0
E28B:  A9 00     LDA #$00        A:3F  X:81  Y:0F  SP:99  P:24  nvTbdIzc  Cy:61405904  PPU-Cy:0
E28D:  8D 06 20  STA $2006       A:00  X:81  Y:0F  SP:99  P:26  nvTbdIZc  Cy:61405906  PPU-Cy:0
E290:  8D 06 20  STA $2006       A:00  X:81  Y:0F  SP:99  P:26  nvTbdIZc  Cy:61405910  PPU-Cy:0
E293:  8D 06 20  STA $2006       A:00  X:81  Y:0F  SP:99  P:26  nvTbdIZc  Cy:61405914  PPU-Cy:0
E296:  A6 FF     LDX $FF         A:00  X:81  Y:0F  SP:99  P:26  nvTbdIZc  Cy:61405918  PPU-Cy:0
E298:  9A        TXS             A:00  X:F1  Y:0F  SP:99  P:A4  NvTbdIzc  Cy:61405921  PPU-Cy:0
E299:  60        RTS             A:00  X:F1  Y:0F  SP:F1  P:A4  NvTbdIzc  Cy:61405923  PPU-Cy:0
DCD6:  A6 4B     LDX $4B         A:00  X:F1  Y:0F  SP:F3  P:A4  NvTbdIzc  Cy:61405929  PPU-Cy:0
DCD8:  F0 10     BEQ $DCEA       A:00  X:01  Y:0F  SP:F3  P:24  nvTbdIzc  Cy:61405932  PPU-Cy:0
DCDA:  A5 3C     LDA $3C         A:00  X:01  Y:0F  SP:F3  P:24  nvTbdIzc  Cy:61405934  PPU-Cy:0
DCDC:  85 3E     STA $3E         A:36  X:01  Y:0F  SP:F3  P:24  nvTbdIzc  Cy:61405937  PPU-Cy:0
DCDE:  A5 3D     LDA $3D         A:36  X:01  Y:0F  SP:F3  P:24  nvTbdIzc  Cy:61405940  PPU-Cy:0
DCE0:  85 3F     STA $3F         A:E8  X:01  Y:0F  SP:F3  P:A4  NvTbdIzc  Cy:61405943  PPU-Cy:0
DCE2:  A5 3B     LDA $3B         A:E8  X:01  Y:0F  SP:F3  P:A4  NvTbdIzc  Cy:61405946  PPU-Cy:0
DCE4:  8D 00 C0  STA $C000       A:4F  X:01  Y:0F  SP:F3  P:24  nvTbdIzc  Cy:61405949  PPU-Cy:0
DCE7:  8E 01 C0  STX $C001       A:4F  X:01  Y:0F  SP:F3  P:24  nvTbdIzc  Cy:61405953  PPU-Cy:0
DCEA:  A9 00     LDA #$00        A:4F  X:01  Y:0F  SP:F3  P:24  nvTbdIzc  Cy:61405957  PPU-Cy:0
DCEC:  9D 00 E0  STA $E000,X     A:00  X:01  Y:0F  SP:F3  P:26  nvTbdIZc  Cy:61405959  PPU-Cy:0
So it writes 0 to $2006, then sets up IRQ variables, then enables IRQs. This happens around scanline 249.

Should this setting $2006 to zero cause an extra clock to happen somewhere other then the normal scanline clocks?

Either that, or it expects setting $2006 to 0x3F00 to not clock the IRQ for some reason.
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: MMC3 clocking and palettes, what are the details?

Post by Fiskbit »

The $3F00 $0000 write pattern you see there is a workaround for a poorly-understood palette corruption bug. It won't clock the counter because the PPU address already had A12 set for writing to palette RAM, but the fact that it ends with A12 clear means that the next rising edge on A12 will be seen as a clock.

The $3F00 write at the start of that function before the popslide for writing palette data does clock the counter (in Mesen, I see the counter go $17->$16), since v seems to always have A12 clear before that. However, it doesn't seem to bring the counter to 0 and the code you quoted that runs shortly after both acks IRQs and schedules a reload for the next A12 clock, so I don't think that clock can matter.
Alyosha_TAS
Posts: 173
Joined: Wed Jun 15, 2016 11:49 am

Re: MMC3 clocking and palettes, what are the details?

Post by Alyosha_TAS »

ok i think I finally understand what the problem is now.

For clarity, the issue I ave is one the hard mode title screen in Recca (with the flames.)

Shortly after the code I posted, the game writes to 2 times to $2005, the second write sets bit 12 in the t register. This gets set to the vram address at the end of pre-render scanline, before the first nametable fetches, so this causes a clock on the MMC3. I was not implementing this behaviour.

At least I think that's what's wrong.

Thanks for the help Fiskbit.
Alyosha_TAS
Posts: 173
Joined: Wed Jun 15, 2016 11:49 am

Re: MMC3 clocking and palettes, what are the details?

Post by Alyosha_TAS »

Turns out I don't quite have it figured out.

I'm also getting stray clocks from sprite pattern table reads on the pre-render line. What addresses are used for sprite reading on the pre-render line?
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: MMC3 clocking and palettes, what are the details?

Post by lidnariq »

Some months back I recorded the full PPU bus for four vsyncs displaying the SMB3 title screen. I can't directly tell what it is here, but I suspect the eight fetches on the prerender scanline are the possibly-decayed contents of secondary OAM on the final rendered scanline
Attachments
smb3title.sr.zip
open with pulseview/sigrok
(366.24 KiB) Downloaded 22 times
Alyosha_TAS
Posts: 173
Joined: Wed Jun 15, 2016 11:49 am

Re: MMC3 clocking and palettes, what are the details?

Post by Alyosha_TAS »

Thanks for the info, but after double checking with Mesen, it seems that is not my problem either.

Comparing to Mesen, I'm simply missing an IRQ. My IRQs are starting at the correct scanline, but Mesen gets an extra IRQ at the end.

This IRQ seems to be triggered on cycle 1 of the post render scanline. Is there anything happening at this point that can trigger an extra rising edge of A12? This also looks like the point where Mesen changes it's frame counter, maybe this is a glitch in Mesen that happens to work out?

This is very confusing.
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: MMC3 clocking and palettes, what are the details?

Post by Fiskbit »

At the start of post-render, rendering ends and the PPU address bus is changed to the value of v. The lowest bit of fine y from rendering occupies bit 12, so if fine y bit 0 is 1, you'll get an A12 rising edge here because the address bus was previously being used for nametable fetches, and I believe it should clock because background is on the $0000 table, so the M2 filter should have expired.

I wouldn't necessarily take Mesen as gospel here, for what it's worth.
Alyosha_TAS
Posts: 173
Joined: Wed Jun 15, 2016 11:49 am

Re: MMC3 clocking and palettes, what are the details?

Post by Alyosha_TAS »

Aha! Yes if I implement that then everything seems to work correctly in both Recca and Where's Waldo without breaking anything.

I suppose such a case is seldom encountered as most games only use one or two IRQ's per screen and have them turned off by the time vblank happens.

Really happy to have this one finally sorted. I probably still have a few not quite correct edge cases, but it's a big step in the right direction.

Thanks for the help!
Alyosha_TAS
Posts: 173
Joined: Wed Jun 15, 2016 11:49 am

Re: MMC3 clocking and palettes, what are the details?

Post by Alyosha_TAS »

Small bit of follow up here.

It seems Burai Fighter expects soam to decay during vblank, otherwise extra clocks occur on scanline 0 causing the screen to shake, due to left over sprite values. At least that fixes it for me.
Post Reply