; > Macros8051

; Offsets between opcodes

OffImm  *       0
OffDir  *       1
OffAtRi *       2
OffRn   *       4

        GBLS    arg
        GBLA    oper
        GBLA    oper2
        GBLA    opim
        GBLA    opat
        GBLA    oprn
        GBLA    offset
        GBLL    wasim
        GBLL    wasat
        GBLL    wasrn
        GBLA    RegPtr
        GBLL    Pass2

Pass2   SETL    ({OPT}:AND:1)<>0

        MACRO
        org     $addr
        ASSERT . <= ($addr)
        %       ($addr)-.
        MEND

        MACRO
$name   Register
        ASSERT  @ < &20         ; registers are from 00 to 1F
$name   #       1
        MEND

        MACRO
$name   Bit     $addr, $bitnum
        ASSERT  ($bitnum)>=0 :LAND: ($bitnum)<=7
        [ ($addr)>=&20 :LAND: ($addr)<=&2F
$name   *       ((($addr):AND:&0F):SHL:3)+($bitnum)
        |
        ASSERT  ($addr)>=&80 :LAND: (($addr):AND:7)=0
$name   *       ($addr)+($bitnum)
        ]
        MEND

        MACRO
        RelOffset $addr, $pc
        [ Pass2                 ; if on 2nd pass
offset  SETA    (($addr)-($pc)+128):EOR:128
        |
offset  SETA    0
        ]
        MEND

        MACRO
        TIM     $src
        [ ("$src":LEFT:1)="#"
wasim   SETL    {TRUE}
arg     SETS    "$src" :RIGHT: ((:LEN: "$src")-1)
        [ Pass2
opim    SETA    $arg
        |
opim    SETA    0
        ]
        |
wasim   SETL    {FALSE}
        ]
        MEND

        MACRO
        TAT     $src
        [ ("$src":LEFT:1)="@"
        ASSERT  RegPtr<>-1
arg     SETS    "$src" :RIGHT: ((:LEN: "$src")-1)
        [ "$arg"="R0" :LOR: "$arg"="R1"
arg     SETS    "RegPtr+":CC:("$arg":RIGHT:1)
        ]
opat    SETA    ($arg)-RegPtr
        ASSERT  opat=0 :LOR: opat=1
wasat   SETL    {TRUE}
        |
wasat   SETL    {FALSE}
        ]
        MEND

        MACRO
        TRN     $src
        [ (:LEN:"$src"=2) :LAND: (("$src":LEFT:1)="R") :LAND: ("$src":RIGHT:1)>="0" :LAND: ("$src":RIGHT:1)<="7"
arg     SETS    "$src" :RIGHT 1
oprn    SETA    $arg
wasrn   SETL    {TRUE}
        |
oprn    SETA    ($src)-RegPtr
wasrn   SETL    oprn >=0 :LAND: oprn <=7 :LAND: RegPtr<>-1
        ]
        MEND

        MACRO
$l      SetRP   $dst
$l
        ASSERT  (($dst):AND::NOT:&18)=0
        mov     PSW, #$dst
RegPtr  SETA    $dst
        MEND

        MACRO
$l      NoRP
$l
RegPtr  SETA    -1
        MEND

        MACRO
$l      RPIs    $dst
$l
        ASSERT  (($dst):AND::NOT:&18)=0
RegPtr  SETA    $dst
        MEND

        MACRO
        AThing  $addr11, $op
        =       (((.+2):EOR:($addr11)):AND:&F800):OR:((($addr11):AND:&0700):SHR:3):OR:($op), (($addr11):AND:&FF)
        MEND

        MACRO
        LThing  $addr16, $op
        [ Pass2
offset  SETA    $addr16
        |
offset  SETA    0
        ]
        =       $op, offset/256, offset:AND:&FF
        MEND

        MACRO
$l      acall   $addr11
$l
        AThing  $addr11, &11
        MEND

        MACRO
$l      ajmp    $addr11
$l
        AThing  $addr11, &01
        MEND

        MACRO
$l      lcall   $addr16
$l
        LThing  $addr16, &12
        MEND

        MACRO
$l      ljmp    $addr16
$l
        LThing  $addr16, &02
        MEND

        MACRO
        Arith   $src, $base, $immok
        LCLL    immok2
        [ "$immok"=""
immok2  SETL    {TRUE}
        |
immok2  SETL    $immok
        ]
        TAT     $src
        [ wasat
        =       $base+OffAtRi+opat
        |
        TIM     $src
        [ wasim :LAND: immok2
        =       $base+OffImm, opim
        |
        TRN     $src
        [ wasrn
        =       $base+OffRn+oprn
        |
oper    SETA    $src
        =       $base+OffDir, oper
        ]
        ]
        ]
        MEND

        MACRO
