CPU - PPU clock alignment

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

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

CPU - PPU clock alignment

Post by Bregalad » Wed Mar 17, 2010 9:50 am

I want someone to confirm my troughs...

NTSC : 1 CPU Cycle = 3 PPU Cycles, so there is 1 * 3 = 3 possible alignments on reset

PAL : 5 CPU Cycles = 16 PPU Cycles, so there is 5 * 16 = 80 possible alignments on reset

Is this right ? I just got surprised that a program I wrote using raster effects behaves differently depending on resets and I want to understand why.
Life is complex: it has both real and imaginary components.

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg » Wed Mar 17, 2010 11:28 am

Nope, there are four for NTSC. Here are some notes I made a while back:

After power/reset, PPU is randomly in one of four synchronizations with CPU. This synchronization cannot be changed without resetting/powering down. Trials of 50-60 power/resets were done to determine likelihoods. The third synchronization is the preferred one for emulators and test ROMs, due to the least special cases, and highest likelihood.

Code: Select all

NMI     VBL         Hit             Overflow    Likelihood
        Reset   Reset   Set     Reset   Set
                6819+   7502+   6819+   7290+   Power   Reset
-------------------------------------------------------------
-1      -1      -1      0       -1      -1      27%     26%
0       -1      0       0       0       0       15%     22%
0       0       0       0       0       0       31%     30%
0       0       0       +1      0       0       27%     22%
Why four instead of three? It's due to the PPU and CPU using separate dividers. The CPU divides the master clock by 12, the PPU by 4. Thus, the CPU has four possible positions it can be in relative to the PPU:

Code: Select all

PPU   X---X---X---X---X---X---X---X---X---X---X-...
CPU 1 X-----------X-----------X-----------X-----...
CPU 2 -X-----------X-----------X-----------X----...
CPU 3 --X-----------X-----------X-----------X---...
CPU 4 ---X-----------X-----------X-----------X--...
I expect the same for the PAL system. The CPU divides the master clock by 16, the PPU by 5.

Code: Select all

PPU X----X----X----X----X----X----X----X----X----X----X----X----X----X----X----X----X--...
CPU X---------------X---------------X---------------X---------------X---------------X--...
Look at that, there is only ONE overall synchronization for PAL. The CPU hits all five sub-synchronizations from one clock to the next, though. That makes it both easier and harder for emulation of all the PAL special cases. It's easier in that there's only one to research, and no choice of which to emulate, but harder in that all 5 sub-synchronizations must be checked for different effects.

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

Post by Bregalad » Wed Mar 17, 2010 1:43 pm

Mmh... Thank you very much for your diagrams, they clarify things a lot.

So I really don't understand why my program using a raster effect has a line who seems to sometimes flicker, and sometimes be solid depending on resets on my PAL NES. I didn't mean it to be a test demo or anything - I just want to understand what is happening.

I synchronize from VBlank NMI for the effect, so I don't see how this can be an issue (but maybe it can ?).
Life is complex: it has both real and imaginary components.

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg » Wed Mar 17, 2010 4:44 pm

Interesting. Can you remove unncessary bits from your code until you're left with a very small amount which still displays different stable behavior depending on some power-up state? Or wait, we didn't examine the possible CPU synchronizations with respect to VBL. Basically consider all the possible number of PPU clocks between two VBL settings, and see if any are multiples of 5. Let's say the PPU frame length was 160000 (just some made-up value). That's a multiple of 16, so VBL would fall on the same relative CPU position every frame. It could be something like this going on.

User avatar
jwdonal
Posts: 719
Joined: Sat Jun 27, 2009 11:05 pm
Location: New Mexico, USA
Contact:

wow

Post by jwdonal » Thu Mar 18, 2010 12:02 am

blargg wrote:After power/reset, PPU is randomly in one of four synchronizations with CPU. This synchronization cannot be changed without resetting/powering down. Trials of 50-60 power/resets were done to determine likelihoods. The third synchronization is the preferred one for emulators and test ROMs, due to the least special cases, and highest likelihood.
Holy cow Blargg, you are frigin hard core with this RE'ing stuff. Haha, that is awesome. I'll tuck this post away for a much later date when I get to the point of fine tuning my emulator and so I can add an option to randomize these power up states to make it as close to the original as possible. THANKS! :)

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg » Thu Mar 18, 2010 9:25 am

