In game palette glitchy re-writing / VRAM access

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
In game palette glitchy re-writing / VRAM access
by on (#84780)
I have a demo with a firery background and i wish to 'flicker' the fire by cycling one of the colors in my palettes.

I've been able to get the colors switched however the screen shakes for a split second when i do this.
(I've put my color change call right after V-blank but it doesn't help.)


Code:
//accessing the 2nd color in the palette (3F01)
//knes
PPU_ADDR(0x3F01); //writes the high and low byte of the address
PPU.data = palette_fire2; //stores the new color


Just for fun I also tried inline asm to just store the value at address 3F01 but that didn't work at all :) :

Code:
__asm__ ("lda %v", palette_fire);
__asm__ ("sta $3F01");


I'm simply trying to do the realtime color cycling super mario bros does with it's coin/question block color. (SMB is glitch free of course.)

by on (#84781)
First of all what are you doing in vblank besides this? It seems SOMETHING is taking too long and spilling into rendering time.

Also after your writes try resetting the scroll by rewriting your current scroll value to $2005. (takes two writes...if not scrolling try using value #$00)

by on (#84783)
You need to reset PPU_ADDR to zero before visible part of the screen starts, i.e. right after your VBlank code.
Re: In game palette glitchy re-writing / VRAM access
by on (#84784)
Brickman wrote:
I've been able to get the colors switched however the screen shakes for a split second when i do this.
(I've put my color change call right after V-blank but it doesn't help.)

I'm guessing the screen jumps because your palette write messes up the scroll (because it modifies the PPU address). Changes to the PPU must happen during VBlank (i.e. they must be part of your VBlank handler), but they must be before the resetting of the scroll (i.e. the writes to $2000 and $2005, which must be the last PPU operation of the Vblank render).

Quote:
Just for fun I also tried inline asm to just store the value at address 3F01 but that didn't work at all :) :

That's because "STA $3F01" tries to store a value in the CPU addressing space, not the PPU addressing space. Always keep in mind that these two addressing spaces exist, and that the PPU space can only be accessed by the CPU through registers $2006 (address) and $2007 (data).

by on (#84785)
Shiru wrote:
You need to reset PPU_ADDR to zero before visible part of the screen starts, i.e. right after your VBlank code.

Resetting PPU_ADDR (i.e. writing $00 to $2006 twice) works in most cases, but the correct way to fully reset the scroll is to write to $2000 and $2005 instead. Write once to $2000 to select the name table and twice to $2005 to set the horizontal and vertical scroll. If you do that you don't need to reset $2006.

by on (#84788)
To recap what others were saying, in KNES setting the scroll would look something like this:

Code:
// BASE_NT0 defines the highest bit of scroll.
PPU.ctrl = BASE_NT0|ADDRINC_1|SPR_CHR0|BG_CHR1|SPR_8X8|NMI_ON;
// Set the low 8 bits of scroll.
PPU_SCROLL( 0, 0 );

It's a good idea to have code like this at the very end of vblank, after you've done all the PPU related updates.

by on (#84792)
thefox wrote:
Code:
// Set the low 8 bits of scroll.
PPU_SCROLL( 0, 0 );



That did it! (Writing 0 to $2006 twice), no screens bump at all now. Thank you all for your help!
:D
Re: In game palette glitchy re-writing / VRAM access
by on (#84795)
tokumaru wrote:
Brickman wrote:

Quote:
Just for fun I also tried inline asm to just store the value at address 3F01 but that didn't work at all :) :

That's because "STA $3F01" tries to store a value in the CPU addressing space, not the PPU addressing space. Always keep in mind that these two addressing spaces exist, and that the PPU space can only be accessed by the CPU through registers $2006 (address) and $2007 (data).


Ok, that's good to know -- thank you for clearing that up that mystery. :idea:

by on (#84796)
Brickman wrote:
thefox wrote:
Code:
// Set the low 8 bits of scroll.
PPU_SCROLL( 0, 0 );



That did it! (Writing 0 to $2006 twice), no screens bump at all now. Thank you all for your help!
:D

FYI this code doesn't write to $2006 twice, it writes to $2005.

by on (#84798)
Brickman wrote:
Code:
// Set the low 8 bits of scroll.
PPU_SCROLL( 0, 0 );


Don't forget about PPU.ctrl (which was also in thefox's suggestion), it's also important.

by on (#84800)
tokumaru wrote:
Brickman wrote:
Code:
// Set the low 8 bits of scroll.
PPU_SCROLL( 0, 0 );


Don't forget about PPU.ctrl (which was also in thefox's suggestion), it's also important.


Yeah, I had that implemented (from one of the KNES demo src's.)