News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: NES Question - What causes $2006 to be increased by one?  (Read 3278 times)

RetroRain

  • Sr. Member
  • ****
  • Posts: 287
    • View Profile
NES Question - What causes $2006 to be increased by one?
« on: May 26, 2017, 10:40:25 pm »
I have this code, where I want to change the palettes of PPU addresses $3F11 and $3F12.

Originally I had it where I set $2006 to $3F11, and then I did two writes to $2007.

However, for whatever reason (and I tried playing around with clearing and setting Carry), at some points, it will jump to $3F13 and write a value there.  And I don't know why it does it.

So I tried separating $3F11 and $3F12, and it is still doing it.  At some random point, it will write a value to $3F13, even though there is clearly no code making that happen.

I know that the register $2007 has a quirk to it, so I was wondering if that is what is causing the problem.

If it helps any, the code is when you press a button, it changes the palette of the character.

(I don't have it shown in the code, but just before the code, I have a LDA $2002 and a BPL (wait for Vblank), and after the code a LDA #$20 and #$00 written to $2006 to reset the PPU)

Code: [Select]
   :61E3:A9 3F     LDA #$3F
   :61E5:8D 06 20  STA $2006 = #$13
   :61E8:A9 11     LDA #$11
   :61EA:8D 06 20  STA $2006 = #$13

   :61ED:A6 5F     LDX $005F = #$02
   :61EF:BD 10 62  LDA $6210,X @ $6212 = #$30
   :61F2:8D 07 20  STA $2007 = #$20

   :61F5:A9 3F     LDA #$3F
   :61F7:8D 06 20  STA $2006 = #$13
   :61FA:A9 12     LDA #$12
   :61FC:8D 06 20  STA $2006 = #$13

   :61FF:BD 18 62  LDA $6218,X @ $621A = #$2C
   :6202:8D 07 20  STA $2007 = #$20

If anyone has any ideas, feel free to let me know.  Thanks.

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: NES Question - What causes $2006 to be increased by one?
« Reply #1 on: May 26, 2017, 10:44:19 pm »
If rendering is switched on (either bit 3 or 4 of $2001 is set), the PPU will constantly be updating the internal address as it renders the screen.  It is ill advised to touch $2007 during rendering unless you are extremely careful with your timing.

Though if you are waiting for VBlank, that wouldn't be happening.  The only other way the address can be changed is via $2005/6/7 writes (or $2007 reads).

Also, FWIW, spinning on $2002 to wait for vblank is unreliable.  You might end up waiting 2 frames sometimes ... but for a quick hack it's fine.

RetroRain

  • Sr. Member
  • ****
  • Posts: 287
    • View Profile
Re: NES Question - What causes $2006 to be increased by one?
« Reply #2 on: May 26, 2017, 10:48:56 pm »
So in other words I'm screwed?

Could I try turning the screen off and then back on?  It would probably be very visible, the flash of the screen.

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: NES Question - What causes $2006 to be increased by one?
« Reply #3 on: May 26, 2017, 11:01:44 pm »
Well the question is... are your writes happening during rendering or not?

If you set a breakpoint on your code, the FCEUX debugger will tell you what scanline it's on.  Lines -1 to 239 are rendering lines (-1 might be called 262 depending on how it numbers them).

You don't need to change palettes mid-frame, so if your code is running during rendering, the fix is to make it run during VBlank.  Turning off/on the screen won't matter if you're in VBlank, and if you're in rendering it will likely create noticable glitches.


But if all your code is happening outside of rendering, then there shouldn't be a problem.  Only way I can see something screwing it up in that case is if an interrupt is happening in the middle of your code, and the interrupt handler is messing with PPU stuff.

RetroRain

  • Sr. Member
  • ****
  • Posts: 287
    • View Profile
Re: NES Question - What causes $2006 to be increased by one?
« Reply #4 on: May 27, 2017, 12:16:02 am »
Yeah, it's running during rendering, but the thing is, I am running my code during Vblank, and it is still happening anyway.

I don't know why.  I'll keep playing around with it.

Thanks for your help.

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: NES Question - What causes $2006 to be increased by one?
« Reply #5 on: May 27, 2017, 12:46:11 am »
Sorry, terminology confusion.

"During rendering" is a time.
"During vblank" is a time.

These times do not overlap.  You're either in one or the other.

Which one is your code running in?  Or rather, what does FCEUX say the scanline is when your code is running?

RetroRain

  • Sr. Member
  • ****
  • Posts: 287
    • View Profile
Re: NES Question - What causes $2006 to be increased by one?
« Reply #6 on: May 27, 2017, 02:25:20 am »
The scanline numbers that have been showing up are 3, 5, 6, 10, 12, etc.

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: NES Question - What causes $2006 to be increased by one?
« Reply #7 on: May 27, 2017, 02:31:32 am »
That is definitely during rendering.

It appears your code that is supposed to be waiting for VBlank is incorrect.  Can you post it?

EDIT:  Or your wait-for-VBlank code isn't running at all.  Or it's running a loooooong time before this code is running.
« Last Edit: May 27, 2017, 02:37:36 am by Disch »

RetroRain

  • Sr. Member
  • ****
  • Posts: 287
    • View Profile
Re: NES Question - What causes $2006 to be increased by one?
« Reply #8 on: May 27, 2017, 02:44:10 am »
Here it is.  Sorry, I probably should've just showed it like this from the get-go.

Code: [Select]
; wait for vblank
   :61DE:AD 02 20  LDA $2002 = #$10
   :61E1:10 FB     BPL $61DE

; set $2006 to PPU address $3F11
   :61E3:A9 3F     LDA #$3F
   :61E5:8D 06 20  STA $2006 = #$00
   :61E8:A9 11     LDA #$11
   :61EA:8D 06 20  STA $2006 = #$00

; write data using $2007
   :61ED:A6 5F     LDX $005F = #$00
   :61EF:BD 10 62  LDA $6210,X @ $630F = #$00
   :61F2:8D 07 20  STA $2007 = #$20

; set $2006 to PPU address $3F12
   :61F5:A9 3F     LDA #$3F
   :61F7:8D 06 20  STA $2006 = #$00
   :61FA:A9 12     LDA #$12
   :61FC:8D 06 20  STA $2006 = #$00

; write data using $2007
   :61FF:BD 18 62  LDA $6218,X @ $6317 = #$00
   :6202:8D 07 20  STA $2007 = #$20

; reset $2006 to the top-left of the screen
   :6205:A9 20     LDA #$20
   :6207:8D 06 20  STA $2006 = #$00
   :620A:A9 00     LDA #$00
   :620C:8D 06 20  STA $2006 = #$00
   :620F:60        RTS

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: NES Question - What causes $2006 to be increased by one?
« Reply #9 on: May 27, 2017, 02:52:10 am »
It's possible you're catching this at the very end of vblank.   Do another LDA $2002 just before your loop to clear the flag if it's already set.

... although even if that's happening, you wouldn't be hitting your drawing code on scanline 12.  It'd be scanline 1 at the very latest.

Are you sure that BPL loop is running?



EDIT:

An NMI might be firing.... but I would expect that to mess with your BPL loop.



Anyway --- you're probably going about this wrong.  You shouldn't be using $2002 ... you should be hooking into the game's NMI handler and running your code there -- so that it's sure to be happening in VBlank.



« Last Edit: May 27, 2017, 02:58:50 am by Disch »

RetroRain

  • Sr. Member
  • ****
  • Posts: 287
    • View Profile
Re: NES Question - What causes $2006 to be increased by one?
« Reply #10 on: May 27, 2017, 02:58:15 am »
Honestly, I don't know if that BPL is running.  I don't really use BPL all that much.  In the past, this is how I've seen people wait for vblank, by doing the LDA $2002 and then having the BPL after it jump back to it.

Is there a better way of waiting for vblank?

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: NES Question - What causes $2006 to be increased by one?
« Reply #11 on: May 27, 2017, 03:00:18 am »
Whoops you replied after my edit.   ;D -- or rather, I edited after your reply!

Is there a better way of waiting for vblank?

Yeah -- go in the NMI handler.

Basically whatever code is jumping to this drawing code should set some flag to indicate the palette needs to be redrawn, instead (but should not actually do the drawing itself).
Then in the NMI handler, you'd check that flag and do the drawing if it's set.

RetroRain

  • Sr. Member
  • ****
  • Posts: 287
    • View Profile
Re: NES Question - What causes $2006 to be increased by one?
« Reply #12 on: May 27, 2017, 03:05:42 am »
Alright I'll check it out.

Thanks Disch. :)

