Yes, another Orgams dedicated thread!

It could be useful to share here some useful macros. It could save time for everyone.

I was tired to replace FILL x,0 by a DJNZ loop so I wrote this one:

MACRO nops n ; n must be >4
ld b,n-1 /4
djnz $
FILL n-1 MOD 4,0
ENDM

Then we can write nops(30) to wait 30 nops (b register and Z flag are affected).

Examples copied from the manual.

**ALIGN(n) **
Advance $ to the closest multiple of n.

If $ is already a multiple if n, it is unchanged.

NB: $$ is incremented by the same amount

MACRO ALIGN n
SKIP -$ MOD n
ENDM

Explanation:

We want to skip x bytes such that $+x = 0 [n] and 0 <= x < n

This amounts to x = -$ MOD n

**ASSERT(predicate)**

Raise an error if predicate isn't true.

There is no ASSERT directive. It can be simulated by:

MACRO ASSERT predicate
IF predicate:ELSE
!! ERROR !!
END
ENDM

Explanation:

The '!! ERROR !!' part is not seen at all if predicate is true,

otherwise it triggers an assembly error.

**ASSERT_NOT(predicate)**

MACRO ASSERT_NOT predicate
IF predicate
!! ERROR !!
END
ENDM
[...]
ASSERT_NOT (my_table AND &ff) ; Ensure my_table is xx00 aligned address.

While '=' operator is missing (

**if toto=4**), use

**CHECK_EQUALS**:

MACRO CHECK_EQUALS x,y
IF x-y
!!! Error values are not equal.
END
ENDM

Useful to make sure a variable hasn't moved or a routine is properly aligned:

CHECK_EQUALS(drive_id, &9060)
rvi0
[...]
CHECK_EQUALS($, &bc40)
[...]

Attente qui marche pour

**n >= 0**.

MACRO nops n ; n >= 0
if n-1 AND &ffc
ld b,n-1 /4
djnz $
FILL n-1 MOD 4,0
else
FILL n,0
end
ENDM

Ohoh! Well done.

In the same spirit, to wait l lines (l*64 nops):

MACRO lines l
ld bc,l*8 -1
nop
dec bc
ld a,b
or c
jr nz,$-4
nops(6)
ENDM

Modify A, B, and C registers.

This happens to work, yet it's more prudent and clearer to name your parameter **n** instead of **l**.

Oh yes, I don't think about the synonymy with L register!