$l      add     $A, $src
$l
        ASSERT  "$A"="A"
        Arith   $src, &24
        MEND

        MACRO
$l      addc    $A, $src
$l
        ASSERT  "$A"="A"
        Arith   $src, &34
        MEND

        MACRO
$l      subb    $A, $src
$l
        ASSERT  "$A"="A"
        Arith   $src, &94
        MEND

        MACRO
        Logical $reg, $src, $base
        [ "$reg"="A"
        Arith   $src, $base
        |
        [ "$src"="A"
oper    SETA    $reg
        =       $base-2, oper
        |
        TIM     $src
        ASSERT  wasim
oper    SETA    $reg
        =       $base-1, oper, opim
        ]
        ]
        MEND

        MACRO
$l      anl     $reg, $src
$l
        [ "$reg"="C"
        [ ("$src":LEFT:1)="/"
arg     SETS    "$src" :RIGHT: ((:LEN: "$src")-1)
oper    SETA    $arg
        =       &B0, oper
        |
oper    SETA    $src
        =       &82, oper
        ]
        |
        Logical $reg, $src, &54
        ]
        MEND

        MACRO
$l      orl     $reg, $src
$l
        [ "$reg"="C"
        [ ("$src":LEFT:1)="/"
arg     SETS    "$src" :RIGHT: ((:LEN: "$src")-1)
oper    SETA    $arg
        =       &A0, oper
        |
oper    SETA    $src
        =       &72, oper
        ]
        |
        Logical $reg, $src, &44
        ]
        MEND

        MACRO
$l      xrl     $reg, $src
$l
        Logical $reg, $src, &64
        MEND

        MACRO
$l      cjne    $reg, $src, $rel
$l
        RelOffset $rel, .+3
        [ "$reg"="A"
        TIM     $src
        [ wasim
        =       &B4, opim, offset
        |
oper    SETA    $src
        =       &B5, oper, offset
        ]
        |
        TIM     $src
        ASSERT  wasim
        TAT     $reg
        [ wasat
        =       &B6+opat, opim, offset
        |
        TRN     $reg
        ASSERT  wasrn
        =       &B8+oprn, opim, offset
        ]
        ]
        MEND

        MACRO
$l      clr     $reg
$l
        ASSERT "$reg"="A"
        =       &E4
        MEND

        MACRO
$l      clrb    $reg
$l
        [ "$reg"="C"
        =       &C3
        |
oper    SETA    $reg
        =       &C2, oper
        ]
        MEND

        MACRO
$l      cpl     $reg
$l
        [ "$reg"="A"
        =       &F4
        |
        [ "$reg"="C"
        =       &B3
        |
oper    SETA    $reg
        =       &B2, oper
        ]
        ]
        MEND

        MACRO
$l      da      $reg
$l
        ASSERT  "$reg"="A"
        =       &D4
        MEND

        MACRO
$l      dec     $src
$l
        [ "$src"="A"
        =       &14
        |
        Arith   $src, &14, {FALSE}
        ]
        MEND

        MACRO
$l      div     $reg
$l
        ASSERT  "$reg"="AB"
        =       &84
        MEND

        MACRO
$l      djnz    $src, $rel
$l
        TRN     $src
        [ wasrn
        RelOffset $rel, .+2
        =       &D8+oprn, offset
        |
        RelOffset $rel, .+3
oper    SETA    $src
        =       &D5, oper, offset
        ]
        MEND

        MACRO
$l      inc     $src
$l
        [ "$src"="DPTR"
        =       &A3
        |
        [ "$src"="A"
        =       &04
        |
        Arith   $src, &04, {FALSE}
        ]
        ]
        MEND

        MACRO
$l      jb      $bit, $rel
$l
        RelOffset $rel, .+3
        =       &20, ($bit), offset
        MEND

        MACRO
$l      jbc     $bit, $rel
$l
        RelOffset $rel, .+3
        =       &10, ($bit), offset
        MEND

        MACRO
$l      jc      $rel
$l
        RelOffset $rel, .+2
        =       &40, offset
        MEND

        MACRO
$l      jmp     $reg
$l
        ASSERT  "$reg"="@A+DPTR"
        =       &73
        MEND

        MACRO
$l      jnb     $bit, $rel
$l
        RelOffset $rel, .+3
        =       &30, ($bit), offset
        MEND

        MACRO
