Day 12 - VBlank And Interrupts
If you don't know what VBlank is, pretend I'm hitting you with a trout. If
you do know what VBlank is, pretend I'm hitting you with a trout. If you have
no idea what a trout has to do with the NES, pretend I'm hitting you with a trout.
Now that we have an imaginary fish stench in the room, let's learn a better
way to sync with VBlank.
Patater GBAGuy Mirror
How do we use it?
First, we have a label, say 'VBlank_Routine', so we put it in the addresses
in Bank 1 at $FFFA. Like so:
.dw VBlank_Routine ; address to execute on VBlank
.dw Start ; address to execute at RESET.
.dw 0 ; address to execute during a BRK instruction (Another Day, Another time).
.org $0000 ;variables
VBlankOrNo .db 0
.org $8000 ;code
;start of function to execute on VBlank
; add one (1) to VBlankOrNo, will be 1 if VBlank, 0 if not.
rti ; RTI is (Interrupt RETurn or ReTurn from Interrupt)
;start of main code
;blah some code
;waitforvblank: old code
; lda $2002 old code
; bpl waitforvblank old code
; the new code is :
lda VBlankOrNo ; A = VBlankOrNO
cmp #1 ; if A == 1 then is VBlank
bne WaitForVBlank ; if not VBlank, then loop and do again
dec VBlankOrNo ; 1-- or VBlankOrNO - 1 . VBlankOrNo will be 0 again.
; blah, code as usual.
I hope you get the general idea. I may have gotten something backwards or something,
so if you know this is wrong, please tell me (I'm tired and may have not typed right!).
UPDATE: Don't forget to set the "Generate VBlank bit" in one of the PPU Control ports!
(it's bit 7 of one of them, I think).
This Day In Review
This method will, appearantely, be much more stable than our old loop.
-Mike H a.k.a GbaGuy
Intro - Day 13