59 lines
1.6 KiB
Plaintext
59 lines
1.6 KiB
Plaintext
;assume that the NES's screen is active and NMI occurs at the end of every frame.
|
|
|
|
mutex equ $01 ;these addresses in zero page memory will serve as the global variables.
|
|
vblankflag equ $02
|
|
|
|
main:
|
|
;if your time-sensitive function has parameters, pre-load them into global memory here.
|
|
;The only thing the NMI should have to do is write the data to the hardware registers.
|
|
|
|
jsr waitframe
|
|
LDA #$01 ;there's not enough time for a second vblank to occur between these two calls to waitframe().
|
|
STA mutex ;release the mutex. the next NMI will service the function we just unlocked.
|
|
jsr waitframe
|
|
|
|
halt:
|
|
jmp halt ;we're done - trap the cpu. NMI will still occur but nothing of interest happens since the mutex is locked.
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
nmi: ;every 1/60th of a second the CPU jumps here automatically.
|
|
pha
|
|
txa
|
|
pha
|
|
tya
|
|
pha ;pushAll
|
|
|
|
;for simplicity's sake the needs of the hardware are going to be omitted. A real NES game would perform sprite DMA here.
|
|
|
|
LDA mutex
|
|
BEQ exit_nmi
|
|
|
|
; whatever you wanted to gatekeep behind your mutex goes here.
|
|
; typically it would be something like a text box printer, etc.
|
|
; Something that needs to update the video RAM and do so ASAP.
|
|
|
|
LDA #$00
|
|
STA mutex ;lock the mutex again.
|
|
|
|
exit_nmi:
|
|
LDA #$01
|
|
STA vblankflag ;allow waitframe() to exit
|
|
|
|
pla
|
|
tay
|
|
pla
|
|
tax
|
|
pla ;popAll
|
|
rti
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
waitframe:
|
|
pha
|
|
LDA #0
|
|
sta vblankflag
|
|
.again:
|
|
LDA vblankflag
|
|
BEQ again ;this would loop infinitely if it weren't for vblankflag being set during NMI
|
|
pla
|
|
rts
|