Well, the assembler is proceeding apace... features so far include:

Flag Equates:

Flags are local to labels, but each flag must be named uniquely. You can
have more than one flag name per bit position though.

eg. Say you're setting up the LMPR register for use later. You can set up
the flags at the same time!

LMPR: EQU 250
LMPR: EQUF 7 : WPROT, 6 : ROM1, 5 : ROM0

... or even...

FLAGS: EQUF 3 : DOTHIS, 2 : DOTHAT, 1:DOTHEOTHER, 0:ERROR

However, in this case, FLAGS is not defined anywhere else; so LD A,(FLAGS)
would give an undefined label error. However, you could still do LD
A,FLAGS:DOTHIS and it'd be quite happy.

And you'd access the flags like this...

        IN A,(LMPR)
        BIT LMPR:WPROT, A
        AND LMPR:ROM1 | LMPR:ROM0

Bit Value/Position operators:

~ returns a bit position (log2 n)
@ returns a bit value (2^n)

BIT, RES and SET's all have implicit bit position operators on all flags
equates used. So, for the example above:

        IN A,(LMPR)
        BIT LMPR:WPROT, A   ; is actually... BIT ~LMPR:WPROT,A

All other uses of flags have an implicit bit-value operator. So for the AND
part of the example above, that is:

        AND @LMPR:ROM1 | @LMPR:ROM0

Errors are generated if the @ operator is passed a value which is not a
positive integer from 0-31, or if the ~ operator is passed a value which is
not 2^n where 0 <=  n <= 31.

The BIT,RES and SET instructions, before utilising the value provided, will
ensure that it is a +ve integer from 0-7 was passed in. If the value is not
a positive integer (or zero), it will generate an error. If it is out of
range (ie. > 7), it will be moved into range (& 7) and a warning will be
generated.

Macros work like this:

        DEFMACRO pushall
l1:     PUSH AF
        EX AF,AF'
        PUSH AF
l2:     PUSH DE
        PUSH BC
        PUSH HL
        EXX
        PUSH DE
        PUSH BC
        PUSH HL
        PUSH IX
        PUSH IY
        ENDMACRO

To use the macro in your code, you'd do this:

        MACRO pushall

To access the labels in the macro (which are local to the macro), you'd do
this:

        OR A
        JP Z,mymacro:l2

mymacro:        MACRO pushall

...

passing data into macros works as in #DEFINE in C; you pass a string, and it
gets tokenized. EG:

        DEFMACRO mymacro($rega,$regb)
        PUSH AF
        LD A,rega
        LD rega,regb
        LD regb,A
        POP AF
        ENDMACRO

 - but this needs more work.




Other label operations:

<label>:M - get physical output address of label (ie. the DISP address)
<label>:P - get physical output page of label (ie. the DISP page)

<label>:L - get length of code/string/values on the line that the label
refers to.
eg.

label1: DEFB 0,1,2,3,4,5,6,7   ;label1:L = 8
label2: DEFM "Hi", "Hello" ;label2:L refers only to first string; so
label2:L = 2
label3: DEFF 0.0F,0.3F ;label3:L = sizeof(float) * 2

Self-modifying code stuff:

<label>:D - references the data part of an opcode
eg.
infix.storage: LD A,0
        OR A
        JR NZ,blah

        LD A,23
        LD (infix.storage:D),A ; equivalent to LD (infix.storage+1),A

<label>:IX - references an index offset for an IX or IY operation
eg.
modify: LD A,(IX + 0)
        ...
        LD (modify:IX),32

-------------------------

Data defines:

DEFB - define series of byte values
DEFW - define series of word values
DEFF - define series of floating point/fixed point values
Yet to be defined. Some kind of switch mechanism will let you change how
this works - eg. floating point? fixedpoint? SAM floating point? etc etc
etc.

DEFM - define string (not terminated)
DEFZ - define string (zero terminated)
DEFH - define string (bit 7 of last character is set)
DEFS - fill N bytes with values
eg.
        DEFS 30 ; fills the next 30 bytes with zeroes
        DEFS 10,2 ; fills the next 10 bytes with 0x02
        DEFS 100, 1,2,3,4 ; fills the next 100 bytes with the repeating
values 1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4....

... more to come...

Si

Reply via email to