wiki:file-picmips.inc
; ---------------------------------------------------------------------------------------- tools box
; --------------------------------------------------------------------------------------------------
 
        variable BANK0 = 0x20  ; first free byte in bank0
        variable BANK1 = 0xA0  ; first free byte in bank1
        variable BANK2 = 0x110 ; first free byte in bank2
        variable BANK3 = 0x190 ; first free byte in bank3
        variable BANK4 = 0x70  ; first free byte in shared bank

        CBLOCK BANK0 
          _W0           ; working register 
          _W1           ; working register
          _M1BAK        ; macro register backup
          _WBAK         ; W      backup 
          _PCLATHBAK    ; PCLATH backup 
        ENDC 
        variable BANK0 = _PCLATHBAK+1

        CBLOCK BANK4 
          _M1           ; macro register
          _STATUSBAK    ; STATUS backup 
        ENDC 
        variable BANK4 = _STATUSBAK+1

SAVEREG macro        
        movwf   _WBAK           ; save W
        swapf   STATUS,W        ; W <- STATUS [ 3:0 , 7:4 ]
        movwf   _STATUSBAK      ; save STATUS, without change Z flag
        clrf    STATUS          ; STATUS <- 0 then BANK0
        movf    _M1,W           ;
        movwf   __M1BAK         ; save _M1 (macro register)
        movf    PCLATH,W        ;
        movwf   _PCLATHBAK      ; save PCLATH
        clrf    PCLATH          ; PCLATH <- 0 then PAGE0
        endm

RESTREG macro
        movf    _M1BAK,W        ;
        movwf   _M1             ; restore _M1
        movf    _PCLATHBAK,W    ;
        movwf   PCLATH          ; restore PCLATH
        swapf   _STATUSBAK,W    ; 
        movwf   STATUS          ; restore STATUS
        swapf   _WBAK,F         ; 
        swapf   _WBAK,W         ; restore W
        retfie                  ; return & GIE <- 1
        endm
 
        ; ----------------------------------------------------------------------
        ; MACRO DEDIEE AU TEST DES CAUSES D'INTERRUPTION
        ; ----------------------------------------------------------------------
        ; ISR : Interrupt Service Routine= adresse de la routine d'interruption
        ; IER : Interrupt Enable Register= numero du registre du bit enable
        ; IEB : Interrupt Enable Bit     = numero du bit enable dans IER 
        ; IFR : Interrupt Flag Register  = numero du registre du bit drapeau
        ; IFB : Interrupt Flag Bit       = numero du bit drapeau dans IFR 
        ; ENABLE  : drapeau d'activation du test de cause, 3 valeurs possibles
        ; ----------------------------------------------------------------------
        variable never_enable  = 0 ; interruption jamais utilisée
        variable always_enable = 1 ; interruption utilisée et non masquable
        variable maybe_enable  = 2 ; interruption utilisée et masquable
        variable _pie1_copied  = 0 ; à 1 quand la recopie de registre est faite
        variable _pie2_copied  = 0 ; à 1 quand la recopie de registre est faite

ISRCALL macro   ISR,IER,IEB,IFR,IFB,ENABLE
          if (ENABLE!=never_enable)   ; si l'interruption est utilisée on entre
            if (ENABLE==maybe_enable) ; sinon si l'int pas tjs util on teste ena
              variable _IER = IER     ; par defaut le registre enable est IER
              if (IER==PIE1)
                variable _IER = _W0   ; changement de registre enable
              endif
              if (IER==PIE2)
                variable _IER = _W1   ; changement de registre enable
              endif
              if ((IER==PIE1)&&(_pie1_copied==0))
                variable _pie1_copied = 1
                bsf     STATUS,RP0    ; passe du bank0 au bank1
                movf    PIE1,w        ; va chercher le registre PIE1
                bcf     STATUS,RP0    ; passe du bank0 au bank1
                movwf   _W0           ; et en fait une copie
              endif
              if ((IER==PIE2)&&(_pie2_copied==0))
                variable _pie2_copied = 1
                bsf     STATUS,RP0    ; passe du bank0 au bank1
                movf    PIE2,w        ; va chercher le registre PIE2
                bcf     STATUS,RP0    ; passe du bank0 au bank1
                movwf   _W1           ; et en fait une copie
              endif
              btfss   _IER, IEB ; on teste juste le bit enable
              goto    $+3       ; le bit enable n'est pas à 1, on saute
            endif
            btfsc   IFR, IFB    ; saute à la routine de traitement si FLAG = 1
            goto    ISR         ; routine de traitement de l'ISR
          endif
        endm

