; file: macross12f509.inc ; ; started 20070715 poly@omino.com ; -------------------------------------------- ; various general purpose macros for the ; microchip 12f509 mcu. these generally follow ; conventions similar to the standard opcodes. ; it is generally assumed that the W and STATUS ; registers are affected ; --------------------------------------------- MOVLF MACRO v,freg MOVLW v XMOVWF freg ENDM ADDLF MACRO v,freg MOVLW v ADDWF freg,f ENDM XORLF MACRO v,freg MOVLW v XORWF freg,f ENDM ADDFF MACRO fregsrc,fregdst MOVFW fregsrc ADDWF fregdst,f ENDM SUBFF MACRO fregsrc,fregdst MOVFW fregsrc SUBWF fregdst,f ENDM MOVFF MACRO fregsrc,fregdst XMOVFW fregsrc XMOVWF fregdst ENDM ; simplifications of common "skip" functions IFZ MACRO BTFSC STATUS,Z ENDM IFNZ MACRO BTFSS STATUS,Z ENDM IFC MACRO BTFSC STATUS,C ENDM IFNC MACRO BTFSS STATUS,C ENDM IFBC MACRO _reg,_bit BTFSS _reg,_bit ENDM IFBS MACRO _reg,_bit BTFSC _reg,_bit ENDM ; Decrement a file register unless it's ; already at zero. 3 cycles every time. DECFPIN MACRO freg INCF freg,f DECFSZ freg,f DECF freg,f ENDM ; Increment or decrement a file register ; to bring it closer to the destination. ; already there? no change. ; 8 cycles & 8 instructions exactly. ; no gotos. MIGFPIN MACRO fregcur,fregdst MOVFW fregcur SUBWF fregdst,w MOVLW 1 ; assume increment IFNC MOVLW 0xff ; negative sub, so decrement IFZ MOVLW 0 ; oh, they were equal ADDWF fregcur,f ENDM ; insert a handful of NOPs, as many as you ask for. NOPS MACRO cycles _delay_k SET cycles WHILE _delay_k > 0 _delay_k SET _delay_k - 1 NOP ENDW ENDM ; fetch one of our indirect registers to W MOVIW MACRO _iReg MOVLF _iReg,FSR MOVFW INDF CLRF FSR ; otherwise upper bits affect MOVs ENDM MOVIF MACRO _iReg,_reg MOVIW _iReg MOVWF _reg ENDM MOVFI MACRO _reg,_iReg MOVFW _reg MOVWI _iReg ENDM _setRegBitFromConst MACRO _const,_reg,_bit IF (_const & (1 << _bit)) == 0 BCF _reg,_bit ELSE BSF _reg,_bit ENDIF ENDM XMOVWF MACRO _dstReg IF _dstReg < 0x20 MOVWF _dstReg ELSE ; how to set a value in FSR affecting to regs? ; 1 bit at a time _setRegBitFromConst _dstReg,FSR,0 _setRegBitFromConst _dstReg,FSR,1 _setRegBitFromConst _dstReg,FSR,2 _setRegBitFromConst _dstReg,FSR,3 _setRegBitFromConst _dstReg,FSR,4 _setRegBitFromConst _dstReg,FSR,5 MOVWF INDF CLRF FSR ENDIF ENDM XMOVFW MACRO _dstReg IF _dstReg < 0x20 MOVFW _dstReg ELSE MOVLF _dstReg,FSR MOVFW INDF CLRF FSR ENDIF ENDM ; Call from upper page to lower, restoring ; STATUS:PA0 to high. CALLLO MACRO _addr IF $ < 0x200 CALL _addr ELSE BCF STATUS,PA0 CALL _addr BSF STATUS,PA0 ENDIF ENDM GOTOHILO MACRO _addr IF _addr >= 0x200 BSF STATUS,PA0 ELSE BCF STATUS,PA0 ENDIF GOTO _addr ENDM ; decrement and skip if zero, but for register in any bank ; leaves back back at zero XDECFSZ MACRO _reg IF _reg < 0x20 DECFSZ _reg ELSE MOVLF _reg,FSR ; set the indirect DECF INDF ; decrement it, set Z flag maybe BCF FSR,5 ; FSR back in lower bank, thanks BTFSS STATUS,Z ; skip if Z ENDIF ENDM ; Poke a random value into a file register ; mask is anded, and min is added ; RANDF x,31,10 to get 10..41 ; (requires a local register named rnd) RANDF MACRO fregdst,mask,min MOVFW rnd ADDWF TMR0,w RLF rnd,f RLF rnd,f ADDWF rnd,f MOVFW rnd IF mask != 0xff ANDLW mask ENDIF MOVWF fregdst IF min != 0 MOVLW min ADDWF fregdst,f ENDIF ENDM