/************************************************************************
 *    Code  to  implement portable mappings to and from internal word	*
 *    and  byte  order.  Note  we  dont  use the standard htons() and	*
 *    htonl()  because  these  are only available on systems with the	*
 *    socket  library.  This  code is so that we can generate machine	*
 *    independent  .cm  files.  This  currently  works for 68020s and	*
 *    80386's,  and  Vaxes, but will probably need changing for other	*
 *    machines.								*
 ************************************************************************/
# include	"list.h"

static short one = 1;
static char *onep = (char *) &one;

static char one234[4] = {1,2,3,4};

int
WGET16(n)
int	n;
{	short s = (short) n;

	if (*onep == 0)
		return s;
	return ((s >> 8) & 0xff) | ((s & 0xff) << 8);
}
long
WGET32(n)
long n;
{	long l = *(long *) one234;
	unsigned char	buf[4];
	
	*(long *) buf = n;
	if (l == 0x01020304)
		return n;
	if (l == 0x04030201)
		return ((long) buf[0] << 24) | ((long) buf[1] << 16) |
		       (buf[2] << 8) | buf[3];
	printf("l=%08lx, What?\n", l);
	abort();
	/* NOTREACHED */
	return 0;
}
void
LPUT16(lp, n)
LIST	*lp;
register int n;
{
	register u_char *cp = (u_char *) lp;

	*++cp = (u_char) (n >> 8);
	*++cp = (u_char) n;
}
void
LPUT32(lp, n)
LIST	*lp;
register long n;
{
	register u_char *cp = (u_char *) lp;

	*++cp = (u_char) (n >> 24);
	*++cp = (u_char) (n >> 16);
	*++cp = (u_char) (n >>  8);
	*++cp = (u_char) n;
}
long
LGET32(lp)
register LIST *lp;
{	
	return ((long) lp[1] << 24) | (long) lp[2] << 16 | 
		(long) lp[3] << 8 | (long) lp[4];
}

/**********************************************************************/
/*   Routine  to  read  a  64-bit  double  precision  floating point  */
/*   number.  We  use  LGET32() to preserve byte orderedness amongst  */
/*   machines,  but  we  dont  have  a  generic  mapping from one FP  */
/*   representation to another.					      */
/**********************************************************************/
void
LGET_FLOAT(lp, dp)
LIST	*lp;
double	*dp;
{	long	*bufp = (long *) dp;

	*bufp++ = LGET32(lp);
	lp += 4;
	*bufp = LGET32(lp);
}

/**********************************************************************/
/*   Function  to  store  a float in a hopefully machine independent  */
/*   manner.							      */
/**********************************************************************/
void
LPUT_FLOAT(lp, val)
LIST	*lp;
double	val;
{	long	*bufp = (long *) &val;
	LPUT32(lp, *bufp);
	lp += 4;
	bufp++;
	LPUT32(lp, *bufp);
}
/**********************************************************************/
/*   Get  a  16-bit  word  from the list structure pointed to by lp.  */
/*   Only define function if we aren't using the macro version.	      */
/**********************************************************************/
# if !defined(LGET16)
u_int16
LGET16(lp)
register LIST *lp;
{	
	  return (u_int16) (lp[1] << 8) | lp[2];
}
# endif
void
swap_words(warray, size)
register u_int32	*warray;
int	size;
{	register int i;

	for (i = 0; i < size; i++, warray++)
		*warray = WGET32(*warray);
}

/**************************************************************/
/*							      */
/* If porting to a new system, the following:		      */
/*							      */
/* 	a.out 01020304					      */
/*							      */
/* should generate:					      */
/*							      */
/*	03 04 01 02 03 04				      */
/*							      */
/* as output in order for the .cm files to be portable	      */
/* across to other CPU types.				      */
/**************************************************************/
# if 0
main(argc, argv)
char **argv;
{	long	l;
	int	i;
	char	buf[6];

	sscanf(argv[1], "%lx", &l);
	i = l & 0xffff;
	*(short *) buf = WGET16(i);
	*(long *) (buf+2) = WGET32(l);
	for (i = 0; i < 6; i++)
		printf("%c", buf[i]);
}
# endif	