BTOB    macro   @from,@to       ; bank to bank                  change RP bits from @from to @to 
        if (((@from & 0x080) == 0) && ((@to & 0x080) != 0))
            bsf STATUS, RP0
        endif
        if (((@from & 0x080) != 0) && ((@to & 0x080) == 0))
            bcf STATUS, RP0
        endif
        if (((@from & 0x100) == 0) && ((@to & 0x100) != 0))
            bsf STATUS, RP1
        endif
        if (((@from & 0x100) != 0) && ((@to & 0x100) == 0))
            bcf STATUS, RP1
        endif
        endm

; --------------------------------------------------------------------------------------- Arithmetic
; --------------------------------------------------------------------------------------------------
add     macro   @r1,@r2,@r3     ; add                           @r1 = @r2 + @r3
        movf    @r3,w
        if (@r1 != @r2)
            addwf   @r2,w
            movwf   @r1
        else
            addwf   @r2,f
        endif
        endm
sub     macro   @r1,@r2,@r3     ; subtract                      @r1 = @r2 - @r3
        movf    @r3,w
        if (@r1 != @r2)
            subwf   @r2,w
            movwf   @r1
        else
            subwf   @r2,f
        endif
        endm
addi    macro   @r1,@r2,@i3     ; add immediate                 @r1 = @r2 + @i3
        if ((@r1 == @r2) && (@i3 == 1))
            incf    @r1,f
        else
	    movlw   @i3
            if (@r1 != @r2)
                addwf   @r2,w
                movwf   @r1
            else
                addwf   @r2,f
            endif
        endif
        endm
subi    macro   @r1,@r2,@i3     ; subtract immediate            @r1 = @r2 - @r3
        if ((@r1 == @r2) && (@i3 == 1))
            decf    @r1,f
        else
            movlw   @i3
            if (@r1 != @r2)
                subwf   @r2,w
                movwf   @r1
            else
                subwf   @r2,f
            endif
        endif
        endm
; ------------------------------------------------------------------------------------------ Logical
; --------------------------------------------------------------------------------------------------
and     macro   @r1,@r2,@r3     ; and                           @r1 = @r2 & @r3
        movf    @r3,w
        if (@r1 != @r2)
            andwf   @r2,w
            movwf   @r1
        else
            andwf   @r2,f
        endif
        endm
or      macro   @r1,@r2,@r3     ; or                            @r1 = @r2 | @r3
        movf    @r3,w
        iorwf   @r2,w
        movwf   @r1
        endm
xor     macro   @r1,@r2,@r3     ; exclusive or                  @r1 = @r2 ^ @r3
        movf    @r3,w
        xorwf   @r2,w
        movwf   @r1
        endm
andi    macro   @r1,@r2,@i3     ; and immediate                 @r1 = @r2 & @i3
        movlw   @i3,w
        andwf   @r2,w
        movwf   @r1
        endm
ori     macro   @r1,@r2,@i3     ; or immediate                  @r1 = @r2 | @i3
        movlw   @i3,w
        iorwf   @r2,w
        movwf   @r1
        endm
xori    macro   @r1,@r2,@i3     ; exclusive or immediate        @r1 = @r2 ^ @i3
        movlw   @i3
        xorwf   @r2,w
        movwf   @r1
        endm
sll     macro   @r1,@r2         ; shift left logical            @r1 = @r2 << 1
        bcf     STATUS,c
        rlf     @r2,w
        movwf   @r1
        endm
srl     macro   @r1,@r2         ; shift right logical           @r1 = @r2 >> 1
        bcf     STATUS,c
        rrf     @r2,w
        movwf   @r1
        endm
