vhelin / wla-dx

WLA DX - Yet Another GB-Z80/Z80/Z80N/6502/65C02/65CE02/65816/68000/6800/6801/6809/8008/8080/HUC6280/SPC-700/SuperFX Multi Platform Cross Assembler Package
Other
546 stars 98 forks source link

Nested macro loses argument type #617

Open willbritton opened 9 months ago

willbritton commented 9 months ago

Following documentation here as well as discussion here I think I've established that using \?1 etc. is the only way to write a macro for 6502 which would work equally well for immediate mode as well as zero page mode arguments.

This appears to work fine for a single simple macro (LOAD_DATA in the example below) but when calling a macro from within another macro it seems like the argument type gets lost (COPY_DATA with immediate arg in the example below).

(Side note: I still haven't managed to get my head around why the immediacy of the argument does get removed at all - I understand macros aren't simple token replacements in wla but it would feel like the intuitive behaviour of macros in situations like this would be to pass the # symbol through all the way and let the assembler make the decisions about addressing mode.)

.memorymap
  defaultslot 0
  slotsize $100
  slot 0 $0000
.endme
.rombankmap
  bankstotal 1
  banksize $100
  banks 1
.endro

.macro LOAD_DATA
  .if \?1 == ARG_IMMEDIATE
    lda #\1
  .else
    lda \1
  .endif
.endm

.macro COPY_DATA
  LOAD_DATA(\1)
  sta \2
.endm

.bank 0 slot 0
.orga $0000

LOAD_DATA($aa)       ; emits      A5 AA (lda $aa)  - correct
LOAD_DATA(#$aa)      ; emits      A9 AA (lda #$aa) - correct
COPY_DATA($55, $00)  ; emits      A5 55 (lda $55) 85 00 (sta $00) - correct
COPY_DATA(#$55, $00) ; emits      A5 55 (lda $55) 85 00 (sta $00) - incorrect

EDIT: I should say that the following does resolve this issue for the above example:

.macro COPY_DATA
  .if \?1 == ARG_IMMEDIATE
    LOAD_DATA(#\1)
  .else
    LOAD_DATA(\1)
  .endif
  sta \2
.endm

However this quickly becomes impractical when dealing with multiple arguments. My real-world example involved a macro with 5 arguments, at least 4 of which I wanted to support either immediate or zero-page values; and that macro called another with 3 arguments all of which I wanted to support either type of value; so in the first macro I would have had to have 8 branches on an .if statement just to cover all the potential combinations of incoming arguments that needed to be passed on.

vhelin commented 9 months ago

I assume we are not copying the argument type when copying the arguments to a new .MACRO call. I'll try to fix this asap!