dougeff

  • Sr. Member
  • ****
  • Posts: 358
    • View Profile
Re: NES Question - What causes $2006 to be increased by one?
« Reply #13 on: May 27, 2017, 10:58:15 am »
Quote
Could I try turning the screen off and then back on?

If you turn the screen off and on, during rendering, the PPU will try drawing the top of the screen again... midscreen (the lower half of the frame will be shifted down). Also, you will draw a line of the main BG color accross the screen during the OFF period...and if you are drawing palettes, that line will be rainbow colored.

There is a way to adjust the scroll for the 'screen back on' lower portion of the frame that is misaligned (to realign it), but it requires that you know the exact scanline you are on, and also requires exactly perfect timing.

TL,DR...do it during V-blank.
nesdoug.com -- blog/tutorial on programming for the NES

RetroRain

  • Sr. Member
  • ****
  • Posts: 287
    • View Profile
Re: NES Question - What causes $2006 to be increased by one?
« Reply #14 on: May 27, 2017, 11:12:47 pm »
Disch you're the best!  It works like a freakin' charm!  I got it to work! :D

Thanks buddy! :)

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: NES Question - What causes $2006 to be increased by one?
« Reply #15 on: May 28, 2017, 12:30:33 am »
Congrats!  Glad to hear it's working.  And happy to help.   :beer:

Bregalad

  • Hero Member
  • *****
  • Posts: 2751
    • View Profile
Re: NES Question - What causes $2006 to be increased by one?
« Reply #16 on: May 28, 2017, 11:24:17 am »
What exactly are you trying to do? If you want to change a palette in a game, it's better to re-use existing palette-writing routine rather than code your own.