rl      macro   @r1,@r2         ; rotate left                   @r1 = (@r2 << 1) | @r2.7
        rlf     @r2,w
        rlf     @r2,w
        movwf   @r1
        endm
rr      macro   @r1,@r2         ; rotate right                  @r1 = @r2.0 | (@r2 >> 1)
        rrf     @r2,w
        rrf     @r2,w
        movwf   @r1
        endm
; ------------------------------------------------------------------------------------ Data transfer
; SFR registers are only acceded through mfsfr and mtsfr
; all registers indirectly acceded with push, pop, lb, sb are olny in bank 2 ou 3
; --------------------------------------------------------------------------------------------------
li      macro   @r1,@i2         ; load immediate                @r1 = immediate @i2
        if (@i2)
            movlw   @i2
            movwf   @r1
        else
            clrf    @r1
        endif
        endm
move    macro   @r1,@r2         ; move reg to reg               @r1 = @r2
        movf    @r2,w
        movwf   @r1
        endm
mfsfr   macro   @r1,@sfr        ; move from sfr reg             @r1 = @sfr
        BTOB    @r1,@sfr
        movf    @sfr,w
        BTOB    @sfr,@r1
        movwf   @r1
        endm
mtsfr   macro   @r1,@sfr        ; move to sfr reg               @sfr = @r1
        movf    @r1,w
        BTOB    @r1,@sfr
        movwf   @sfr
        BTOB    @sfr,@r1
        endm
pushi   macro   @i1,@r2         ; push byte                     memory[--_SP_] = @i1
        bsf     STATUS, IRP
        decf    @r2,f
        decf    @r2,w
        movwf   FSR
        movlw   @i1
        movwf   INDF
        endm
push    macro   @r1,@r2         ; push byte                     memory[--@r2] = @r1
        bsf     STATUS, IRP
        decf    @r2,f
        decf    @r2,w
        movwf   FSR
        movf    @r1,w
        movwf   INDF
        endm
pop     macro   @r1,@r2         ; pop byte                      @r1 = memory[@r2++]
        bsf     STATUS, IRP
        movf    @r2,w
        movwf   FSR
        incf    @r2,f
        movf    INDF,w
        movwf   @r1
        endm
sb      macro   @r1,@i2,@r3     ; store word                    Memory[@r3+@i2] = @r1
        bsf     STATUS, IRP
        movf    @r3,w
        addlw   @i2
        movwf   FSR
        movf    @r1,w
        movwf   INDF
        endm
lb      macro   @r1,@i2,@r3    	; load word                     @r1 = Memory[@r3+@i2]
        bsf     STATUS, IRP
        movf    @r3,w
        addlw   @i2
        movwf   FSR
        movf    INDF,w
        movwf   @r1
        endm
; ------------------------------------------------------------------------------- Conditional branch
; --------------------------------------------------------------------------------------------------
brpc    macro   @r1             ; branch relative PC            goto PC + 1 + @r1
        movlw   high($+7)
        movwf   PCLATH
        movlw   $+5
        addwf   @r1,w
        btfsc   STATUS,C
        incf    PCLATH,f
        movwf   PCL
        endm
beq     macro   @r1,@r2,@l3     ; branch on equal               if (@r1 == @r2) go @l3
        movf    @r1,w
        subwf   @r2,w
        btfsc   STATUS,Z
        goto    @l3
        endm
bne     macro   @r1,@r2,@l3     ; branch on not equal           if (@r1 != @r2) go @l3
        movf    @r1,w
        subwf   @r2,w
        btfss   STATUS,Z
        goto    @l3
        endm
beqi    macro   @r1,@r2,@l3     ; branch on equal               if (@r1 == @r2) go @l3
        movf    @r1,w
        subwf   @r2,w
        btfsc   STATUS,Z
        goto    @l3
        endm
bnei    macro   @r1,@r2,@l3     ; branch on not equal           if (@r1 != @r2) go @l3
        movf    @r1,w
        subwf   @r2,w
        btfss   STATUS,Z
        goto    @l3
        endm
bgtu    macro   @r1,@r2,@l3     ; branch if greater than        if (@r1 > @r2) go @l3
        movf    @r1, W
        subwf   @r2, W
        btfss   STATUS, C
        goto    @l3
        endm
