At the moment, some of my projects relating to the AD9850 are using two different routines to test if the frequency is above or below preset levels.
Obviously a waste of program space that I would like to rectify (I didn't write the currently used routines, they came from the various PIC-El files).
So the question is, can the following code (found on PIClist), which I am using in another program, be easily expanded to do 32bit compares or is there an easier way?
I have spent a fair amount of time searching the 'net, but most of what I've found makes my head hurt.
The currently used code routines are:
And:
Obviously a waste of program space that I would like to rectify (I didn't write the currently used routines, they came from the various PIC-El files).
So the question is, can the following code (found on PIClist), which I am using in another program, be easily expanded to do 32bit compares or is there an easier way?
I have spent a fair amount of time searching the 'net, but most of what I've found makes my head hurt.
Code:
;*******************************************************************
; A not too optimised 16 bit compare routine for 16bit absolute
; values, Antonio L Benci (PIClist)
; ie 0 -> 65536.
; Compare WORD to COMP (a word value).
; If WORD = COMP return with 00
; If WORD > COMP return with 01
; If WORD < COMP return with 80
;*******************************************************************
hword equ 0x10 ; storage for high byte of WORD
lword equ hword+1 ; storage for low byte of WORD
hcomp equ 0x12 ; storage for high byte of COMP
lcomp equ hcomp+1 ; storage for low byte of COMP
COMP
movfw hcomp ; get high byte of comp value
subwf hword ; subtract values
btfsc status,z ; first check if result is 0
goto COMPL ; if zero compare low bytes
btfsc status,c ; else test carry bit
retlw 0x01 ; if WORD > COMP, return with 01h
retlw 0x80 ; if WORD < COMP, return with 80h
COMPL
movfw lcomp ; get low byte of comp value
subwf lbyte ; subtract values
btfsc status,z ; first check if result is 0
retlw 0x00 ; if result is 0, return with 00
btfsc status,c ; if c set then WORD > COMP
retlw 0x01 ; if WORD > COMP, return with 01h
retlw 0x80 ; if WORD < COMP, return with 80h
end
;******************************************************************
The currently used code routines are:
Code:
; *******************************************************************************
; * *
; * Purpose: Check if freq exceeds the upper limit. *
; * *
; * Input: The 32 bit values in freq *
; * *
; * Output: If freq is below the limit, it is unchanged. Otherwise, it is *
; * set to equal the upper limit. *
; * *
; *******************************************************************************
;
check_add
;
; Check the most significant byte.
;
movlw 0xFF-limit_3 ; Get (FF - limit of high byte)
addwf freq_3,w ; Add it to the current high byte
btfsc STATUS,C ; Was high byte too large?
goto set_max ; Yes, apply limit
movlw limit_3 ; Get high limit value
subwf freq_3,w ; Subtract the limit value
btfss STATUS,C ; Are we at the limit for the byte?
goto exit1 ; No, below. Checks are done.
;
; Check the second most significant byte.
;
movlw 0xFF-limit_2 ; Get (FF - limit of next byte)
addwf freq_2,w ; Add it to the current byte
btfsc STATUS,C ; Is the current value too high?
goto set_max ; Yes, apply the limit
movlw limit_2 ; Second limit byte
subwf freq_2,w ; Subtract limit value
btfss STATUS,C ; Are we at the limit for the byte?
goto exit1 ; No, below. Checks are done.
;
; Check the third most significant byte.
;
movlw 0xFF-limit_1 ; Get (FF - limit of next byte)
addwf freq_1,w ; Add it to the current byte
btfsc STATUS,C ; Is the current value too high?
goto set_max ; Yes, apply the limit
movlw limit_1 ; Third limit byte
subwf freq_1,w ; Subtract limit value
btfss STATUS,C ; Are we at the limit for the byte?
goto exit1 ; No, below. Checks are done.
;
; Check the least significant byte.
;
movlw limit_0 ; Fourth limit byte
subwf freq_0,w ; Subtract limit value
btfss STATUS,C ; Are we at the limit for the byte?
goto exit1 ; No, below. Checks are done.
set_max
movlw limit_0 ; Get least significant limit
movwf freq_0 ; Set it in freq
movlw limit_1 ; Get the next byte limit
movwf freq_1 ; Set it in freq_1
movlw limit_2 ; Get the next byte limit
movwf freq_2 ; Set it in freq_2
movlw limit_3 ; Get the most significant limit
movwf freq_3 ; Set it in freq_3
exit1
return ; Return to the caller
And:
Code:
; *******************************************************************************
; * *
; * Function: low_limit_chk *
; * *
; * Purpose: Test the new frequency to see if it is above the lower band *
; * limit. If not, the frequency is set to the band lower limit. *
; * *
; * Input: Freq_0...3 and Low_limit_0...3 *
; * *
; * Output: Original frequency if above low limit or low_limit_0..3 in *
; * Freq_0...3 *
; * *
; *******************************************************************************
;
low_limit_chk
; Check the most significant byte.
;
btfsc freq_3,7
goto set_low ; Yes, set to lower frequency limit
movf freq_3,w
subwf low_limit_3,w
btfss STATUS,C ; Are we at the limit for the byte?
goto limit_exit ; No, above.
btfss STATUS,Z ; Are the bytes equal?
goto set_low ; No, so vfo_X_3 > limit_3.
;
; Check the second most significant byte when MSB equals limit_3
;
movf freq_2,w
subwf low_limit_2,w
btfss STATUS,C ; Are we at the limit for the byte?
goto limit_exit ; No, above. Check next.
btfss STATUS,Z ; Might they be equal?
goto set_low ; Nope, so vfo_X_2 > limit_2
;
; Check the third most significant byte.
;
movf freq_1,w
subwf low_limit_1,w
btfss STATUS,C ; Are we at the limit for the byte?
goto limit_exit ; No, above. Checks are done.
btfss STATUS,Z ; Check if the bytes are equal
goto set_low ; No, so vfo_X_1 > limit_1
;
; Check the least significant byte.
;
movf freq_0,w
subwf low_limit_0,w
btfss STATUS,C ; Are we at the limit for the byte?
goto limit_exit ; No, above. Checks are done.
;
; The frequency is below the band lower limit. Set frequency to the
; band starting frequency.
set_low
;
movf low_limit_0,w
movwf freq_0
movf low_limit_1,w
movwf freq_1
movf low_limit_2,w
movwf freq_2
movf low_limit_3,w
movwf freq_3
;
limit_exit
call invert_fstep ; Put fstep back to original value
return ; Return to caller