2

I'm using the assembler that came with the Manx Aztec C compiler (version 5.0) on a Commodore Amiga 500.

I want to code the equivalent of the following C code:

enum STATUS {
    STATUS_OKAY,
    STATUS_WAITING,
    STATUS_ERROR
};

I tried the following—which works—but it seems kind of hokey:

s_id            set 0
STATUS_OKAY     equ s_id
s_id            set s_id+1
STATUS_WAITING  equ s_id
s_id            equ s_id+1
STATUS_ERROR    equ s_id

I know I could do:

STATUS_OKAY    equ 0
STATUS_WAITING equ 1
STATUS_ERROR   equ 2

But I would like to be able to insert and rearrange values without having to manually renumber.

I was thinking I might be able to do something with macros, but I don't have much experience with them.

tim.smith
  • 143
  • 7

3 Answers3

3

I'd guess you'd want to write a macro that you can use like AUTONUMBER s_id STATUS_OKAY that takes two args: 2nd is the symbol name to define, 1st is the counter to increment.

You'd want it to expand to something like:

STATUS_OKAY     equ s_id
s_id            set s_id+1    # post-incr so it uses the initial value of s_id

(I don't know that assembler or its syntax for defining macros; I assume that's possible though.)

Some assemblers have a special macro directive for redefining a preprocessor constant, allowing you to increment. e.g. NASM wouldn't work with foo equ foo+1, you'd need %define. You used s_id set s_id+1 in most of your lines, but equ in the last one, so that's probably just a typo.


So full usage would look like:

s_id  set 0       # starting value
AUTONUMBER s_id  STATUS_OKAY
AUTONUMBER s_id  STATUS_WAITING
AUTONUMBER s_id  STATUS_ERROR

I put the counter name first because it's the same length every time (and short). Putting it 2nd required more indenting to avoid ragged columns. And it puts the unique part of the line at one end, where it's visually more obvious.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
2

After Peter Cordes' suggestion, I came up with the following macro, which works great:

        macro   ENUM
\2      set     \1
\1      set     \1+1
        endm

s_id    set     0
        ENUM    s_id,STATUS_OKAY
        ENUM    s_id,STATUS_WAITING
        ENUM    s_id,STATUS_ERROR
tim.smith
  • 143
  • 7
0

I think it was done like so back in the days:

    rsreset
Enum0: rs.b 1
Enum1: rs.b 1
Enum2: rs.b 1

You can also have gaps or multiple values like:

    rsreset
    rs.b 1 ; skip 0
Enum1: rs.b 1
Enum2: rs.b 1
    rs.b 10 ; skip 10 values
Enum13: rs.b 1
Enum14: rs.b 0 ; no increase
Also14: rs.b 1
Enum15: rs.b 1

If you don't have gaps and want to know the count of values you can do:

    rsreset
Enum0: rs.b 1
Enum1: rs.b 1
Enum2: rs.b 1
MyEnum_Count: rs.b 0
Robert S.
  • 1,942
  • 16
  • 22
  • It really depends on which assembler you're using. I've used several 6502 assemblers that used this syntax but not all of them do. Personally I'm not a fan of this syntax since it's hard to tell at a glance what the address actually is for each entry. – puppydrum64 Jun 29 '23 at 12:50
  • That's true but it relates to the question and the given C enum has the same problem as it isn't much more expressive. – Robert S. Aug 02 '23 at 21:06
  • The advantage is that you can rearrange things easily. At least without gaps. Sometimes you don't need to know the exact values/addresses. – Robert S. Aug 02 '23 at 21:07