augustinetez
Active Member
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