I've recently found that passing arguments can prove to be somewhat troublesome depending on what you have in mind. Obviously, one might go for a route where each CPU register holds one of the arguments assuming there are up to 3 arguments. Some situations might call for a method that only uses 'A' to pass arguments, especially whenever it's important to be able to use instructions with indexed addressing. I see two ways it might be done, and I'd be interested to know which of these works better, or if there's a better way of doing it.
For example, this is an ASM6 macro I have in my game that can be used in any entity's AI to accelerate the entity over time:
I have no choice but to push the return address in advance (AccelerateObject ends with an RTS), otherwise the arguments get buried under it and messing with 'S' seems to be a lot less optimal.
The other method I've used before was to pass arguments using zero page temporaries:
Now both of these are sort of "hybrids", mixing the the 'registers-method' with the other one respectively, but of course this avoids a pointless PHA-PLA pair in the end.
All in all, is there a generally acceptable "best way" of doing this, or is it always situational?
For example, this is an ASM6 macro I have in my game that can be used in any entity's AI to accelerate the entity over time:
Code:
.macro ACCELERATE Xhi,Xlo,Yhi,Ylo
; accelerate the current object
; pass arguments via the stack
lda #>(accelreturn-1) ; push return address in advance
pha
lda #<(accelreturn-1) ; push return address in advance
pha
; recognize and avoid unnecessary lda-s
lda #Yhi
pha
.if Yhi != Ylo
lda #Ylo
.endif
pha
.if Ylo != Xhi
lda #Xhi
.endif
pha
.if Xhi != Xlo
lda #Xlo
.endif
jmp AccelerateObject
accelreturn:
.endm
; accelerate the current object
; pass arguments via the stack
lda #>(accelreturn-1) ; push return address in advance
pha
lda #<(accelreturn-1) ; push return address in advance
pha
; recognize and avoid unnecessary lda-s
lda #Yhi
pha
.if Yhi != Ylo
lda #Ylo
.endif
pha
.if Ylo != Xhi
lda #Xhi
.endif
pha
.if Xhi != Xlo
lda #Xlo
.endif
jmp AccelerateObject
accelreturn:
.endm
I have no choice but to push the return address in advance (AccelerateObject ends with an RTS), otherwise the arguments get buried under it and messing with 'S' seems to be a lot less optimal.
The other method I've used before was to pass arguments using zero page temporaries:
Code:
.macro LOADPALETTE target,palID,amount
; Load palettes and raise the update flag
load=PaletteSet+(palID*4)
lda #<load
sta temp+14
lda #>load
sta temp+15 ; set up indirect vector
lda #amount ; number of extra palettes to load
sta temp+1
lda #target ; target in the buffer
jsr LoadThePalette
.endm
; Load palettes and raise the update flag
load=PaletteSet+(palID*4)
lda #<load
sta temp+14
lda #>load
sta temp+15 ; set up indirect vector
lda #amount ; number of extra palettes to load
sta temp+1
lda #target ; target in the buffer
jsr LoadThePalette
.endm
Now both of these are sort of "hybrids", mixing the the 'registers-method' with the other one respectively, but of course this avoids a pointless PHA-PLA pair in the end.
All in all, is there a generally acceptable "best way" of doing this, or is it always situational?