Arakula / A09

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

Bug in CMPA 0,X #15

Open mickecamino opened 1 year ago

mickecamino commented 1 year ago

I have assembled an old code from 1983 and discovered a bug in the code generated. If the line is CMPA 0,X the generated output is A1 00 when it should be A1 84. I have verified with TSC FLEX assembler asmb and asm09. This is a small code example to show the issue:

        ORG     0000
START   LDX     #100
        CMPA    0,X
        BEQ     SLUT
        CMPA    -1,X
        BEQ     SLUT
        CMPA    0,X+
        BEQ     SLUT
SLUT    JMP     START
        END

code output from A09, CMPA 0,X generates A100

                              ORG     0000
 0000 8E0064          START   LDX     #100
 0003 A100                    CMPA    0,X
 0005 2708                    BEQ     SLUT
 0007 A11F                    CMPA    -1,X
 0009 2704                    BEQ     SLUT
 000B A180                    CMPA    0,X+
 000D 2700                    BEQ     SLUT
 000F 0E00            SLUT    JMP     START
                              END

Code output from ASM09, CMPA 0,x generates A1 84

0002 0000                            ORG     0000
0003 0000 8e 00 64           START   LDX     #100
0004 0003 a1 84                      CMPA    0,X
0005 0005 27 08                      BEQ     SLUT
0006 0007 a1 1f                      CMPA    -1,X
0007 0009 27 04                      BEQ     SLUT
0008 000b a1 80                      CMPA    0,X+
0009 000d 27 00                      BEQ     SLUT
0010 000f 0e 00              SLUT    JMP     START
0011                                 END

                              END

It only affects when it is 0,X. not with -1,X or 10,X

mickecamino commented 1 year ago

Update, When I remove the 0 (zero) from the code it compiles OK: ./a09 bug-a09.src -l

        NAM     BUGCHECK
        ORG     0000
START   LDX     #100
        CMPA    ,X
        BEQ     SLUT
        CMPA    -1,X
        BEQ     SLUT
        CMPA    10,X
        BEQ     SLUT
        CMPA    0,Y
        BEQ     SLUT
SLUT    JMP     START
        END

Result:

                              NAM     BUGCHECK
                              ORG     0000
 0000 8E0064          START   LDX     #100
 0003 A184                    CMPA    ,X
 0005 270C                    BEQ     SLUT
 0007 A11F                    CMPA    -1,X
 0009 2708                    BEQ     SLUT
 000B A10A                    CMPA    10,X
 000D 2704                    BEQ     SLUT
 000F A120                    CMPA    0,Y
 0011 2700                    BEQ     SLUT
 0013 0E00            SLUT    JMP     START
                              END

SYMBOL TABLE
      SLUT 02 0013     START 02 0000
2 SYMBOLS
phillipeaton commented 1 year ago

I have a feeling (but I can't remember any detail) I ran into the same situation, but, after discussion with Arakula, we concluded it was working correctly i.e. you shouldn't be using 0,X.

The reason might be something like the same syntax works differently on other CPUs e.g. 6800, so the assembler will not optimise to ,X, but I can't really remember and I can't find any reference to it in GitHub or my personal emails.

However, from the Opcode map below, 0,X looks like it will takes more cycles/bytes, which is a good reason to not use it:

image image https://www.maddes.net/m6809pm/appendix_f.htm

mickecamino commented 1 year ago

I can live with that, it was used only in a few places in the code. The code that I compiled is here https://github.com/mickecamino/RT-datorn/tree/main/Nya%20RT-datorn/Monitor%20CBUG43 It is a Monitor listing for an old 6809 computer designed in Sweden in the 80's. Thanks for the comment.

Arakula commented 1 year ago

"It's not a bug, it's a feature" 😎 ... yes, really, that's a little odd feature in A09.

Most assemblers will treat CMPA 0,X as CMPA ,X. And that's a good idea if you're creating new code, since it is the more efficient form of the operation.

The main reason for A09 (at least for me personally ... sorry, you got to live with that little bias 😁 ), however, was to recreate binaries disassembled by f9dasm and dasmfw. And that's why A09 will continue to treat them differently - both A1 00 and A1 84 are valid instructions, and while I agree that A1 84 would create code that's 1 cycle more efficient, it would break this binary-to-source-to-binary cycle.

I might add a compatibility option for that, though. So I'm leaving this issue open for now as a reminder.