$l      jnc     $rel
$l
        RelOffset $rel, .+2
        =       &50, offset
        MEND

        MACRO
$l      jnz     $rel
$l
        RelOffset $rel, .+2
        =       &70, offset
        MEND

        MACRO
$l      jz      $rel
$l
        RelOffset $rel, .+2
        =       &60, offset
        MEND

        MACRO
$l      mov     $des, $src
$l
        [ "$des"="DPTR"
         TIM     $src
         ASSERT  wasim
         =       &90, (opim/256), (opim:AND:255)
        |
         [ "$des"="C"
          =       &A2, $src
         |
          [ "$src"="C"
           =       &92, $des
          |
           [ "$des"="A"
            TIM     $src
            [ wasim
             =       &74, opim
            |
             Arith   $src, &E4, {FALSE}
            ]
           |
            TAT     $des
            [ wasat
             [ "$src"="A"
              =       &F6+opat
             |
              TIM     $src
              [ wasim
               =       &76+opat, opim
              |
oper           SETA    $src
               =       &A6+opat, oper
              ]
             ]
            |
             TRN     $des
             [ wasrn
              [ "$src"="A"
               =       &F8+oprn
              |
               TIM     $src
               [ wasim
                =       &78+oprn, opim
               |
                TAT     $src
                [ wasat
oper             SETA   $des
                 =       &86+opat, oper
                |                 
oper             SETA    $src
                 =       &A8+oprn, oper
                ]
               ]
              ]
             |
oper          SETA    $des
              [ "$src"="A"
               =       &F5, oper
              |
               TIM     $src
               [ wasim
                =       &75, oper, opim
               |
                TAT     $src
                [ wasat
                 =       &86+opat, oper
                |
                 TRN     $src
                 [ wasrn
                  =       &88+oprn, oper
                 |
oper2             SETA    $src
                  =       &85, oper2, oper
                 ]
                ]
               ]
              ]
             ]
            ]
           ]
          ]
         ]
        ]
        MEND

        MACRO
$l      movc    $A, $reg
$l
        ASSERT  "$A"="A"
        [ "$reg"="@A+DPTR"
        =       &93
        |
        ASSERT  "$reg"="@A+PC"
        =       &83
        ]
        MEND

        MACRO
$l      movx    $des, $src
$l
        [ "$des"="A"
        [ "$src"="@DPTR"
        =       &E0
        |
        TAT     $src
        ASSERT  wasat
        =       &E2+opat
        ]
        |
        ASSERT  "$src"="A"
        [ "$des"="@DPTR"
        =       &F0
        |
        TAT     $des
        ASSERT  wasat
        =       &F2+opat
        ]
        ]
        MEND

        MACRO
$l      nop
$l
        =       &00
        MEND

        MACRO
$l      mul     $ab
$l
        ASSERT  "$ab"="AB"
        =       &A4
        MEND

        MACRO
$l      pop     $src
$l
oper    SETA    $src
        =       &D0, oper
        MEND

        MACRO
$l      pull    $src
$l      pop     $src
        MEND

        MACRO
$l      push    $src
$l
oper    SETA    $src
        =       &C0, oper
        MEND

        MACRO
$l      ret
$l
        =       &22
        MEND

        MACRO
$l      reti
$l
        =       &32
        MEND

        MACRO
$l      rl      $A
$l
        ASSERT  "$A"="A"
        =       &23
        MEND

        MACRO
$l      rlc     $A
$l
        ASSERT  "$A"="A"
        =       &33
        MEND

        MACRO
$l      rr      $A
$l
        ASSERT  "$A"="A"
        =       &03
        MEND

        MACRO
$l      rrc     $A
$l
        ASSERT  "$A"="A"
        =       &13
        MEND

        MACRO
$l      setb    $src
$l
        [ "$src"="C"
        =       &D3
        |
        =       &D2, $src
        ]
        MEND

        MACRO
$l      sjmp    $rel
$l
        RelOffset $rel, .+2
        =       &80, offset
        MEND

        MACRO
$l      swap    $A
$l
        ASSERT  "$A"="A"
        =       &C4
        MEND

        MACRO
$l      xch     $A, $src
$l
        ASSERT  "$A"="A"
        TAT     $src
        [ wasat
        =       &C6+opat
        |
        TRN     $src
        [ wasrn
        =       &C8+oprn
        |
oper    SETA    $src
        =       &C5, oper
        ]
        ]
        MEND

        MACRO
$l      xchd    $A, $src
$l
        ASSERT  "$A"="A"
        TAT     $src
        ASSERT  wasat
        =       &D6+opat
        MEND

        END
