RosettaCodeData/Task/Mutex/6502-Assembly/mutex.6502

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