I'm trying to separate my game logic from NMI to main. Right now all my game logic is in NMI, but as I don't want to be limited to ~1500cy I want to set a flag in NMI, do NMI-only stuff there and then check in main if the flag is set for further processing.
Important thing: if I do like this (aka Everything-In-NMI), everything in this configuration works fine and smooth:
Code: Select all
.proc main
forever:
jmp forever
rts
.endproc
Code: Select all
.proc handler_nmi
php
pha
txa
pha
tya
pha
lda #nmi_flag::set ; <--- I set up the flag here
sta zp_nmi_flag
nmi_oam_map
nmi_loader_jsr ; <--- This is the game logic stuff
nmi_ppuctrl_set
nmi_ppumask_set
nmi_screen_scroll
pla
tay
pla
tax
pla
plp
rti
.endproc
But, as I mentioned, I want to do the game logic in main like adult people do:
Code: Select all
.proc main
forever:
jsr _vblank_process
; My other stuff that will be run in non-vblank time (nothing here yet)
jmp forever
.endproc
Code: Select all
.proc _vblank_process
wait: ; <--- I sync to the nearest VBLANK looping here
lda zp_nmi_flag
cmp #nmi_flag::set
bne wait
nmi_loader_jsr ; <<---- My game logic is now here, should be run in VBLANK
lda #nmi_flag::unset
sta zp_nmi_flag
rts
.endproc
But when I do stuff like this I have severe graphical glitches during my gameplay, like if I smashed ppu-pointers, or write wrong ppu-addresses.
What have I done wrong? That's literally complete main at the moment, I can't see what can go wrong - I backup the registers, status byte, never use anything that is related to PPU in main but still have a lot of glitches in the second case. My NMI is very short and doesn't oversize the VBLANK time (futhermore the NMI-only case works fine).
Thank you in advance.