; ---------------------------------------------------------------------------------------- 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 11 years ago
Last modified on Jan 4, 2014, 7:21:44 PM