   .if .not .def _MACROS_
_MACROS_ = 1

   .if .not .def _STDDEF_
      .include #stddef
   .endif
   
; version 2.12.90 (C) Natuerlich! (This comes from 4 years ago)
; -------------------------------------------------------------
; Purists might object to the use of 'BASIC'-like macros
; and it is true, that with every macro U use you might be losing
; some control (if you aren't careful) or that at least the
; temptation is very big to code sloppily to use a macro. But
; since I am currently editing on on a 24 line display, too many
; lda sta, sequences would just fill up too much screen space
; and I am not that brilliant to keep all this stuff in my brain,
; in 100% KODAK quality. Also I don't like printer output
; ----------------------------------------------------------------
;
; defines for macro use
;

; Note that in order to not bother the internal label table with
; too many "temporary helper" variables, we are going to use the
; following shortcut:
; @0 means low level temporary variable (e.g. @STT)
; @1 means first level ..               (e.g. POKE)
; @2 means second level..
; from the fourth level, we just use @<name>


   .macro @stt
@0 .= @a
      .if %0 = 2
@0 .= %2
      .endif
      .if  @0 = @a
         sta   %1
      .else
         .if @0 = @x
            stx   %1
         .else
            sty   %1
         .endif
      .endif
   .endm


   .macro @ldi
@0 .= @a
      .if %0 = 2
@0 .= %2
      .endif
      .if %2 = @a
         lda   #%1
      .else
         .if %2 = @x
            ldx   #%1
         .else
            ldy   #%1
         .endif
      .endif
   .endm

   .macro @ldf
@0 .= @a
      .if %0 = 2
@0 .= %2
      .endif
      .if   %2 = @a
         lda   %1
      .else
         .if   %2 = @x
            ldx   %1
         .else
            ldy   %1
         .endif
      .endif
   .endm


   .macro poke
@1 .= @a
      .if   %0 = 3
@1 .= %3
      .endif
      @LDI  %2,@1
      @STT  %1,@1
   .endm


   .macro dpoke
@1 .= @a
      .if %0 = 3
@1 .= %3
      .endif
      @LDI  <%2,@1
      @STT  %1,@1
      @LDI  >%2,@1
      @STT  %1+1,@1
   .endm

   .macro move
@1 .= @a
      .if %0 = 3
@1 .= %3
      .endif
      @LDF  %1,@1
      @STT  %2,@1
   .endm

   .macro dmove
@1 .= @a
      .if %0 = 3
@1 .= %3
      .endif         
      @LDF  %1,@1
      @STT  %2,@1
      @LDF  %1+1,@1
      @STT  %2+1,@1
   .endm

; the following macros are for indirect pokes

   .macro poke_x
      lda   #<%2
      sta   %1,x
   .endm

   .macro poke_y
      lda   #<%2
      sta   %1,y
   .endm

   .macro _move_x
      lda   %1
      sta   %2,x
   .endm

   .macro _move_y
      lda   %1
      sta   %2,y
   .endm

   .macro dpoke_x
      lda   #<%2
      sta   %1,x
      lda   #>%2
      sta   %1+1,x
   .endm

   .macro dpoke_y
      lda   #<%2
      sta   %1,y
      lda   #>%2
      sta   %1+1,y
   .endm

   .macro _dmove_x
      lda   %1
      sta   %2,x
      lda   %1+1
      sta   %2+1,x
   .endm

   .macro _dmove_y
      lda   %1
      sta   %2,y
      lda   %1+1
      sta   %2+1,y
   .endm

; usage: ddec <address> decrements 8 bit byte by 2
   .macro ddec
      dec   %1
      dec   %1
   .endm

; usage: dinc <address> increments 8 bit byte by 2
   .macro dinc
      inc   %1
      inc   %1
   .endm

; usage: ddey          decrements Y by 2
   .macro ddey
      dey
      dey
   .endm

; usage: diny          increments Y by 2
   .macro diny
      iny
      iny
   .endm

; usage: dinx          decrements X by 2
   .macro ddex
      dex
      dex
   .endm

; usage: dinx          increments X by 2
   .macro dinx
      inx
      inx
   .endm

; usage: lxy <value>,[flags] loads value in x/y LSB/MSB
   .macro lxy
@0 .= @p1
   .if %0 = 2
@0 .= %2
   .endif
   .if @0 & @p1      
      ldx   #<%1
      ldy   #>%1
   .else
      ldx   %1
      ldy   %1+1
   .endif
   .endm

; usage: sxy <address> stores x/y in LSB/MSB of a 16 bit word
   .macro sxy
      stx   %1
      sty   %1+1
   .endm

; -------------------------------------------------------------
; This is the macro for other macros. Assembles either a move
; or a poke (or a DPOKE or a DMOVE)
; Usage:
;        @MOKE  src,dst,select
; src as in    POKE dst,src    MOVE src,dst
; select -> see stddef.h65 ONLY %1 can be selected!
; --------------------------------------------------------------
   .macro @moke
      .if %3 & @p1
         poke  %2,%1
      .else
         move  %1,%2
      .endif
   .endm

   .macro @moke_x
      .if %3 & @p1    
         poke_x   %2,%1
      .else
         _move_x   %1,%2
      .endif
   .endm

   .macro @moke_y
      .if %3 & @p1
         poke_y   %2,%1
      .else
         _move_y   %1,%2
      .endif
   .endm


; -------------------------------------------------------------
; This is the macro for other macros. Assembles either a DPOKE
; or DMOVE)
; Usage:
;        @DMOKE  src,dst,select
;
; select -> stddef.h65
; --------------------------------------------------------------
   .macro @dmoke
      .if %3 & @p1
         dpoke %2,%1
      .else
         dmove %1,%2
      .endif
   .endm

   .macro @dmoke_x
      .if %3 & @p1
         dpoke_x  %2,%1
      .else
         _dmove_x  %1,%2
      .endif
   .endm

   .macro @dmoke_y
      .if %3 & @p1
         dpoke_y  %2,%1
      .else
         _dmove_y  %1,%2
      .endif
   .endm

; -------------------------------------------------------------
; This is the macro for other macros. Assembles either a direct
; or an immediate load.
; Usage:
;        @MOAD  src,select[,reglsb]
;
; select -> stddef.h65
; reglsb -> @a @x @y
; --------------------------------------------------------------
   .macro @moad
@2lsb .= @a
      .if %0 > 2
@2lsb .= %3
      .endif
      .if %2 & @p1
         @ldi   <%1,@2lsb
      .else
         @ldf   %1,@2lsb
      .endif
   .endm

; -------------------------------------------------------------
; This is the macro for other macros. Assembles either a direct
; or an immediate load. (as you can see these comments were
; copied again and again) 
; Usage:
;        @DMOAD  src,select[,reglsb,regmsb]
;
; select -> stddef.h65
; reglsb -> @a @x @y
; --------------------------------------------------------------
   .macro @dmoad
@2lsb .= @a
@2msb .= @y
      .if %0 > 2
@2lsb .= %3
@2msb .= %4
      .endif
      .if %2 & @p1
         @ldi  <%1,@2lsb
         @ldi  >%1,@2msb
      .else
         @ldf  %1,@2lsb
         @ldf  %1+1,@2msb
      .endif
   .endm

   .endif
