
;************************************************************************************************************************************
;FILE NAME:						
;STATUS:					
;DATE CREATED:												 
;Date of Last Modification:		 
;
;PURPOSE:
;PROCESSOR:						PIC 12F683				
;CLOCK SOURCE:									
;************************************************************************************************************************************


;************************************************************************************************************************************
;PROCESSOR DECLARATIONS, INCLUDE FILES, CONFIG WORD SETUP
;************************************************************************************************************************************

	list      p=12f683           ; list directive to define processor
	#include <P12F683.INC>       ; processor specific variable definitions

	errorlevel  -302              ; suppress message 302 from list file

	__CONFIG   _FCMEN_OFF & _IESO_OFF & _BOD_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF  & _HS_OSC

;************************************************************************************************************************************
;END OF PROCESSOR DECLARATIONS
;************************************************************************************************************************************



;************************************************************************************************************************************
;RAM VARIABLES SETUP
;************************************************************************************************************************************

	cblock		H'020'

;*****Counter variables
VAR_COUNT1						
VAR_COUNT2						
VAR_AVG_CTR								;variable used to count through the number of A/D readings averaged
VAR_FLAGS								;Variable containing various flags used in the program

;*****Variables for lookup tables
VAR_TEXT_INDEX						;Used to pass the offset to the various lookup tables.  This variable is not altered by the lookup routine
VAR_TABLE_OFFSET						;Used within the lookup routines to hold the offset

;*****Variables for math operations
VAR_1_16BIT_H					
VAR_1_16BIT_L					
VAR_2_16BIT_H					
VAR_2_16BIT_L					

VAR_TEMP1_H						
VAR_TEMP1_L						
VAR_TEMP2_H							
VAR_TEMP2_L							
VAR_TEMP3_H						
VAR_TEMP3_L							

VAR_MULT_CTR								;Counter varible used in the multiply routine

;*****Variables used in the Goertzel algorithm
VAR_Y0_A_H								;These are the values computed during the Goertzel algorithm
VAR_Y0_A_L							
VAR_Y1_A_H							
VAR_Y1_A_L							
VAR_Y2_A_H							
VAR_Y2_A_L							
VAR_X0_H							
VAR_X0_L							

VAR_COS_COEFF								;Stores the cosine coefficient used in the algorithm
VAR_SIN_COEFF								;Stores the cosine coefficient used in the algorithm

VAR_SAMPLE_CTR								;Used for stepping through the samples in each scan
VAR_WINDOW_CTR									;Counter variable used to lookup the correct Hamming window value

VAR_REAL_H									;variables used to store the real and imaginary parts of the final result of the
VAR_REAL_L								;algorithm.  These are then used to determine the magnitude
VAR_IMAG_H							
VAR_IMAG_L							
VAR_MAGNITUDE_H							;Variables to store the magnitude of the algorithm output
VAR_MAGNITUDE_L					


VAR_FREQ_SETTING_H							;variables to store the freqency select input reading
VAR_FREQ_SETTING_L					

VAR_DETECTION_THRESHOLD_H					;Stores the detection threshold value currently in use.  The actual value stored
VAR_DETECTION_THRESHOLD_L				;will be equal to either the upper or lower threshold, depending on the previous
													;state of the detector output.  This is used for the hysteresis
VAR_UPPER_THRESHOLD_H						;Stores the upper detection threshold corresponding to the detection threshold input
VAR_UPPER_THRESHOLD_L				

VAR_LOWER_THRESHOLD_H						;Stores the lower detection threshold corresponding to the detection threshold input
VAR_LOWER_THRESHOLD_L			

;*****Variables for serial transmission
VAR_SERIAL_DATA								;Variable used to pass the byte to be transmitted to the serial output routine
VAR_SER_DELAY_CTR							;Variable used in the delay used to set the serial output bit timing
VAR_SER_BIT_CTR							;Variable used to count through the bits in the byte to be transmitted

;Other variables
VAR_FSR_TEMP							;Temporary location for storing the state of the FSR
DECIMAL_DIGITS		:5					;First location of a block of 5 bytes used for the 5 decimal digits that result form
													;the binary to decimal conversion routine

VAL_DECIMAL_CONVERSION_CTR				;Counter variable used for cycling through the decimal digits


	endc

;************************************************************************************************************************************
;END OF RAM VARIBLES SETUP
;************************************************************************************************************************************
      

;************************************************************************************************************************************
;EQUATES
;************************************************************************************************************************************

CHAR_CARRIAGE_RETURN				EQU		H'0A'	;value of carriage return in ASCII
CHAR_NEW_LINE						EQU		H'0D'	;value of new line in ASCII

BAUD_RATE_VAL						EQU		D'48'	;value used in delay to set proper serial bit timing for 9600 baud

SAMPLE_DELAY_H						EQU		H'FE'	;Sample delay values for Timer 1, corresponding to 4400Hz sampl3 rate.
SAMPLE_DELAY_L						EQU		H'46'

NUMBER_OF_SAMPLES					EQU		D'200'	;This is the number of samples taken and processed during the Goertzel algorithm


;**********GPIO	Assignments
;GP0=AN0 Analog Input for audio signal 
;GP1=AN1 Detection threshold setting analog input
;GP2=Main Output
;GP3=Frequency select enable
;GP4=XTAL
;GP5=XTAL

OUTPUT_PIN							EQU		D'2'	;Output pin that is set high if the programmed sequence is detected
FREQ_SELECT_ENABLE					EQU		D'3'
SERIAL_OUT							EQU		D'5'	;Output for red LED

