Memory Full

Forum / Development

Orgams - Useful Macros!

Hicks * 28 Jul 2019 12:22:17 * Modified at 12:24:02

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).

m_dr_m * 28 Jul 2019 18:38:27 * Modified at 18:39:44

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.

m_dr_m * 03 Aug 2019 20:45:36 * Modified at 20:50:08

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)
   [...]



m_dr_m * 04 Aug 2019 21:17:18 * Modified at 21:18:07

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

Hicks * 09 Aug 2019 14:18:38 * Modified at 14:19:30

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.

m_dr_m * 09 Aug 2019 18:05:00

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

Hicks * 13 Aug 2019 08:50:26

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

m_dr_m * 01 Apr 2020 02:35:06

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.

m_dr_m * 29 Apr 2020 09:35:56 * Modified at 09:36:08

Same flags than CP r!

MACRO CP_HL_DE
 or a:sbc hl,de   ; Set flags
 add hl,de        ; Restore hl.
ENDM