So how do you actually use this nifty instruction ?
I'm going to use ``RAMx'' and ``RAMy'' to indicate values in a RAM register, ``K'' to indicate some fixed constant value (often defined using the ``EQU'' assembler directive). (If you want to compare 2 constant values, use the assembler directive ``#if ... #else ... #endif''. The grid below *should* cover all other combinations. ).
Q: Hey ! you left out all the ``greater than'' operators !
A: Whoops. Well, if you need ``A > B'', you can always use ``B < A''.
Most of these are from Tony Nixon.
I'm going to go on the assumption that you want to execute a chunk of code only if the conditional is *true*. (This is what ``if()'' means in C and other decent high-level languages. Don't let those BASIC programmers confuse you.)
Put that chunk of code (or a CALL to it) immediately after these blocks of code, and follow that chunk with some unique label. Then replace the word "Endif" with the name of that label.
If that chunk of code is *exactly* one instruction long (say ``CALL''), and you're very clever, you can optimize this code even more.
[FIXME: how do I code ``if - then - else - endif'' blocks ?]
[FIXME: is there a *reason* Tony Nixon uses ``addlw'' and ``addwf'' rather than ``sublw'' and ``subwf'' ? All PICs support sublw and subwf, don't they ?]
;if RAMx <= K ;Tony Nixon movf RAMx,w addlw 255 - K ; eg if RAMx > 5 ... addlw d'250' btfsc status,carry goto Endif ;if K <= RAMx ;Tony Nixon movf RAMx,w addlw 255 - K + 1 ; eg if RAMx < 5 ... addlw d'251' btfss status,carry goto Endif ;if RAMx < K ; Tony Nixon movf RAMx,w addlw 255 - K + 1 ; eg if RAMx >= 5 ... addlw d'251' btfsc status,carry goto Endif ;if K < RAMx ; Tony Nixon movf RAMx,w addlw 255 - K ; eg if RAMx <= 5 ... addlw d'250' btfss status,carry goto Endif
More.
;if RAMx <= RAMy ; Tony Nixon movf RAMy,w sublw 0xFF addwf RAMx,w btfsc status,carry goto Endif ;if RAMx <= RAMy ; Scott Dattalo movf RAMx,w subwf RAMy,w skpc goto Endif ; better ! ;16cxxx 4*14 = 52 bits of program memory (14 bit core) ;?????? 4*12 = 48 bits of program memory (12 bit core) ;if RAMx <= RAMy ; better, but only works on 18cxxx chips ! ; Scott Dattalo movf RAMx,w ;wreg = RAMx subwf RAMy,w ;wreg = RAMy - RAMx bn Endif ;Branch if negative ; (You could use the bnc [branch if no carry] to achieve the same effect. ; The negative bit has a clearer meaning in this context). ;The N bit will be cleared if RAMx == RAMy or ;RAMy > RAMx, and will be set if RAMy < RAMx ;18cxxx 3*16 = 48 bits of program memory ;16cxxx 5*14 = 70 bits of program memory ;[DAV: Huh ? Does bn really work on the 16cxxx 14 bit core ?]
More.
;if RAMy <= RAMx ; Tony Nixon movf RAMx,w sublw 0xFF addwf RAMy,w btfsc status,carry goto Endif ;if RAMy <= RAMx ; unknown -- perhaps James Newton ? movf RAMx, w subwf RAMy, w skpz ;for the case that RAMx=RAMy where C will be 1 skpnc goto Endif ;if RAMx < RAMy ; Tony Nixon movf RAMx,w sublw 0xFF addwf RAMy,w btfss status,carry goto Endif
; ``Tony's sequence can be reduced by an instruction. '' -- Scott Dattalo
;if RAMx < RAMy ; better, but only works on 18cxxx chips ! ; Scott Dattalo movf RAMy,w ;wreg = RAMy subwf RAMx,w ;wreg = RAMx - RAMy bnn Endif ;branch if not negative ;The N bit will be cleared if RAMx == RAMy or ;RAMx > RAMy, and will be set if RAMy < RAMx ; Again, you could use the bc (branch on carry) instruction too. ;if RAMy < RAMx movf RAMy,w sublw 0xFF addwf RAMx,w btfss status,carry goto Endif