	FUNCTION CHECK_SUM, PACKET, I1, I2
;+
; Project     :	SOHO - CDS
;
; Name        :	CHECK_SUM()
;
; Purpose     :	Calculates the checksum of a CDS science telemetry packet
;
; Explanation :	This routine calculates the checksum of a CDS science telemetry
;		packet, using an XOR logic.
;
; Use         :	Result = CHECK_SUM(PACKET,I1,I2)
;
; Inputs      :	PACKET	= Input packet to calculate the checksum for.  Must be
;			  passed as a byte or short integer array.
;		I1,I2	= Range of short integer words to calculate the check
;			  sum against.  For example, use
;
;				CHK = CHECK_SUM(PACKET, 6, 151)
;
;			  for complete packets from the realtime telemetry.
;
; Opt. Inputs :	None.
;
; Outputs     :	The result of the function is the checksum value.
;
; Opt. Outputs:	None.
;
; Keywords    :	None.
;
; Env. Vars.  :	CDS_EXTERNAL_C = Points to a sharable object file containing
;			       associated C software callable by CALL_EXTERNAL.
;			       If this environment variable exists, then the
;			       routine uses CALL_EXTERNAL to calculate the
;			       checksum.  Otherwise the checksum is calculated
;			       within IDL, which is slower.
;
;			       For backwards compatibility, the software will
;			       also look for the environment variable
;			       CDS_EXTERNAL if it doesn't find CDS_EXTERNAL_C
;
;		SSW_EXTERNAL_PREFACE = On some operating systems, such as older
;			       versions of SunOS, this needs to be set to the
;			       underscore character "_".  Otherwise, it doesn't
;			       need to be defined.
;
; Calls       :	None.
;
; Common      :	None.
;
; Restrictions:	In order to keep this routine as fast as possible, there are
;		almost no checks for errors.
;
; Side effects:	None.
;
; Category    :	Telemetry
;
; Prev. Hist. :	None.
;
; Written     :	William Thompson, GSFC, 27 June 1995
;
; Modified    :	Version 1, William Thompson, GSFC, 27 June 1995
;		Version 2, William Thompson, GSFC, 16 July 1998
;			Look for CDS_EXTERNAL_C evar before CDS_EXTERNAL
;			Check for SSW_EXTERNAL_PREFACE instead of !version.os
;
; Version     :	Version 2, 16 July 1998
;-
;
	ON_ERROR, 2
;
;  Check to see if the logical name CDS_EXTERNAL_C exists.  If it does, then
;  use the CALL_EXTERNAL portion of this routine.
;
	CDS_EXTERNAL_C = GETENV('CDS_EXTERNAL_C')
	IF CDS_EXTERNAL_C NE '' THEN BEGIN
	    EVAR_FOUND = "CDS_EXTERNAL_C"
	    GOTO, CALL_EXTERNAL
	ENDIF
;
;  Also check the CDS_EXTERNAL environment variable.  If this works, then use
;  CALL_EXTERNAL with the value of this environment variable.
;
	CDS_EXTERNAL_C = GETENV('CDS_EXTERNAL')
	IF CDS_EXTERNAL_C NE '' THEN BEGIN
	    EVAR_FOUND = "CDS_EXTERNAL"
	    GOTO, CALL_EXTERNAL
	ENDIF
;
;  If a byte array, then convert to an integer array first.
;
	IF DATATYPE(PACKET,2) EQ 2 THEN TEMP = PACKET ELSE	$
		TEMP = FIX(PACKET,0,N_ELEMENTS(PACKET)/2)
;
;  Calculate the checksum.
;
	OUT = TEMP(I1)
	FOR J = I1+1,I2 DO OUT = OUT XOR TEMP(j)
	GOTO, FINISH
;
;******************************************************************************
;	This is the beginning of the CALL_EXTERNAL part of the routine.
;******************************************************************************
;
CALL_EXTERNAL:
;
;  If Unix, then the routine name will have the form "name_c" instead of
;  "NAME".  If the environment variable SSW_EXTERNAL_PREFACE is set to the "_"
;  character, then this will be prepended to the name.  This is required in
;  some situations, such as older versions of SunOS.
;
	ROUTINE_NAME = 'CHECK_SUM'
	IF !VERSION.OS NE "vms" THEN ROUTINE_NAME =	$
		STRLOWCASE(ROUTINE_NAME) + "_c"
	ROUTINE_NAME = GETENV("SSW_EXTERNAL_PREFACE") + ROUTINE_NAME
;
;  Form the name of the sharable object file.
;
	IF !VERSION.OS EQ "vms" THEN FILENAME = EVAR_FOUND ELSE	$
		FILENAME = CDS_EXTERNAL_C
;
;  Perform the check_sum.
;
	OUT = 0
	VALUE = BYTARR(4)
	IF !VERSION.OS EQ 'vms' THEN VALUE(1:2) = 1B
	TEST1 = CALL_EXTERNAL(FILENAME, ROUTINE_NAME, PACKET, I1, I2,	$
		OUT, VALUE=VALUE)
;
;  Convert the result to host representation, and return.
;
FINISH:
	IEEE_TO_HOST, OUT
;
	RETURN, OUT
	END
