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!
Magic numbers are bad for a number of reasons. Especially when you have to read a source of yours after being captive in the Columbia forest for 4 months.
; What ??
ld a,128 ; Hu...
cubes# = 128 ; Power of two
[...]
ld a,cubes#
We can go one step further (I know, "Name of your sex tape"), by annotating via code why it must be a power of two. I'll assume that you need a cheap modulo:
MACRO IS_POWER_OF_2(n)
IF n AND [n-1]:
!!! Error must be power of 2
END
ENDM
[...]
IS_POWER_OF_2(cubes#)
inc a:and cubes# - 1 ; modulo
Hence the constraint is next to the code needing it. If the code is removed, also removing the constraint is a no-brainer.
Same flags than CP r!
MACRO CP_HL_DE
or a:sbc hl,de ; Set flags
add hl,de ; Restore hl.
ENDM