Closed Awuwunya closed 3 years ago
This is a pain I know well. But from what I have seen, this is unfixable: when macros are expanded, AS loops through all lines and replaces the values of the parameters as a preprocessing step. When you reach a shift in a rept/while in a macro, it is too late because it already has the value substituted in.
But there may be a way to handle this: for iterations requiring a single argument, you can do something like this:
mymacro macro
irp argvalue,ALLARGS
; code goes here, with argvalue having the value of each parameter
endm
endm
Maybe I can add an irpn version that allows you to specify the number (and name) of parameters used up in each step?
There is also a very specific case that I had issues with back when, I am not sure if your solution would work with this: https://github.com/NatsumiFox/AMPS-Sonic-2/blob/master/AMPS/code/68k%20Commands.asm#L798
Indeed irp does not work for that case; but here is how my proposed irpn addition would handle this macro:
dVoiceReg macro
; 2 is the number of parameters used in each iteration
; The next 2 parameters are names of these parameters
; All others form an array of parameters fed into those
; If there are not enough parameters, the parameters
; without values get a blank value, like in a macro
irpn 2,offset,reg,ALLARGS
move.b (a4)+,(a5) ; write value to buffer
moveq #reg,d3 ; load register to d3
or.b d2,d3 ; add channel offset to register
move.b d3,(a5)+ ; write register to buffer
if offset>1
addq.w #offset-1,a4 ; offset a4 by specific amount
endif
endm
endm
unless I'm mistaken, this would work different to my macro. The first argument is always offset
, eveey other argument is reg
. offset is only passed in once.
Oh, you are correct, I misread your macro; that is what happens when you write code on your phone, I guess.
Reading it properly, plain irp
would actually work for you:
dVoiceReg macro offset
._x := offset
shift
irp reg,ALLARGS
move.b (a4)+,(a5)+ ; write value to buffer
moveq #reg,d3 ; load register to d3
or.b d2,d3 ; add channel offset to register
move.b d3,(a5)+ ; write register to buffer
if ._x>1
addq.w #._x-1,a4 ; offset a4 by specific amount
endif
endm
endm
I also fixed a typo in the previous version where I had accidentally deleted the +
in (a5)+
.
Still, I will keep this open and implement irpn
because I actually have uses for it.
This has at least been an issue in older versions of AS. You can't iterate through macro arguments without recursively calling the macro! Although shift will work, it won't remap the actual macro variable names into these new values. This was never a problem in ASM68K and makes programming macros a pain in AS. This is especially the case if not every single macro argument is to be iterated through (you may have the first argument be interpreted before the actual looping portion!)