Bregalad, have you tested to be sure there really is some state that can only be changed by resetting/powering down and then up? That is, you power up, run your program many times, get one particular visual effect, then reset, run your program, and consistently get a different effect, then reset, and get another effect consistently (or maybe the first again)?

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

Post by tepples » Thu Mar 18, 2010 9:45 am

There's the effect of the PPU ignoring writes to half its registers for the first frame after reset.

User avatar
Dwedit
Posts: 4309
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post by Dwedit » Thu Mar 18, 2010 9:50 am

Synchronized to vblank from NMI? Maybe do some timed OAMDATA reads, then execute some instructions to get the timing into a narrower range.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!

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

Post by Bregalad » Fri Mar 19, 2010 1:20 pm

blargg wrote:Bregalad, have you tested to be sure there really is some state that can only be changed by resetting/powering down and then up? That is, you power up, run your program many times, get one particular visual effect, then reset, run your program, and consistently get a different effect, then reset, and get another effect consistently (or maybe the first again)?
Yes I am sure, it's like you said.
I did originally not meant to release it as a standalone, but anyway it is for the good of NESdev, so I uploaded it here.
The last line of the logo sometimes flicker, and is sometimes solid depending on resets. (note : I think the flickering is due to the second $2006 writes being sometimes slightly past cc 256, and as a result the adress loaded is incorrect). It seems it never flickers on power on, and other lines show fine.

PS : Note that the point of this thread is NOT to solve the flickering issue (which I know how to deal with) but to understand why timing depends on resets.
Life is complex: it has both real and imaginary components.

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg » Fri Mar 19, 2010 3:51 pm

It could still be that the initial timing it's started at is what determines this flicker, rather than something in hardware. The source code would help.

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

Post by Bregalad » Sat Mar 20, 2010 2:11 am

Life is complex: it has both real and imaginary components.

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg » Tue Jun 01, 2010 2:48 pm

Been doing some PAL testing today (some info already known, just verifying). 312 scanlines per frame, 341 PPU clocks per scanline. 3.2 CPU clocks per PPU clock/0.3125 PPU clocks per CPU clock. Every frame is 312*341 PPU clocks, regardless of rendering being enabled; there's no skipped clock on odd rendered frames as on NTSC. This means that every frame is 33247.5 CPU clocks. It also means that there are eight PPU-CPU synchronizations that it can power up/reset into! There are so many partly because of the lack of a short frame as on NTSC. There are 16 different positions a PPU clock can fall within a CPU clock, and since the frame length ends in half a CPU clock, this is halved to 8, as it toggles between two synchronizations every frame.

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

Post by Bregalad » Wed Jun 02, 2010 5:05 am

It also means that there are eight PPU-CPU synchronizations that it can power up/reset into!
You lost me there. You told me before there was only one. Altough I definitely confirm a demo of mine, along with another old OAM reading demo, acted differently between resets, so you last theory seems much more realist to me.

I still don't understand why there is 8 alignements.
Life is complex: it has both real and imaginary components.

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg » Wed Jun 02, 2010 7:29 am

Yeah, I'm still trying to get my head around this.

OK, there is one CPU clock every 16 master clocks. Therefore, VBL can begin at 16 different positions within a CPU clock. VBL occurs every 312*341 PPU clocks. There are 5 master clocks in a PPU clock, so VBL occurs every 312*341*5=531960 master clocks. This is a multiple of 8, but not 16, so VBL's position within a CPU clock will alternate between two points, each a half CPU clock apart. For a given power/reset, it will never fall on anything other than these two points in a CPU cycle. Since there are 16 points available, 16/2=8 possible states it could power/reset into.

The above was from the CPU's point of view, which would be relevant for things like NMI. From the PPU's point of view, CPU reads/writes can occur in one of 5 positions within a PPU clock, which the CPU constantly cycles through every 5 CPU clocks. Every successive CPU clock begins one master clock (1/5 PPU clock) later within a PPU clock. This would suggest that the state at power/reset is irrelevant from the PPU's view, but PPU clocks aren't the only regular event in the PPU: there's also VBL. As above, after a power/reset, a CPU clock can begin in only two possible positions relative to VBL, each 8 master clocks apart.

I've been working on tests which are able to show how many different power/reset states it can be in, by being able to have it print which one it's on, and never print anything different except after another power/reset.

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg » Wed Jun 02, 2010 4:33 pm

I just confirmed that there are 8 distinct PPU-CPU synchronizations a PAL NES can power up/reset into, as predicted. Whatever one it uses (at random) doesn't change until you reset/power again. Lovely.

Post Reply