What you want to do is perhaps change an array in ram of 32 bytes which
represents the current palette, and then in your nmi routine you can upload this palette to RAM locations $3F00-$3F1F as stated above by tepples.
Here's a suggestion (but not a fully implemented one), which shows you what I am talking about. It assumes you know how to load a full 32 byte palette with rendering off prior to entering your game loop.
Note, you do not need that extra vblank wait before changing the ppu palette. You want to do it in your nmi routine. I'm going to assume that your "regulate_frames" routine waits for the last vblank to be completed.
Code:
;zeropage variables
dynamic_palette: .rs 32
some_colors_index: .rs 1
;code
;; 4. Load palettes, sprites and graphics
jsr load_full_palette ;---going to assume you have graphics off here and load a full 32 byte palette for sprites and background, from somewhere in ROM. I also assume this loads up dynamic_palette with an exact copy of what you upload to the PPU palette, here. This way when we re-upload dynamic_palette, only the colors you are cycling will change.
jsr load_sprites ; Load sprites
jsr bkg_setup ; Set background address and pointers
jsr bkg_load ; Load background
jsr ppu_update ; Turn on sprites and backgrounds
;initialize the color cycling index
lda #15
sta some_colors_index
jmp main_loop
;; 5. The main loop
main_loop:
jsr regulate_frames ; Regulate frames
jsr ctlr1_read ; Read controller 1
jsr cycle_color ; Change one color in dynamic_palette, each frame, picked from some_colors.
;cycle some_colors_index. it'll pick a new color from some_colors each frame.
dec some_colors_index
bpl :+
lda #15
sta some_colors_index
:
jmp main_loop
cycle_color:
ldx some_colors_index
lda some_colors,x
sta dynamic_palette+6 ;we're just going to cycle one color, for learning purposes.
rts
some_colors:
.db 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ;you would want to change these to actual NES colors you want, not just arbitrary values like I picked here
... ... ...
nmi:
pha
txa
pha
tya
pha
;load dynamic_palette into the ppu.
ldy #0
lda #$3F
sta $2006
lda #$00
sta $2006
ldx #$00
: lda dynamic_palette,y
sta $2007
inx
iny
cpx #$20
bne :-
;going to assume you know to reset the vram address and scroll registers as your last step in nmi.
;going to assume you have a way to alert the main loop that your nmi routine has finished running, and that regulate_frames waits for this flag to be set.
pla
tay
pla
tax
pla
rti