This is from SMB and is pretty smart:
This is an interesting solution, it was used in other games too, but is using the stack really better than having a label to reference the pointers where I marked with an '*'? For example, you could load x and y with the high and low of the label and then call the jump engine. Or Is there a big advantage I am missing?
(Note there are multiple blocks of code that call the jumpengine, not just OperModeExecutionTree.)
Code:
OperModeExecutionTree:
lda OperMode ;this is the heart of the entire program,
jsr JumpEngine ;most of what goes on starts here
.dw TitleScreenMode ; <-- *
.dw GameMode
.dw VictoryMode
.dw GameOverMode
;....
;later somewhere else in ROM:
;$04 - address low to jump address
;$05 - address high to jump address
;$06 - jump address low
;$07 - jump address high
JumpEngine:
asl ;shift bit from contents of A
tay
pla ;pull saved return address from stack
sta $04 ;save to indirect
pla
sta $05
iny
lda ($04),y ;load pointer from indirect
sta $06 ;note that if an RTS is performed in next routine
iny ;it will return to the execution before the sub
lda ($04),y ;that called this routine
sta $07
jmp ($06) ;jump to the address we loaded
lda OperMode ;this is the heart of the entire program,
jsr JumpEngine ;most of what goes on starts here
.dw TitleScreenMode ; <-- *
.dw GameMode
.dw VictoryMode
.dw GameOverMode
;....
;later somewhere else in ROM:
;$04 - address low to jump address
;$05 - address high to jump address
;$06 - jump address low
;$07 - jump address high
JumpEngine:
asl ;shift bit from contents of A
tay
pla ;pull saved return address from stack
sta $04 ;save to indirect
pla
sta $05
iny
lda ($04),y ;load pointer from indirect
sta $06 ;note that if an RTS is performed in next routine
iny ;it will return to the execution before the sub
lda ($04),y ;that called this routine
sta $07
jmp ($06) ;jump to the address we loaded
This is an interesting solution, it was used in other games too, but is using the stack really better than having a label to reference the pointers where I marked with an '*'? For example, you could load x and y with the high and low of the label and then call the jump engine. Or Is there a big advantage I am missing?
(Note there are multiple blocks of code that call the jumpengine, not just OperModeExecutionTree.)