/**************************************************************************/
/**************************************************************************/
/*
header.c: This file contains those functions needed to handle the header
	creation and management for output CSX packets.
*/
/**************************************************************************/
/*
Copyright, 1995 Atari Corporation.
Written for Atari by Highlight Software Solutions.
*/
/**************************************************************************/

#include "hdef.h"	/* this file contains the data types and constants. */


/**************************************************************************/
/*
Function: CreateCSXHeader

definition:
	This function creates a CSX Header at the address passed to it
	and uses the filter number passed to allocate locations for
	state variables. The function returns the number of HWORDS
	used in the header. Only the CSXHEADER value is actually
	written into the header in this function. All other locations
	are initialized to zeros.

arguments:
	add: this argument contains the address at which to create a
		csx header.
	fnum: this argument contains the filter number (specifically
		the order number) of the first filter in the maxiblock.
		This is needed to allocate one HWORD for each filter
		order for filter state space.
---------------------------------------------------------------------
returns:
	this function returns a HINT with the number of elements in the
	header.
---------------------------------------------------------------------
example:
hdrwords = CreateCSXHeader(bufadd, 3);
calls this function which creates a CSX header at bufadd reserving
state space for a third order filter. hdrwords contains the length
of the header to let the calling function know where to start packing
data after the header.
*/
/**************************************************************************/
HWORD CreateCSXHeader(LPHWORD add, HINT fnum)
{
LPHWORD tadd;
HWORD i;

tadd = add;

*tadd++ = CSXHEADER;    	/* Header Word */
*tadd++ = 0;			/* Pre-Emph State Word */
*tadd++ = 0;			/* APCM Gain Coefficient */
*tadd++ = 0;			/* Random Number Coefficient */
for (i = 0; i < ((MAXIBLOCK/MINIBLOCK)/2); i++) {
	*tadd++ = 0;
}
for (i = 0; i < fnum; i++) {
	*tadd++ = 0;		/* filter state space */
}

return((HINT) (tadd - add));
} /* end of CreateCSXHeader */



/**************************************************************************/
/*
Function: CSXHeaderParameters

definition:
	This function is called for each miniblock to put the winning
	filter and packing bits information into the header. The
	position is calculated by the count sent to the function. The
	function returns an HINT which should be zero under normal
	operation.

arguments:
	packet: this is a pointer to the start of the CSX header.
	count: this is the number of the miniblock within the maxiblock.
		The first one is zero and it counts up until done.
	filter: This is the filter number (Maximum 4 bits) that is the
		winning filter for this miniblock.
	packbitsplus: This is the number of bits needed to pack the
		winning filter (from 1 to 16). This is stored in the
		header as 0 to 15.
---------------------------------------------------------------------
returns:
	this function returns a HINT which normally would be zero.
---------------------------------------------------------------------
example:
	CSXHeaderParameters(hdr, 0, 2, 14);
	This calls the function to load winning filter 2, using 14 pack bits,
	into miniblock zero (the first miniblock in the maxiblock). The
	header starts at address hdr.
*/
/**************************************************************************/
HINT CSXHeaderParameters(LPHWORD packet, HINT count, HINT filter, HINT packbitsplus)
{
LPHWORD	add;			/* address to use for packing filter state */
HWORD	temp;
HWORD 	packbits;

packbits = packbitsplus - 1;
add = packet + WINFILTEROFF;	/* get starting address of win filter info */
add += (count / 2);		/* get the address to use for win filter info */
if (count & 0x0001) {
	/* odd miniblock, use Least Sign. Byte */
	temp = (filter << 4) + packbits;
	temp &= 0x00FF;
	*add |= temp;
}
else {
	/* even miniblock, use Most Sign. Byte */
	temp = ((filter << 12) + (packbits << 8)) & 0xff00;
	*add &= 0x00FF;
	*add |= temp;
}
return(0);
} /* end of CSXHeaderParameters */

/**************************************************************************/
/*
Function: CSXHeaderStates

definition:
	This function loads the filter states for the proper order
	filter into the CSX header. It does not create header locations,
	that was done via CreateCSXHeader. It does fill in the values to
	these addresses. The address called is the start of the CSX Header.
	The function normally returns an HINT with value of zero.
	It loads the scalefactor,pre-emph state, and dither
	random number if appropriate.

arguments:
	buf: This is the address of the CSX Header.
	fss: This is a pointer to an HWORD array that contains the filter
	state values with at least one entry for each filter order.
	filter: This is the value of the filter (hence its order) to
	let the function know how many values to get from the fss array.
	sf: This is the scalefactor for the maxiblock.
	pestate: This is the pre-emphisis state
	randno: This is the random number seed for the dither for the
	maxiblock.
---------------------------------------------------------------------
returns:
	this function returns a HINT which normally would be zero.
---------------------------------------------------------------------
example:
	CSXHeaderStates(hdr, fss, 1, 255, ps,rand);
	This calls the function to load 1 element at address fss (because
	filter number is 1) into the CSX header at address hdr. The scale
	factor is 255 (means 255/64K) and the pre-emp state is in ps.
	The random number seed to be entered in the header is rand.
*/
/**************************************************************************/

HINT CSXHeaderStates(LPHWORD buf,LPHWORD fss, HINT filter,HINT sf, HINT pestate,HINT randno) {
LPHWORD	add;			/* address to use for packing filter state */
HINT i;

add = buf + FILTERSTATEOFF;	/* get starting address of filter state */
for (i = 0; i < filter; i++) {
	add[i] = fss[i];
}
add = buf + PREEMPOFF;		/* get preemp address */
*add = pestate;
add = buf + SFOFF;		/* get scale factor address */
*add = sf;
add = buf + RANDOFF;		/* get random number address */
*add = randno;

return(0);
}  /* End of CSXHeaderStates */