Page 1 of 1

Re: Scroll glitch while turning of PPU right after NMI

Posted: Wed Feb 13, 2019 9:37 am
by tokumaru
A full scroll reset needs a write to $2000, in addition to the 2 writes to $2005. Seeing as the missing $2000 write is supposed to select the name table where the scroll starts at, and you're seeing "the other name table", this might be it.

I don't understand the purpose of "ppu_Off" though.

Re: Scroll glitch while turning of PPU right after NMI

Posted: Wed Feb 13, 2019 10:14 am
by tokumaru
When are you getting the wrong scroll exactly? Is it just for a frame when turning rendering on?

Re: Scroll glitch while turning of PPU right after NMI

Posted: Wed Feb 13, 2019 10:22 am
by tokumaru
Are pushseg and popseg backing up and restoring the CPU registers in the NMI handler? Those names are kinda misleading, since ca65 has directives with those names and they do something else. Maybe pushreg and popreg instead?

Anyway, just wanted to be sure that the registers are being preserved in the NMI handler, since your main thread relies on the accumulator being preserved in order to detect NMIs (and in case of lag frames you need X and Y to be backed up too).

Re: Scroll glitch while turning of PPU right after NMI

Posted: Wed Feb 13, 2019 10:22 am
by lidnariq
What scroll value does Mesen show for the garbage frame?

Re: Scroll glitch while turning of PPU right after NMI

Posted: Wed Feb 13, 2019 11:32 am
by lidnariq
yaros wrote:Funny enough, unless I'm stupid and read wrong value it is 0.
So the screen shot shows right after the bad frame. The PPU viewer implies your scroll is somehow $237B during the bad frame (upper left corner of grey box is at tile (27,28) fine Y scroll 2)—which sounds like something somewhere is trying to write to the PPU before it should.

Re: Scroll glitch while turning of PPU right after NMI

Posted: Wed Feb 13, 2019 3:18 pm
by tokumaru
Yeah, I'm not seeing anything obvious here that could be causing the problem, so there must be something else influencing this logic.

One thing that I personally don't like is that the NMI flag is being manipulated in various places, because that might result in conflicts. A better approach would be to have the NMI simply INC a variable, so that you can wait for the NMI just by waiting for that variable to change:

Code: Select all

NMI:
  (...)
  inc FrameCounter
  rti

WaitForNMI:
  lda FrameCounter
@loop:
  cmp FrameCounter
  beq @loop
  rts
Not only is this shorter and faster, but it's also safer, because it's not possible for different routines to step on each other's toes and put the flag in inconsistent states. I'm not saying this will solve your current problem, but it could about headaches in the long run run.

Another minor correction I have is that the $2003 (PPU_SPR_ADDR) write is NOT meant to set the low byte of the address of your OAM mirror, it's actually meant to set the TARGET position in OAM where the transfer will begin. The code works because this is usually 0 anyway, but the way the code is written suggests the wrong concept. This is a misconception that's still being spread by some tutorials.

Re: Scroll glitch while turning of PPU right after NMI

Posted: Thu Feb 14, 2019 6:37 pm
by gravelstudios
Not to change the subject, but...

Code: Select all

NMI:
  (...)
  inc FrameCounter
  rti

WaitForNMI:
  lda FrameCounter
@loop:
  cmp FrameCounter
  beq @loop
  rts
Tokumaru, when I saw this, I immediately put it into my current project. I was using a separate boolean to keep track of when my NMI routine was finished. It didn't occur to me to use the frame counter to do it. Thanks. You saved me a few bytes and cycles.

Re: Scroll glitch while turning of PPU right after NMI

Posted: Thu Feb 14, 2019 10:45 pm
by tokumaru
Cool. I think it was tepples who first pitched this idea around here.

Re: Scroll glitch while turning of PPU right after NMI

Posted: Fri Feb 15, 2019 10:02 am
by tepples
You don't need to reset it. If FrameCounter contains $38 before you wait for vblank, then $38 gets loaded into A. The loop continues until FrameCounter becomes no longer $38.