bgeu    macro   @r1,@r2,@l3     ; branch if greater or equal    if (@r1 >= @r2) go @l3
        movf    @r2, W
        subwf   @r1, W 
        btfsc   STATUS, C
        goto    @l3
        endm
bltu    macro   @r1,@r2,@l3     ; branch if lower than          if (@r1 < @r2) go @l3
        movf    @r2, W
        subwf   @r1, W 
        btfss   STATUS, C
        goto    @l3
        endm
bleu    macro   @r1,@r2,@l3     ; branch if lower or equal      if (@r1 <= @r2) go @l3
        movf    @r1, W
        subwf   @r2, W
        btfsc   STATUS, C
        goto    @l3
        endm
bgtiu   macro   @r1,@i2,@l3     ; branch if greater than        if (@r1 > @i2) go @l3
        movf    @r1, W
        sublw   @i2
        btfss   STATUS, C
        goto    @l3
        endm
bgeiu   macro   @r1,@i2,@l3     ; branch if greater or equal    if (@r1 >= @i2) go @l3
        movlw   @i2
        subwf   @r1, W 
        btfsc   STATUS, C
        goto    @l3
        endm
bltiu   macro   @r1,@i2,@l3     ; branch if lower than          if (@r1 < @i2) go @l3
        movlw   @i2
        subwf   @r1, W 
        btfss   STATUS, C
        goto    @l3
        endm
bleiu   macro   @r1,@i2,@l3     ; branch if lower or equal      if (@r1 <= @i2) go @l3
        movf    @r1, W
        sublw   @i2
        btfsc   STATUS, C
        goto    @l3
        endm
bgts    macro   @r1,@r2,@l3     ; branch if greater than        if (@r1 > @r2) go @l3
        movf    @r2, W
        addlw   0x80
        movwf   _M1
        movf    @r1, W
        addlw   0x80
        subwf   _M1, W
        btfss   STATUS, C
        goto    @l3
        endm
bges    macro   @r1,@r2,@l3     ; branch if greater or equal    if (@r1 >= @r2) go @l3
        movf    @r1, W
        addlw   0x80
        movwf   _M1
        movf    @r2, W
        addlw   0x80
        subwf   _M1, W
        btfsc   STATUS, C
        goto    @l3
        endm
blts    macro   @r1,@r2,@l3     ; branch if lower than          if (@r1 < @r2) go @l3
        movf    @r1, W
        addlw   0x80
        movwf   _M1
        movf    @r2, W
        addlw   0x80
        subwf   _M1, W
        btfss   STATUS, C
        goto    @l3
        endm
bles    macro   @r1,@r2,@l3     ; branch if lower or equal      if (@r1 <= @r2) go @l3
        movf    @r2, W
        addlw   0x80
        movwf   _M1
        movf    @r1, W
        addlw   0x80
        subwf   _M1, W
        btfsc   STATUS, C
        goto    @l3
        endm
bgtis   macro   @r1,@i2,@l3     ; branch if greater than        if (@r1 > @i2) go @l3
        movf    @r1, W
        addlw   0x80
        sublw   0x80 | @i2
        btfss   STATUS, C
        goto    @l3
        endm
bgeis   macro   @r1,@i2,@l3     ; branch if greater or equal    if (@r1 >= @i2) go @l3
        movf    @r1, W
        addlw   0x80
        sublw   0x80 | @i2
        btfss   STATUS,Z
        btfss   STATUS, C
        goto    @l3
        endm
bltis   macro   @r1,@i2,@l3     ; branch if lower than          if (@r1 < @i2) go @l3
        movf    @r1, W
        addlw   0x80
        movwf   _M1
        movlw   0x80 | @i2
        subwf   _M1, W
        btfss   STATUS, C
        goto    @l3
        endm
bleis   macro   @r1,@i2,@l3     ; branch if lower or equal      if (@r1 <= @i2) go @l3
        movf    @r1, W
        addlw   0x80
        sublw   0x80 | @i2
        btfsc   STATUS, C
        goto    @l3
        endm
Last modified 10 years ago Last modified on Jan 4, 2014, 7:21:44 PM