UPPER_THRESHOLD_FACTOR				EQU		D'72'	;These values correspond to a hysterestis window width of 1/4 of the center value
LOWER_THRESHOLD_FACTOR				EQU		D'56'	;(1/8 of the window above and below the center"

DETECTION_THRESHOLD_SCALE_FACTOR	EQU		D'52'	;This value is used in the process of mapping the 10 bit A/D full scale range to
													;The desired full scale range of values producted by the algorithm output

DETECT_THRESHOLD_OFFSET_H			EQU		D'0'	;These values are used to establish the absolute minimum value of the threshold
DETECT_THRESHOLD_OFFSET_L			EQU		D'27'	;It cannot be zero, otherwise the detection will be triggered by noise

;VAR_FLAGS register bits
SIGN_VAL_1							EQU		D'0'
SIGN_VAL_2							EQU		D'1'
POWER_UP							EQU		D'2'

;************************************************************************************************************************************
;END OF EQUATES
;************************************************************************************************************************************
 
	ORG			H'000'

	GOTO		PROGRAM_START

	ORG			H'005'

PROGRAM_START			

;************************************************************************************************************************************
;CONFIGURATION OF THE PROCESSOR
;************************************************************************************************************************************
		
		BCF     STATUS,RP1 
		BCF     STATUS,RP0      ;Change to Bank0

;Clear the gpio port

		CLRF	GPIO
 
        BSF     STATUS,RP0      ;Change to Bank1 

;Configure I/O ports as inputs or outputs

       	MOVLW   B'00111011'     ;Configure GPIO I/O
        MOVWF	TRISIO           

;Set A/D conversion clock to Fosc/16, and configure GPIO #0 as an analog input.
;Note: The conversion process takes 11 Tad, and Tad will be 2usec for an 8MHz oscillator and these settings, so the conversion
;time will be 22usec or 44 instruction cycles.

		MOVLW	b'01010011'
		MOVWF	ANSEL

		BCF     STATUS,RP0      ;Change to Bank0
		
		CLRF	GPIO

;Configure the A/D converter for right justified results, reference voltage of Vdd (5 volts), 
;select ananlog channel 0, and turn the converter ON.

		MOVLW	B'10000001'		
		MOVWF	ADCON0
	
;Turn off the comparator module

		BCF		STATUS,RP0
		MOVLW	H'07'
		MOVWF	CMCON0

		CLRF	VAR_FLAGS		;Clear the VAR_FLAGS variable to begin with

;************************************************************************************************************************************
;END CONFIGURATION OF THE PROCESSOR
;************************************************************************************************************************************
		BSF		GPIO,SERIAL_OUT		;Set the serial output pin high (this is the idle state)
	
		CALL	SUB_DELAY_125MS

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;Main Program
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

		CALL	SUB_DELAY_500_MICROSEC

		MOVLW	H'78'					;Initialize the detection threshold to begin with
		MOVWF	VAR_DETECTION_THRESHOLD_H
		MOVLW	H'00'
		MOVWF	VAR_DETECTION_THRESHOLD_L


		BSF		VAR_FLAGS,POWER_UP		;This flag is set here, and cleared later.  It is used to ensure that the frequency
										;select input is always read after power up.  After that it is only read if the
										;FREQ_SELECT_ENABLE input is LOW
CHECK_FREQ_SELECT_ENABLE

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;The following code will be commented out to deactivate it.  This portion of the code typically runs each detection loop, to
;read the frequency select input to determine the frequency to test for.  Since this version of code uses a fixed 1750 Hz
;frequency, this code is not needed.
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;Is Power up flag set?

;		BTFSC	VAR_FLAGS,POWER_UP
;		GOTO	READ_FREQ_SETTING

;Is the frequency select enable input low?

;		BTFSC	GPIO,FREQ_SELECT_ENABLE
;		GOTO	SCAN_FOR_FREQ	
	
READ_FREQ_SETTING

;		BCF		VAR_FLAGS,POWER_UP

;Select analog input 1 for reading the target frequency setting

;		BCF		ADCON0,CHS1
;		BSF		ADCON0,CHS0

;		CALL	SUB_AVG_ANALOG_READING

;		MOVFW	VAR_1_16BIT_H
;		MOVWF	VAR_FREQ_SETTING_H
;		MOVFW	VAR_1_16BIT_L
;		MOVWF	VAR_FREQ_SETTING_L

;Rotate the value to the right once to positon the bits for use as an index value for looking up the sin and cos coefficients.

;		BCF		STATUS,C

;		RRF		VAR_1_16BIT_H,f
;		RRF		VAR_1_16BIT_L,f

;Bit 0 of VAR_1_16BIT_H now determines which bank (0 or 1) the values are looked up from
;The bits of VAR_1_16BIT_L are the value used to look up from the tables.

;		MOVFW	VAR_1_16BIT_L
;		MOVWF	VAR_TEXT_INDEX

;		BTFSC	VAR_1_16BIT_H,0
;		GOTO	LOOK_UP_USING_1_TABLES

;		CALL	SUB_SIN_COEFF_0_LOOKUP

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;The coefficents corresponding to 1748 Hz are directly used here.  1748 Hz is the closest value to 1750 Hz that was in the 
;lookup table that is used in the standard version of the code

		MOVLW		D'38'		;Sine coefficient for 1760 Hz
		MOVWF	VAR_SIN_COEFF
;		CALL	SUB_COS_COEFF_0_LOOKUP

		MOVLW		D'180'	;Cosine coefficient for 1760 Hz
		MOVWF	VAR_COS_COEFF
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

;		GOTO	LOOKUP_COMPLETE

LOOK_UP_USING_1_TABLES

;		CALL	SUB_SIN_COEFF_1_LOOKUP
;		MOVWF	VAR_SIN_COEFF
;		CALL	SUB_COS_COEFF_1_LOOKUP
;		MOVWF	VAR_COS_COEFF

LOOKUP_COMPLETE


SCAN_FOR_FREQ

;***************Determine the Upper and Lower Detection Thresholds

;Select analog input AN1 for reading the detection threshold input

		BCF		ADCON0,CHS1
		BSF		ADCON0,CHS0

		CALL	SUB_AVG_ANALOG_READING

;Add the offset, used to establish the minimum allowable value of the detection threshold

		MOVLW	DETECT_THRESHOLD_OFFSET_H
		MOVWF	VAR_2_16BIT_H

		MOVLW	DETECT_THRESHOLD_OFFSET_L
		MOVWF	VAR_2_16BIT_L

		CALL	SUB_MATH_16BIT_ADD

;Multiply by 32 (left shift 5 times)

		BCF		STATUS,C
		RLF		VAR_1_16BIT_L,f
		RLF		VAR_1_16BIT_H,f
		BCF		STATUS,C
		RLF		VAR_1_16BIT_L,f
		RLF		VAR_1_16BIT_H,f
		BCF		STATUS,C
		RLF		VAR_1_16BIT_L,f
		RLF		VAR_1_16BIT_H,f
		BCF		STATUS,C
		RLF		VAR_1_16BIT_L,f
		RLF		VAR_1_16BIT_H,f
		BCF		STATUS,C
		RLF		VAR_1_16BIT_L,f
		RLF		VAR_1_16BIT_H,f

;Multiply the value by a scale factor

		MOVLW	DETECTION_THRESHOLD_SCALE_FACTOR	
		MOVWF	VAR_2_16BIT_L

		CALL	SUB_MATH_MULTIPLY

;The value is now equal to the center value of the detection threshold. Store the value

		MOVFW	VAR_1_16BIT_H
		MOVWF	VAR_TEMP2_H

		MOVFW	VAR_1_16BIT_L
		MOVWF	VAR_TEMP2_L

;Determine the upper threshold

		MOVLW	UPPER_THRESHOLD_FACTOR	
		MOVWF	VAR_2_16BIT_L

		CALL	SUB_MATH_MULTIPLY

;Store the upper threshold

		MOVFW	VAR_1_16BIT_H
		MOVWF	VAR_UPPER_THRESHOLD_H

		MOVFW	VAR_1_16BIT_L
		MOVWF	VAR_UPPER_THRESHOLD_L

;Determine the lower threshold

		MOVFW	VAR_TEMP2_H
		MOVWF	VAR_1_16BIT_H

		MOVFW	VAR_TEMP2_L
		MOVWF	VAR_1_16BIT_L

		MOVLW	LOWER_THRESHOLD_FACTOR	
		MOVWF	VAR_2_16BIT_L

		CALL	SUB_MATH_MULTIPLY

;Store the lower threshold

		MOVFW	VAR_1_16BIT_H
		MOVWF	VAR_LOWER_THRESHOLD_H

		MOVFW	VAR_1_16BIT_L
		MOVWF	VAR_LOWER_THRESHOLD_L

;**********Transmit the settings over serial

;***Transmit the Target frequency 

;The value in VAR_FREQ_SETTING is currently just the value read from the frequency select input
;Since this software is configured to detect frequencies from 100Hz to 2148Hz, the value needs
;to be processes first so that it represents the target frequency, in Hz

;Target frequency, in Hz = 2*frequency select reading + 100

;First, mulitply the value by 2

		MOVFW	VAR_FREQ_SETTING_H
		MOVWF	VAR_1_16BIT_H
		MOVFW	VAR_FREQ_SETTING_L
		MOVWF	VAR_1_16BIT_L

		BCF		STATUS,C
		RLF		VAR_1_16BIT_L,f
		RLF		VAR_1_16BIT_H,f

;Next, add 100 to the value.

		CLRF	VAR_2_16BIT_H
		MOVLW	D'100'
		MOVWF	VAR_2_16BIT_L

		CALL	SUB_MATH_16BIT_ADD

		CALL	SUB_CONVERT_AND_TRANSMIT

;***Transmit the Upper detection threshold

		MOVFW	VAR_UPPER_THRESHOLD_H
		MOVWF	VAR_1_16BIT_H
		MOVFW	VAR_UPPER_THRESHOLD_L
		MOVWF	VAR_1_16BIT_L

		CALL	SUB_CONVERT_AND_TRANSMIT

;***Transmit the Lower detection threshold

		MOVFW	VAR_LOWER_THRESHOLD_H
		MOVWF	VAR_1_16BIT_H
		MOVFW	VAR_LOWER_THRESHOLD_L
		MOVWF	VAR_1_16BIT_L

		CALL	SUB_CONVERT_AND_TRANSMIT

;***Transmit the Current detection threshold

		MOVFW	VAR_DETECTION_THRESHOLD_H
		MOVWF	VAR_1_16BIT_H
		MOVFW	VAR_DETECTION_THRESHOLD_L
		MOVWF	VAR_1_16BIT_L

		CALL	SUB_CONVERT_AND_TRANSMIT

;**********Run the Goertzel Routine to determine if the target frequency is present

		CALL	SUB_GOERTZEL_SAMPLE

;Load VAR_MAGNITUDE into VAR_1 for comparison to threshold

		MOVFW	VAR_MAGNITUDE_H
		MOVWF	VAR_1_16BIT_H
		MOVFW	VAR_MAGNITUDE_L
		MOVWF	VAR_1_16BIT_L

;Compare magnitude to threshold to decide whether frequency is present

		MOVFW	VAR_DETECTION_THRESHOLD_H
		MOVWF	VAR_2_16BIT_H
		MOVLW	VAR_DETECTION_THRESHOLD_L
		MOVWF	VAR_2_16BIT_L

		CALL	SUB_MATH_16BIT_SUBTRACT

		MOVLW	'X'
		MOVWF	VAR_SERIAL_DATA
		CALL	SUB_SERIAL_TX

		BTFSS	VAR_1_16BIT_H,7
		GOTO	FREQ_DETECTED

		BCF		GPIO,OUTPUT_PIN				;Set the output LOW if the frequency is not detected

;If the result is less than the current threshold, set the lower threshold as the current threshold for the next time the algorithm is run
;This is for the hysteresis

		MOVFW	VAR_UPPER_THRESHOLD_H
		MOVWF	VAR_DETECTION_THRESHOLD_H
		MOVFW	VAR_UPPER_THRESHOLD_L
		MOVWF	VAR_DETECTION_THRESHOLD_L

;Transmit a "0" indicating that the frequency has not been detected

		MOVLW	'0'
		MOVWF	VAR_SERIAL_DATA
		CALL	SUB_SERIAL_TX

;Transmit the magnitude of the filter output via serial

		GOTO	TRANSMIT_MAGNITUDE_OVER_SERIAL

FREQ_DETECTED

		BSF		GPIO,OUTPUT_PIN

;If the result is greater than the current threshold, set the lower threshold as the current threshold for the next time the algorithm is run
;This is for the hysteresis

		MOVFW	VAR_LOWER_THRESHOLD_H
		MOVWF	VAR_DETECTION_THRESHOLD_H
		MOVFW	VAR_LOWER_THRESHOLD_L
		MOVWF	VAR_DETECTION_THRESHOLD_L

;Transmit a "1" indicating that the frequency has been detected

		MOVLW	'1'
		MOVWF	VAR_SERIAL_DATA
		CALL	SUB_SERIAL_TX

TRANSMIT_MAGNITUDE_OVER_SERIAL

		MOVLW	','
		MOVWF	VAR_SERIAL_DATA
		CALL	SUB_SERIAL_TX

;Convert the magnitde to decimal and transmit over serial

;Load VAR_MAGNITUDE into VAR_1 for conversion to decimal

		MOVFW	VAR_MAGNITUDE_H
		MOVWF	VAR_1_16BIT_H
		MOVFW	VAR_MAGNITUDE_L
		MOVWF	VAR_1_16BIT_L

		CALL	SUB_CONVERT_AND_TRANSMIT

;Transmit a carriage return and new line

		MOVLW	CHAR_CARRIAGE_RETURN
		MOVWF	VAR_SERIAL_DATA
		CALL	SUB_SERIAL_TX

		MOVLW	CHAR_NEW_LINE
		MOVWF	VAR_SERIAL_DATA
		CALL	SUB_SERIAL_TX

		GOTO	CHECK_FREQ_SELECT_ENABLE

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;END of Main Program
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;BEGINNING OF SUBROUTINE CODE
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


;************************************************************************************************************************************
; Subroutine SUB_DELAY_500_MICROSEC 
;************************************************************************************************************************************
SUB_DELAY_500_MICROSEC
		
		movlw	D'125'
		movwf	VAR_COUNT1
LOOP1
		nop
		nop
		nop
		nop
		nop
		decfsz	VAR_COUNT1,f
		goto	LOOP1

		return					;Return from SUB_DELAY_500_MICROSEC
;************************************************************************************************************************************
;       END of Subroutine SUB_DELAY_500_MICROSEC
;************************************************************************************************************************************


;************************************************************************************************************************************
;Subroutine SUB_DELAY_125MS
;************************************************************************************************************************************
SUB_DELAY_125MS
		movlw	D'250'
		movwf	VAR_COUNT2

LOOP2
		call	SUB_DELAY_500_MICROSEC
	
		decfsz	VAR_COUNT2,f
		goto 	LOOP2

		return					;Return from SUB_DELAY_125MS
;************************************************************************************************************************************		
;       END of Subroutine SUB_DELAY_125MS
;*************************************************************************************************************************************


;************************************************************************************************************************************
;Subroutine	SUB_MATH_16BIT_ADD
;This subroutine adds two 16 bit numbers.  Each number is stored in two 8 bit variables.  The result is returned via the 
;VAR_1_16BIT variables.  
;Total execution time, including call and return = 10 cycles
;************************************************************************************************************************************

SUB_MATH_16BIT_ADD

		MOVFW	VAR_2_16BIT_L
		ADDWF	VAR_1_16BIT_L,F

		BTFSC	STATUS,C
		INCF	VAR_1_16BIT_H,F

		MOVFW	VAR_2_16BIT_H
		ADDWF	VAR_1_16BIT_H,F

		RETURN					;Return from Subroutine SUB_MATH_16BIT_ADD
;************************************************************************************************************************************
;       END of Subroutine SUB_MATH_16BIT_ADD
;************************************************************************************************************************************


;************************************************************************************************************************************
;Subroutine	SUB_MATH_16BIT_SUBTRACT
;This subroutine adds two 16 bit numbers.  Each number is stored in two 8 bit variables.  The result is returned via the 
;VAR_1_16BIT variables.  The routine subtracts value 2 from value 1.  
;\Total execution time, including call and return = 10 instruction cycles
;************************************************************************************************************************************

SUB_MATH_16BIT_SUBTRACT

;Subtract the low bytes
		MOVFW	VAR_2_16BIT_L
		SUBWF	VAR_1_16BIT_L,f

		BTFSS	STATUS,C
		DECF	VAR_1_16BIT_H,f

;Subtract the high bytes
	
		MOVFW	VAR_2_16BIT_H
		SUBWF	VAR_1_16BIT_H,f

		RETURN					;Return from Subroutine SUB_MATH_16BIT_SUBTRACT

;************************************************************************************************************************************
;       END of Subroutine SUB_MATH_16BIT_SUBTRACT
;************************************************************************************************************************************


;**********************************************************************************************************************************
;Subroutine SUB_ABS_VAL
;This subroutine takes the absolute value of the 2's complement number in VAR_1.  The result is returned via VAR_1.
;Execution time, including the call and return = 12 instruction cycles,
;**********************************************************************************************************************************
SUB_ABS_VAL

		BTFSS	VAR_1_16BIT_H,7		;Check to see if the most significant bit is a 1, indicating  negative value
		GOTO	END_ABS_VAL		;If MSB =0, value is positive, and no further processing is required

		COMF	VAR_1_16BIT_H,F		;If value is  negative, convert to postive by taking 2's complement, which 
		COMF	VAR_1_16BIT_L,F		;requires inverting all the bits and adding 1

		MOVLW	D'1'
		ADDWF	VAR_1_16BIT_L,F

		BTFSC	STATUS,C
		INCF	VAR_1_16BIT_H,f

END_ABS_VAL

		RETURN					;Return from SUB_ABS_VAL
;**********************************************************************************************************************************
;       END of Subroutine SUB_ABS_VAL
;**********************************************************************************************************************************


;**********************************************************************************************************************************
;Subroutine SUB_MATH_MULTIPLY
;This routine multiplies a 16 bit number (in VAR1) by an 8 bit number (in VAR_2_16BIT_L)
;The 8 bit number is of the form 0X.XXXXXX  That is, it can reprsent a decimal number between 0 and 1.984
;Maximum execution time, including call and return = 2 + 8 + 6*(17) + 16 + 2 = 130 instruction cycles
;That is the maximum execution time.  The execution time will vary depending on the numbers to be multiplied
;**********************************************************************************************************************************

SUB_MATH_MULTIPLY

;Move the VAR1 variable into temp1
		MOVFW	VAR_1_16BIT_H
		MOVWF	VAR_TEMP1_H

		MOVFW	VAR_1_16BIT_L
		MOVWF	VAR_TEMP1_L

;Clear out the VAR1

		CLRF	VAR_1_16BIT_H
		CLRF	VAR_1_16BIT_L

		MOVLW	D'7'
		MOVWF	VAR_MULT_CTR

SHIFT_AND_ADD

		BTFSS	VAR_2_16BIT_L,6		
		GOTO	ROTATE_VALS		;There is no value to add if the bit is zero

;Add the shifted value to VAR_1

		BCF		STATUS,C		;Clear the carry bit

		MOVFW	VAR_TEMP1_L
		ADDWF	VAR_1_16BIT_L,f

		BTFSS	STATUS,C
		GOTO	ADD_HIGH_BYTES_MULTIPLY	
	
		INCF	VAR_1_16BIT_H,f
	
ADD_HIGH_BYTES_MULTIPLY

		MOVFW	VAR_TEMP1_H
		ADDWF	VAR_1_16BIT_H,f

;Rotate values

ROTATE_VALS

;Rotate the 16bit value (divide by 2)

		BCF		STATUS,C
		RRF		VAR_TEMP1_H,f
		RRF		VAR_TEMP1_L,f

;Rotate the multiplier left to position the next bit into bit 6

		RLF		VAR_2_16BIT_L,f

		DECFSZ	VAR_MULT_CTR,f
		GOTO	SHIFT_AND_ADD

		RETURN

;**********************************************************************************************************************************
;       END of Subroutine SUB_MATH_MULTIPLY
;**********************************************************************************************************************************


;************************************************************************************************************************************
;Subroutine	SUB_MATH_MULTIPLY_SIGNED
;This subroutine
;Total execution time, including call and return = 164 instruction cycles
;That is the maximum execution time.  The execution time will vary depending on the numbers to be multiplied
;************************************************************************************************************************************

SUB_MATH_MULTIPLY_SIGNED

;Determine the signs of the two values and set the flags accordingly

		BCF		VAR_FLAGS,SIGN_VAL_1		;Clear these two flags to begin
		BCF		VAR_FLAGS,SIGN_VAL_2	

		BTFSC	VAR_1_16BIT_H,7
		BSF		VAR_FLAGS,SIGN_VAL_1			;Set if number is negative

		BTFSC	VAR_2_16BIT_L,7
		BSF		VAR_FLAGS,SIGN_VAL_2		;Set if number is negative

		BTFSS	VAR_1_16BIT_H,7
		GOTO	MULTIPLY_NUMBERS		

;Multiply Y1 by -1 (two's complement) if it is a negative value

		COMF	VAR_1_16BIT_H,F		;If value is  negative, convert to postive by taking 2's complement, which 
		COMF	VAR_1_16BIT_L,F		;requires inverting all the bits and adding 1

		MOVLW	D'1'
		ADDWF	VAR_1_16BIT_L,f

		BTFSC	STATUS,C
		INCF	VAR_1_16BIT_H,f

;Multiply the two numbers

MULTIPLY_NUMBERS

		CALL	SUB_MATH_MULTIPLY	;This routine takes 130 instruction cycles max

;Determine if the result should be positive or negative.  If one or the other but not both of the
;two numbers multiplied are negative, then the result is negative and the value must be multiplied
;by -1.  (two's complement) 

		MOVFW	VAR_FLAGS
		ANDLW	b'00000011'
		XORLW	b'00000011'
		BTFSC	STATUS,Z
		GOTO	END_OF_SIGNED_MULTIPLY

		MOVFW  	VAR_FLAGS
		ANDLW	b'00000011'
		XORLW	b'00000000'
		BTFSC	STATUS,Z
		GOTO	END_OF_SIGNED_MULTIPLY

;Multiply by negative 1 otherwise

		COMF	VAR_1_16BIT_H,F		;If value is  negative, convert to postive by taking 2's complement, which 
		COMF	VAR_1_16BIT_L,F		;requires inverting all the bits and adding 1

		MOVLW	D'1'
		ADDWF	VAR_1_16BIT_L,f

		BTFSC	STATUS,C
		INCF	VAR_1_16BIT_H,f

END_OF_SIGNED_MULTIPLY

		RETURN					;Return from Subroutine SUB_MATH_MULTIPLY_SIGNED
;************************************************************************************************************************************
;       END of Subroutine SUB_MATH_MULTIPLY_SIGNED
;************************************************************************************************************************************


;**********************************************************************************************************************************
;Subroutine SUB_MATH_16BIT_MAGNITUDE
;This subroutine is used to provide an approximation of the magnitude of a vector. This is the max + 1/4*min version.
;It is used to avoid the more complicated math of the pythagorean therorm to determine the magnitude of a vector.
;It is used in this application to estimate the magnitude of the algorithm output from the real and imaginary parts.
;**********************************************************************************************************************************
SUB_MATH_16BIT_MAGNITUDE

		CALL	SUB_ABS_VAL		;take absolute value of VAR_1

		MOVFW	VAR_1_16BIT_H	;store the absolute value of the first value in TEMP2
		MOVWF	VAR_TEMP2_H
		MOVFW	VAR_1_16BIT_L
		MOVWF	VAR_TEMP2_L

		MOVFW	VAR_2_16BIT_H		;Move the second value from VAR2 into VAR_1
		MOVWF	VAR_1_16BIT_H
		MOVFW	VAR_2_16BIT_H
		MOVWF	VAR_1_16BIT_L

		CALL	SUB_ABS_VAL		;take absolute value of VAR_1

		MOVFW	VAR_1_16BIT_H	;store the absolute value of the second value in TEMP3
		MOVWF	VAR_TEMP3_H
		MOVFW	VAR_1_16BIT_L
		MOVWF	VAR_TEMP3_L

;Subtract the two values to determine which is the min and which is the max

		MOVFW	VAR_TEMP2_H
		MOVWF	VAR_1_16BIT_H
		MOVFW	VAR_TEMP2_L
		MOVWF	VAR_1_16BIT_L

		MOVFW	VAR_TEMP3_H
		MOVWF	VAR_2_16BIT_H
		MOVFW	VAR_TEMP3_L
		MOVWF	VAR_2_16BIT_L

		CALL	SUB_MATH_16BIT_SUBTRACT

		BTFSC	VAR_1_16BIT_H,7		;Check bit 7 of VAR_1,  and branch depending on which value was largest
		GOTO	VAR2_MAX				;This is needed for the magnitude approximation

;**********VAR1>=VAR2
VAR1_MAX

;The value in TEMP3 is the minimum of the two values

		MOVFW	VAR_TEMP3_H		
		MOVWF	VAR_1_16BIT_H
		MOVFW	VAR_TEMP3_L
		MOVWF	VAR_1_16BIT_L

;Divide the minimum value by 4	

		BCF		STATUS,C
		RRF		VAR_1_16BIT_H,F
		RRF		VAR_1_16BIT_L,F
		BCF		STATUS,C
		RRF		VAR_1_16BIT_H,F
		RRF		VAR_1_16BIT_L,F

;Add the max value to 1/4 of the min value (this is the magnitude approximation)

		MOVFW	VAR_TEMP2_H				
		MOVWF	VAR_2_16BIT_H
		MOVFW	VAR_TEMP2_L
		MOVWF	VAR_2_16BIT_L

		CALL	SUB_MATH_16BIT_ADD	

		GOTO	END_MAGNITUDE

;**********VAR1<VAR2
VAR2_MAX

;The value in TEMP2 is the minimum of the two values
		MOVFW	VAR_TEMP2_H
		MOVWF	VAR_1_16BIT_H
		MOVFW	VAR_TEMP2_L
		MOVWF	VAR_1_16BIT_L

;Divide the minimum value by 4	
	
		BCF		STATUS,C
		RRF		VAR_1_16BIT_H,F
		RRF		VAR_1_16BIT_L,F
		BCF		STATUS,C
		RRF		VAR_1_16BIT_H,F
		RRF		VAR_1_16BIT_L,F

;Add the max value to 1/4 of the min value (this is the magnitude approximation)
		MOVFW	VAR_TEMP3_H
		MOVWF	VAR_2_16BIT_H
		MOVFW	VAR_TEMP3_L
		MOVWF	VAR_2_16BIT_L

		CALL	SUB_MATH_16BIT_ADD	

END_MAGNITUDE

		RETURN					;Return from SUB_MATH_16BIT_MAGNITUDE
;**********************************************************************************************************************************
;       END of Subroutine SUB_MATH_16BIT_MAGNITUDE
;**********************************************************************************************************************************


;************************************************************************************************************************************
;Subroutine	SUB_GOERTZEL_SAMPLE
;This subroutine is the Goertzel routine itself.  It returns the magnitude of the response in the VAR_MAGNITUDE variable.
;************************************************************************************************************************************

SUB_GOERTZEL_SAMPLE

;Clear Y0, Y1, and Y2

		CLRF	VAR_Y0_A_H		
		CLRF	VAR_Y0_A_L
		CLRF	VAR_Y1_A_H
		CLRF	VAR_Y1_A_L
		CLRF	VAR_Y2_A_H
		CLRF	VAR_Y2_A_L
	
;Load sample counter with number of samples

		MOVLW	NUMBER_OF_SAMPLES
		MOVWF	VAR_SAMPLE_CTR

;Clear window counter

		CLRF	VAR_WINDOW_CTR

;Set the A/D converter to read from AN0 (audio input)

		BCF		ADCON0,CHS1
		BCF		ADCON0,CHS0

GOERTZEL_LOOP

		MOVLW 	B'00000000'		;Turn timer1 OFF, select 1:1 prescaler, use system clock
		MOVWF	T1CON

;Load the sample delay values into TMR1 high and low bytes

		MOVLW	SAMPLE_DELAY_H
		MOVWF	TMR1H
		MOVLW	SAMPLE_DELAY_L
		MOVWF	TMR1L

		BCF		PIR1,TMR1IF		;Make sure the overflow flag is cleared to begin
		BSF		T1CON,TMR1ON			;Turn on timer 1 by setting the TMR1ON bit in T1CON

;Copy Y1A to Y2A

		MOVFW	VAR_Y1_A_H					
		MOVWF	VAR_Y2_A_H
		MOVFW	VAR_Y1_A_L
		MOVWF	VAR_Y2_A_L

;Copy Y0A to Y1A

		MOVFW	VAR_Y0_A_H
		MOVWF	VAR_Y1_A_H
		MOVFW	VAR_Y0_A_L
		MOVWF	VAR_Y1_A_L


;Get sample from A/D

		CALL	SUB_ADC_READING

;Look up the window value for multiplication

		MOVFW	VAR_WINDOW_CTR
		MOVWF	VAR_TEXT_INDEX

		CALL	SUB_WINDOW_LOOKUP	;This routine takes 18 instruction cycles

		INCF	VAR_WINDOW_CTR,f

		MOVWF	VAR_2_16BIT_L
		CLRF	VAR_2_16BIT_H

;Multiply the A/D reading by the window value

		CALL	SUB_MATH_MULTIPLY	;This routine takes 130 instruction cycles max


;Store the X0 value for later

		MOVFW	VAR_1_16BIT_H		
		MOVWF	VAR_X0_H
		MOVFW	VAR_1_16BIT_L
		MOVWF	VAR_X0_L

;****Calculate Y0

;Y0 is given by the following formula: Y0=X0 + 2*COS_COEFF*Y1 - Y2
;First, take care of the second term, 2*COS_COEFF*Y1. 

		MOVFW	VAR_Y1_A_H		
		MOVWF	VAR_1_16BIT_H
		MOVFW	VAR_Y1_A_L		
		MOVWF	VAR_1_16BIT_L

		MOVFW	VAR_COS_COEFF
		MOVWF	VAR_2_16BIT_L
		CLRF	VAR_2_16BIT_H

		CALL	SUB_MATH_MULTIPLY_SIGNED

;Multiply the the result in VAR1 by 2 (shift to the left)

		BCF		STATUS,C
		RLF		VAR_1_16BIT_L,f
		RLF		VAR_1_16BIT_H,f

;The 2*COS_COEFF*Y1 value is now in VAR_1.  Next we will subtract Y2

		MOVFW	VAR_Y2_A_H		;Move Y2 into VAR_2_16BIT to prepare for calculating Y0
		MOVWF	VAR_2_16BIT_H
		MOVFW	VAR_Y2_A_L	
		MOVWF	VAR_2_16BIT_L

		CALL	SUB_MATH_16BIT_SUBTRACT	;This routine takes 10 instruction cycles

;The value in VAR_1 is now 2*COS_COEFF*Y1-Y2.  Next we will add X0

		MOVFW	VAR_X0_H		;Move Y2 into VAR_2_16BIT to prepare for calculating Y0
		MOVWF	VAR_2_16BIT_H
		MOVFW	VAR_X0_L	
		MOVWF	VAR_2_16BIT_L

		CALL	SUB_MATH_16BIT_ADD

;The result is in the VAR_1_16BIT variables.  Transfer to Y0

		MOVFW	VAR_1_16BIT_H	
		MOVWF	VAR_Y0_A_H
		MOVFW	VAR_1_16BIT_L
		MOVWF	VAR_Y0_A_L

;Poll timer 1 overflow to determine if delay is complete

WAIT_FOR_DELAY_COMPLETE

		BTFSS	PIR1,TMR1IF
		GOTO	WAIT_FOR_DELAY_COMPLETE

;Decrement sample counter, goto end if 0 is reached. Otherwise, go to start of sampling loop

		DECFSZ	VAR_SAMPLE_CTR,F
		GOTO	GOERTZEL_LOOP

;***********Calculate the real and imaginary values


;*****COMPUTE REAL PART
;The real part is REAL=Y1-Y2*COS_COEFF

;First, compute Y2*COS_COEFF

		MOVFW	VAR_Y2_A_H		
		MOVWF	VAR_1_16BIT_H
		MOVFW	VAR_Y2_A_L		
		MOVWF	VAR_1_16BIT_L

		MOVFW	VAR_COS_COEFF
		MOVWF	VAR_2_16BIT_L
		CLRF	VAR_2_16BIT_H

		CALL	SUB_MATH_MULTIPLY_SIGNED

;Now subtract the result from Y1

		MOVFW	VAR_1_16BIT_H		
		MOVWF	VAR_2_16BIT_H
		MOVFW	VAR_1_16BIT_L		
		MOVWF	VAR_2_16BIT_L

		MOVFW	VAR_Y1_A_H		
		MOVWF	VAR_1_16BIT_H
		MOVFW	VAR_Y1_A_L		
		MOVWF	VAR_1_16BIT_L

		CALL	SUB_MATH_16BIT_SUBTRACT

;Store the Real Part
		MOVFW	VAR_1_16BIT_H		
		MOVWF	VAR_REAL_H
		MOVFW	VAR_1_16BIT_L		
		MOVWF	VAR_REAL_L

;*****COMPUTE IMAGINARY PART
;The imaginary part is IMAG=Y2*SIN_COEFF

		MOVFW	VAR_Y2_A_H		
		MOVWF	VAR_1_16BIT_H
		MOVFW	VAR_Y2_A_L		
		MOVWF	VAR_1_16BIT_L

		MOVFW	VAR_SIN_COEFF
		MOVWF	VAR_2_16BIT_L
		CLRF	VAR_2_16BIT_H

		CALL	SUB_MATH_MULTIPLY_SIGNED

;Store the Imaginary Part
		MOVFW	VAR_1_16BIT_H		
		MOVWF	VAR_IMAG_H
		MOVFW	VAR_1_16BIT_L		
		MOVWF	VAR_IMAG_L

;Calculate the magnitude

		MOVFW	VAR_REAL_H
		MOVWF	VAR_1_16BIT_H
		MOVFW	VAR_REAL_L
		MOVWF	VAR_1_16BIT_L

		MOVFW	VAR_IMAG_H
		MOVWF	VAR_2_16BIT_H
		MOVFW	VAR_IMAG_L
		MOVWF	VAR_2_16BIT_L

		CALL	SUB_MATH_16BIT_MAGNITUDE

;Move the results into the variable VAR_MAGNITUDE

		MOVFW	VAR_1_16BIT_H
		MOVWF	VAR_MAGNITUDE_H
		MOVFW	VAR_1_16BIT_L
		MOVWF	VAR_MAGNITUDE_L

		RETURN					;Return from Subroutine SUB_GOERTZEL_SAMPLE
;************************************************************************************************************************************
;       END of Subroutine SUB_GOERTZEL_SAMPLE
;************************************************************************************************************************************


;**********************************************************************************************************************************
;Subroutine SUB_SER_DELAY
;This is a delay used for the bit timing of the serial transmit subroutine.  The value provides the correct timing for 9600 baud
;transmission when using an 8MHZ clock (2MHz instruction clock)
;**********************************************************************************************************************************

SUB_SER_DELAY
		nop
		movlw	BAUD_RATE_VAL
		movwf	VAR_SER_DELAY_CTR
SER_DELAY_LOOP
		nop
		decfsz	VAR_SER_DELAY_CTR,f
		goto	SER_DELAY_LOOP

		return					;Return from SUB_SER_DELAY
;**********************************************************************************************************************************
;       END of Subroutine SUB_SER_DELAY
;**********************************************************************************************************************************



;**********************************************************************************************************************************
; Subroutine SUB_SERIAL_TX
;This subroutine sends the byte contained in variable SER_DATA out through a port pin,
;one bit at a time.  The byte is sent least significant bit first.  The bits are
;preceded by a start bit (LOW) and ended with a stop bit (HIGH). 
;**********************************************************************************************************************************
SUB_SERIAL_TX

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;To deactivate the serial output function, I simply added a RETURN command at the beginning of this subroutine.
;That way, when the code tries to transmit a character, the code simply returns immediately.

		RETURN

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


;Check to see if serial transmission is enabled.  If it is not, skip to the end of the subroutine

		bcf		GPIO,SERIAL_OUT	;Transmit START bit (LOW)
		movlw	D'8'
		movwf	VAR_SER_BIT_CTR
		call	SUB_SER_DELAY
		nop		;these 4 nop instructions are to make the length of the start bit the same
		nop		;as all the other bits
		nop
		nop		

XMIT_DATA_BITS		
		btfss	VAR_SERIAL_DATA,0
		goto	BIT_LOW

;Code executes here if bit to xmit is a 1
		nop		
		bsf		GPIO,SERIAL_OUT
		goto	ROTATE

;Code jumps here if bit to xmit is a 0
BIT_LOW								
		bcf		GPIO,SERIAL_OUT
		nop						;Add 2 nop instructions to make both the low and high
		nop						;bit transmission take the same lenght of time
ROTATE
		rrf		VAR_SERIAL_DATA,f		;rotate the next bit into the LSB of SER_DATA
		call	SUB_SER_DELAY		;delay
	
		decfsz	VAR_SER_BIT_CTR,f	;Check to see if all data bits have been sent
		goto	XMIT_DATA_BITS

		nop		;these 4 nop instructions are to make the length of the last data bit the same
		nop		;as all the other bits
		nop
		nop	

		bsf		GPIO,SERIAL_OUT	;Transmit STOP bit (HIGH)
		call	SUB_SER_DELAY	


		RETURN					;Return from SUB_SERIAL_TX
;**********************************************************************************************************************************
;       END of Subroutine SUB_SERIAL_TX
;**********************************************************************************************************************************



;**********************************************************************************************************************************
; Subroutine SUB_ADC_READING
;This subroutine initiates an analog to digital conversion.  The correct analog channel must be selected before calling the 
;subroutine.  The value is returned via the VAR_1 variable.
;Total execution time = 58 instruction cycles, including call and return.
;**********************************************************************************************************************************

SUB_ADC_READING

;Start conversion by setting the GO/DONE bit in ADCON0 register
		BSF			ADCON0,GO_DONE

;Poll the go done bit.  The conversion is complete when the bit is cleared

POLL_GO_DONE_1

		BTFSC		ADCON0,GO_DONE
		GOTO		POLL_GO_DONE_1

;Read out the A/D value from ADRESH and ADRESL.

		MOVFW		ADRESH
		MOVWF		VAR_1_16BIT_H
	
;Change to bank 1 to read ASRESL

		BSF			STATUS,RP0
		MOVFW		ADRESL

;Change to bank 0 

		BCF			STATUS,RP0
		MOVWF		VAR_1_16BIT_L

		RETURN					;Return from SUB_ADC_READING
;**********************************************************************************************************************************
;       END of Subroutine SUB_ADC_READING
;**********************************************************************************************************************************



;**********************************************************************************************************************************
;Subroutine SUB_WINDOW_LOOKUP
;This subroutine is used to lookup the values of the window function.  These values are for a Hamming window
;Maximum execution time, including call and return = 18 instruction cycles
;**********************************************************************************************************************************
SUB_WINDOW_LOOKUP

		MOVFW	VAR_TEXT_INDEX
		MOVWF	VAR_TABLE_OFFSET

		MOVLW	low(SUB_WINDOW_TABLE+1)
		ADDWF	VAR_TABLE_OFFSET,F
		MOVLW	HIGH SUB_WINDOW_TABLE
		BTFSC	STATUS,C
		ADDLW	1
		MOVWF	PCLATH
		MOVF	VAR_TABLE_OFFSET,W
		CALL	SUB_WINDOW_TABLE

		RETURN					;Return from SUB_WINDOW_LOOKUP
;**********************************************************************************************************************************
;       END of Subroutine SUB_WINDOW_LOOKUP
;**********************************************************************************************************************************


;**********************************************************************************************************************************
;Subroutine SUB_WINDOW_TABLE
;This subroutine is called by subroutine SUB_WINDOW_LOOKUP.  The value will be in the
;W register when this subroutine returns.
;**********************************************************************************************************************************
SUB_WINDOW_TABLE	
	
		MOVWF	PCL	
	
		RETLW		D'5'
		RETLW		D'5'
		RETLW		D'5'
		RETLW		D'5'
		RETLW		D'5'
		RETLW		D'5'
		RETLW		D'6'
		RETLW		D'6'
		RETLW		D'6'
		RETLW		D'6'
		RETLW		D'7'
		RETLW		D'7'
		RETLW		D'7'
		RETLW		D'8'
		RETLW		D'8'
		RETLW		D'8'
		RETLW		D'9'
		RETLW		D'9'
		RETLW		D'10'
		RETLW		D'10'
		RETLW		D'11'
		RETLW		D'11'
		RETLW		D'12'
		RETLW		D'12'
		RETLW		D'13'
		RETLW		D'14'
		RETLW		D'14'
		RETLW		D'15'
		RETLW		D'16'
		RETLW		D'17'
		RETLW		D'17'
		RETLW		D'18'
		RETLW		D'19'
		RETLW		D'20'
		RETLW		D'20'
		RETLW		D'21'
		RETLW		D'22'
		RETLW		D'23'
		RETLW		D'24'
		RETLW		D'25'
		RETLW		D'25'
		RETLW		D'26'
		RETLW		D'27'
		RETLW		D'28'
		RETLW		D'29'
		RETLW		D'30'
		RETLW		D'31'
		RETLW		D'32'
		RETLW		D'33'
		RETLW		D'34'
		RETLW		D'35'
		RETLW		D'35'
		RETLW		D'36'
		RETLW		D'37'
		RETLW		D'38'
		RETLW		D'39'
		RETLW		D'40'
		RETLW		D'41'
		RETLW		D'42'
		RETLW		D'43'
		RETLW		D'44'
		RETLW		D'45'
		RETLW		D'45'
		RETLW		D'46'
		RETLW		D'47'
		RETLW		D'48'
		RETLW		D'49'
		RETLW		D'50'
		RETLW		D'50'
		RETLW		D'51'
		RETLW		D'52'
		RETLW		D'53'
		RETLW		D'53'
		RETLW		D'54'
		RETLW		D'55'
		RETLW		D'55'
		RETLW		D'56'
		RETLW		D'57'
		RETLW		D'57'
		RETLW		D'58'
		RETLW		D'58'
		RETLW		D'59'
		RETLW		D'59'
		RETLW		D'60'
		RETLW		D'60'
		RETLW		D'61'
		RETLW		D'61'
		RETLW		D'62'
		RETLW		D'62'
		RETLW		D'62'
		RETLW		D'63'
		RETLW		D'63'
		RETLW		D'63'
		RETLW		D'63'
		RETLW		D'63'
		RETLW		D'64'
		RETLW		D'64'
		RETLW		D'64'
		RETLW		D'64'
		RETLW		D'64'
		RETLW		D'64'
		RETLW		D'64'
		RETLW		D'64'
		RETLW		D'64'
		RETLW		D'64'
		RETLW		D'64'
		RETLW		D'63'
		RETLW		D'63'
		RETLW		D'63'
		RETLW		D'63'
		RETLW		D'63'
		RETLW		D'62'
		RETLW		D'62'
		RETLW		D'62'
		RETLW		D'61'
		RETLW		D'61'
		RETLW		D'60'
		RETLW		D'60'
		RETLW		D'59'
		RETLW		D'59'
		RETLW		D'58'
		RETLW		D'58'
		RETLW		D'57'
		RETLW		D'57'
		RETLW		D'56'
		RETLW		D'55'
		RETLW		D'55'
		RETLW		D'54'
		RETLW		D'53'
		RETLW		D'53'
		RETLW		D'52'
		RETLW		D'51'
		RETLW		D'50'
		RETLW		D'50'
		RETLW		D'49'
		RETLW		D'48'
		RETLW		D'47'
		RETLW		D'46'
		RETLW		D'45'
		RETLW		D'45'
		RETLW		D'44'
		RETLW		D'43'
		RETLW		D'42'
		RETLW		D'41'
		RETLW		D'40'
		RETLW		D'39'
		RETLW		D'38'
		RETLW		D'37'
		RETLW		D'36'
		RETLW		D'35'
		RETLW		D'35'
		RETLW		D'34'
		RETLW		D'33'
		RETLW		D'32'
		RETLW		D'31'
		RETLW		D'30'
		RETLW		D'29'
		RETLW		D'28'
		RETLW		D'27'
		RETLW		D'26'
		RETLW		D'25'
		RETLW		D'25'
		RETLW		D'24'
		RETLW		D'23'
		RETLW		D'22'
		RETLW		D'21'
		RETLW		D'20'
		RETLW		D'20'
		RETLW		D'19'
		RETLW		D'18'
		RETLW		D'17'
		RETLW		D'17'
		RETLW		D'16'
		RETLW		D'15'
		RETLW		D'14'
		RETLW		D'14'
		RETLW		D'13'
		RETLW		D'12'
		RETLW		D'12'
		RETLW		D'11'
		RETLW		D'11'
		RETLW		D'10'
		RETLW		D'10'
		RETLW		D'9'
		RETLW		D'9'
		RETLW		D'8'
		RETLW		D'8'
		RETLW		D'8'
		RETLW		D'7'
		RETLW		D'7'
		RETLW		D'7'
		RETLW		D'6'
		RETLW		D'6'
		RETLW		D'6'
		RETLW		D'6'
		RETLW		D'5'
		RETLW		D'5'
		RETLW		D'5'
		RETLW		D'5'
		RETLW		D'5'

;**********************************************************************************************************************************
;       END of Subroutine SUB_WINDOW_TABLE
;**********************************************************************************************************************************


;**********************************************************************************************************************************
; Subroutine SUB_16BIT_TO_DECIMAL
;This subroutine converts a 16 bit binary number into a 5 digit decimal number (leading zeros are included)
;
;**********************************************************************************************************************************

SUB_16BIT_TO_DECIMAL

		MOVFW	FSR								;Store the FSR register to a temp file so it can be restored before returning from subroutine
		MOVWF	VAR_FSR_TEMP

		MOVLW	DECIMAL_DIGITS					;Point the FSR at the first decimal digit location in RAM
		MOVWF	FSR

		MOVLW	D'5'							;load the counter with the number of digits to convert (in this case it is 5)
		MOVWF	VAL_DECIMAL_CONVERSION_CTR

		CLRF	VAR_TEXT_INDEX					;set the lookup index for the constants to zero to begin

DECIMAL_CONVERSION_LOOP1

		CALL	SUB_DEC_CONV_CONST_LOOKUP		;Look up the high byte of the constant and store it in VAR_2
		MOVWF	VAR_2_16BIT_H
		INCF	VAR_TEXT_INDEX,f
		CALL	SUB_DEC_CONV_CONST_LOOKUP		;Look up the high byte of the constant and store it in VAR_2
		MOVWF	VAR_2_16BIT_L
		INCF	VAR_TEXT_INDEX,f

		CLRF	INDF							;Set the decimal digit value to zero to begin

DECIMAL_CONVERSION_LOOP2

		CALL	SUB_MATH_16BIT_SUBTRACT		;Subtract the constant from VAR_1

		BTFSC	VAR_1_16BIT_H,7					;if the result is negative, the constant needs to be added back
		GOTO	ADD_BACK
		INCF	INDF,f							;if the result is not negative, increment the decimal digit and go through loop2 again

		GOTO	DECIMAL_CONVERSION_LOOP2

ADD_BACK	
		CALL	SUB_MATH_16BIT_ADD				;Add back the constant
		
		MOVLW	H'30'
		IORWF	INDF,f							;Make the upper nibble = 3 so that it is a valid ASCII char for the decimal digit
		INCF	FSR,F							;incrment the FSR to point to the next memory location for the next decimal digit
		DECFSZ	VAL_DECIMAL_CONVERSION_CTR,f	;if all digits have been determined, restore FSR and return
	
		GOTO	DECIMAL_CONVERSION_LOOP1		;if more digits remain to convert, go through loop 1 again.
	
		MOVFW	VAR_FSR_TEMP					;Restore the FSR value 
		MOVWF	FSR

		RETURN

;**********************************************************************************************************************************
;       END of Subroutine SUB_16BIT_TO_DECIMAL
;**********************************************************************************************************************************


;**********************************************************************************************************************************
;Subroutine SUB_DEC_CONV_CONST_LOOKUP
;This subroutine is used to lookup values used in the subroutine that converts a 16 bit binary number into a 5 digit decimal number.
;**********************************************************************************************************************************
SUB_DEC_CONV_CONST_LOOKUP

		MOVFW	VAR_TEXT_INDEX
		MOVWF	VAR_TABLE_OFFSET

		MOVLW	LOW	(SUB_DEC_CONV_CONST_TABLE + 1)
		ADDWF	VAR_TABLE_OFFSET,F
		MOVLW	HIGH SUB_DEC_CONV_CONST_TABLE
		BTFSC	STATUS,C
		ADDLW	1
		MOVWF	PCLATH
		MOVF	VAR_TABLE_OFFSET,W
		CALL	SUB_DEC_CONV_CONST_TABLE

		RETURN					;Return from SUB_DEC_CONV_CONST_LOOKUP

;**********************************************************************************************************************************
;       END of Subroutine SUB_DEC_CONV_CONST_LOOKUP
;**********************************************************************************************************************************

;**********************************************************************************************************************************
;Subroutine SUB_DEC_CONV_CONST_TABLE
;This subroutine is called by subroutine SUB_DEC_CONV_CONST_LOOKUP.  The character will be in the
;W register when this subroutine returns.
;**********************************************************************************************************************************
SUB_DEC_CONV_CONST_TABLE		
		MOVWF	PCL	

		RETLW	H'27'		;Ten thousand					
		RETLW	H'10'
		RETLW	H'03'		;One thousand					
		RETLW	H'E8'
		RETLW	H'00'		;One Hundred					
		RETLW	H'64'
		RETLW	H'00'			;Ten					
		RETLW	H'0A'
		RETLW	H'00'			;One					
		RETLW	H'01'

;**********************************************************************************************************************************
;       END of Subroutine SUB_DEC_CONV_CONST_TABLE
;**********************************************************************************************************************************



;**********************************************************************************************************************************
;Subroutine SUB_AVG_ANALOG_READING
;This routine reads the analog input (selected before the routine is called) 8 times and returns the average via the VAR_1 variable
;**********************************************************************************************************************************

SUB_AVG_ANALOG_READING

		CLRF	VAR_2_16BIT_H
		CLRF	VAR_2_16BIT_L

		MOVLW	D'8'
		MOVWF	VAR_AVG_CTR

READ_ADC_FOR_AVERAGE

		CALL	SUB_DELAY_500_MICROSEC

;Read the A/D input to get the setting of the frequency select input

;Get sample from A/D

		CALL	SUB_ADC_READING

		CALL	SUB_MATH_16BIT_ADD

		MOVFW	VAR_1_16BIT_H
		MOVWF	VAR_2_16BIT_H

		MOVFW	VAR_1_16BIT_L
		MOVWF	VAR_2_16BIT_L

		DECFSZ	VAR_AVG_CTR,f
		GOTO	READ_ADC_FOR_AVERAGE

;Divide the total by 8 to get the average

		BCF		STATUS,C
		RRF		VAR_1_16BIT_H,F
		RRF		VAR_1_16BIT_L,F
		BCF		STATUS,C
		RRF		VAR_1_16BIT_H,F
		RRF		VAR_1_16BIT_L,F
		BCF		STATUS,C
		RRF		VAR_1_16BIT_H,F
		RRF		VAR_1_16BIT_L,F

		RETURN					;Return from SUB_AVG_ANALOG_READING
;**********************************************************************************************************************************
;       END of Subroutine SUB_AVG_ANALOG_READING
;**********************************************************************************************************************************



;**********************************************************************************************************************************
;Subroutine SUB_CONVERT_AND_TRANSMIT
;This routine converts a 16 bit number in VAR_1 to its ASCII decimal, and then transmits them over the serial output
;**********************************************************************************************************************************

SUB_CONVERT_AND_TRANSMIT

		CALL	SUB_16BIT_TO_DECIMAL

		MOVFW	DECIMAL_DIGITS
		MOVWF	VAR_SERIAL_DATA
		CALL	SUB_SERIAL_TX
		MOVFW	DECIMAL_DIGITS+1
		MOVWF	VAR_SERIAL_DATA
		CALL	SUB_SERIAL_TX
		MOVFW	DECIMAL_DIGITS+2
		MOVWF	VAR_SERIAL_DATA
		CALL	SUB_SERIAL_TX
		MOVFW	DECIMAL_DIGITS+3
		MOVWF	VAR_SERIAL_DATA
		CALL	SUB_SERIAL_TX
		MOVFW	DECIMAL_DIGITS+4
		MOVWF	VAR_SERIAL_DATA
		CALL	SUB_SERIAL_TX
		MOVLW	','
		MOVWF	VAR_SERIAL_DATA
		CALL	SUB_SERIAL_TX

		RETURN

;**********************************************************************************************************************************
;       END of Subroutine SUB_CONVERT_AND_TRANSMIT
;**********************************************************************************************************************************



;**********************************************************************************************************************************
;Subroutine SUB_COS_COEFF_0_LOOKUP
;This subroutine is used to lookup values 
;**********************************************************************************************************************************
SUB_COS_COEFF_0_LOOKUP

		MOVFW	VAR_TEXT_INDEX
		MOVWF	VAR_TABLE_OFFSET

		MOVLW	LOW	(SUB_COS_COEFF_0_TABLE + 1)
		ADDWF	VAR_TABLE_OFFSET,F
		MOVLW	HIGH SUB_COS_COEFF_0_TABLE
		BTFSC	STATUS,C
		ADDLW	1
		MOVWF	PCLATH
		MOVF	VAR_TABLE_OFFSET,W
		CALL	SUB_COS_COEFF_0_TABLE

		RETURN					;Return from SUB_COS_COEFF_0_LOOKUP

;**********************************************************************************************************************************
;       END of Subroutine SUB_COS_COEFF_0_LOOKUP
;**********************************************************************************************************************************



;**********************************************************************************************************************************
;Subroutine SUB_COS_COEFF_0_TABLE
;This subroutine is called by subroutine SUB_COS_COEFF_0_LOOKUP.  The character will be in the
;W register when this subroutine returns.
;**********************************************************************************************************************************
SUB_COS_COEFF_0_TABLE		
		MOVWF	PCL	
	
		RETLW		D'63'		;100 Hz
		RETLW		D'63'		;104 Hz
		RETLW		D'63'		;108 Hz
		RETLW		D'63'		;112 Hz
		RETLW		D'63'		;116 Hz
		RETLW		D'63'		;120 Hz
		RETLW		D'63'		;124 Hz
		RETLW		D'63'		;128 Hz
		RETLW		D'63'		;132 Hz
		RETLW		D'63'		;136 Hz
		RETLW		D'63'		;140 Hz
		RETLW		D'63'		;144 Hz
		RETLW		D'63'		;148 Hz
		RETLW		D'62'		;152 Hz
		RETLW		D'62'		;156 Hz
		RETLW		D'62'		;160 Hz
		RETLW		D'62'		;164 Hz
		RETLW		D'62'		;168 Hz
		RETLW		D'62'		;172 Hz
		RETLW		D'62'		;176 Hz
		RETLW		D'62'		;180 Hz
		RETLW		D'62'		;184 Hz
		RETLW		D'62'		;188 Hz
		RETLW		D'62'		;192 Hz
		RETLW		D'62'		;196 Hz
		RETLW		D'61'		;200 Hz
		RETLW		D'61'		;204 Hz
		RETLW		D'61'		;208 Hz
		RETLW		D'61'		;212 Hz
		RETLW		D'61'		;216 Hz
		RETLW		D'61'		;220 Hz
		RETLW		D'61'		;224 Hz
		RETLW		D'61'		;228 Hz
		RETLW		D'61'		;232 Hz
		RETLW		D'60'		;236 Hz
		RETLW		D'60'		;240 Hz
		RETLW		D'60'		;244 Hz
		RETLW		D'60'		;248 Hz
		RETLW		D'60'		;252 Hz
		RETLW		D'60'		;256 Hz
		RETLW		D'60'		;260 Hz
		RETLW		D'60'		;264 Hz
		RETLW		D'59'		;268 Hz
		RETLW		D'59'		;272 Hz
		RETLW		D'59'		;276 Hz
		RETLW		D'59'		;280 Hz
		RETLW		D'59'		;284 Hz
		RETLW		D'59'		;288 Hz
		RETLW		D'59'		;292 Hz
		RETLW		D'58'		;296 Hz
		RETLW		D'58'		;300 Hz
		RETLW		D'58'		;304 Hz
		RETLW		D'58'		;308 Hz
		RETLW		D'58'		;312 Hz
		RETLW		D'58'		;316 Hz
		RETLW		D'57'		;320 Hz
		RETLW		D'57'		;324 Hz
		RETLW		D'57'		;328 Hz
		RETLW		D'57'		;332 Hz
		RETLW		D'57'		;336 Hz
		RETLW		D'57'		;340 Hz
		RETLW		D'56'		;344 Hz
		RETLW		D'56'		;348 Hz
		RETLW		D'56'		;352 Hz
		RETLW		D'56'		;356 Hz
		RETLW		D'56'		;360 Hz
		RETLW		D'56'		;364 Hz
		RETLW		D'55'		;368 Hz
		RETLW		D'55'		;372 Hz
		RETLW		D'55'		;376 Hz
		RETLW		D'55'		;380 Hz
		RETLW		D'55'		;384 Hz
		RETLW		D'54'		;388 Hz
		RETLW		D'54'		;392 Hz
		RETLW		D'54'		;396 Hz
		RETLW		D'54'		;400 Hz
		RETLW		D'54'		;404 Hz
		RETLW		D'53'		;408 Hz
		RETLW		D'53'		;412 Hz
		RETLW		D'53'		;416 Hz
		RETLW		D'53'		;420 Hz
		RETLW		D'53'		;424 Hz
		RETLW		D'52'		;428 Hz
		RETLW		D'52'		;432 Hz
		RETLW		D'52'		;436 Hz
		RETLW		D'52'		;440 Hz
		RETLW		D'52'		;444 Hz
		RETLW		D'51'		;448 Hz
		RETLW		D'51'		;452 Hz
		RETLW		D'51'		;456 Hz
		RETLW		D'51'		;460 Hz
		RETLW		D'50'		;464 Hz
		RETLW		D'50'		;468 Hz
		RETLW		D'50'		;472 Hz
		RETLW		D'50'		;476 Hz
		RETLW		D'50'		;480 Hz
		RETLW		D'49'		;484 Hz
		RETLW		D'49'		;488 Hz
		RETLW		D'49'		;492 Hz
		RETLW		D'49'		;496 Hz
		RETLW		D'48'		;500 Hz
		RETLW		D'48'		;504 Hz
		RETLW		D'48'		;508 Hz
		RETLW		D'48'		;512 Hz
		RETLW		D'47'		;516 Hz
		RETLW		D'47'		;520 Hz
		RETLW		D'47'		;524 Hz
		RETLW		D'47'		;528 Hz
		RETLW		D'46'		;532 Hz
		RETLW		D'46'		;536 Hz
		RETLW		D'46'		;540 Hz
		RETLW		D'46'		;544 Hz
		RETLW		D'45'		;548 Hz
		RETLW		D'45'		;552 Hz
		RETLW		D'45'		;556 Hz
		RETLW		D'45'		;560 Hz
		RETLW		D'44'		;564 Hz
		RETLW		D'44'		;568 Hz
		RETLW		D'44'		;572 Hz
		RETLW		D'44'		;576 Hz
		RETLW		D'43'		;580 Hz
		RETLW		D'43'		;584 Hz
		RETLW		D'43'		;588 Hz
		RETLW		D'42'		;592 Hz
		RETLW		D'42'		;596 Hz
		RETLW		D'42'		;600 Hz
		RETLW		D'42'		;604 Hz
		RETLW		D'41'		;608 Hz
		RETLW		D'41'		;612 Hz
		RETLW		D'41'		;616 Hz
		RETLW		D'41'		;620 Hz
		RETLW		D'40'		;624 Hz
		RETLW		D'40'		;628 Hz
		RETLW		D'40'		;632 Hz
		RETLW		D'39'		;636 Hz
		RETLW		D'39'		;640 Hz
		RETLW		D'39'		;644 Hz
		RETLW		D'38'		;648 Hz
		RETLW		D'38'		;652 Hz
		RETLW		D'38'		;656 Hz
		RETLW		D'38'		;660 Hz
		RETLW		D'37'		;664 Hz
		RETLW		D'37'		;668 Hz
		RETLW		D'37'		;672 Hz
		RETLW		D'36'		;676 Hz
		RETLW		D'36'		;680 Hz
		RETLW		D'36'		;684 Hz
		RETLW		D'36'		;688 Hz
		RETLW		D'35'		;692 Hz
		RETLW		D'35'		;696 Hz
		RETLW		D'35'		;700 Hz
		RETLW		D'34'		;704 Hz
		RETLW		D'34'		;708 Hz
		RETLW		D'34'		;712 Hz
		RETLW		D'33'		;716 Hz
		RETLW		D'33'		;720 Hz
		RETLW		D'33'		;724 Hz
		RETLW		D'32'		;728 Hz
		RETLW		D'32'		;732 Hz
		RETLW		D'32'		;736 Hz
		RETLW		D'31'		;740 Hz
		RETLW		D'31'		;744 Hz
		RETLW		D'31'		;748 Hz
		RETLW		D'31'		;752 Hz
		RETLW		D'30'		;756 Hz
		RETLW		D'30'		;760 Hz
		RETLW		D'30'		;764 Hz
		RETLW		D'29'		;768 Hz
		RETLW		D'29'		;772 Hz
		RETLW		D'29'		;776 Hz
		RETLW		D'28'		;780 Hz
		RETLW		D'28'		;784 Hz
		RETLW		D'28'		;788 Hz
		RETLW		D'27'		;792 Hz
		RETLW		D'27'		;796 Hz
		RETLW		D'27'		;800 Hz
		RETLW		D'26'		;804 Hz
		RETLW		D'26'		;808 Hz
		RETLW		D'26'		;812 Hz
		RETLW		D'25'		;816 Hz
		RETLW		D'25'		;820 Hz
		RETLW		D'25'		;824 Hz
		RETLW		D'24'		;828 Hz
		RETLW		D'24'		;832 Hz
		RETLW		D'24'		;836 Hz
		RETLW		D'23'		;840 Hz
		RETLW		D'23'		;844 Hz
		RETLW		D'23'		;848 Hz
		RETLW		D'22'		;852 Hz
		RETLW		D'22'		;856 Hz
		RETLW		D'22'		;860 Hz
		RETLW		D'21'		;864 Hz
		RETLW		D'21'		;868 Hz
		RETLW		D'20'		;872 Hz
		RETLW		D'20'		;876 Hz
		RETLW		D'20'		;880 Hz
		RETLW		D'19'		;884 Hz
		RETLW		D'19'		;888 Hz
		RETLW		D'19'		;892 Hz
		RETLW		D'18'		;896 Hz
		RETLW		D'18'		;900 Hz
		RETLW		D'18'		;904 Hz
		RETLW		D'17'		;908 Hz
		RETLW		D'17'		;912 Hz
		RETLW		D'17'		;916 Hz
		RETLW		D'16'		;920 Hz
		RETLW		D'16'		;924 Hz
		RETLW		D'16'		;928 Hz
		RETLW		D'15'		;932 Hz
		RETLW		D'15'		;936 Hz
		RETLW		D'14'		;940 Hz
		RETLW		D'14'		;944 Hz
		RETLW		D'14'		;948 Hz
		RETLW		D'13'		;952 Hz
		RETLW		D'13'		;956 Hz
		RETLW		D'13'		;960 Hz
		RETLW		D'12'		;964 Hz
		RETLW		D'12'		;968 Hz
		RETLW		D'12'		;972 Hz
		RETLW		D'11'		;976 Hz
		RETLW		D'11'		;980 Hz
		RETLW		D'11'		;984 Hz
		RETLW		D'10'		;988 Hz
		RETLW		D'10'		;992 Hz
		RETLW		D'9'		;996 Hz
		RETLW		D'9'		;1000 Hz
		RETLW		D'9'		;1004 Hz
		RETLW		D'8'		;1008 Hz
		RETLW		D'8'		;1012 Hz
		RETLW		D'8'		;1016 Hz
		RETLW		D'7'		;1020 Hz
		RETLW		D'7'		;1024 Hz
		RETLW		D'7'		;1028 Hz
		RETLW		D'6'		;1032 Hz
		RETLW		D'6'		;1036 Hz
		RETLW		D'5'		;1040 Hz
		RETLW		D'5'		;1044 Hz
		RETLW		D'5'		;1048 Hz
		RETLW		D'4'		;1052 Hz
		RETLW		D'4'		;1056 Hz
		RETLW		D'4'		;1060 Hz
		RETLW		D'3'		;1064 Hz
		RETLW		D'3'		;1068 Hz
		RETLW		D'3'		;1072 Hz
		RETLW		D'2'		;1076 Hz
		RETLW		D'2'		;1080 Hz
		RETLW		D'1'		;1084 Hz
		RETLW		D'1'		;1088 Hz
		RETLW		D'1'		;1092 Hz
		RETLW		D'0'		;1096 Hz
		RETLW		D'0'		;1100 Hz
		RETLW		D'0'		;1104 Hz
		RETLW		D'129'		;1108 Hz
		RETLW		D'129'		;1112 Hz
		RETLW		D'129'		;1116 Hz
		RETLW		D'130'		;1120 Hz
	
;**********************************************************************************************************************************
;       END of Subroutine SUB_COS_COEFF_0_TABLE
;**********************************************************************************************************************************

	
	
;**********************************************************************************************************************************
;Subroutine SUB_COS_COEFF_1_LOOKUP
;This subroutine is used to lookup values 
;**********************************************************************************************************************************
SUB_COS_COEFF_1_LOOKUP

		MOVFW	VAR_TEXT_INDEX
		MOVWF	VAR_TABLE_OFFSET

		MOVLW	LOW	(SUB_COS_COEFF_1_TABLE + 1)
		ADDWF	VAR_TABLE_OFFSET,F
		MOVLW	HIGH SUB_COS_COEFF_1_TABLE
		BTFSC	STATUS,C
		ADDLW	1
		MOVWF	PCLATH
		MOVF	VAR_TABLE_OFFSET,W
		CALL	SUB_COS_COEFF_1_TABLE

		RETURN					;Return from SUB_COS_COEFF_1_LOOKUP
;**********************************************************************************************************************************
;       END of Subroutine SUB_COS_COEFF_1_LOOKUP
;**********************************************************************************************************************************


;**********************************************************************************************************************************
;Subroutine SUB_COS_COEFF_1_TABLE
;This subroutine is called by subroutine SUB_COS_COEFF_1_LOOKUP.  The character will be in the
;W register when this subroutine returns.
;**********************************************************************************************************************************
SUB_COS_COEFF_1_TABLE
		
		MOVWF	PCL	

		RETLW		D'130'		;1124 Hz
		RETLW		D'131'		;1128 Hz
		RETLW		D'131'		;1132 Hz
		RETLW		D'131'		;1136 Hz
		RETLW		D'132'		;1140 Hz
		RETLW		D'132'		;1144 Hz
		RETLW		D'132'		;1148 Hz
		RETLW		D'133'		;1152 Hz
		RETLW		D'133'		;1156 Hz
		RETLW		D'133'		;1160 Hz
		RETLW		D'134'		;1164 Hz
		RETLW		D'134'		;1168 Hz
		RETLW		D'135'		;1172 Hz
		RETLW		D'135'		;1176 Hz
		RETLW		D'135'		;1180 Hz
		RETLW		D'136'		;1184 Hz
		RETLW		D'136'		;1188 Hz
		RETLW		D'136'		;1192 Hz
		RETLW		D'137'		;1196 Hz
		RETLW		D'137'		;1200 Hz
		RETLW		D'137'		;1204 Hz
		RETLW		D'138'		;1208 Hz
		RETLW		D'138'		;1212 Hz
		RETLW		D'139'		;1216 Hz
		RETLW		D'139'		;1220 Hz
		RETLW		D'139'		;1224 Hz
		RETLW		D'140'		;1228 Hz
		RETLW		D'140'		;1232 Hz
		RETLW		D'140'		;1236 Hz
		RETLW		D'141'		;1240 Hz
		RETLW		D'141'		;1244 Hz
		RETLW		D'141'		;1248 Hz
		RETLW		D'142'		;1252 Hz
		RETLW		D'142'		;1256 Hz
		RETLW		D'142'		;1260 Hz
		RETLW		D'143'		;1264 Hz
		RETLW		D'143'		;1268 Hz
		RETLW		D'144'		;1272 Hz
		RETLW		D'144'		;1276 Hz
		RETLW		D'144'		;1280 Hz
		RETLW		D'145'		;1284 Hz
		RETLW		D'145'		;1288 Hz
		RETLW		D'145'		;1292 Hz
		RETLW		D'146'		;1296 Hz
		RETLW		D'146'		;1300 Hz
		RETLW		D'146'		;1304 Hz
		RETLW		D'147'		;1308 Hz
		RETLW		D'147'		;1312 Hz
		RETLW		D'147'		;1316 Hz
		RETLW		D'148'		;1320 Hz
		RETLW		D'148'		;1324 Hz
		RETLW		D'148'		;1328 Hz
		RETLW		D'149'		;1332 Hz
		RETLW		D'149'		;1336 Hz
		RETLW		D'150'		;1340 Hz
		RETLW		D'150'		;1344 Hz
		RETLW		D'150'		;1348 Hz
		RETLW		D'151'		;1352 Hz
		RETLW		D'151'		;1356 Hz
		RETLW		D'151'		;1360 Hz
		RETLW		D'152'		;1364 Hz
		RETLW		D'152'		;1368 Hz
		RETLW		D'152'		;1372 Hz
		RETLW		D'153'		;1376 Hz
		RETLW		D'153'		;1380 Hz
		RETLW		D'153'		;1384 Hz
		RETLW		D'154'		;1388 Hz
		RETLW		D'154'		;1392 Hz
		RETLW		D'154'		;1396 Hz
		RETLW		D'155'		;1400 Hz
		RETLW		D'155'		;1404 Hz
		RETLW		D'155'		;1408 Hz
		RETLW		D'156'		;1412 Hz
		RETLW		D'156'		;1416 Hz
		RETLW		D'156'		;1420 Hz
		RETLW		D'157'		;1424 Hz
		RETLW		D'157'		;1428 Hz
		RETLW		D'157'		;1432 Hz
		RETLW		D'158'		;1436 Hz
		RETLW		D'158'		;1440 Hz
		RETLW		D'158'		;1444 Hz
		RETLW		D'159'		;1448 Hz
		RETLW		D'159'		;1452 Hz
		RETLW		D'159'		;1456 Hz
		RETLW		D'159'		;1460 Hz
		RETLW		D'160'		;1464 Hz
		RETLW		D'160'		;1468 Hz
		RETLW		D'160'		;1472 Hz
		RETLW		D'161'		;1476 Hz
		RETLW		D'161'		;1480 Hz
		RETLW		D'161'		;1484 Hz
		RETLW		D'162'		;1488 Hz
		RETLW		D'162'		;1492 Hz
		RETLW		D'162'		;1496 Hz
		RETLW		D'163'		;1500 Hz
		RETLW		D'163'		;1504 Hz
		RETLW		D'163'		;1508 Hz
		RETLW		D'164'		;1512 Hz
		RETLW		D'164'		;1516 Hz
		RETLW		D'164'		;1520 Hz
		RETLW		D'164'		;1524 Hz
		RETLW		D'165'		;1528 Hz
		RETLW		D'165'		;1532 Hz
		RETLW		D'165'		;1536 Hz
		RETLW		D'166'		;1540 Hz
		RETLW		D'166'		;1544 Hz
		RETLW		D'166'		;1548 Hz
		RETLW		D'166'		;1552 Hz
		RETLW		D'167'		;1556 Hz
		RETLW		D'167'		;1560 Hz
		RETLW		D'167'		;1564 Hz
		RETLW		D'168'		;1568 Hz
		RETLW		D'168'		;1572 Hz
		RETLW		D'168'		;1576 Hz
		RETLW		D'169'		;1580 Hz
		RETLW		D'169'		;1584 Hz
		RETLW		D'169'		;1588 Hz
		RETLW		D'169'		;1592 Hz
		RETLW		D'170'		;1596 Hz
		RETLW		D'170'		;1600 Hz
		RETLW		D'170'		;1604 Hz
		RETLW		D'170'		;1608 Hz
		RETLW		D'171'		;1612 Hz
		RETLW		D'171'		;1616 Hz
		RETLW		D'171'		;1620 Hz
		RETLW		D'172'		;1624 Hz
		RETLW		D'172'		;1628 Hz
		RETLW		D'172'		;1632 Hz
		RETLW		D'172'		;1636 Hz
		RETLW		D'173'		;1640 Hz
		RETLW		D'173'		;1644 Hz
		RETLW		D'173'		;1648 Hz
		RETLW		D'173'		;1652 Hz
		RETLW		D'174'		;1656 Hz
		RETLW		D'174'		;1660 Hz
		RETLW		D'174'		;1664 Hz
		RETLW		D'174'		;1668 Hz
		RETLW		D'175'		;1672 Hz
		RETLW		D'175'		;1676 Hz
		RETLW		D'175'		;1680 Hz
		RETLW		D'175'		;1684 Hz
		RETLW		D'176'		;1688 Hz
		RETLW		D'176'		;1692 Hz
		RETLW		D'176'		;1696 Hz
		RETLW		D'176'		;1700 Hz
		RETLW		D'177'		;1704 Hz
		RETLW		D'177'		;1708 Hz
		RETLW		D'177'		;1712 Hz
		RETLW		D'177'		;1716 Hz
		RETLW		D'178'		;1720 Hz
		RETLW		D'178'		;1724 Hz
		RETLW		D'178'		;1728 Hz
		RETLW		D'178'		;1732 Hz
		RETLW		D'178'		;1736 Hz
		RETLW		D'179'		;1740 Hz
		RETLW		D'179'		;1744 Hz
		RETLW		D'179'		;1748 Hz
		RETLW		D'179'		;1752 Hz
		RETLW		D'180'		;1756 Hz
		RETLW		D'180'		;1760 Hz
		RETLW		D'180'		;1764 Hz
		RETLW		D'180'		;1768 Hz
		RETLW		D'180'		;1772 Hz
		RETLW		D'181'		;1776 Hz
		RETLW		D'181'		;1780 Hz
		RETLW		D'181'		;1784 Hz
		RETLW		D'181'		;1788 Hz
		RETLW		D'181'		;1792 Hz
		RETLW		D'182'		;1796 Hz
		RETLW		D'182'		;1800 Hz
		RETLW		D'182'		;1804 Hz
		RETLW		D'182'		;1808 Hz
		RETLW		D'182'		;1812 Hz
		RETLW		D'183'		;1816 Hz
		RETLW		D'183'		;1820 Hz
		RETLW		D'183'		;1824 Hz
		RETLW		D'183'		;1828 Hz
		RETLW		D'183'		;1832 Hz
		RETLW		D'184'		;1836 Hz
		RETLW		D'184'		;1840 Hz
		RETLW		D'184'		;1844 Hz
		RETLW		D'184'		;1848 Hz
		RETLW		D'184'		;1852 Hz
		RETLW		D'184'		;1856 Hz
		RETLW		D'185'		;1860 Hz
		RETLW		D'185'		;1864 Hz
		RETLW		D'185'		;1868 Hz
		RETLW		D'185'		;1872 Hz
		RETLW		D'185'		;1876 Hz
		RETLW		D'185'		;1880 Hz
		RETLW		D'186'		;1884 Hz
		RETLW		D'186'		;1888 Hz
		RETLW		D'186'		;1892 Hz
		RETLW		D'186'		;1896 Hz
		RETLW		D'186'		;1900 Hz
		RETLW		D'186'		;1904 Hz
		RETLW		D'187'		;1908 Hz
		RETLW		D'187'		;1912 Hz
		RETLW		D'187'		;1916 Hz
		RETLW		D'187'		;1920 Hz
		RETLW		D'187'		;1924 Hz
		RETLW		D'187'		;1928 Hz
		RETLW		D'187'		;1932 Hz
		RETLW		D'188'		;1936 Hz
		RETLW		D'188'		;1940 Hz
		RETLW		D'188'		;1944 Hz
		RETLW		D'188'		;1948 Hz
		RETLW		D'188'		;1952 Hz
		RETLW		D'188'		;1956 Hz
		RETLW		D'188'		;1960 Hz
		RETLW		D'188'		;1964 Hz
		RETLW		D'189'		;1968 Hz
		RETLW		D'189'		;1972 Hz
		RETLW		D'189'		;1976 Hz
		RETLW		D'189'		;1980 Hz
		RETLW		D'189'		;1984 Hz
		RETLW		D'189'		;1988 Hz
		RETLW		D'189'		;1992 Hz
		RETLW		D'189'		;1996 Hz
		RETLW		D'189'		;2000 Hz
		RETLW		D'190'		;2004 Hz
		RETLW		D'190'		;2008 Hz
		RETLW		D'190'		;2012 Hz
		RETLW		D'190'		;2016 Hz
		RETLW		D'190'		;2020 Hz
		RETLW		D'190'		;2024 Hz
		RETLW		D'190'		;2028 Hz
		RETLW		D'190'		;2032 Hz
		RETLW		D'190'		;2036 Hz
		RETLW		D'190'		;2040 Hz
		RETLW		D'190'		;2044 Hz
		RETLW		D'190'		;2048 Hz
		RETLW		D'191'		;2052 Hz
		RETLW		D'191'		;2056 Hz
		RETLW		D'191'		;2060 Hz
		RETLW		D'191'		;2064 Hz
		RETLW		D'191'		;2068 Hz
		RETLW		D'191'		;2072 Hz
		RETLW		D'191'		;2076 Hz
		RETLW		D'191'		;2080 Hz
		RETLW		D'191'		;2084 Hz
		RETLW		D'191'		;2088 Hz
		RETLW		D'191'		;2092 Hz
		RETLW		D'191'		;2096 Hz
		RETLW		D'191'		;2100 Hz
		RETLW		D'191'		;2104 Hz
		RETLW		D'191'		;2108 Hz
		RETLW		D'191'		;2112 Hz
		RETLW		D'192'		;2116 Hz
		RETLW		D'192'		;2120 Hz
		RETLW		D'192'		;2124 Hz
		RETLW		D'192'		;2128 Hz
		RETLW		D'192'		;2132 Hz
		RETLW		D'192'		;2136 Hz
		RETLW		D'192'		;2140 Hz
		RETLW		D'192'		;2144 Hz
	
;**********************************************************************************************************************************
;       END of Subroutine SUB_COS_COEFF_1_TABLE
;**********************************************************************************************************************************
	
	

;**********************************************************************************************************************************
;Subroutine SUB_SIN_COEFF_0_LOOKUP
;This subroutine is used to lookup values 
;**********************************************************************************************************************************
SUB_SIN_COEFF_0_LOOKUP

		MOVFW	VAR_TEXT_INDEX
		MOVWF	VAR_TABLE_OFFSET

		MOVLW	LOW	(SUB_SIN_COEFF_0_TABLE + 1)
		ADDWF	VAR_TABLE_OFFSET,F
		MOVLW	HIGH SUB_SIN_COEFF_0_TABLE
		BTFSC	STATUS,C
		ADDLW	1
		MOVWF	PCLATH
		MOVF	VAR_TABLE_OFFSET,W
		CALL	SUB_SIN_COEFF_0_TABLE

		RETURN					;Return from SUB_SIN_COEFF_0_LOOKUP
;**********************************************************************************************************************************
;       END of Subroutine SUB_SIN_COEFF_0_LOOKUP
;**********************************************************************************************************************************


;**********************************************************************************************************************************
;Subroutine SUB_SIN_COEFF_0_TABLE
;This subroutine is called by subroutine SUB_SIN_COEFF_0_LOOKUP.  The character will be in the
;W register when this subroutine returns.
;**********************************************************************************************************************************
SUB_SIN_COEFF_0_TABLE	
	
		MOVWF	PCL		

		RETLW		D'9'		;100 Hz
		RETLW		D'9'		;104 Hz
		RETLW		D'10'		;108 Hz
		RETLW		D'10'		;112 Hz
		RETLW		D'11'		;116 Hz
		RETLW		D'11'		;120 Hz
		RETLW		D'11'		;124 Hz
		RETLW		D'12'		;128 Hz
		RETLW		D'12'		;132 Hz
		RETLW		D'12'		;136 Hz
		RETLW		D'13'		;140 Hz
		RETLW		D'13'		;144 Hz
		RETLW		D'13'		;148 Hz
		RETLW		D'14'		;152 Hz
		RETLW		D'14'		;156 Hz
		RETLW		D'14'		;160 Hz
		RETLW		D'15'		;164 Hz
		RETLW		D'15'		;168 Hz
		RETLW		D'16'		;172 Hz
		RETLW		D'16'		;176 Hz
		RETLW		D'16'		;180 Hz
		RETLW		D'17'		;184 Hz
		RETLW		D'17'		;188 Hz
		RETLW		D'17'		;192 Hz
		RETLW		D'18'		;196 Hz
		RETLW		D'18'		;200 Hz
		RETLW		D'18'		;204 Hz
		RETLW		D'19'		;208 Hz
		RETLW		D'19'		;212 Hz
		RETLW		D'19'		;216 Hz
		RETLW		D'20'		;220 Hz
		RETLW		D'20'		;224 Hz
		RETLW		D'20'		;228 Hz
		RETLW		D'21'		;232 Hz
		RETLW		D'21'		;236 Hz
		RETLW		D'22'		;240 Hz
		RETLW		D'22'		;244 Hz
		RETLW		D'22'		;248 Hz
		RETLW		D'23'		;252 Hz
		RETLW		D'23'		;256 Hz
		RETLW		D'23'		;260 Hz
		RETLW		D'24'		;264 Hz
		RETLW		D'24'		;268 Hz
		RETLW		D'24'		;272 Hz
		RETLW		D'25'		;276 Hz
		RETLW		D'25'		;280 Hz
		RETLW		D'25'		;284 Hz
		RETLW		D'26'		;288 Hz
		RETLW		D'26'		;292 Hz
		RETLW		D'26'		;296 Hz
		RETLW		D'27'		;300 Hz
		RETLW		D'27'		;304 Hz
		RETLW		D'27'		;308 Hz
		RETLW		D'28'		;312 Hz
		RETLW		D'28'		;316 Hz
		RETLW		D'28'		;320 Hz
		RETLW		D'29'		;324 Hz
		RETLW		D'29'		;328 Hz
		RETLW		D'29'		;332 Hz
		RETLW		D'30'		;336 Hz
		RETLW		D'30'		;340 Hz
		RETLW		D'30'		;344 Hz
		RETLW		D'31'		;348 Hz
		RETLW		D'31'		;352 Hz
		RETLW		D'31'		;356 Hz
		RETLW		D'31'		;360 Hz
		RETLW		D'32'		;364 Hz
		RETLW		D'32'		;368 Hz
		RETLW		D'32'		;372 Hz
		RETLW		D'33'		;376 Hz
		RETLW		D'33'		;380 Hz
		RETLW		D'33'		;384 Hz
		RETLW		D'34'		;388 Hz
		RETLW		D'34'		;392 Hz
		RETLW		D'34'		;396 Hz
		RETLW		D'35'		;400 Hz
		RETLW		D'35'		;404 Hz
		RETLW		D'35'		;408 Hz
		RETLW		D'36'		;412 Hz
		RETLW		D'36'		;416 Hz
		RETLW		D'36'		;420 Hz
		RETLW		D'36'		;424 Hz
		RETLW		D'37'		;428 Hz
		RETLW		D'37'		;432 Hz
		RETLW		D'37'		;436 Hz
		RETLW		D'38'		;440 Hz
		RETLW		D'38'		;444 Hz
		RETLW		D'38'		;448 Hz
		RETLW		D'38'		;452 Hz
		RETLW		D'39'		;456 Hz
		RETLW		D'39'		;460 Hz
		RETLW		D'39'		;464 Hz
		RETLW		D'40'		;468 Hz
		RETLW		D'40'		;472 Hz
		RETLW		D'40'		;476 Hz
		RETLW		D'41'		;480 Hz
		RETLW		D'41'		;484 Hz
		RETLW		D'41'		;488 Hz
		RETLW		D'41'		;492 Hz
		RETLW		D'42'		;496 Hz
		RETLW		D'42'		;500 Hz
		RETLW		D'42'		;504 Hz
		RETLW		D'42'		;508 Hz
		RETLW		D'43'		;512 Hz
		RETLW		D'43'		;516 Hz
		RETLW		D'43'		;520 Hz
		RETLW		D'44'		;524 Hz
		RETLW		D'44'		;528 Hz
		RETLW		D'44'		;532 Hz
		RETLW		D'44'		;536 Hz
		RETLW		D'45'		;540 Hz
		RETLW		D'45'		;544 Hz
		RETLW		D'45'		;548 Hz
		RETLW		D'45'		;552 Hz
		RETLW		D'46'		;556 Hz
		RETLW		D'46'		;560 Hz
		RETLW		D'46'		;564 Hz
		RETLW		D'46'		;568 Hz
		RETLW		D'47'		;572 Hz
		RETLW		D'47'		;576 Hz
		RETLW		D'47'		;580 Hz
		RETLW		D'47'		;584 Hz
		RETLW		D'48'		;588 Hz
		RETLW		D'48'		;592 Hz
		RETLW		D'48'		;596 Hz
		RETLW		D'48'		;600 Hz
		RETLW		D'49'		;604 Hz
		RETLW		D'49'		;608 Hz
		RETLW		D'49'		;612 Hz
		RETLW		D'49'		;616 Hz
		RETLW		D'50'		;620 Hz
		RETLW		D'50'		;624 Hz
		RETLW		D'50'		;628 Hz
		RETLW		D'50'		;632 Hz
		RETLW		D'50'		;636 Hz
		RETLW		D'51'		;640 Hz
		RETLW		D'51'		;644 Hz
		RETLW		D'51'		;648 Hz
		RETLW		D'51'		;652 Hz
		RETLW		D'52'		;656 Hz
		RETLW		D'52'		;660 Hz
		RETLW		D'52'		;664 Hz
		RETLW		D'52'		;668 Hz
		RETLW		D'52'		;672 Hz
		RETLW		D'53'		;676 Hz
		RETLW		D'53'		;680 Hz
		RETLW		D'53'		;684 Hz
		RETLW		D'53'		;688 Hz
		RETLW		D'53'		;692 Hz
		RETLW		D'54'		;696 Hz
		RETLW		D'54'		;700 Hz
		RETLW		D'54'		;704 Hz
		RETLW		D'54'		;708 Hz
		RETLW		D'54'		;712 Hz
		RETLW		D'55'		;716 Hz
		RETLW		D'55'		;720 Hz
		RETLW		D'55'		;724 Hz
		RETLW		D'55'		;728 Hz
		RETLW		D'55'		;732 Hz
		RETLW		D'56'		;736 Hz
		RETLW		D'56'		;740 Hz
		RETLW		D'56'		;744 Hz
		RETLW		D'56'		;748 Hz
		RETLW		D'56'		;752 Hz
		RETLW		D'56'		;756 Hz
		RETLW		D'57'		;760 Hz
		RETLW		D'57'		;764 Hz
		RETLW		D'57'		;768 Hz
		RETLW		D'57'		;772 Hz
		RETLW		D'57'		;776 Hz
		RETLW		D'57'		;780 Hz
		RETLW		D'58'		;784 Hz
		RETLW		D'58'		;788 Hz
		RETLW		D'58'		;792 Hz
		RETLW		D'58'		;796 Hz
		RETLW		D'58'		;800 Hz
		RETLW		D'58'		;804 Hz
		RETLW		D'59'		;808 Hz
		RETLW		D'59'		;812 Hz
		RETLW		D'59'		;816 Hz
		RETLW		D'59'		;820 Hz
		RETLW		D'59'		;824 Hz
		RETLW		D'59'		;828 Hz
		RETLW		D'59'		;832 Hz
		RETLW		D'60'		;836 Hz
		RETLW		D'60'		;840 Hz
		RETLW		D'60'		;844 Hz
		RETLW		D'60'		;848 Hz
		RETLW		D'60'		;852 Hz
		RETLW		D'60'		;856 Hz
		RETLW		D'60'		;860 Hz
		RETLW		D'60'		;864 Hz
		RETLW		D'61'		;868 Hz
		RETLW		D'61'		;872 Hz
		RETLW		D'61'		;876 Hz
		RETLW		D'61'		;880 Hz
		RETLW		D'61'		;884 Hz
		RETLW		D'61'		;888 Hz
		RETLW		D'61'		;892 Hz
		RETLW		D'61'		;896 Hz
		RETLW		D'61'		;900 Hz
		RETLW		D'62'		;904 Hz
		RETLW		D'62'		;908 Hz
		RETLW		D'62'		;912 Hz
		RETLW		D'62'		;916 Hz
		RETLW		D'62'		;920 Hz
		RETLW		D'62'		;924 Hz
		RETLW		D'62'		;928 Hz
		RETLW		D'62'		;932 Hz
		RETLW		D'62'		;936 Hz
		RETLW		D'62'		;940 Hz
		RETLW		D'62'		;944 Hz
		RETLW		D'62'		;948 Hz
		RETLW		D'63'		;952 Hz
		RETLW		D'63'		;956 Hz
		RETLW		D'63'		;960 Hz
		RETLW		D'63'		;964 Hz
		RETLW		D'63'		;968 Hz
		RETLW		D'63'		;972 Hz
		RETLW		D'63'		;976 Hz
		RETLW		D'63'		;980 Hz
		RETLW		D'63'		;984 Hz
		RETLW		D'63'		;988 Hz
		RETLW		D'63'		;992 Hz
		RETLW		D'63'		;996 Hz
		RETLW		D'63'		;1000 Hz
		RETLW		D'63'		;1004 Hz
		RETLW		D'63'		;1008 Hz
		RETLW		D'63'		;1012 Hz
		RETLW		D'64'		;1016 Hz
		RETLW		D'64'		;1020 Hz
		RETLW		D'64'		;1024 Hz
		RETLW		D'64'		;1028 Hz
		RETLW		D'64'		;1032 Hz
		RETLW		D'64'		;1036 Hz
		RETLW		D'64'		;1040 Hz
		RETLW		D'64'		;1044 Hz
		RETLW		D'64'		;1048 Hz
		RETLW		D'64'		;1052 Hz
		RETLW		D'64'		;1056 Hz
		RETLW		D'64'		;1060 Hz
		RETLW		D'64'		;1064 Hz
		RETLW		D'64'		;1068 Hz
		RETLW		D'64'		;1072 Hz
		RETLW		D'64'		;1076 Hz
		RETLW		D'64'		;1080 Hz
		RETLW		D'64'		;1084 Hz
		RETLW		D'64'		;1088 Hz
		RETLW		D'64'		;1092 Hz
		RETLW		D'64'		;1096 Hz
		RETLW		D'64'		;1100 Hz
		RETLW		D'64'		;1104 Hz
		RETLW		D'64'		;1108 Hz
		RETLW		D'64'		;1112 Hz
		RETLW		D'64'		;1116 Hz
		RETLW		D'64'		;1120 Hz
	
;**********************************************************************************************************************************
;       END of Subroutine SUB_SIN_COEFF_0_TABLE
;**********************************************************************************************************************************


;**********************************************************************************************************************************
;Subroutine SUB_SIN_COEFF_1_LOOKUP
;This subroutine is used to lookup values 
;**********************************************************************************************************************************
SUB_SIN_COEFF_1_LOOKUP

		MOVFW	VAR_TEXT_INDEX
		MOVWF	VAR_TABLE_OFFSET

		MOVLW	LOW	(SUB_SIN_COEFF_1_TABLE + 1)
		ADDWF	VAR_TABLE_OFFSET,F
		MOVLW	HIGH SUB_SIN_COEFF_1_TABLE
		BTFSC	STATUS,C
		ADDLW	1
		MOVWF	PCLATH
		MOVF	VAR_TABLE_OFFSET,W
		CALL	SUB_SIN_COEFF_1_TABLE

		RETURN					;Return from SUB_SIN_COEFF_1_LOOKUP
;**********************************************************************************************************************************
;       END of Subroutine SUB_SIN_COEFF_1_LOOKUP
;**********************************************************************************************************************************


;**********************************************************************************************************************************
;Subroutine SUB_SIN_COEFF_1_TABLE
;This subroutine is called by subroutine SUB_SIN_COEFF_1_LOOKUP.  The character will be in the
;W register when this subroutine returns.
;**********************************************************************************************************************************
SUB_SIN_COEFF_1_TABLE
		
		MOVWF	PCL		
	
		RETLW		D'64'		;1124 Hz
		RETLW		D'64'		;1128 Hz
		RETLW		D'64'		;1132 Hz
		RETLW		D'64'		;1136 Hz
		RETLW		D'64'		;1140 Hz
		RETLW		D'64'		;1144 Hz
		RETLW		D'64'		;1148 Hz
		RETLW		D'64'		;1152 Hz
		RETLW		D'64'		;1156 Hz
		RETLW		D'64'		;1160 Hz
		RETLW		D'64'		;1164 Hz
		RETLW		D'64'		;1168 Hz
		RETLW		D'64'		;1172 Hz
		RETLW		D'64'		;1176 Hz
		RETLW		D'64'		;1180 Hz
		RETLW		D'64'		;1184 Hz
		RETLW		D'63'		;1188 Hz
		RETLW		D'63'		;1192 Hz
		RETLW		D'63'		;1196 Hz
		RETLW		D'63'		;1200 Hz
		RETLW		D'63'		;1204 Hz
		RETLW		D'63'		;1208 Hz
		RETLW		D'63'		;1212 Hz
		RETLW		D'63'		;1216 Hz
		RETLW		D'63'		;1220 Hz
		RETLW		D'63'		;1224 Hz
		RETLW		D'63'		;1228 Hz
		RETLW		D'63'		;1232 Hz
		RETLW		D'63'		;1236 Hz
		RETLW		D'63'		;1240 Hz
		RETLW		D'63'		;1244 Hz
		RETLW		D'63'		;1248 Hz
		RETLW		D'62'		;1252 Hz
		RETLW		D'62'		;1256 Hz
		RETLW		D'62'		;1260 Hz
		RETLW		D'62'		;1264 Hz
		RETLW		D'62'		;1268 Hz
		RETLW		D'62'		;1272 Hz
		RETLW		D'62'		;1276 Hz
		RETLW		D'62'		;1280 Hz
		RETLW		D'62'		;1284 Hz
		RETLW		D'62'		;1288 Hz
		RETLW		D'62'		;1292 Hz
		RETLW		D'62'		;1296 Hz
		RETLW		D'61'		;1300 Hz
		RETLW		D'61'		;1304 Hz
		RETLW		D'61'		;1308 Hz
		RETLW		D'61'		;1312 Hz
		RETLW		D'61'		;1316 Hz
		RETLW		D'61'		;1320 Hz
		RETLW		D'61'		;1324 Hz
		RETLW		D'61'		;1328 Hz
		RETLW		D'61'		;1332 Hz
		RETLW		D'60'		;1336 Hz
		RETLW		D'60'		;1340 Hz
		RETLW		D'60'		;1344 Hz
		RETLW		D'60'		;1348 Hz
		RETLW		D'60'		;1352 Hz
		RETLW		D'60'		;1356 Hz
		RETLW		D'60'		;1360 Hz
		RETLW		D'60'		;1364 Hz
		RETLW		D'59'		;1368 Hz
		RETLW		D'59'		;1372 Hz
		RETLW		D'59'		;1376 Hz
		RETLW		D'59'		;1380 Hz
		RETLW		D'59'		;1384 Hz
		RETLW		D'59'		;1388 Hz
		RETLW		D'59'		;1392 Hz
		RETLW		D'58'		;1396 Hz
		RETLW		D'58'		;1400 Hz
		RETLW		D'58'		;1404 Hz
		RETLW		D'58'		;1408 Hz
		RETLW		D'58'		;1412 Hz
		RETLW		D'58'		;1416 Hz
		RETLW		D'57'		;1420 Hz
		RETLW		D'57'		;1424 Hz
		RETLW		D'57'		;1428 Hz
		RETLW		D'57'		;1432 Hz
		RETLW		D'57'		;1436 Hz
		RETLW		D'57'		;1440 Hz
		RETLW		D'56'		;1444 Hz
		RETLW		D'56'		;1448 Hz
		RETLW		D'56'		;1452 Hz
		RETLW		D'56'		;1456 Hz
		RETLW		D'56'		;1460 Hz
		RETLW		D'56'		;1464 Hz
		RETLW		D'55'		;1468 Hz
		RETLW		D'55'		;1472 Hz
		RETLW		D'55'		;1476 Hz
		RETLW		D'55'		;1480 Hz
		RETLW		D'55'		;1484 Hz
		RETLW		D'54'		;1488 Hz
		RETLW		D'54'		;1492 Hz
		RETLW		D'54'		;1496 Hz
		RETLW		D'54'		;1500 Hz
		RETLW		D'54'		;1504 Hz
		RETLW		D'53'		;1508 Hz
		RETLW		D'53'		;1512 Hz
		RETLW		D'53'		;1516 Hz
		RETLW		D'53'		;1520 Hz
		RETLW		D'53'		;1524 Hz
		RETLW		D'52'		;1528 Hz
		RETLW		D'52'		;1532 Hz
		RETLW		D'52'		;1536 Hz
		RETLW		D'52'		;1540 Hz
		RETLW		D'52'		;1544 Hz
		RETLW		D'51'		;1548 Hz
		RETLW		D'51'		;1552 Hz
		RETLW		D'51'		;1556 Hz
		RETLW		D'51'		;1560 Hz
		RETLW		D'50'		;1564 Hz
		RETLW		D'50'		;1568 Hz
		RETLW		D'50'		;1572 Hz
		RETLW		D'50'		;1576 Hz
		RETLW		D'50'		;1580 Hz
		RETLW		D'49'		;1584 Hz
		RETLW		D'49'		;1588 Hz
		RETLW		D'49'		;1592 Hz
		RETLW		D'49'		;1596 Hz
		RETLW		D'48'		;1600 Hz
		RETLW		D'48'		;1604 Hz
		RETLW		D'48'		;1608 Hz
		RETLW		D'48'		;1612 Hz
		RETLW		D'47'		;1616 Hz
		RETLW		D'47'		;1620 Hz
		RETLW		D'47'		;1624 Hz
		RETLW		D'47'		;1628 Hz
		RETLW		D'46'		;1632 Hz
		RETLW		D'46'		;1636 Hz
		RETLW		D'46'		;1640 Hz
		RETLW		D'46'		;1644 Hz
		RETLW		D'45'		;1648 Hz
		RETLW		D'45'		;1652 Hz
		RETLW		D'45'		;1656 Hz
		RETLW		D'45'		;1660 Hz
		RETLW		D'44'		;1664 Hz
		RETLW		D'44'		;1668 Hz
		RETLW		D'44'		;1672 Hz
		RETLW		D'44'		;1676 Hz
		RETLW		D'43'		;1680 Hz
		RETLW		D'43'		;1684 Hz
		RETLW		D'43'		;1688 Hz
		RETLW		D'42'		;1692 Hz
		RETLW		D'42'		;1696 Hz
		RETLW		D'42'		;1700 Hz
		RETLW		D'42'		;1704 Hz
		RETLW		D'41'		;1708 Hz
		RETLW		D'41'		;1712 Hz
		RETLW		D'41'		;1716 Hz
		RETLW		D'41'		;1720 Hz
		RETLW		D'40'		;1724 Hz
		RETLW		D'40'		;1728 Hz
		RETLW		D'40'		;1732 Hz
		RETLW		D'39'		;1736 Hz
		RETLW		D'39'		;1740 Hz
		RETLW		D'39'		;1744 Hz
		RETLW		D'38'		;1748 Hz
		RETLW		D'38'		;1752 Hz
		RETLW		D'38'		;1756 Hz
		RETLW		D'38'		;1760 Hz
		RETLW		D'37'		;1764 Hz
		RETLW		D'37'		;1768 Hz
		RETLW		D'37'		;1772 Hz
		RETLW		D'36'		;1776 Hz
		RETLW		D'36'		;1780 Hz
		RETLW		D'36'		;1784 Hz
		RETLW		D'36'		;1788 Hz
		RETLW		D'35'		;1792 Hz
		RETLW		D'35'		;1796 Hz
		RETLW		D'35'		;1800 Hz
		RETLW		D'34'		;1804 Hz
		RETLW		D'34'		;1808 Hz
		RETLW		D'34'		;1812 Hz
		RETLW		D'33'		;1816 Hz
		RETLW		D'33'		;1820 Hz
		RETLW		D'33'		;1824 Hz
		RETLW		D'32'		;1828 Hz
		RETLW		D'32'		;1832 Hz
		RETLW		D'32'		;1836 Hz
		RETLW		D'31'		;1840 Hz
		RETLW		D'31'		;1844 Hz
		RETLW		D'31'		;1848 Hz
		RETLW		D'31'		;1852 Hz
		RETLW		D'30'		;1856 Hz
		RETLW		D'30'		;1860 Hz
		RETLW		D'30'		;1864 Hz
		RETLW		D'29'		;1868 Hz
		RETLW		D'29'		;1872 Hz
		RETLW		D'29'		;1876 Hz
		RETLW		D'28'		;1880 Hz
		RETLW		D'28'		;1884 Hz
		RETLW		D'28'		;1888 Hz
		RETLW		D'27'		;1892 Hz
		RETLW		D'27'		;1896 Hz
		RETLW		D'27'		;1900 Hz
		RETLW		D'26'		;1904 Hz
		RETLW		D'26'		;1908 Hz
		RETLW		D'26'		;1912 Hz
		RETLW		D'25'		;1916 Hz
		RETLW		D'25'		;1920 Hz
		RETLW		D'25'		;1924 Hz
		RETLW		D'24'		;1928 Hz
		RETLW		D'24'		;1932 Hz
		RETLW		D'24'		;1936 Hz
		RETLW		D'23'		;1940 Hz
		RETLW		D'23'		;1944 Hz
		RETLW		D'23'		;1948 Hz
		RETLW		D'22'		;1952 Hz
		RETLW		D'22'		;1956 Hz
		RETLW		D'22'		;1960 Hz
		RETLW		D'21'		;1964 Hz
		RETLW		D'21'		;1968 Hz
		RETLW		D'20'		;1972 Hz
		RETLW		D'20'		;1976 Hz
		RETLW		D'20'		;1980 Hz
		RETLW		D'19'		;1984 Hz
		RETLW		D'19'		;1988 Hz
		RETLW		D'19'		;1992 Hz
		RETLW		D'18'		;1996 Hz
		RETLW		D'18'		;2000 Hz
		RETLW		D'18'		;2004 Hz
		RETLW		D'17'		;2008 Hz
		RETLW		D'17'		;2012 Hz
		RETLW		D'17'		;2016 Hz
		RETLW		D'16'		;2020 Hz
		RETLW		D'16'		;2024 Hz
		RETLW		D'16'		;2028 Hz
		RETLW		D'15'		;2032 Hz
		RETLW		D'15'		;2036 Hz
		RETLW		D'14'		;2040 Hz
		RETLW		D'14'		;2044 Hz
		RETLW		D'14'		;2048 Hz
		RETLW		D'13'		;2052 Hz
		RETLW		D'13'		;2056 Hz
		RETLW		D'13'		;2060 Hz
		RETLW		D'12'		;2064 Hz
		RETLW		D'12'		;2068 Hz
		RETLW		D'12'		;2072 Hz
		RETLW		D'11'		;2076 Hz
		RETLW		D'11'		;2080 Hz
		RETLW		D'11'		;2084 Hz
		RETLW		D'10'		;2088 Hz
		RETLW		D'10'		;2092 Hz
		RETLW		D'9'		;2096 Hz
		RETLW		D'9'		;2100 Hz
		RETLW		D'9'		;2104 Hz
		RETLW		D'8'		;2108 Hz
		RETLW		D'8'		;2112 Hz
		RETLW		D'8'		;2116 Hz
		RETLW		D'7'		;2120 Hz
		RETLW		D'7'		;2124 Hz
		RETLW		D'7'		;2128 Hz
		RETLW		D'6'		;2132 Hz
		RETLW		D'6'		;2136 Hz
		RETLW		D'5'		;2140 Hz
		RETLW		D'5'		;2144 Hz

;**********************************************************************************************************************************
;       END of Subroutine SUB_SIN_COEFF_1_TABLE
;**********************************************************************************************************************************



;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;END OF SUBROUTINE CODE
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


	END
