Color Cylcle / Altering palette while program running

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Color Cylcle / Altering palette while program running
by on (#1819)
I wanted to change the palette in a given interval to do some color cylcling. Though I don't know wheter my cycle routine works or not I just copied the palette loading routine from the beginning of the program to be executed on every 60th vBlank. Of course I turned off the screen before writing the palette and turned it on again afterwards. But after that's done the first time the screen is brown.
My routines to turn the screen on and off work, because in the beginning screen and palette are displayed properly.
Do I have to do the init-screen-procedure (writing a byte to each $2000 and $2001) every time the screen was turned off again?

by on (#1820)
I'm not sure what you mean by the init-screen procedure.

The way I'd normally do color cycling is by using a copy of the palette in RAM (zeropage), and write it to the PPU every frame in the NMI routine. Then the main program would be able to change the palette freely without disabling/enabling the screen.

by on (#1821)
Code:
init_screen:
   lda #%00001000
   sta $2000
   lda #%00011110
   sta $2001
   rts


If I understood that correctly the PPU only contains pointers to the location where the palette values are stored. Is that correct?
Where in RAM is the zeropage?

by on (#1825)
The palette values are always stored in a separate area of memory, conceptually thought of as $3F00 to $3F1F of VRAM but actually on a separate bus within the PPU.

"Zero page" is the first 256 bytes of CPU RAM ($0000-$00FF). But because of the way indexed addressing works on the 6502 processor, storing the palette in zero page would probably not be any faster than storing the palette somewhere in the rest of CPU RAM ($0100-$07FF).

by on (#1827)
The think I prefer myself is uploading the palette in the NMI routine if a flag is set. In your "main code" you can freele change the palette buffer then set the flag. (you don't need to turn the screen off scince it's done in the VBlank routine)

by on (#1829)
Can I .incbin my old palette file in RAM and alter it? I did so, but the palette does not change. Perhaps my cycle routine is wrong.
Code:
mainloop:
   lda Timer
   cmp #60
   bne mainloop
   ldx #0
   lda testpal, x
cycleloop:
   inx
   ldy testpal, x
   sta testpal, x
   tya
   cpx #15
   bne cycleloop
infin:
   jmp mainloop


This should just cycle the colors forward by one.

by on (#1830)
L0p1N wrote:
Can I .incbin my old palette file in RAM and alter it?

You can .incbin only in ROM, anything you put in RAM will need to be initialized at start-up it with some code (copy it out of ROM).

Your cycle routine looks fine to me. LDY,X is an opcode I haven't seen very often, heheh.

by on (#1832)
Seems I get some problems with nesasm.
I declared the palette with testpal .db $21, $..... (32 values in total).
Now I get a grey screen.
How do I input the data in nesasm without giving every byte an extra name?

by on (#1833)
The grey you're seeing is probably color $00.

You only need one label for the table. You used 'testpal' as the name for both in your examples, but really you need two labels. One in ROM with your starting data and one in RAM with your modifiable data.

Code:
palette_buffer = $300 ;(or wherever in RAM you want to use)

 ldx #0
:
 lda testpal,x
 sta palette_buffer,x
 inx
 cpx #32
 bne :-

testpal: .db $21,$...

by on (#1835)
OK, the .incbin'd testpal is only used for copying it's content into the buffer. As you said, the starting values have to be in ROM, so I asume I can still incbin a file.
I think I can just load the palette while NMI and remove the palette loading routine at the beginning of the code. But when I do so, I again get a grey screen (no matter if the cycle routine is in NMI or in the mainloop).
Seems there is an error in the cycle routine. But as it looks it doesn't work at all. When I first initialise the palette and then reload it to PPU every NMI the screen shows but the colors don't change, no matter if the cycle routine is used or not.
Do you find an error in my code?

by on (#1841)
I can only guess where the problem might be, without seeing all the source. Could be a misunderstanding or a simple typo. If you're still stuck, you can post it and I'll look it over.

I still think the cycling code looks ok. That is, assuming the 'testpal' label in there is in RAM which was pre-loaded with the colors to use. Actually, that contradicts my usage in the last example I posted. :?

by on (#1863)
OK. I just mailed you the code (think that's better than posting it all here).

by on (#1866)
Removed the turn_screen_on routine, now the screen is mixed up a bit, in both cases after the timer starts the cycle the first time the background disappears.

by on (#1888)
Try putting
Code:
lda #0
sta $2006
sta $2006


In there after the VRAM update. The background graphics could be messed up because of that, it's beginning the screen display from $3F20.