CPU - PPU clock alignment

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

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

Post by blargg »

I finally had time to go over your program. You're doing PPU writes during rendering. If you're doing a write within a small window, a small timing change could cause it to fall outside it and cause a graphical glitch. Your code doesn't seem to synchronize with the PPU very precisely, so it'd be easy for this to happen.

Your code runs off NMI, with a simple HERE: JMP HERE loop running between NMIs. So you already have a variation of 3*16-1=47 master clocks when your NMI is called. You do sprite DMA during the NMI, which can take one extra CPU clock, so that adds another 16 master clocks of variance, totaling 63 master clocks. Divide by 5 and you get 12.6 PPU clocks.

But, depending on the timing of the NMI routine and power/reset synchronization, it might not vary over this full 12.6 PPU clock range; after some powers/resets it may vary by less, and thus not flicker, while others it may vary by the full 12.6 PPU clocks. Analyzing this could be very complex, because the timing of every execution of NMI is relevant; the number of clocks until it RTIs determines when the JMP HERE loop resumes, and thus affects when the next NMI occurs relative to VBL.

I wrote a simple test program that puts up a vertical line in a nametable, then does some $2006 writes mid-frame which have a major glitch only after some powers/resets.

pal_flicker_sometimes.zip

Normally it causes a slight flickering glitch to the right on one scanline (left image), but after some powers/resets, the whole vertical bar below flickers to the right every few frames (right image).

Image

After setting up the nametable and enabling NMI and rendering, the code is very simple:

Code: Select all

wait:   jmp wait


nmi:    ; Do sprite DMA and reset PPUADDR to 0
        bit PPUSTATUS
        lda #0
        sta SPRADDR
        sta SPRDMA
        sta PPUADDR
        sta PPUADDR
        
        delay 15012
        
        ; Set PPUADDR to $2121 mid-frame
        lda #$21
        sta PPUADDR
        sta PPUADDR
        
        rti
So, the conclusion is that yes, PAL has multiple PPU-CPU synchronizations, and that it's very easy to have code that works fine after some powers/resets, but not others.
User avatar
Eugene.S
Posts: 317
Joined: Sat Apr 18, 2009 4:36 am
Location: UTC+3
Contact:

Re: CPU - PPU clock alignment

Post by Eugene.S »

Researches of Dendy/Famiclone PAL hardware:

- Eliminator Boat Duel (USA) hangs on depending of reset.
- Star Wars JVC (USA) does same, but rare
- Ninja Ryukenden 1 (Japan) works on hardware, but must "blackout" during 1'st cutscene. This game crash on most-of cycle accurate emulators.
- Vice Project Doom/Gun Dec works correctly on hardware.
It have interesting behavior on Nestopia, MyNES and Mesen-alignment build.
Game hangs at the end of 3'rd level (boss's room) depending of CPU/PPU initial states.

I have EDN8, EDN8-PRO and Faminvite. All of these flashcartridges gives different results.
Classic & Junior PCBs runs boatduel much more frequent on Faminvite than EDN8.
But i'm tired to test all PCB models on all flashes.
Attachments
alignment.png
excel-alignment.zip
(13.87 KiB) Downloaded 78 times
Last edited by Eugene.S on Mon Feb 13, 2023 5:54 am, edited 2 times in total.
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: CPU - PPU clock alignment

Post by Fiskbit »

I haven't looked at all these games yet, but based on Eliminator Boat Duel, the issue appears to be caused by the PPU bug where the vblank flag is lost if $2002 is read on the same dot the flag is set on. On NTSC and PAL systems (does this bug happen on official PAL PPUs?), frames do not last a whole number of CPU cycles, so if your current frame were aligned such that the buggy dot could coincide with a CPU read, the next frame wouldn't have this alignment and you'd see the flag then. Dendy, however, has a 35464 cycle frame length, so the console is either in an alignment that allows the bug on every frame, or an alignment that never allows the bug.

The common $2002 wait loop of BIT, BPL is 7 cycles long. In the case of Eliminator Boat Duel, this crosses a page boundary, so it's 8 cycles. 8 evenly divides the Dendy frame length of 35464 cycles, so if execution is aligned such that the flag is lost on the first frame, it will be lost on every frame thereafter, crashing the game. Tepples has been kind enough to add this information to the wiki, suggesting that the length of any $2002 wait loop not evenly divide 35464 cycles for Dendy compatibility.

Thanks for your work on this, Eugene.S.
User avatar
Eugene.S
Posts: 317
Joined: Sat Apr 18, 2009 4:36 am
Location: UTC+3
Contact:

Re: CPU - PPU clock alignment

Post by Eugene.S »

After huge testings i can say that flashcartridge type affects alignments.
I have one console (look at "JuniorRemake PCB") which fails boatduel almost every time if EDN8 is used.
And vice-versa: boatduel run almost every time if Faminvite is used here.
Really strange story.

Need to test all 3 flashcart types on each hardware exemplar, but i'm so tired now.
User avatar
Eugene.S
Posts: 317
Joined: Sat Apr 18, 2009 4:36 am
Location: UTC+3
Contact:

Re: CPU - PPU clock alignment

Post by Eugene.S »

*outdated info was deleted*
User avatar
Eugene.S
Posts: 317
Joined: Sat Apr 18, 2009 4:36 am
Location: UTC+3
Contact:

Re: CPU - PPU clock alignment

Post by Eugene.S »

My research continues after a long break.

The most mysterious glitch occurs in the Ninja Ryukenden (Japan)
I used many different PCBs, flash-carts and chipsets (UMC UA6527P/6538, TA-03NP1/TA-02NP, 1818P and UM6561) for this test.
I am not sure if this behavior is related to alignment or has other reasons.

Unlike Eliminator Boat Duel and Star Wars, the Ninja Ryukenden always starts on any hardware at every power-on/reset.
It also does NOT freeze when you press "start" in the main menu, and allows turn on the first level

Almost always the following behavior occurs on the hardware:
TEST VIDEO
- A black screen appears instead of the sword in the first cut-scene
- Game hangs during second cut-scene with funny artifacts

But emulators behavior is quite different. Look at my excel-list a few posts above
- Game hangs when you press "start" in the main menu [Mesen 0.9.8, nintendulator, bizhawk, nestopiaue, fceux]
- Emulator gives out the wrong opcode after start pressed, then goes normal after you press start again [Mesen 0.9.9, nintendulatorNRS, myNES]
- Game hangs immidately giving illegal opcode [puNES, Mesen 0.9.9 at some alignments]

The Ninja Gaiden (USA) starts without problems on all of these emulators.

What's going-on on start-up with the Japanese version?
User avatar
Eugene.S
Posts: 317
Joined: Sat Apr 18, 2009 4:36 am
Location: UTC+3
Contact:

Re: CPU - PPU clock alignment

Post by Eugene.S »

Interesting finding.
I found a new game (Kyouryuu Sentai Zyuranger) that randomly [hangs/work correct] between cutscenes and doorway transitions on Nestopia and MyNES, despite the fact that both of these cycle-accurate emulators have constant CPU/PPU alignment.

Moreover, both of them have similar bug on [Vice Project Doom/Gun Dec] - Game hangs at the end of 3'rd level (boss's room).
This bug appears consistently unlike Kyouryuu Sentai Zyuranger random hangs.
I was able to replicate this bug on Mesen-alignment build (based on 0.9.9) oudated now
I've already written about this a few posts above

So, i need to test Zyuranger on Mesen/puNES new builds too, at every alignment states.
My hardware (bunch of 6527P/6538 (UMC and TA manufacturers), T1818P, UM6561F-2) never replicate this bugs.
Post Reply