Arakula / A09

A09 6800/6801/6809/6309/68HC11 Assembler
GNU General Public License v2.0
40 stars 8 forks source link

Nested macro calls get repeated #8

Closed raybellis closed 4 years ago

raybellis commented 4 years ago

The relasmb manual says that macros may be nested.

Macros can be nested both in calls and in definitions. That is, one macro may call another and one macro may be defined inside another.

However when I try this with A09 (v1.42) any macro that is called from another macro gets expanded twice over (presumably once in each pass).

This code, for example, produces four instances of the BRN instruction instead of just two:

        OPT     EXP,TSC

SPIN3   MACRO
        BRN      *
        ENDM

SPIN6   MACRO
        SPIN3
        SPIN3
        ENDM

        ORG     $8000

        SPIN6
        RTS

Is this a misunderstanding on my part, or a bug in A09?

Arakula commented 4 years ago

Bug.

A first little fix is to change line 6270 from

szMacParm[nMacParms] = srcptr++; /* store parameter start pointer */

to

  szMacParm[nMacParms] = srcptr;        /* store parameter start pointer     */
  if (*srcptr)
    srcptr++;

... but there's obviously more to do, since (at least on my PC here) this gives incorrect code output (and a slightly weird listing).

Arakula commented 4 years ago

Can't you just write simple code, like all others do? :-)

raybellis commented 4 years ago

Hey, at least you know someone's using your code! :)

raybellis commented 4 years ago

BTW, the whole TX81Z disassembly I'm working on is at https://github.com/raybellis/TX81Z/

Arakula commented 4 years ago

Here is a partial fix. Works here, but the output listing isn't perfect yet. Could you please try it?

Arakula commented 4 years ago

... oh, and BTW: the RELASMB documentation casually mentions that macros override normal mnemonics. Please don't even try that yet 8-)

raybellis commented 4 years ago

Thanks - I'll try that this evening (I'm working at the moment).

And yeah, I've no plan to override any mnemonics ;)

raybellis commented 4 years ago

It seems to be working fine. For my particular use case I'm not seeing any changes in the output listing that I wouldn't expect. Thanks again!

Arakula commented 4 years ago

I committed a new version right now; this one should ... .) produce roughly the same output as RELASMB with and without OPT EXP .) allow up to 31 levels of macro call nesting (to kill the version I uploaded earlier in this issue, you just need to write

RECU MACRO
     RECU
     ENDM
     RECU

and poof, A09 goes up in smoke after filling up your memory ...). Please try it; if it works for you, feel free to close the issue.

raybellis commented 4 years ago

Thanks, this works perfectly :)

I do though have one other macro-related problem. This isn't a recently introduced issue, and I can move it to a separate Github issue if you prefer.

If you look at this piece of conditional code I'm using an IFC line to determine which of two versions of a macro is defined.

If I reverse the macro to a shorter (and arguably more logical) form:

BANK_SW                 MACRO
            IFC &BANK,HI
&0                      BANK_LO
            ELSE
&0                      BANK_HI
            ENDIF
            ENDM

then the ELSE branch of the IFC construct is always taken, even though the listing output shows the expansion of &BANK to be correct.

Here are snippets of the listing for hi.asm:

                      ;
                      ; Bank swap depends on which bank we're in
                      ;
#                     BANK_SW                 MACRO
#                                             IFC     &BANK,HI
+                   (                         IFC     HI,HI )
#                     &0                      BANK_LO
#                                             ELSE
#                     &0                      BANK_HI
#                                             ENDIF
#                                             ENDM

and subsequently:

 8023 BDE014          hdlr_DIV0               JSR     DIV0
 8026 3B                                      RTI
 8027 BDE014                                  JSR     DIV0            ; entry point from LO bank
&                                             BANK_SW                 ; return to LO bank
+                                           BANK_HI
+802A 720817                                OIM     #%00001000,PORT6
+                                             ENDM
+                                             ENDM
 802D 3B                                      RTI

Where this should be substituting a BANK_LO (AIM) instruction, not OIM.

raybellis commented 4 years ago

I've attached a standalone test case for the above issue. test.txt

Arakula commented 4 years ago

Okay ... fixed that, too. Now please give me a week or so until you find the next problem, I got other work to do :-)

raybellis commented 4 years ago

I got other work to do :-)

So I hear! :p. Good luck, and thanks for the fixes :)

Arakula commented 4 years ago

No, not the Behringer stuff. Real work :-)