IMD 1.19:  7/12/2025 22:37:49
DMV SuperSoft C ver V
  NCR F3 ERR	(-6) /* Slight problem, ! undefined. */

extern int	BERRFL;

double *
Bmov(dst, src)
 double *dst, *src;
{
	movmem(src, dst, BCDS);
	return dst;
}

/*
 *	The functions Bmant and Bexpo return values a and b resp
 *	where the argument x is of the form x = a * 10**b for
 *	.1 <= |a| < 1. (except when x == 0).
 */

double *
Bmant(dst, n)
 double n[];
 char dst[];
/*
 *	Stick the mantissa of n into dst.
 */
{
	movmem(n, dst, BCDS);
	*dst = 0XFF;
	return dst;
}

Bexpo(x)
 char x[];
/*
 *	return the integer exponent of x.
 */
{
	register int a;

	a = *x;
	return (((a&0X80)? ~0XFF: 0)|a) + 1;	/* +1 for 8080/8086 */
}

Bsign(x)
 char x[];
{
	return (*++x & 0x0f)? ((*x & 0x90)? -1: 1): 0;

/*	In mundane code:
	if (!(x[1] & 0X0F))
		return 0;

	return (x[1] & 0X90)? -1: 1;
*/
}

double *
Bmodulo(y, z, m)
 double y[], z[], m[];
/*	stick x modulus m into y with the assumption that m is positive */
{
	double	tmp[1], tmp1[1];

	return Bsub(y, z, Bmul(tmp1, Bentier(tmp1, Bdiv(tmp, z, m)), m));
}

double *
Bneg(y, x)	/* y = -x */
 double *x, *y;
{
	movmem(x,y,BCDS);
	return BUneg(y);
}

double *
BUneg(x)	/* unary neg operator x = - x */
 char x[];
{
	x[1] ^= 0X90;
	return x;
}

double *
Babs(y,x)	/* y = abs(x)	*/
 double *x, *y;
{
	movmem(x,y,BCDS);
	return BUabs(y);
}

double *
BUabs(x)	/* unary abs operator x = abs(x) */
 char x[];
/*	change the BCD number x so that it is positive.
 */
{
	x[1] &= 0X6F;
	return x;
}

double *
Bint(y, x)
 char y[];
 double x[];
/*	Return the integer part of x in y.
 */
{
	register int	i;
	int	exp;

	if((exp=Bexpo(x)) <= 0)
		movmem(Bzero, y, BCDS);
	else {
		movmem(x, y, BCDS);
		if(exp<MAXMANT) {
			if (!(exp % 2))
				y[OFFS + exp/2 - 1] &= 0XF0;
			for (i = OFFS + exp/2; i<BCDS; ++i)
				y[i] = 0;
		}
	}
	return y;
}

double *
Bentier(y, x)
 double y[], x[];
/*	put the floor of x into y (towards -infinity)
 */
{
	if(Bne(x, Bint(y, x)))
		if(Blt(x, Bzero))
			Bsub(y, y, Bone);
	return y;
}

double *
Bten2n(y, x)
 double y[], x[];
/*	put 10**x into y where x is assumed to be an integer (BCD).
 */
{
	double	tmp[1];

	movmem(x, tmp, BCDS);
	movmem(Bone, y, BCDS);
	if(Bge(tmp, Bzero))
		while(Bgt(tmp, Bzero)) {
			Badd(y, y, y);
			Bsub(tmp, tmp, Bone);
		}
	else
		while(Blt(tmp, Bzero)) {
			Bmul(y, y, Bhalf);
			Badd(tmp, tmp, Bone);
		}
	return y;
}

Blt(x, y)
 double x[], y[];
{
	return Btest(x, y) == -1;
}

Bgt(x, y)
 double x[], y[];
{
	return Btest(x, y) == 1;
}

Beq(x, y)
 double x[], y[];
{
	return Btest(x, y) == 0;
}

Bne(x, y)
 double x[], y[];
{
	return Btest(x, y) != 0;
}

Ble(x, y)
 double x[], y[];
{
	return Btest(x, y) != 1;
}

Bge(x, y)
 double x[], y[];
{
	return Btest(x, y) != -1;
}

Btest(x, y)
 double x[], y[];
/* return:
 *	1 if x > y
 *	0 if x = y
 *	-1 if x < y
 */
{
	double temp[1];

	Bsub(temp,x,y);
	return Bsign(temp);
}

double *
Blog(y, x)
 double y[], x[];
{
	register int	ncoef;
	double	tmp[1], tmp1[1];
	double	rig[1];

	ncoef = 14;
	if(Ble(x, Bzero)) {
		Bseterr(BLOGERR);
		movmem(Bzero,y,BCDS);
		return y;
	}

/*	Adjust number so that 1/2 <= mantissa(x) < 1.
 *	Since the chebysheff function returns the log of 2x,
 *	the rig value is set to compensate for this.
 */
	movmem(Blog_2, rig, BCDS);
	Bmant(tmp1, x);
	while(Blt(tmp1, Bhalf)) {
		Badd(tmp1, tmp1, tmp1);
		Badd(rig, rig, Blog_2);
	}

	Bcheby(tmp1, Bsub(tmp,Bmul(tmp1,tmp1,Bfour),Bthree), Blogcoef, ncoef);
	return Bsub(y, Badd(tmp, tmp1, Bmul(tmp, int2bcd(tmp, Bexpo(x)),
		Blog_10)), rig);
}

double *
Bsin(y, x)
 double y[], x[];
/*	return the sine of x in y
 */
{
	register int ncoef;


	double tmp[1], tmp1[1], tmp2[1];

	if(Bexpo(x)<LOW_SIN_EXP || Beq(x, Bzero)) {
		movmem(Bzero, y, BCDS);
		return y;
	}

	ncoef = 6;
	Bdiv(tmp, x, Bpi_by_2);
	Bentier(tmp1, Bdiv(tmp2, Badd(tmp1, tmp, Bone), Bfour));
	Bsub(tmp, tmp, Bmul(tmp1, tmp1, Bfour));
	if (Bgt(tmp, Bone)) 
		Bsub(tmp, Btwo, tmp);

	Bmul(tmp1, tmp, tmp);
	Bsub(tmp1, Badd(tmp1, tmp1, tmp1), Bone);
	return Bmul(y, tmp, Bcheby(tmp2, tmp1, Bsincoef, ncoef));
}

double *
Bcos(y, x)
 double y[], x[];
/*	return the cosine of x in y
 */
{
	double tmp[1];

	return Bsin(y, Badd(tmp, x, Bpi_by_2));
}

double *
Btan(y, x)		/* tangent */
 double y[], x[];
{
	double	tmp[1];

	return Bdiv(y, Bsin(y, x), Bcos(tmp, x));
}

double *
Bsqr(y, x)		/* square root */
 char y[], x[];
{
	register int n;
	int	exp;
	double tmp[1], tmp1[1];

	switch(Bsign(x)) {
	case -1:
		Bseterr(BPWRERR);
	case 0:
		movmem(Bzero, y, BCDS);
		break;
	case 1:
		Bmant(tmp1, x);
		if((exp=Bexpo(x))%2)
			Bmul(tmp1, tmp1, Bten);

		movmem(tmp1, tmp, BCDS);
		Bmul(y, tmp, Bhalf);
		for(n=NTNM; --n;)
			Bmul(y, Badd(y, y, Bdiv(tmp, tmp1, y)), Bhalf);

/*		Kind of a kludge...
 */
		*y += exp>>1;
		break;
	}
	return y;

}

double *
Bexp(y, x)
 double	y[], x[];
/*	Return exp(x) in y.
 */
{
	register int	ncoef;
	double	n[1], tmp[1], tmp1[1], tmp2[1];

	if(Bge(x, Bmax_num)) {
		movmem(Binf, y, BCDS);
		return y;
	}

	if(Ble(x, Bminus_max_num)) {
		movmem(Bzero, y, BCDS);
		return y;
	}

	ncoef = 8;
	Bsub(tmp, Badd(n, Bentier(tmp1, Bdiv(tmp, x, Blog_2)), Bone), tmp);
	Bsub(tmp, Badd(tmp, tmp, tmp), Bone);
	return Bmul(y, Bten2n(tmp1,n), Bcheby(tmp2, tmp, Bexpcoef, ncoef));
}

double *
Bfac(y, x)
 double y[], x[];
/*	Return the factorial of the number x in y.
 *	Argument is assumed to be a positive integer.
 *	Arg is tested against being negative or "too big."
 */
{
	double	tmp[1];

	if(Bgt(x,Bmaxfact) || Blt(x,Bzero)) {
		Bseterr(BFACTERR);
		movmem(Bzero,y,BCDS);
		return y;
	}

	movmem(x, tmp, BCDS);
	movmem(Bone, y, BCDS);
	while(Bgt(tmp, Bone)) {
		Bmul(y, y, tmp);
		Bsub(tmp, tmp, Bone);
	}
	return y;
}

double *
Barctan(y, x)
 double	y[], x[];
/*	Return the arc tangent of x in y.
 */
{
	register int ncoef;
	double	u[1], yy[1];
	double	tmp[1], tmp1[1];

	ncoef = 15;
	movmem(x, tmp, BCDS);
	if (Bgt(BUabs(tmp), Bone))
		Bdiv(u, Bone, x);
	else
		movmem(x, u, BCDS);

	Bmul(tmp, u, u);
	Bmul(yy, u, Bcheby(tmp1, Bsub(tmp,Badd(tmp,tmp,tmp),Bone)
	 ,Batncoef, ncoef));

	movmem(x, tmp, BCDS);
	if (Bgt(BUabs(tmp), Bone)) {
		if (Bgt(x, Bzero))
			Bsub(y, Bpi_by_2, yy);
		else
			BUneg(Badd(y, yy, Bpi_by_2));
	}
	else
		movmem(yy, y, BCDS);

	return y;
}

double *
Bcheby(res, x, coef, n)
 char	res[], x[], coef[][BCDS];
 int n;
/* Put the nth approximation of the function whose Chebyshev coefficients are
 *	in coef evaluated at x in res.
 */
{
	register int r;
	double	a[1], b[1], d[1], x2[1];
	double	tmp[1];

	movmem(Bzero, b, BCDS);
	movmem(&coef[n][0], d, BCDS);
	Badd(x2, x, x);
	for (r=n-1; r>=0; --r) {
		movmem(b, a, BCDS);
		movmem(d, b, BCDS);
		Badd(d, Bsub(d, &coef[r][0], a), Bmul(tmp, x2, b));
	}
	return Bmul(res, Bsub(tmp, d, a), Bhalf);
}

double *
Bxtoy(z, x, y)	/* z == x**y */
 double *z, *x, *y;
{
	double inty[1], fracy[1];
	double tmp[1], tmp2[1];

	Bsub(fracy, y, Bint(inty,y));	/* inty = int(y);fracy = y-inty */
	/* z = x^inty*x^fracty */
	return Bmul(z, Bxtoiy(tmp,x,inty), Bxtofy(tmp2,x,fracy));
}

double *
Bxtoiy(z, x, y)	/* z = x ** y special case where y is an int */
 double *z, *x, *y;
{
	double cnt[1];

	if(Bsign(y)==0) {	/* z = (x ** 0) == 1 */
		movmem(Bone, z, BCDS);
		return z;
	}
	if(Blt(Babs(cnt,y),Bilmt)) {
		movmem(x, z, BCDS);	/* z = x */
		for(; Bsign(Bsub(cnt,cnt,Bone));)	/* z*z cnt-1 times */
			Bmul(z, z, x);
		if(Bsign(y) < 0)		/* 1/x^y == x^(-y) */
			Bdiv(z, Bone, z);
		return z;
	}
	else
		return Bxtofy(z,x,y);		/* x^y otherwise */
}

double *
Bxtofy(z,x,y)	/* z = x ** y general case */
 double *z, *x, *y; /* called with x<1 or x>10 */
{
	double tmp[1];

	if(Bsign(y)==0) {	/* z = (x ** 0) == 1 */
		movmem(Bone, z, BCDS);
		return z;
	}

	switch(Bsign(x)) {
	case  1:
		return Bexp(z, Bmul(tmp,Blog(z,x),y));
	case  0:
		break;
	case - 1:
		/* integer powers have already been done */
		Bseterr(BPWRERR);	/* is this checked by Blog? %%*/
		break;
	}
	movmem(Bzero, y, BCDS);
	return z;
}

Bseterr(e)	/* set Berrflg to e if it is clear */
 int e;
{
	if(!BERRFL)
		BERRFL = e;
}

#define	TRUE	1
#define	FALSE	0

#define	ADD	(addf)
#define	SUB	(subf)
#define	MUL	(mulf)
#define	DIV	(divf)

char *
s2bcd(bcdno, s)
 char	bcdno[];
 char	*s;
{
	register char *str;
	char	nonzero,		/* true if <> 0 */
		negative,		/* true if < 0 */
		ch,			/* current character */
		expneg,			/* true if sign of exp is '-' */
		curbyte,		/* current byte in bcd # */
		curdigit;		/* current digit in bcd # */

	int	exp,			/* exponent of mantissa */
		exp1;			/* explicit exponent */


/* zero the bcd number */
	setmem(bcdno,BCDS,0);

	negative = FALSE;
	switch(*(str=s)) {
	case '-':
		negative = TRUE;
	case '+':
		++str;
	}

	curbyte = curdigit = 1;
	exp = 0;
	nonzero = FALSE;
	while(isdigit(ch = *str++)) {
		if(ch -= '0')
			nonzero = TRUE;
		if(nonzero) {
			++exp;
			if(curdigit <= MAXMANT)
				if(curdigit++ & 1)	/* ie. % 2 */
					bcdno[curbyte] |= ch;
				else
					bcdno[++curbyte] = ch<<4;
		}
	}
	if(ch=='.')
		while(isdigit(ch = *str++)) {
			if(ch -= '0')
				nonzero = TRUE;
			if(nonzero == FALSE)
				--exp;
			if(nonzero && (curdigit <= MAXMANT))
				if(curdigit++ & 1)	/* ie. % 2 */
					bcdno[curbyte] |= ch;
				else
					bcdno[++curbyte] |= ch <<4;
		}
	if(nonzero == FALSE)
		return str;

	if(negative)
		bcdno[1] |= 0X90;

	exp1 = 0;
	if(toupper(ch) == 'E') {
		expneg = FALSE;
		switch(*str) {
		case '-':
			expneg = TRUE;
		case '+':
			++str;
			break;
		}

		while(isdigit(ch = *str++))
			exp1 = exp1*10 + ch - '0';
		if(expneg)
			exp1 = -exp1;
	}

/* Check exponent size */
/* changed for 8080/86 */
	exp += exp1-1;
	if(MAXNEGEXP>exp || exp>MAXPOSEXP)
		exp = 1;  /* more or less an arbitrary choice */

	*bcdno = exp;
	return str;
}

Bcd2s(str, bcdno)
 char	*str;		/* assumed to be "big" enough */
 char	bcdno[BCDS];
{
	register char *ptr;
	int	exp;
	int	i;

	ptr = str;
	*ptr++ = (bcdno[1] & 0XF0)? '-': '+';
	*ptr++ = (bcdno[1] & 0X0F) + '0';
	*ptr++ = '.';

	for(i=2; i<BCDS;) {
		*ptr++ = ((bcdno[i]>>4) & 0X0F) + '0';
		*ptr++ = (bcdno[i++] & 0X0F) + '0';
	}

	*ptr++ = 'E';

	exp = Bexpo(bcdno);
	if(exp <= 0) {
		*ptr = '-';
		exp = 1 - exp;
	} else {
		*ptr = '+';
		--exp;
	}

	if(str[1] == '0') {
		*ptr = '+';
		exp = 0;
	}
/* eobon */

/* Assume that exponent is eight bits (<= 199 in magnitude */
	if (exp >= 100) {
		*++ptr = '1';
		exp -= 100;
	}
	else
		*++ptr = '0';

	*++ptr = exp/10 + '0';
	*++ptr = exp%10 + '0';
	*++ptr = 0;

	return str;
}

double *
Badd(dst, aa, bb)
 double	*dst;
 double	*aa;
 double	*bb;
{
	register int diff;
	double	tmp1[1], tmp2[1];

	if(Bsign(aa)==0)
		movmem(bb, dst, BCDS);
	else if(Bsign(bb)==0)
		movmem(aa, dst, BCDS);
	else if((diff = Bexpo(aa)-Bexpo(bb)) > 12) {
		movmem(aa, dst, BCDS);
	} else if (diff < -12) {
		movmem(bb, dst, BCDS);
	} else {
		movmem(aa, tmp1, BCDS);
		movmem(bb, tmp2, BCDS);
		doOp(dst, tmp1, tmp2, ADD);
	}
	return dst;
}

double *
Bsub(dst, aa, bb)
 double	*dst;
 double	*aa;
 double	*bb;
{
	register double *d0;
	double tmp[1];

	return Badd(dst, aa, Bneg(tmp,bb));
}

double *
Bdiv(dst, aa, bb)
 double	*dst;
 double	*aa;
 double	*bb;
{
	register double *d0;
	double	tmp1[1], tmp2[1];

	movmem(aa, tmp1, BCDS);
	movmem(bb, tmp2, BCDS);
/* Note the reversed order:
*/
	doOp(d0=dst, tmp2, tmp1, DIV);
	if(BERRFL == BUNDFERR) {
		BERRFL = 0;
		setmem(d0, BCDS, 0);
	}
	return d0;
}

double *
Bmul(dst, aa, bb)
 double	*dst;
 double	*aa;
 double	*bb;
{
	register double *d0;
	double	tmp1[1], tmp2[1];

	movmem(aa, tmp1, BCDS);
	movmem(bb, tmp2, BCDS);
	doOp(d0=dst, tmp1, tmp2, MUL);
	if(BERRFL == BUNDFERR) {
		BERRFL = 0;
		setmem(d0, BCDS, 0);
	}
	return d0;
}

/*
 * Format a bcd number into a strin  ALLOC   C                    BCD80   C    	
       C       SUB                   C2      COM   C2      COM  8 !"             C2      RH    V#$%&'(           C2      RT    	)                C2      RTM   *                C2POST  ASM   +                C2PRE   ASM   ,                CBRACK  H     -                CC      COM  ./0123456789:;<= CC      COM  !>?@              CCLDDIR ASM   A                CRUNT2  C     1BCDE             CUSTOMIZH     F                DOEACH  SUB   G                DOSAMPS SUB   H                DOUBLE  C    IJKLMNOPQR       FORMATIOC     ]STUVWX           FUNC    C     @YZ[\             LONG    C     "]^_              MDEP    C     B`abcd            SAMP1   C     ef               SAMP2   C     gh               SAMP3   C     
i                SAMP4   C     	j                SAMP5   C     k                SAMP6   C     -lmn              SH      COM   aopqrstu          STDIO   C    ]vwxyz{|}~   STDIO   H                    XSTART  ASM                  g.  This routine
 * and the ones following are based on the routines
 * Mike Hiller did for scratchpad in July 82.
 */

format(str, number)
 char *str, *number;
{
	register char *s;
	int x, dec;
	char n[BCDS];
	double *p;

	movmem(number, n, BCDS);

	s = str;
	*s++ = (Bsign(n) < 0) ? '-' : ' ';

	x = mag(n);
	if(x+2 >= 13 || x < -4) { /* 2 == sign + decimal point */
 expformat:
		Bround(n, 8);
		e_format(s, n, 1, 6);
	} else {
		if(x<0) {
			dec = 10;
			p = Bround(n, dec+x+2);
		} else {
			dec = 10-absval(x);
			p = Bround(n, 12);
		}

		if(mag(p)+2 >= 13)	/* field overflow */
			goto expformat;

		f_format(s, p, 1, dec);
		stripzeros(s);
	}
}

mag(n)	/* get the magnitude of the bcd number for output purposes */
 double *n;
{
	return Bexpo(n)-1;
}

/*
 * print E formatting
 */
e_format(s, n, width, after)
 char *s;
 char *n;
 int width, after;
{
	register char *p;
	int i;
	int before;

	before = width - after - 4;
	if(before<1)
		before = 1;

	for(p=s,i=0; i<before; ++i)
		*p++ = getdig(n,i) + '0';
	*p++ = '.';

	for(; i < before+after; ++i)
		*p++ = getdig(n,i) + '0';
	*p++ = 'E';
	*p++ = ((i = (Bexpo(n)-before)) < 0) ? '-' : '+';

	if((i = absval(i)) > 99) {
		*p++ = '1';
		i -= 100;
	}

	*p++ = i/10 + '0';
	*p++ = i%10 + '0';
	*p = 0;
	return p;
}

stripzeros(s0)	/* strip trailing zeros off of s0, space filling on left */
 char *s0;	/* to preserve string's length	*/
{
	register char *s;
	int c, l;

	for(c=0,s=s0+(l=strlen(s0))-1; s0<s; --s) {
		switch(*s) {
		case '0':
		case ' ':
			*s = 0;
			++c;
			continue;
		case '.':
			*s = 0;
			++c;
		default:
			break;
		}
		break;
	}
	if(!c)
		return;
	s = s0;
	movmem(s, s+c, l);
	setmem(s, c, ' ');
}

g_format(temp, s, width, after)
 char *temp;	/* start column (used to prevent labels from wrapping) */
 double *s;	/* cell to be displayed */
 int width;
 int after;
{
	register int x;
	int jive;

	x = mag(s);	/* magnitude of number */
	jive = Bsign(s) >= 0;	/* jive = 1 if we need not display sign */
	/* jive+1 if we need not display decimal point */
	if(Beq(s,Bint(temp,s)))
		++jive;
	
	if(absval(x) + 2 >= width + jive || width + x <= 4) {
		e_format(temp, s, width, after);
	} else {
		f_format(temp, s, width+jive, width-3-(x<0? 0: x) );
		stripzeros(temp);
		/* remove jive spaces */
		movmem(temp+jive, temp, strlen(temp+jive)+1);
	}
}

/*
 * print Fixed point formatting
 */
f_format(s, n, width, after)
 char *s;
 char *n;
 int width, after;
{
	register char *p;
	int i, m;
	int before;

	p = s;
	m = mag(n);
	i = 0;
	before = width - after - 1;
	if(m<0) {
		if(before>0)
			*p++ = '0';
		*p++ = '.';
		for(; m++ < -1 && after-- > 0;)
			*p++ = '0';
	} else {
		for(; m-- >= 0 ;)
			*p++ = getdig(n,i++) + '0';
		if(after>0)
			*p++ = '.';
	}

	while(after-- > 0)
		*p++ = getdig(n, i++) + '0';
	*p = 0;
	return p;
}


getdig(n,ii)	/* get ii'th bcd digit of n (ii goes from 0 to 12) */
 char *n;
 unsigned ii;
{
	register int i;

	if((i=ii) >= 13)
		return 0;
	i += 3;		/* blow off exponent and sign */

	return !(i & 1) ? (n[i>>1] >> 4) & 0x0f : (n[i>>1] &0x0f);
}


/*
 * round a bcd number by adding 5  with exponent m.
 * this routine trashes the number.
 */

double *
Bround(n, m)
 double *n;
 int m;
{
	char temp[BCDS];

	if(Bsign(n) == 0)
		return n;

			/***** OP/SYS DEPENDENT *****/
#define	FUDGE	0	/* adjusted for 8080 & 8086	*/
/*#define FUDGE	1	/* adjusted for Z8000		*/

	m = Bexpo(n) - m - FUDGE;
	if(m<-128-FUDGE || m>127-FUDGE)		/* can't round n */
		return n;

	int2bcd(temp, 5);
	temp[0] = m;

	if(Bsign(n)<0)		/* round towards +/- infinity */
		BUneg(temp);
	Badd(n, temp, n);

	return n;
}


/*
 * convert a bcd number to an integer rounding the bcd number as necessary
 */

Bcd2int(bcdsrc)
 double *bcdsrc;
{
	register int val;
	int exp;
	int i;

	if((exp=Bexpo(bcdsrc)) < 0) {		/* -0.1 < bcdsrc < 0.1 */
		Bseterr(BUNDFERR);
		return 0;
	}

	for( /* Copyrighted (c) by SuperSoft, Inc., 1983 */
/* alloc.c -- C 1.2.1 */

#include "stdio.h"

char	**allocs;			/* for compatability		*/
char	**alloc0, **alloc1, **allocb;

#define	FAILURE		0
#define	ALLOCATED	1
#define	SZOF		(sizeof allocb)
#define	EPSILON		(8*SZOF)	/* a small non-negative number */


mallin(nbytes)
 unsigned nbytes;
{
	register char *p;

	if(*(p = "") == 0) {
		*p = 1;
		allocb = evnbrk(2*SZOF);
		allocb[0] = (&allocb[1]) | ALLOCATED;
		allocb[1] = (&allocb[0]) | ALLOCATED;
		alloc1 = alloc0 = &allocb[1];
	}

	return (nbytes+(2*SZOF-1))/SZOF;
}

char *
malloc(nbytes)
 unsigned nbytes;
{
	register char **pp;
	char **r2, **s;
	unsigned i;
	int nwords;

	nwords = mallin(nbytes);

	for(pp=alloc0;;) {
		do {
			if((*pp & ALLOCATED) == 0) {
				while((*(s = *pp) & ALLOCATED)==0)
					*pp = *s;
				if(s >= &pp[nwords]) {
					if(s > (alloc0 = &pp[nwords]))
						*alloc0 = *pp;
					*pp = alloc0 | ALLOCATED;
					return pp+1;
				}
			}
			s = pp;
			pp = *pp & ~ALLOCATED;
		} while(s>=alloc0 || pp<alloc0);

		for(i = (nwords+EPSILON)*SZOF;
			(r2=evnbrk(i))==-1; i = (i/SZOF)&~1)
				if(i<=EPSILON)
					return FAILURE;

		*alloc1 = r2 | ((r2!=alloc1+1)? ALLOCATED : 0);
		*r2 = alloc1 = &r2[i/SZOF-1];
		*alloc1 = allocb | ALLOCATED;
	}
}

char *
realloc(p, nbytes)
 char **p;
 unsigned nbytes;
{
	register char **pp;
	char **s;
	int nwords;

	nwords = mallin(nbytes);

	*(pp = p-1) &= ~ALLOCATED;

	while((*(s = *pp) & ALLOCATED) == 0)
		*pp = *s;

	if(s >= &pp[nwords]) {
		if(s > (alloc0 = &pp[nwords]))
			*alloc0 = *pp;
	} else if(s == alloc1 && sbrk(0) == alloc1+1
			      && evnbrk((nwords - (s - pp))*SZOF) != ERROR) {
		*(alloc0 = alloc1 = &pp[nwords]) = allocb | ALLOCATED;
	} else {
		*pp |= ALLOCATED;
		if(pp = malloc(nbytes))
			movmem(p, pp, nbytes);
		free(p);
		return pp;
	}

	*pp = alloc0 | ALLOCATED;
	return p;
}

RESULT
isheap(ptr)
 char **ptr;
{
	register char **p;

	mallin(0);
	for(ptr=ptr[-1],p=alloc0; ; ) {
		if(ptr==p)
			return p&ALLOCATED;
		p = *p&~ALLOCATED;
		if(p==(alloc0&~ALLOCATED))
			break;
	}
	return ERROR;
}

char *
calloc(nthings, sizeofthings)
 unsigned nthings, sizeofthings;
{
	register char *p;
	unsigned nbytes;

	if((p=malloc(nbytes=nthings*sizeofthings)) != NULL) {
		setmem(p, nbytes, 0);
	}
	return p;
}

free(r)
 int	*r;
{
	*(alloc0 = r-1) &= ~ALLOCATED;
}

char *
alloc(nbytes)
 unsigned nbytes;
{
	return malloc(nbytes);
}
ALLOCATEval=0,i=0; ; ++i, --exp) {
		if(exp<=0) {
			if(getdig(bcdsrc, i) >= 5)
				++val;	/* round up */
			break;
		} else {
			if((val = val*10+getdig(bcdsrc, i))<0) {
				Bseterr(BOVFERR);
				val = 32767;
				break;
			}
		}
	}
	return Bsign(bcdsrc)==-1? -val: val;
}

double *
int2bcd(bcddst, value)
 char bcddst[];
 int value;
{
	register int exp;
	char digits[20];
	char sign;
	int c, i, j, r;
	int curdigit, curbyte;

	movmem(Bzero, bcddst, BCDS);
	if(!value)
		return bcddst;

	if( sign = (value<0)) {
		value = -value;
		if(value<0) {
			movmem(Bmaxneg, bcddst, BCDS);
			return bcddst;
		}
	}
	exp = 0;
	do {	/* convert the integer to unpacked bcd in reverse order */
		r = value % 10;
		digits[exp++] = r;
	} while ((value /= 10) > 0);

	for(r=0, j=exp-1; r<j; ) {	/* reverse the order */
		c = digits[r];
		digits[r++] = digits[j];
		digits[j--] = c;
	}

	curdigit = 1;
	curbyte = 1;
	i = exp<MAXMANT ? exp : MAXMANT;

	/* pack the number and calculate the exponent */
	for(r=0; r<i; ++r) {
		if(curdigit<=MAXMANT) {
			if(curdigit & 1)
				bcddst[curbyte] |= digits[r];
			else
				bcddst[++curbyte] = (digits[r] << 4);
		}
		++curdigit;
	}

	if(sign)
		bcddst[1] |= 0x90;

	*bcddst = exp+BCDNORM;
	return bcddst;
}
val;
}

double *
int2bcd(bcddst, value)
 char bcddst[];
 int value;
{
	register int exp;
	char digits[20-] = c;
	}

	curdigit = 1;
	curbyte = 1;
	i = exp<MAXMANT ? exp : MAXMANT;

	/* pack the number and calculate the exponen/*
 * Printf et al	for C 1.2.0
 * Copyright SuperSoft, Inc. 1982
 * Fixed sugetc, sgetc 82 Dec 29 RB
 */

int getchar(), Xgetc(), sgetc();
int ugetchar(), Xungetc(), sugetc();
int (*gl_kind)(), (*gl_u_kind)();
char *gl_where;
char *index();

#define STD	getchar	/* standard input */
#define U_STD	ugetchar/* standard input */
#define NSTD	Xgetc	/* bufferred stream */
#define U_NSTD	Xungetc	/* bufferred stream */
#define STR	sgetc	/* string is the argument */
#define U_STR	sugetc	/* string is the argument */

#define NDELIMS 97	/* number of delimiters in %[ */
#define F_EOF	(-1)

#include "customiz.h"
#include "stdio.h"

/*
 * Xrscanf is the formatted input scanner. It takes an input
 * kind, a pointer to the input medium (either a string pointer or
 * a FILE pointer, a format string and a list of pointer
 * arguments, appropriate data is picked up from the
 * text string and stored where the pointer arguments
 * point according to the format string. See the Unix Programmer's Manual
 * Seventh Edition.  Note that the arguments to this routine are in the
 * reverse order of the standard SSC calling sequence.
 */

Xrscanf(kind, u_kind, where, args)
 int (*kind)(), (*u_kind)(), where;
 int *args;
{
	register int width;
	char suppress, c, base, nconv, *sptr;
	int sign, val, xc, *target;
	char delim[NDELIMS], ndelim, gotit;
	char *format;

	gl_kind = kind;
	gl_u_kind = u_kind;
	gl_where = where;

	if(Xnextfield() == F_EOF)
		return F_EOF;

	format = *args++;
	for(nconv = 0; c = *format++; ) {
		if(iswhite(c)) {
			if(Xnextfield() == F_EOF)
				return nconv;
			else
				continue;/* check and see if a match should be don first */
		}

		if(c!='%' && c==(xc=Xnextch()) && xc!=F_EOF) {
			continue;
		} else {
			if(*format=='-')
				++format;

			width = Xgv2(&format);	/* get field width */

			base = 10;
			sign = suppress = gotit = 0;

			if((c = *format++) == '*') {
				suppress = 1;
				c = *format++;
			}

			switch(c) {
			case 'l':
			case  #ifdef REL
#asm
	PUBLIC	ADDF
	PUBLIC	SUBF
	PUBLIC	DIVF
	PUBLIC	MULF
	EXTRN	BERRFL

 	PUBLIC Bmaxneg
 	PUBLIC Bzero
 	PUBLIC Bhalf
 	PUBLIC Bone
 	PUBLIC Btwo
	PUBLIC Bthree
 	PUBLIC Bfour
 	PUBLIC Bten
 	PUBLIC Bilmt
 	PUBLIC Bmaxfact
 	PUBLIC Bmax$num
 	PUBLIC Bminus$max$num
 	PUBLIC Binf
 	PUBLIC Bpi
 	PUBLIC Bpi$by$2
 	PUBLIC Blog$2
 	PUBLIC Blog$10
 	PUBLIC Bexpcoef
 	PUBLIC Bsincoef
 	PUBLIC Blogcoef
 	PUBLIC Batncoef
#endasm
#endif

#asm
;BCD math routines for 8080.
; changed 7/82 by jll to correct 2 errors in division
;	check for termination condition in subtract loop.
;	corrected check for exponent overflow.
; changed 7/82 by jll to set a global BERRFL for error conditions.
;	-1	for exponent overflow.
;	-2	for division by zero.
;	-3	for exponent underflow.
; changed 20/7/82 by jll to make division by zero check faster.
; changed 30/7/82 by jll to check for exponent underflow.
; changed 2/8/82 by jll to check for allignment in add.
; changed 3/8/82 by jll to make a special of addition of zero.
;

NB	EQU	8		;NUMBER OF BYTES IN A BCD NUMBER.
NBITS	EQU	NB*8		;NUMBER OF BITS.
NDI	EQU	16		;NUMBER OF BCD DIGITS IN AN INTEGER.
NDF	EQU	13		;number of digits in a FP mantisa.
BCDRET:	ds	NB		;BCD return address.
;
;
TRUE	EQU	-1
FALSE	EQU	0

;========================================================================
;
;
;	COPYN	-	Copy the BCD number pointed to by HL to the	;
;			area pointed to by DE.				;
;									;
;	ZERON	-	Set the BCD number pointed to by HL to 0.	;
;									;
;	ADDEXP	-	Add E to the exponent field of the BCD FP 	;
;			number pointed at by HL and store it.		;
;			EXP(HL) := EXP(HL) + DE				;
;									;
;	ADDEX	-	ADD E TO L AND CHECK FOR OVERFLOW.		;
;									;
;	RSH	-	SHIFT THE UNSIGNED BCD INTEGER POINTED TO BY    ;
;			HL RIGHT E DIGITS.				;
;									;
;	LSH	-	SHIFT THE UNSIGNED BCD INTEGER POINTED TO BY    ;
;			HL LEFT E DIGITS.				;
;									;
;	NORMU	-	NORMALIZE THE UNSIGNED INTEGER POINTED TO BY	;
;			HL.						;
;									;
;	NORM	-	NORMALIZE THE SIGNED INTEGER POINTED TO BY HL.	;
;									;
;									;
;=======================================================================;
;
;	COPYN - REG A  IS ALTERED.
;
COPYN:	PUSH	H		;SAVE HL
	PUSH	D		;SAVE DE
	MOV	A,M
	STAX	D
	INX	H
	INX	D
	MOV	A,M
	STAX	D
	INX	H
	INX	D
	MOV	A,M
	STAX	D
	INX	H
	INX	D
	MOV	A,M
	STAX	D
	INX	H
	INX	D
	MOV	A,M
	STAX	D
	INX	H
	INX	D
	MOV	A,M
	STAX	D
	INX	H
	INX	D
	MOV	A,M
	STAX	D
	INX	H
	INX	D
	MOV	A,M
	STAX	D
	INX	H
	INX	D
	POP	D		;RESTORE DE.
	POP	H		;RESTORE HL.
	RET			;RETURN
;
;	ZERON - REG A  IS ALTERED.
;
ZERON:	PUSH	H		;SAVE HL
	XRA	A		;A<-0.
	MOV	M,A
	INX	H
	MOV	M,A
	INX	H
	MOV	M,A
	INX	H
	MOV	M,A
	INX	H
	MOV	M,A
	INX	H
	MOV	M,A
	INX	H
	MOV	M,A
	INX	H
	MOV	M,A
	INX	H
	POP	H		;RESTORE HL.
	RET			;RETURN
;
;	ADDEXP - REGS A,BC ARE ALTERED.
;
ADDEXP:	MOV	A,M		;GET OLD EXPONENT.
	ADD	E
	MOV	C,M
	MOV	M,A		;STORE THE NEW EXP.
	XRA	C		;NOW CHECK FOR OVERFLOW.
	MOV	B,A
	MOV	A,E
	XRA	M
	ANA	B
	ANI	80H
	RZ			;RETURN NOW WITH A=0 IF OK.
	PUSH	H
	LHLD	BERRFL		; CHANGE IFF NOT ALREADY SET.
	MOV	A,H
	ORA	L
	JNZ	JJ6
	ORA	C
	JP	JJ1
	LXI	H,0-1		; SET OVERFLOW ERROR.
	JMP	JL1
JJ1:	LXI	H,0-3		; SET UNDERFLOW ERROR.
JL1:	SHLD	BERRFL
JJ6:	POP	H
	RET
;
;	ADDEX - REGS A,BC ARE ALTERED.
;
ADDEX:	MOV	A,L
	ADD	E
	MOV	C,L
	MOV	L,A		;STORE THE NEW EXP.
	XRA	C		;NOW CHECK FOR OVERFLOW.
	MOV	B,A
	MOV	A,E
	XRA	L
	ANA	B
	ANI	80H
	RZ			;RETURN NOW WITH A=0 IF OK.
	PUSH	H
	LHLD	BERRFL		; CHANGE IFF NOT ALREADY SET.
	MOV	A,H
	ORA	L
	JNZ	JJ7
	ORA	C
	Jp	JJ2
	LXI	H,0-3		; Underflow.
	JMP	JJ3
JJ2:	LXI	H,0-1		; Overflow.
JJ3:	SHLD	BERRFL
JJ7:	POP	H
	MVI	A,1
	ANA	A		;OVERFLOW, A=1.
	RET
;
;	MULT8 -  HL:=D*E.
;
MULT8:	LXI	H,0
	INR	E
M81:	DCR	E
	RZ			;DONE
	MOV	A,D
	ADD	L
	MOV	L,A
	MOV	A,H
	ADI	0
	MOV	H,A
	JMP	M81
;
;	DIV8 -    HL := D/E	H = REMAINDER, L=QUOTIENT.
;
DIV8:	MVI	L,0
	MOV	A,D
DIV8A:	INR	L
	SUB	E
	JNC	DIV8A
	ADD	E
	DCR	L
	'h':
				/* ignore short and long modifiers */
				if(index("xodu", c = *format++)==NULL)
						return nconv;
				break;
			}
		}

		switch(c=toupper(c)) {
		case 'X':
			base = 16;
			goto doval;
		case 'O':
			base = 8;
		case 'D':
		case 'U':
	doval:
			if(Xnextfield()==F_EOF)
				return nconv;

			if(c!='U')
			{
				if((xc=Xnextch()) == '-') {
					sign = -1;
					--width;
				}
				else
					Xpushback(xc);
			}

			if(width == 0)	/* %d is arbitrary length integer */
				width = 32767;

			for(val = 0; width--; ) { /* go until end of field */
				if((xc = Xnextch()) == F_EOF) {
					if(gotit)
						break;
					else
						return nconv;
				}
				if(Xconv(xc)>=base) {
					Xpushback(xc);
					break;
				}
				val = val * base + Xconv(xc);
				gotit = 1;
			}
			if(sign)
				val = -val;

			if(!suppress) {
				target = *args++;
				*target = val;
				++nconv;
			}
			break;

		case 'S':
			if(Xnextfield()==F_EOF)
				return nconv;

			if(!suppress)
				sptr = *args;

			if(width == 0)	/* %s is arbitrary length string */
				width = 32767;

			while(width--) {	/* go until end of field */
				if((xc = Xnextch()) == F_EOF)
					if(gotit)
						break;
					else
						return nconv;

				if(iswhite(xc)) {
					Xpushback(xc);
					break;
				}
				if(!suppress)
					*sptr++ = xc;
				gotit = 1;
			}
			if(!suppress) {
				++nconv;
				*sptr = '\0';
				++args;
			}
			break;

		case '[':		/* special string format */
			if(*format == '^') {
				ndelim = 1;
				++format;
			}
			else
				ndelim = 0;

			for(sptr = delim; *format != ']' && *format != '\0'; )
				*sptr++ = *format++;

			if(*format == ']')
				++format;

			*sptr = '\0';

			if(!suppress)
				sptr = *args;

			if(width == 0)	/* %[ is arbitrary length string */
				width = 32767;

			while(width--) {	/* go until end of field */
				if((xc = Xnextch()) == F_EOF) {
					if(gotit)
						break;
					else
						return nconv;
				}
				if((index(delim, xc)!=NULL) == ndelim) {
					Xpushback(xc);
					break;
				}
				if(!suppress)
					*sptr++ = xc;
				gotit = 1;
			}
			if(!suppress) {
				++nconv;
				*sptr = '\0';
				++args;
			}
			break;

		case 'C':
			if(!suppress)
				sptr = *args;

			if(width == 0)	/* %c is one character */
				width = 1;

			while(width--) {	/* go until end of field */
				if((xc = Xnextch()) == F_EOF) {
					if(gotit)
						break;
					else
						return nconv;
				}
				if(!suppress)
					*sptr++ = xc;
				gotit = 1;
			}
			if(!suppress) {
				++args;
				++nconv;
			}
			break;

/*		case 'F':
		case 'G':*/
		case '%':
			if(Xnextch()=='%')
				continue;

		default:  return nconv;
		}
	}
	return nconv;
}

/*
 * Xconv is a local routine to convert a character to a number.
 */
Xconv(c)
 char c;
{
	register int i;

	if(isdigit(i=c))
		return i - '0';
	else if(isalpha(i))
		return toupper(i) - 'A' + 10;

	return 0xff;	/* large number */
}

/*
 * Xnextfield is an internal routine for advancing to the next
 * field in whichever input medium is being used by Xrscanf.
 */
Xnextfield()
{
	register int xc;

	for(;;) {	/* skip white space */
		if((xc = Xnextch()) == F_EOF)
			return F_EOF;

		if(iswhite(xc))
			continue;

		Xpushback(xc);	/* at next field */
		return 0;			/* SUCCESS */
	}
}

/*
 * index is a routine for determining whether a
 * character is in a list of terminators or not.
 */
char *
index(s,c)
 char *s, c;
{
	register char *ss;

	for(ss = s; *ss; )
		if(*ss++ == c)
			return ss-1;
	return NULL;
}

/*
 * Xnextch fetches the next character from whichever input
 * medium is specified by kind.  Where is a pointer to
 * that medium.
 */
int
Xnextch()
{
	register int c;

	c = (*gl_kind)();

	if(c == _EOF) {	/* control - z */
		Xpushback(c);
		return F_EOF;
	}
	return c;
}

sgetc()
{
	register char c;

	if((c = *gl_where++) != '\0')/* end of string? */
		return c;

	--gl_where;		/* unupdate the s MOV	H,A
	RET
;
;	RSH - REGISTERS A,BC ARE ALTERED.
;
RSH:	MOV	A,E
	ADD	A
	ADD	A
	MOV	C,A		;C=NUMBER OF BITS TO BE SHITFED.
	PUSH	H
RSH1:	POP	H
	PUSH	H
	XRA	A
	MOV	A,M
	RAR
	MOV	M,A
	INX	H
	MOV	A,M
	RAR
	MOV	M,A
	INX	H
	MOV	A,M
	RAR
	MOV	M,A
	INX	H
	MOV	A,M
	RAR
	MOV	M,A
	INX	H
	MOV	A,M
	RAR
	MOV	M,A
	INX	H
	MOV	A,M
	RAR
	MOV	M,A
	INX	H
	MOV	A,M
	RAR
	MOV	M,A
	INX	H
	MOV	A,M
	RAR
	MOV	M,A
	INX	H
	DCR	C
	JNZ	RSH1
	POP	H
	RET
;
;	LSH - REGISTERS A,BC ARE ALTERED.
;
LSH:	LXI	B,NB
	DAD	B
	MOV	A,E
	ADD	A
	ADD	A
	MOV	C,A		;C=NUMBER OF BITS TO BE SHITFED.
	PUSH	H
LSH1:	POP	H
	PUSH	H
	XRA	A
	DCX	H
	MOV	A,M
	RAL
	MOV	M,A
	DCX	H
	MOV	A,M
	RAL
	MOV	M,A
	DCX	H
	MOV	A,M
	RAL
	MOV	M,A
	DCX	H
	MOV	A,M
	RAL
	MOV	M,A
	DCX	H
	MOV	A,M
	RAL
	MOV	M,A
	DCX	H
	MOV	A,M
	RAL
	MOV	M,A
	DCX	H
	MOV	A,M
	RAL
	MOV	M,A
	DCX	H
	MOV	A,M
	RAL
	MOV	M,A
	DCR	C
	JNZ	LSH1
	POP	B
	RET
;
;	NORMU - REGS A,BC,DE ARE ALTERED.
;
NORMU:	PUSH	H
	XRA	A
	ORA	M
	INX	H
	ORA	M
	INX	H
	ORA	M
	INX	H
	ORA	M
	INX	H
	ORA	M
	INX	H
	ORA	M
	INX	H
	ORA	M
	INX	H
	ORA	M
	INX	H
	POP	H
	JZ	NORE		;NUMBER IS ZERO, QUIT.
	MVI	D,0		;D=EXPONENT.
NU2:	INX	H
	MOV	A,M
	ANI	0F0H
	DCX	H
	ORA	M
	JZ	NU3		;BRANCH IF SIGN & EXPONENT ARE ZERO.
	MVI	E,1
	CALL	RSH		;SHIFT RIGHT ONE DIGIT.
	INR	D
	JMP	NU2		;TEST EXP & SIGN FOR ZERO.
NU3:	INX	H
	MOV	A,M
	DCX	H
	ANI	0FH
	JNZ	NU4		;DONE IF FIRST DIGIT NON-ZERO.
	MVI	E,1
	CALL	LSH		;LEFT SHIFT ONE DIGIT.
	DCR	D
	JMP	NU3		;CHECK FIRST DIGIT AGAIN.
NU4:	MOV	M,D		;STORE THE EXPONENT.
NORE:	RET
;
;	NORM - REGS A,BC,DE ARE ALTERED.
;
NORM:	INX	H
	MOV	A,M
	ANI	0F0H
	PUSH	PSW		;SAVE THE SIGN.
	MOV	A,M
	ANI	0FH
	MOV	M,A		;STRIP THE SIGN.
	DCX	H
	MVI	M,0		;ZERO THE EXPONENT.
	CALL	NORMU
	POP	B
	INX	H
	MOV	A,M
	ANA	A
	JZ	NORME		;BRANCH IF NUMBER IS ZERO.
	ORA	B
	MOV	M,A		;SET THE SIGN.
NORME:	DCX	H
	RET
;
;=======================================================================;
;									;
;                        BCD INTEGER SUPPORT ROUTINES			;
;									;
;	NEGI	-	Negate the BCD integer pointed to by HL.	;
;			(HL) := -(HL)					;
;									;
;	ADDI	-	Add the two BCD numbers pointed to by DE and HL ;
;			and leave the sum in HL.			;
;			(HL) := (HL)+(DE)				;
;									;
;	SUBI	-	Subtract the BCD number pointed to by HL from	;
;			the BCD number pointed at by DE and place the	;
;			result in (HL).					;
;			(HL) := (HL)-(DE)				;
;									;
;=======================================================================;
;
;	ADDI - REGISTERS BC & A ARE ALTERED.
;
ADDI:	LXI	B,NB-1
	XCHG
	DAD	B
	XCHG			;SET DE TO LAST BYTE.
	DAD	B		;SET HL TO LAST BYTE.
	LDAX	D
	ADD	M
	DAA
	MOV	M,A
	DCX	D
	DCX	H
	LDAX	D
	ADC	M		;A := (DE)+(HL)+CARRY
	DAA
	MOV	M,A		;STORE IN (HL).
	DCX	D
	DCX	H
	LDAX	D
	ADC	M		;A := (DE)+(HL)+CARRY
	DAA
	MOV	M,A		;STORE IN (HL).
	DCX	D
	DCX	H
	LDAX	D
	ADC	M		;A := (DE)+(HL)+CARRY
	DAA
	MOV	M,A		;STORE IN (HL).
	DCX	D
	DCX	H
	LDAX	D
	ADC	M		;A := (DE)+(HL)+CARRY
	DAA
	MOV	M,A		;STORE IN (HL).
	DCX	D
	DCX	H
	LDAX	D
	ADC	M		;A := (DE)+(HL)+CARRY
	DAA
	MOV	M,A		;STORE IN (HL).
	DCX	D
	DCX	H
	LDAX	D
	ADC	M		;A := (DE)+(HL)+CARRY
	DAA
	MOV	M,A		;STORE IN (HL).
	DCX	D
	DCX	H
	LDAX	D
	ADC	M		;A := (DE)+(HL)+CARRY
	DAA
	MOV	M,A		;STORE IN (HL).
	RET
;
;	NEGI - REGISTERS BC & A ARE ALTERED.
;
NEGI:	MVI	B,099H
	MOV	A,B
	SUB	M		;A := 099H-(HL)
	MOV	M,A		;STORE IN (HL).
	INX	H
	MOV	A,B
	SUB	M		;A := 099H-(HL)
	MOV	M,A		;STORE IN (HL).
	INX	H
	MOV	A,B
	SUB	M		;A := 099H-(HL)
	MOV	M,A		;STORE IN (HL).
	INX	H
	MOV	A,B
	SUB	M		;A := 099H-(HL)
	MOV	M,A		;STORE IN (HL).
	INX	H
	MOV	A,B
	SUB	M		;A := 099H-(HL)
	MOV	M,A		;STORE IN (HL).
	INX	H
	MOV	A,B
	SUB	M		;A := 099H-(HL)
	MOV	M,A		;STORE IN (HL).
	INX	H
	MOV	A,B
	SUB	M		;A := 099H-(HL)
	MOV	M,A		;STORE IN (HL).
	INX	H
	MOV	A,B
	SUB	M
	ADI	1
	DAA
	MOV	M,A
	DCX	H
	MOV	A,M
	ACI	0
	DAA
	MOV	M,A
	DCX	H
	MOV	A,M
	ACI	0
	DAA
	MOV	M,A
	DCX	H
	MOV	A,Mtring pointer */
	return F_EOF;
}

Xgetc()
{
	return getc(gl_where);
}

/*
 * Xpushback is an internal routine for pushing a character
 * back onto the input stream.
 */
Xpushback(c)
 char c;
{
	(*gl_u_kind)(c);
/*
	switch(gl_kind) {
	case STD:
		Xugetchar(c);
		break;
	case NSTD:
		Xungetc(c);
		break;
	default:
		sugetc(c);
		break;
	}
*/
}

Xungetc(c)
 char c;
{
	return ungetc(c,gl_where);
}

sugetc(c)
 char c;
{
	*--gl_where = c;
}

/*
 * scanf - just reverse the argument string and call
 * Xrscanf with the correct argument list.
 */
int Xstdin;

scanf(nargs)
 int nargs;
{
	if(nargs < 1)
		return F_EOF;

	return Xrscanf(STD, U_STD, Xstdin, Xrev(&nargs));
}

/* reverse a set of list function arguments */
int *
Xrev(nargs)
 int *nargs;
{
	register int *p;
	register int *q;
	int *temp;

	q = p = nargs;	/* p and q point to start of argument list */
	 /* for p from end of argument list up to beginning... */
	for (p += *p; p >= q; --p) {
		temp = *p;
		*p = *q;
		*q++ = temp;
	}
	return nargs;
}

/*
 * sscanf - just reverse the argument list and call Xrscanf
 */
sscanf(nargs)
 int nargs;
{
	register int *p;

	if(nargs < 2)
		return F_EOF;

	p = Xrev(&nargs);
	return Xrscanf(STR, U_STR, *p, p+1);
}

/*
 * fscanf - just call Xrscanf after reversing the argument list.
 */
fscanf(nargs)
 int nargs;
{
	register int *p;

	if(nargs < 2)
		return F_EOF;

	p = Xrev(&nargs);
	return Xrscanf(NSTD, U_NSTD, *p, p+1);
}

#define MAXLINE 132	/* maximum length of text line */

/*
 *	Xrprintf -- does the formating work given the buffer
 *		AND the arguments in the proper order (reverse of SCC
 *		normal order).
 */

Xrprintf(line,args)
 char *line;
 int *args;
{
	register char *wptr;
	char Xuspr();
	char c, base, *sptr;
	char wbuf[MAXLINE], pf, ljflag;
	int width, precision;
	char negdec, leadch;
	char *format, *backup;
	char *wptr1;

	for(format = *args++; c = *format++; ) /* step through the format */
		if(c!='%')
			*line++ = c; /* just print normal characters */
		else {
			backup = format;
			wptr = wbuf;
			precision = 6;
			negdec = pf = 0;

			 /* left justify this field? */
			if(ljflag = (*format == '-'))
				++format;

			/* normally blank-padding */
			leadch = (*format=='0')? '0': ' '; 

			width = Xgv2(&format);
			if((c = *format++) == '.') {
				precision = Xgv2(&format);
				++pf;
				c = *format++;
			}

			switch(c) {
			case 'l':
			case 'h':
				/* ignore short and long modifiers */
				if(index("xodu", c = *format++)==NULL)
					return;
			}

			if((c = toupper(c)) != 'S' && width == 0)
				width = 1;

			switch(c) { /* format type */

			case 'D':
				if(*args < 0) { /* signed decimal */
					negdec = 1;
					*args = -*args;
				}

			case 'U':  base = 10; goto val; /* unsigned decimal */

			case 'X':  base = 16; goto val;

			case 'O':  base = 8;
				/*
				 * note that arbitrary bases can
				 * be added easily before this line
				 */
				 val:
					wptr1 = wptr;
					width -= Xuspr(&wptr1, *args++, base);
					wptr = wptr1;
					goto pad;

			case 'C':  *wptr++ = *args++; /* character */
				--width;
				goto pad;

			case 'S':
				if(!pf || precision>=MAXLINE)
					precision = MAXLINE-1;

				for(sptr = *args++;;) {
					if(*sptr==0)
						break;

					if(precision==0)
						break;

					if(wptr < wbuf+MAXLINE)
						*wptr++ = *sptr;

					++sptr;
					--width;
					--precision;
				}

			     pad:
					
				if(!ljflag) { /* setmem */
					if(negdec && leadch == '0') {
						*line++ = '-';
						negdec = 0;
						--width;
					}
					while(--width >= 0)
						*line++ = leadch;
				}

				if(negdec) {
					*line++ = '-';
					--width;
				}

				
				for(*wptr='\0', wptr=wbuf; *line++ = *wptr++;)
					;

				--line;		/* forget the '\0' */

				if(ljflag)	/* setmem */
					while(--width >= 0)
						*line++ = ' ';
				break;

/*			case 'F':
			case 'G':*/
			 case '%':
				++bac 
	ACI	0
	DAA
	MOV	M,A
	DCX	H
	MOV	A,M
	ACI	0
	DAA
	MOV	M,A
	DCX	H
	MOV	A,M
	ACI	0
	DAA
	MOV	M,A
	DCX	H
	MOV	A,M
	ACI	0
	DAA
	MOV	M,A
	DCX	H
	MOV	A,M
	ACI	0
	DAA
	MOV	M,A
	RET
;
;	SUBI - REGISTERS BC & A ARE ALTERED.
;
SUBI:	LXI	B,NB-1
	XCHG
	DAD	B
	XCHG			;SET DE TO LAST BYTE.
	DAD	B		;SET HL TO LAST BYTE.
	XCHG
	MVI	A,9AH
	SUB	M
	XCHG
	ADD	M
	DAA
	MOV	M,A
	DCX	D
	DCX	H
	XCHG
	MVI	A,99H
	ACI	0
	SUB	M
	XCHG
	ADD	M		;A := (HL)-(DE).
	DAA
	MOV	M,A		;STORE IN (HL).
	DCX	D
	DCX	H
	XCHG
	MVI	A,99H
	ACI	0
	SUB	M
	XCHG
	ADD	M		;A := (HL)-(DE).
	DAA
	MOV	M,A		;STORE IN (HL).
	DCX	D
	DCX	H
	XCHG
	MVI	A,99H
	ACI	0
	SUB	M
	XCHG
	ADD	M		;A := (HL)-(DE).
	DAA
	MOV	M,A		;STORE IN (HL).
	DCX	D
	DCX	H
	XCHG
	MVI	A,99H
	ACI	0
	SUB	M
	XCHG
	ADD	M		;A := (HL)-(DE).
	DAA
	MOV	M,A		;STORE IN (HL).
	DCX	D
	DCX	H
	XCHG
	MVI	A,99H
	ACI	0
	SUB	M
	XCHG
	ADD	M		;A := (HL)-(DE).
	DAA
	MOV	M,A		;STORE IN (HL).
	DCX	D
	DCX	H
	XCHG
	MVI	A,99H
	ACI	0
	SUB	M
	XCHG
	ADD	M		;A := (HL)-(DE).
	DAA
	MOV	M,A		;STORE IN (HL).
	DCX	D
	DCX	H
	XCHG
	MVI	A,99H
	ACI	0
	SUB	M
	XCHG
	ADD	M		;A := (HL)-(DE).
	DAA
	MOV	M,A		;STORE IN (HL).
	RET
;
;
;=======================================================================;
;									;
;                    BCD FLOATING POINT SUPPORT ROUTINES		;
;									;
;	NEGF	-	Negate the BCD FP number pointed to by HL.	;
;			(HL) := -(HL)					;
;									;
;	ADDF	-	Add the two BCD numbers pointed to by DE and HL ;
;			and leave the sum in HL.			;
;			(HL) := (HL)+(DE)				;
;									;
;	SUBF	-	Subtract the BCD number pointed to by HL from	;
;			the BCD number pointed at by DE and place the	;
;			result in (HL).					;
;			(HL) := (HL)-(DE)				;
;									;
;	MULF	-	Multiply the two BCD FP numbers pointed at by	;
;			DE & HL.HL).	HL points to the product on 	;
;			return if no errors occured.			;
;									;
;	DIVF	-	Divide the BCD FP number pointed at by HL by	;
;			the BCD FP number pointed at by DE.  HL points	;
;			to the quotient on return if no errors occured. ;
;									;
;	NORMF	-	Normalize the floating point number pointed to  ;
;			by HL.						;
;			(HL) := NORMALIZE (HL)				;
;									;
;=======================================================================;
;
;	NEGF - reg A IS altered.
;
NEGF:	INX	H
	MOV	A,M
	XRI	90H		;FLIP THE SIGN DIGIT.
	MOV	M,A		;STORE IT.
	DCX	H
	XRA	A		;RETURN NO ERROR.
	RET
;
;	ADDF - regs A & BC,DE are altered.  (DE), (HL) ARE ALSO ALTERED.
;
ADDF:	PUSH	D
	INX	H
	MOV	B,M
	MOV	A,M
; check if number is zero.
	ANI	0FH
	jnz	notzero
	dcx	h
	pop	d
	xchg
	call	copyn
	xchg
	ret
notzero:
	MOV	M,A		;REMOVE THE SIGN.
	dcx	h
	MOV	E,M
	MVI	M,0		;SET EXP TO 0.
	XTHL
	push	d
	INX	H
	MOV	C,M
	MOV	A,M
	ANI	0FH
	jnz	notz2
	pop	d
	pop	h
	mov	m,e		;wheel exponent back in.
	inx	h
	mov	m,b		;and the sign.
	dcx	h
	ret
notz2:
	MOV	M,A		;REMOVE THE SIGN.
	DCX	H
	MOV	E,M
	MVI	M,0		;SET EXP TO 0.
	XTHL
;	changed by jll to test for lost significance.
	mov	a,e
	sub	l
	jp	pos
	cpi	80h
	jz	lost
	cma
	inr	a
pos:	cpi	0dh
	jm	aok
lost:
	mov	a,l
	cmp	e	; an 8080 signed >=
	jm	jlt	
	jpo	hlbig
	jmp	debig
jlt:	jpe	hlbig
debig:	mov	b,e
	pop	d
	pop	h
	xchg
	call	copyn
	xchg
	mov	m,b
	inx	h
	mov	m,c
	dcx	h
	ret
hlbig:
	pop	d
	pop	h
	mov	m,a
	inx	h
	mov	m,b
	dcx	h
	ret
aok:
	MOV	A,L
	SUB	E
	JZ	ADDF3
	MOV	A,L
	XRA	E
	JP	ADDFA		;BOTH SIGNS ARE ALIKE.
	MOV	A,L
	ANA	A
	JM	ADDF1		;EXP(X) < EXP(Y).
	JMP	ADDF0
ADDFA:	MOV	A,L
	CMP	E
	JM	ADDF1		;EXP(X) < EXP(Y).
ADDF0:	MOV	A,L
	SUB	E
	MOV	E,L
	POP	H
	JMP	ADDF2
ADDF1:	MOV	A,E
	SUB	L
	MOV	H,C
	MOV	C,B
	MOV	B,H
	POP	H
	XTHL
ADDF2:	PUSH	D
	PUSH	B
	MOV	E,A
	CALL	RSH
	POP	B
	POP	D
	PUSH	H
ADDF3:	POP	H
	MOV	A,C
	ANI	0F0H
	JZ	ADDF4
	PUSH	D
	PUSH	B
	CALL	NEGI
	POP	B
	POP	D
ADDF4:	XTHL
	MOV	A,B
	ANI	0F0H
	JZ	ADDF5
	PUSH	D
	CALL	NEGI
	POP	D
ADDF5:	XCHG
	XTHL
	CALL	ADDI
	MOV	A,M	
	ANI	0F0H
	JZ	ADDF6
	CALL	NEGI
	MVI	A,90H
ADDF6:	kup;	/* then do default: */

			 default: *line++ = '%';
		 		format = backup;

		}
	}
	*line = '\0';
}

/*
	Internal routine used by "sprintf" to perform ascii-
	to-decimal conversion and update an associated pointer:
*/
int
Xgv2(sptr)
 int *sptr;
{
	register int n;
	char *ptr;

	for(n = 0, ptr = *sptr; isdigit(*ptr); )
		n = 10 * n + *ptr++ - '0';

	*sptr = ptr;
	return n;
}

/*
	Internal function which converts n into an ASCII
	base `base' representation and places the text
	at the location pointed to by the pointer pointed
	to by `string.' Yes, you read that correctly.
*/

char
Xuspr(string, n, base)
 char **string;
 unsigned n;
 unsigned base;
{
	register unsigned b;

	if(n < (b=base)) {
		*(*string)++ = n + ((n < 10) ? '0' : 'A'-10);
		return 1;
	}

	return
		Xuspr(string, n/b, b)
			+
		Xuspr(string, n%b, b);
}

printf(nargs)
 int nargs;
{
	char line[MAXLINE];

	if(nargs < 1)
		return NULL;

	Xrprintf(line,Xrev(&nargs));
	return puts(line);
}

/*
 * standard sprintf, reverse the arguments on the stack and call rprintf
 */
sprintf(nargs)
 int nargs;
{
	register int *p;

	if(nargs < 2)
		return;

	p = Xrev(&nargs);
	Xrprintf(*p, p+1);
}

/*
 * fprintf -- formatted print on output stream
 * just reverse the arguments and let rprintf do the work
 */

fprintf(nargs)
 int nargs;
{
	register int *p;
	char line[MAXLINE];

	if(nargs < 2)
		return F_EOF;

	p = Xrev(&nargs);
	Xrprintf(line, p+1);
	return fputs(line, *p);
}
e location pointed to by the pointer pointed
	to by `string.' Yes, you read that correctly.
*/

char
Xuspr(string, nter int *p;

	if(nargs < 2)
		return;

	p = Xrev(&nargs);
	Xrprintf(*p, p+1);
}

/*
 * fprintf -- formatted print on output stream
 * just reverse the arguments and let rprintf do the work
 */

fprintf(nargs)
 int nargs;
{
	register int *p;
	char line[MAXLINE];

	if(nargs < 2)
		return F_EOF;

	p = Xrev(&nargs);
	Xrprintf(line, p+1);
	return fputs(line, *p)/* func.c	misc. machine independent functions written in C.
 *
 *		MQH 2/82
 *		RB  4/82 -- efficiency mods
 *		RB  3/20/83 -- setup for C 1.2
 *		RB  1/5/83  fixes for signed character systems
 *
 *	All of these functions are machine independent, with the exception
 *	of bios.
 */

#include	"customiz.h"
#include	"stdio.h"

#define _TRUE	(1/*1 == 1*/)
#define _FALSE	(0/*!_TRUE*/)

isalnum(c)
 char c;
{
	register char cc;

	return isalpha(cc = c) || isdigit(cc);
}

isascii(c)
 char c;
{
	return (c&0x80)==0;
}

iscntrl(c)
 char c;
{
	return (c&0xE0)==0;
}

ispunct(c)
 char c;
{
	register char cc;

	return isascii(cc = c) && !iscntrl(cc) && !isalnum(cc);
}

isprint(c)
 char c;
{
	register int cc;

	return (cc = c&0xff) >= ' ' && cc <= '~';
}

isspace(c)
 char c;
{
	switch(c) {
	case ' ':
	case '\t':
	case '\n':
		return _TRUE;
	default:
		return _FALSE;
	}
}

isnumeric(c,radix)
 char	c;
 int	radix;
{
	register char cc;

	cc = toupper(c);
	if(radix <= 10)
		return (cc >= '0' && cc <= '0' + (radix - 1));
	else
		return (cc >= '0' && cc <= '9')
		    || (cc >= 'A' && cc <= 'A' + (radix - 11));
}

tolower(c)
 char c;
{
	register char cc;

	return isupper(cc=c)? (cc + ' '): cc;
}

strncpy(d,s,n)
 char *d, *s;
 int n;
{
	register char *dd;

	for(dd = d; n--; )
		*dd++ = *s? *s++: 0;

	return d;
}

strcpy(d,s)
 char *d, *s;
{
	register char *rd;

	for(rd=d; *rd++ = *s++; )
		;

	return rd;
}

strcat(d,s)
 char *d, *s;
{
	register char *dd;

	for(dd = d; *dd++; )
		;

	for(--dd; *dd++ = *s++;)
		;

	return d;
}

strncat(d,s,n)
 char *d, *s;
 int n;
{
	register char *dd;

	for(dd = d; *dd++;)
		;

	for(--dd;;) {
		if(!n--) {
			*dd = 0;
			break;
		}
		if(!(*dd++ = *s++))
			break;
	}

	return d;
}

#ifdef STREQ		/* in assembly language on 8080			*/
streq(pattern,str)	/* Like substr, but it returns the end of string */
 char pattern[],str[];	/* instead of the beginning of string	 PUSH	PSW
	CALL	NORMU
	POP	PSW
	POP	D
	MOV	B,A
	INX	H
	MOV	A,M
	ANI	0FH
	DCX	H
	JZ	ADDFE
	INX	H
	ORA	B
	MOV	M,A
	DCX	H
	CALL	ADDEXP
ADDFE:	RET
;
;	SUBF - regs A & BC are altered.
;
SUBF:	XCHG			;X := X-Y
	CALL	NEGF		;Y := -Y
	CALL	ADDF		;X := X+(-Y)
	RET
;
;	MULF - REGS A,BC ARE ALTERED.
;
MULF:	PUSH	D
	MOV	E,M
	MVI	M,0		;SET EXP TO 0.
	INX	H
	MOV	A,M
	MOV	B,M
	ANI	0FH
	MOV	M,A		;ZERO THE SIGN.
	DCX	H
	XTHL
	PUSH	D
;	GETEXP	MOV	E,M
	mov e,m			; change hs 6/12/81
	MVI	M,0		;SET EXP TO 0.
	INX	H
	MOV	A,M
	MOV	C,M
	ANI	0FH
	MOV	M,A		;ZERO THE SIGN.
	DCX	H
	MOV	A,C
	XRA	B
	ANI	0F0H		;COMPUTE THE SIGN OF THE PRODUCT.
	MOV	B,A
	XTHL
	PUSH	B
	CALL	ADDEX
	JNZ	MERR3		; EXPONENT TROUBLES.
	POP	B
	POP	D
	XTHL
	PUSH	B
; MULTIPLY THE MANTISAS NOW.
	PUSH	H
	LXI	H,bcdret
	CALL	ZERON		;INITIALIZE THE PRODUCT.
	POP	H
	INX	H
	PUSH	H
	MOV	A,M
	ANI	0FH
	JZ	MULT2
	LXI	H,bcdret
MULT1:	PUSH	PSW
	CALL	ADDI
	POP	PSW
	DCR	A
	JNZ	MULT1
MULT2:	LXI	H,1
	XCHG
	CALL	RSH
	XCHG
	POP	H
	MVI	C,NB-2
MULT3:	PUSH	B
	INX	H
	PUSH	H
	MOV	A,M
	RAR
	RAR
	RAR
	RAR
	ANI	0FH
	JZ	MULT5
	LXI	H,bcdret
MULT4:	PUSH	PSW
	CALL	ADDI
	POP	PSW
	DCR	A
	JNZ	MULT4
MULT5:	LXI	H,1
	XCHG
	CALL	RSH
	XCHG
	POP	H
	PUSH	H
	MOV	A,M
	ANI	0FH
	JZ	MULT7
	LXI	H,bcdret
MULT6:	PUSH	PSW
	CALL	ADDI
	POP	PSW
	DCR	A
	JNZ	MULT6
MULT7:	LXI	H,1
	XCHG
	CALL	RSH
	XCHG
	POP	H
	POP	B
	DCR	C
	JNZ	MULT3
	LXI	H,bcdret
	CALL	NORMU
	POP	B
	POP	D
	INX	H
	MOV	A,M
	ANA	A
	JZ	MDONE		;QUIT IF NUMBER IS ZERO.
	ORA	B
	MOV	M,A		;SET THE SIGN.
	DCX	H
	CALL	ADDEXP
	INX	H
MDONE:	DCX	H
	RET
MERR3:	POP	H
	POP	H
	POP	H
	RET
;
;	DIVF - ALL REGS, (DE), (HL) ARE ALTERED.
;
; DIVF:	XCHG
DIVF:	INX	H
	MVI	A,0FH		; TAKE CARE OF -0.
	ANA	M
	DCX	H
	xchg
	JZ	DERR1		;DIVISION BY 0.
;INITIALIZE THE NUMBERS.
	PUSH	H
	LXI	H,bcdret
	CALL	ZERON
	XTHL
	XCHG
	INX	H
	MOV	A,M
	MOV	C,M
	ANI	0FH
	MOV	M,A
	DCX	H
	MOV	B,M
	MVI	M,0
	XCHG
	INX	H
	MOV	A,M
	XRA	C		;COMPUTE THE SIGN OF THE QUOTIENT.
	ANI	0F0H
	MOV	C,A
	MOV	A,M
	ANI	0FH
	MOV	M,A
	DCX	H
	MOV	A,M
	MVI	M,0
	XTHL
	INX	H
	MOV	M,C
	DCX	H
	MOV	C,A		;CALCULATE THE EXPONENT OF THE QUOTIENT.
	SUB	B
	MOV	M,A	; move exponent into answer.
	MOV	A,C		;CHECK FOR ARITHMETIC OVERFLOW.
	XRA	B
	ANI	080H
	JZ	EOK
	MOV	A,M
	XRA	C
	ANI	080H
	JZ	EOK
; EXPONENTS ARE SAME SIGN, QUOTIENT SIGN NOT SAME AS
; DIVIDEND SIGN.
	push	h
	LHLD	BERRFL		; CHANGE IFF NOT ALREADY SET.
	MOV	A,H
	ORA	L
	JNZ	JL4
	ORA	C
	JP	JJ4
	LXI	H,0-3			; UNDERFLOW.
	JMP	JJ5
JJ4:	LXI	H,0-1			; OVERFLOW.
JJ5:	SHLD	BERRFL
JL4:	POP	H		;CLEAR THE STACK.
	POP	H
	RET
EOK:	INX	H
	XTHL
	MVI	B,0
DIVF1:	MVI	C,255
DIVF2:	INR	C
; This loop is forced to terminate after 9 iterations.
	MOV	A,C
	CPI	09H
	JZ	DIVFF
	PUSH	B
	CALL	SUBI
	POP	B
	MOV	A,M
	ANI	0F0H
	JZ	DIVF2
	PUSH	B
	CALL	ADDI
	POP	B
DIVFF:	XTHL
	MOV	A,B
	ANI	1
	JNZ	DIVF3
	MOV	A,M
	ORA	C
	MOV	M,A		;STORE AS LOW ORDER DIGIT.
	INX	H
	JMP	DIVF4
DIVF3:	MOV	A,C
	RAL
	RAL
	RAL
	RAL
	ANI	0F0H
	MOV	M,A		;STORE AS HIGH ORDER DIGIT.
DIVF4:	XTHL
	INR	B
	MOV	A,B
	CPI	NDF
	JZ	DIVF5		;DONE.
	PUSH	B
	PUSH	H
	XCHG
	LXI	D,1
	CALL	RSH		;SHIFT Y RIGHT 1 DIGIT.
	XCHG
	POP	H
	POP	B
	JMP	DIVF1
DIVF5:	POP	H
	LXI	H,bcdret
	MOV	E,B
	CALL	NORMF
	RET
DERR1:	PUSH	H
	LHLD	BERRFL		; CHANGE IFF NOT ALREADY SET.
	MOV	A,H
	ORA	L
	JNZ	JJ8
	LXI	H,0-2		; DIVISION BY 0 ERROR.
	SHLD	BERRFL
JJ8:	POP	H
	RET
;
;	NORMF - regs A,BC & DE  are altered.
;
NORMF:	MOV	E,M
	PUSH	D
	MVI	M,0		;SET EXP TO 0.
	CALL	NORM
	POP	D
	INX	H
	MOV	A,M
	DCX	H
	ANI	0FH
	JZ	NORF1		;RESULT IS ZERO, EXIT.
	CALL	ADDEXP		;add the old exponent in.
NORF1:	RET
#endasm

#ifndef CINIT

#asm
;
;
; machine language initialized BCD constants
;
; Copyright (c) 1983  by SuperSoft, Inc.
;

;	DSEG

Bmaxneg:  db 04H,093H,027H,068H,00H,00H,00H,00H

Bzero:  db 00H,00H,00H,00H,00H,00H,00H,00H

Bhalf:  db 0FFH,05H,00H,00H,00H,00H,00H,00H

Bone:  db 00H,01H,00H,00H,00H,00H,00H,00H

Btwo	*/
{
	register char *s;
	char *pat;

	for(pat=pattern, s=str; *pat; ) {
		if(*s++ != *pat++)
			return 0;
	}
	return s-str;
}
#endif

strcmp(s,t)
 char *s, *t;
{
	register char *ss;

	for(ss = s;;) {
		if(*ss != *t++)
			return *ss-t[-1];
		if(*ss++ == '\0')
			return 0;
	}
}

strncmp(s,t,n)
 char *s, *t;
 unsigned n;
{
	register char *ss;

	for(ss = s; --n; ) {
		if(*ss != *t++)
			return *ss-t[-1];
		if(*ss++ == '\0')
			return 0;
	}
	return *ss-*t;
}

char *
rindex(s,c)
 char *s, c;
{
	register char *ss;
	char *match;

	for(match = 0, ss = s; *ss; )
		if(*ss++==c)
			match = ss-1;

	return match;
}

/*
 *	is A a substring of B ?
 */
char *
substr(pa,pb)
 char *pa;
 char *pb;
{
	register char *a;
	char *b;
	char *saveb;

	for(a=pa, saveb=b=pb; ; ) {
		if(*a == '\0')
			return saveb;
		if(*b == '\0')
			return NULL;
		if(*a++ != *b++) {
			a = pa;
			saveb = b;
		}
	}
}

/*
 *	is A a substring of B (case irrelevent) ?
 */
char *
usubstr(pa,pb)
 char *pa;
 char *pb;
{
	register char *a;
	char *b;
	char *saveb;

	for(a=pa, saveb=b=pb; ; ) {
		if(*a == '\0')
			return saveb;
		if(*b == '\0')
			return NULL;
		if(toupper(*a++) != toupper(*b++)) {
			a = pa;
			saveb = b;
		}
	}
}

atoi(n)
 char *n;
{
	register int val; 
	char c;
	char sign;

	while(iswhite(*n++))
		;

	switch(*--n) {
	case '-':
		sign = 1;
		++n;
		break;
	case '+':
		++n;
	default:
		sign = 0;
	}

	for(val=0; isdigit(c = *n++);)
		val = val*10 + c - '0';

	return sign? -val: val;
}

#define MHZ	4
sleep(n)	/* n = xths of seconds on Z80 with speed of MHZ */
 unsigned n;
{
	register unsigned i;

	for( ; --n; )
		for(i = MHZ * 0x900; --i; )
			;
}

#ifndef	ABSVAL
abs(n)
 int	n;
{
	register int nn;

	return (nn=n) < 0? -nn: nn;
}
#endif

absval(n)	/* abs is reserved on certain 8086 assemblers */
 int	n;
{
	register int nn;

	return (nn=n) < 0? -nn: nn;
}

min(a,b)
 int a, b;
{
	return a<b? a: b;
}

max(a,b)
 int a, b;
{
	return a<b? b: a;
}

kbhit()	/* remove me.. */
{
	return cconst();	/* rename me... */
}

pause()
{
	for(;!kbhit();)
		;	
}

putdec(nn)		/* display decimal number w/out printf's overhead */
 int nn;
{
	register unsigned n;

	n = nn>=0? nn: (putchar('-'), -nn);

	if(nn = n/10)
		putdec(nn);

	putchar(n%10+'0');
}

int ccrand;

srand(seed)
 int seed;
{
	register int i;

	if(!seed) {
		puts("Wait a moment, then strike a key");
		for(;!kbhit();++i)
			;
		ccrand = i;
	}
	else
		ccrand = seed;
}

rand()
{
#define M	32749
#define A	32719
#define C	3

	return ccrand = (ccrand * A + C) % M;
}

/* the rest of these functions are not often used */

char
peek(a)
 char *a;
{
	return *a;
}

poke(a,c)
 char *a, c;
{
	*a = c;
}

initw(var,string)
 int *var;
 char *string;
{
	while(string)
		*var++ = getval(&string);
}

initb(var,string)
 char *var, *string;
{
	while(string)
		*var++ = getval(&string);
}

getval(strptr)
 int *strptr;
{
	register char *p;
	int n;

	p = *strptr;
	if(*p == 0)
		return *strptr = 0;

	for(n = 0; isdigit(*p); )
		n = n * 10 + *p++ - '0';

	while(*p && !isdigit(*p))
		++p;

	*strptr = p;
	return n;
}

qsort(base, nrecs, reclen, cmpfn)
 int nrecs, reclen;
 char *base; int (*cmpfn)();
{
	register char *jd;
	int gap, ngap, i, j;
	int t1, t2;

	t1 = nrecs*reclen;
	for(ngap = nrecs/2; ngap > 0; ngap /= 2) {
		gap = ngap*reclen;
		t2 = gap+reclen;
		jd = base+gap;
		for(i = t2; i <= t1; i += reclen)
		for(j = i-t2; j >= 0; j -= gap) {
			if ((*cmpfn)(base+j, jd+j) <=0)
				break;
			Xswp(base+j, jd+j, reclen);
		}
	}
}

static
Xswp(a, b, cnt)
 char *a, *b;
 int cnt;
{
	register char tmp;

	while(cnt--) {
		tmp = *a;
		*a++ = *b;
		*b++ = tmp;
	}
}

perror(s)
 char *s;
{
	if(*s) {
		puts(s);
		puts(": ");
	}

	switch(errno) {
	case 0:
		puts("No error");
		break;
	case BCE:
		puts("Byte count error");
		break;
	case NOFD:
		 :  db 00H,02H,00H,00H,00H,00H,00H,00H
 
Bthree:  db 00H,03H,00H,00H,00H,00H,00H,00H

Bfour:  db 00H,04H,00H,00H,00H,00H,00H,00H

Bten:  db 01H,01H,00H,00H,00H,00H,00H,00H

Bilmt:  db 01H,02H,00H,00H,00H,00H,00H,00H

Bmaxfact:  db 01H,08H,040H,00H,00H,00H,00H,00H

Bmax$num:  db 02H,02H,091H,081H,049H,063H,01H,056H

Bminus$max$num:  db 02H,092H,091H,081H,049H,063H,01H,056H

Binf:  db 07EH,09H,099H,099H,099H,099H,099H,099H

Bpi:  db 00H,03H,014H,015H,092H,065H,035H,089H

Bpi$by$2:  db 00H,01H,057H,07H,096H,032H,067H,094H

Blog$2:  db 0FFH,06H,093H,014H,071H,080H,055H,099H

Blog$10:  db 00H,02H,030H,025H,085H,09H,029H,094H

Bexpcoef:  db 00H,01H,045H,069H,099H,087H,050H,012H
 db 0FFH,092H,048H,076H,024H,033H,090H,052H
 db 0FEH,02H,014H,046H,055H,059H,094H,084H
 db 0FDH,091H,023H,057H,014H,08H,019H,098H
 db 0FBH,05H,034H,053H,05H,081H,079H,00H
 db 0FAH,091H,085H,06H,090H,071H,040H,00H
 db 0F8H,05H,034H,011H,087H,070H,00H,00H
 db 0F7H,091H,032H,015H,016H,00H,00H,00H
 db 0F5H,02H,086H,013H,00H,00H,00H,00H

Bsincoef:  db 00H,02H,055H,025H,057H,092H,048H,04H
 db 0FFH,092H,085H,026H,015H,069H,018H,010H
 db 0FDH,09H,011H,080H,016H,00H,066H,052H
 db 0FCH,091H,036H,058H,075H,013H,054H,020H
 db 0FAH,01H,018H,049H,061H,085H,080H,00H
 db 0F7H,096H,070H,027H,092H,00H,00H,00H
 db 0F5H,02H,066H,073H,00H,00H,00H,00H

Blogcoef:  db 0FFH,07H,052H,090H,056H,025H,083H,083H
 db 0FFH,03H,043H,014H,057H,050H,050H,076H
 db 0FEH,092H,094H,037H,025H,015H,022H,085H
 db 0FDH,03H,036H,070H,089H,025H,055H,064H
 db 0FCH,094H,033H,027H,058H,088H,061H,00H
 db 0FBH,05H,094H,070H,071H,019H,090H,00H
 db 0FAH,098H,050H,029H,067H,054H,010H,00H
 db 0FAH,01H,025H,04H,067H,036H,020H,00H
 db 0F9H,091H,087H,072H,079H,096H,00H,00H
 db 0F8H,02H,086H,030H,025H,010H,00H,00H
 db 0F7H,094H,042H,09H,057H,00H,00H,00H
 db 0F6H,06H,089H,056H,00H,00H,00H,00H
 db 0F6H,091H,08H,045H,010H,00H,00H,00H
 db 0F5H,01H,071H,076H,00H,00H,00H,00H
 db 0F4H,092H,073H,060H,00H,00H,00H,00H

Batncoef:  db 00H,01H,076H,027H,047H,017H,040H,039H
 db 0FFH,091H,05H,089H,029H,024H,054H,067H
 db 0FEH,01H,011H,035H,084H,020H,059H,040H
 db 0FDH,091H,038H,011H,095H,00H,036H,00H
 db 0FCH,01H,085H,074H,029H,073H,027H,090H
 db 0FBH,092H,062H,015H,019H,061H,013H,00H
 db 0FAH,03H,082H,010H,036H,059H,040H,00H
 db 0F9H,095H,069H,091H,086H,017H,00H,00H
 db 0F8H,08H,064H,088H,077H,090H,00H,00H
 db 0F8H,091H,033H,03H,038H,040H,00H,00H
 db 0F7H,02H,06H,085H,06H,00H,00H,00H
 db 0F6H,093H,024H,048H,060H,00H,00H,00H
 db 0F5H,05H,012H,080H,00H,00H,00H,00H
 db 0F4H,098H,015H,050H,00H,00H,00H,00H
 db 0F4H,01H,030H,040H,00H,00H,00H,00H
 db 0F3H,092H,09H,00H,00H,00H,00H,00H

;	CSEG

#endasm
#endif

double	*rval;

#define	BCDS	8

double *
doOp(dst, aa, bb, op)
/*	This routine does the call to the assembly language procs.
*/
 double	*dst;
 double	*aa;
 double	*bb;
 int	op;
{
#asm
bcdcal:	mov	h,b
	mov	l,c
	shld	jltmp1		; save register var
	pop	h		; return address
	shld	jltmp2
	pop	b		; opcode branch addr
	pop	d		; second operand
	lxi	h,adr
	xthl			; first oper <-> ret addr
	push	b		; branch address
	ret			; everything is relative

jltmp1:	ds	2
jltmp2:	ds	2

adr:	shld	rval		; save pointer to answer...
	push	h
	push	h
	push	h
	lhld	jltmp2		; restore ret addr
	push	h
	lhld	jltmp1		; restore register var
	mov	b,h
	mov	c,l
#endasm
	movmem(rval, dst, BCDS);
	return dst;
}
1H,033H,v	l,c
	shld	jltmp1		; save register var
	pop	h		; return address
	shld	jltmp2
	pop	b		; opcode branch addr
	pop	d		; second		puts("No open files");
		break;
	case NOFILE:
		puts("File not found");
		break;
	case INVFD:
		puts("Invalid file (unopened file)");
		break;
	case INVMODE:
		puts("I-O type mismatch");
		break;
	case OPENERR:
		puts("Error on open");
		break;
	case CREATERR:
		puts("Error on creat");
		break;
	case FSPECERR:
		puts("Invalid filename");
		break;
	case BADDEV:
		puts("Device out of range");
		break;
	case CLOSEERR:
		puts("Error in close");
		break;
	case INVREC:
		puts("Invalid record in seek");
		break;
	case INVSEEK:
		puts("Invalid seek");
		break;
	case ENOEXEC:
		puts("Can't exec");
		break;
	case ENOSPC:
		puts("No space");
		break;
	case ERLINK:
		puts("Can't link");
		break;
	case NOMEM:
		puts("Memory allocation failure");
		break;
	case INVBUF:
		puts("Invalid buffer");
		break;
	case READERR:
		puts("Read error");
		break;
	case EOFERR:
		puts("Eof error");
		break;
	case NOGETC:
		puts("No getc");
		break;
	default:
		if(~0xff&errno) {
			puts("bdos error (");
			switch(0x1ff&errno)
			{
			case CC_READ:
				puts("read");
				break;
			case CC_WRITE:
				puts("write");
				break;
			case CC_RREAD:
				puts("random read");
				break;
			case CC_RWRITE:
				puts("random write");
				break;
			case CC_DELETE:
				puts("delete");
				break;
			case CC_OPEN:
				puts("open");
				break;
			case CC_CREAT:
				puts("create");
				break;
			case CC_RENAME:
				puts("rename");
				break;
			case CC_CLOSE:
				puts("close");
				break;
			default:
				putdec((~0x1ff)&errno);
			}
			puts(")");
		}
		break;
	}
	puts("\n");
}

assert(b)
 int b;
{
	if(!b) {
		puts("Assertion failed\n");
		exit(2);
	}
}

swab(src, dst, cnt)
 char *src, *dst;
 unsigned cnt;
{
	register char *s;

	for(s=src; cnt--!=0; ++dst)
	{
		dst[1] = *s++;
		*dst++ = *s++;
	}
}

char *
topofmem()
{
	return sbrk(0);
}
"Eof error");
		break;
	case NOGETC:
		puts("No getc");
		break;
	default:
		if(~0xff&errno) {
		/*
 * MATH.C - Math Routines...
 *
 * for C 1.2
 */

#define NOT	~	/* tilde */

struct {
	unsigned unsign;
};

union ulong {
	long lng[1];
	int word[2];
};

#define	hi	word[0]
#define	lo	word[1]

cc2mov(a,b)
 long *a, *b;
{
	a->hi = b->hi;
	a->lo = b->lo;
}

cc2add(a,b)
 long *a, *b;
{
	register unsigned sum;

	sum = a->lo + b->lo;
	a->hi += b->hi +
	(sum < a->lo.unsign && sum < b->lo.unsign);

	a->lo = sum;
}

cc3add(q,a,b)
 long *q, *a, *b;
{
	register unsigned sum;

	q->lo = sum = a->lo + b->lo;
	q->hi = a->hi + b->hi +
	(sum < a->lo.unsign && sum < b->lo.unsign);
}

cc1inc(a)
 long *a;
{
	if(++(a->lo) == 0)
		++(a->hi);
}

cc1dec(a)
 long *a;
{
	if((a->lo)-- == 0)
		--(a->hi);
}

cc1com(a)
 long *a;
{
	a->hi = NOT a->hi;
	a->lo = NOT a->lo;
}

cc2com(a,b)
 long *a, *b;
{
	a->hi = NOT b->hi;
	a->lo = NOT b->lo;
}

cc2or(a,b)
 long *a, *b;
{
	a->hi |= b->hi;
	a->lo |= b->lo;
}

cc3or(a,b,c)
 long *a, *b, *c;
{
	a->hi = b->hi | c->hi;
	a->lo = b->lo | c->lo;
}

cc2and(a,b)
 long *a, *b;
{
	a->hi &= b->hi;
	a->lo &= b->lo;
}

cc3and(a,b,c)
 long *a, *b, *c;
{
	a->hi = b->hi & c->hi;
	a->lo = b->lo & c->lo;
}

cc2xor(a,b)
 long *a, *b;
{
	a->hi ^= b->hi;
	a->lo ^= b->lo;
}

cc3xor(a,b,c)
 long *a, *b, *c;
{
	a->hi = b->hi ^ c->hi;
	a->lo = b->lo ^ c->lo;
}

#ifdef FIXME
cc2sh(a,b)
 long *a;
 int b;
{
	xdsh(&a->hi,b);
	a->hi |= xdsh(&a->lo,b);
}

cc3sh(a,b,c)
 long *a, *b;
 int c;
{
	cc2mov(a,b);
	ccsdsh(a,c);
}

static
cc2ish(a,i)
 int *a;
 int i;
{
	register int x;
	int j;

	if(i>0) {
		j = 16-i;
		x = a >> j;
		*a <<= i;
	} else if(i<0) {
		j = i-16;
		x = a << j;
		*a >>= -i;
	} else
		return 0;

	return x&((1<<j)-1);
}
#endif FIXME

cc2cmp(a,b)
 long *a, *b;
{
	if(a->hi>b->hi)
		return 1;

	if(a->hi==b->hi) {
		if(a->lo.unsign>b->lo.unsign)
			return 1;
		else if(a->lo.unsign<b->lo.unsign)
			return -1;
		else	return 0;
	}
	return -1;
}


 ;asm/load instructions (assumes running from drive a:):
cc $1.c -OFILEB:$1.COD -BUFSIZ128
c2 B:$1.cod $2 +asm
ERA B:$1.COD
asm $1.BBz
era b:$1.asm
load B:$1
era B:$1.hex
;
; ;m80/l80 instructions:
; era $1.rel
; cc $1.c
; c2 $1.cod $2
; m80 =$1.asm
; l80 c2pre,$1,libc/s,c2post,$1/n/e/y
;
; ;m80/elink instructions:
; era $1.rel
; cc $1.c
; c2 $1.cod $2
; m80 =$1.asm
; elink bc($1);c2pre,$1;sr(libc);in(c2post);en;
;
; ;rmac/link instructions:
; era $1.rel
; cc $1.c
; c2 $1.cod $2 -ofile$1.mac
; rmac $1
; link $1,c2pre,libc[s],c2post
;
; ;rmac/elink instructions:
; era $1.rel
; cc $1.c
; c2 $1.cod $2 -ofile$1.mac
; rmac $1.asm
; elink bc($1);c2pre,$1;sr(libc);in(c2post);en;
;
1.asm
; l80 c2pre,$1,libc/s,c2post,$1/n/e/y
;
; ;m80/elink instructions:
; era $1.rel
; cc $1.c
; c2 $1.cod $2
; m80 =$1.asm
; elink bc($1);c2pre,$1;sr(libc);in(c2post);en;
;
; ;rmac/link instructions:
; era $1.rel
; cc $1.c
; c2 $1.cod $2 -ofÎ{|*<& |͌*9& |0! **|M!
!
! ͢P!  "*p:*(ͷDM}2%`i  o|*&|ʅ?Jp͇
**|ʛ**̓*<& |µ*>& |ʲ?! .cl
d*.  Y`i|.;	ͯY`i|<#.cl'%*(wDM  o|t*&)  e|͇
!
t*#"`i|Y!A  9s#r  9s#rͶ! 9^#V! 9^#V! 9^#V!|ʜ! 9^#V!|¢$å'%Y*(ͷDM  o|`i|	ð*(ͷDM  o|`i|;*%& |3!  DM  9sͶ*(ͷ 9s#r! 9^#V!|U !  9s)! 9^#V!0 ̓|w#9^#V!9 e|ʕ! 9^#V}2%& |ʰ`i$3`i
 =! 9^#V!DM)`i3! 9^#VwDM  o|`i`i|`i|.
`i|ʸ`i|ʸ`i!  """"}2G}2H"2".}29}2F""&"(!  "Ͱ!  "*,|ʈ***,d ͍|ʈ**,d "**"! *z"*#"#"I!  ? 9s#r  DM?#|##`izDM`i ̓|?  9s#r! 9^#Vpo|3! 9^#V! 9^#V z?!?*. 
*F& |W!
Z!
J	!
J	*.|!
J	* 
!K!	!l!!!l!!!l!y!#!(l!g!*!.l!U!/!3l!!:!Al!Bͭ"|&"!Jͭ"|*"!S  M}2C|;!d ",!Vͭ",!Y! ͱ||^!  f!^ͭ"!c  M}2;!g"*!m}2<!u}2A!x}2@!|}2>!}2=!}2:!}2D!}28!  M}2B!}2E!}2?!}2G!ͭ"4!|?!|! "!g!!U!!!  ss! 9^#V! ͱ|DM|ʖ!
 9^#V5ë! 9^#V! 9^#V!9! 9^#V! ͱ|DM|! 95!ͪ! 9^#Vͪ!ͪ!  9e 
!  9e! 9!  !
 9! 9^#V!  ͱ|  Y! 9^#V믾~! 9^#Vn& |~! 9^#Vs#r 9^#Vs#rn& }5! 9^#V!  s!J	!  
!. 	!  
!. 	!   
!J	! 9!  *&|! 9n& *&)  e|
	͇
!t
	!
cc2mul(pa,pb)
 long *pa, *pb;
{
	register char sign;
	long a, b;

	sign = (pa->hi>=0) ^ (pb->hi>=0);

	if(cc2cmp(pa,pb)<0)
	{
		cc2mov(&b,pa);
		cc2mov(pa,pb);
	} else {
		cc2mov(&b,pb);
	}

	if((pa->hi|pa->lo)==0)
		return;

	if((b.hi|b.lo)==0)
	{
		pa->hi = 0;
		pa->lo = 0;
		return;
	}
#ifdef EXPERIMENTAL
	/* really results in a 16 bit mul? */
	if(cc1bits(pa)+cc1bits(b)<=16)
		pa->lo = pa->lo*b.lo;
#endif

	/* sorry: */
	for(cc2mov(&a,pa);;){
		if(b.lo--==0)
			--b.hi;
		if((b.hi|b.lo)==0) {
			if(sign)
				cc1neg(pa);
			return;
		}
		cc2add(pa,&a);
	}
}

static
cc1bits(a)
 long *a;
{
	if(a->hi==0)
		return cc1ibits(a->lo);
	return cc1ibits(a->hi)+16;
}

static
cc1ibits(i)
 int i;
{
	register int j;

	for(j=16;j>=0;--j)
		if(i&(1<<j))
			return j;
	return 0;
}

cc2imul(x,b0,b1)
 long *x;
 int b0, b1;
{
	long b;

	b.hi = b0;
	b.lo = b1;
	cc2mul(x,&b);
}

cc2iadd(x,b0,b1)
 long *x;
 int b0, b1;
{
	long b;

	b.hi = b0;
	b.lo = b1;
	cc2add(x,&b);
}

cc1prt(a)	/* move me to formatio */
 long *a;
{
	printf("%x%4x",a->hi,a->lo);
}

cc3sub(a,b,c)
 long *a, *b, *c;
{
	cc2mov(a,b);
	cc2sub(a,c);
}

cc2sub(a,b)
 long *a, *b;
{
	long bb;

	cc2neg(&bb,b);
	cc2add(a,&bb);
}

cc1neg(d)
 long *d;
{
	cc1com(d);
	cc2iadd(d,0,1);
}

cc2neg(a,b)
 long *a, *b;
{
	cc2com(a,b);
	cc2iadd(a,0,1);
}

/*
 * Xdiv - Do a 32 Bit Signed Division...
 */
cc3div(d,s,ccxdrem)	/* should be cc4div... */
 long *d, *s, *ccxdrem;
{
	long q,v,n;

	cc2mov(&v,d);
	cc2mov(&n,s);
	if(v.hi<0)
		cc1neg(&v);

	if(n.hi<0)
		cc1neg(&n);

	/* 16 bit operation? */
	if((v.hi|n.hi)==0) {
		q.hi = 0;
		q.lo = v.hi/n.lo;
	} else {
	/*
	 * Start Quotient Counter at Negative One,
	 * and subtract the divisor until it goes negative...
	 */
		q.hi = -1;
		q.lo = -1;
		while(v.hi>=0)
		{
			cc2sub(&v,&n);
			cc1inc(&q);
		}
		cc2mov(ccxdrem,&v);
		cc2add(ccxdrem,&n);	/* form remainder */
	/*
	 * Now, negate the Quotient if the signs of the dividend
	 * and divisor were not the same...
	 */
		if((d->hi<0) ^ (s->hi<0))
			cc1neg(&q);

	}
	cc2mov(d,&q);
}
cc2mov(a,b);
	cc2sub(a,c);
}

cc2sub(a,b)
 long *a, *b;
{
	long bb;

	cc2neg(&bb,b);
	cc2add(ave One,
	 * and subtract the divisor until it goes negative...
	 */
		q.hi = -1;
		q.lo = -1;
		while(v.hi>=0)
		{
			cc2sub(&v,&n);
			cc1inc(&q);
		}
		cc2mov(ccxdrem,&v);
		cc2add(ccxdrem,&n);	/* form remainder */
	/*
	 * Now, negate the Qu  9n& ! 9n& ! 9n& |=	*;& |4	! Ϳ!
 Ϳ! 9n& Ϳ! 9^#VDM`in& 	|U	! 9^#Vͱ	*|	*"* 
!J	! 9^#VJ	!J	*.#".*&DM!  "&* 
!J	! 9^#VJ	`i"&*&DM!  "&.9^#VJ	`i"&! 9^#V
! 9^#VJ	! 9^#V!  o|>
! 9^#VQ
!- 	! 9^#V$DM
 v 9s#r|t
! 9^#V 
!
 v!0 	*&|ʰ
*&̓DM!  "&`i#|°
!g	$.sub w Can't write to file  optimizer  code generation  errors --first error on line  -z C -ext EXT -ent PUBLIC -pfx C -rh  -rt c2.rtm -ofile  -bufsiz -wbufsiz -o -q -org -org -cr +subm +silent -h +oc +prgl +old +t +co +l -x -g +bak +a -n +asm -asm c2.rh c2.rt 
; == Optimizer V  SuperSoft Copyright (c) 1983 Can't write to file  ******   ****** :  File close error   <^/  1  ]l80 c2main,c2str,c2prt,c2opt,c2cmov,c2fold,c2gen,c2fio,c2pre,iolib/s,libc/s,c2post,c2x/n/e/y $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$( r@  ! 9s#r! 9^#VTDM##  9s#r`i##! 9^#V͗|\! 9^#V! ##DM|0!t`i##! 9^#V  9s#r 9 ^#Vs#r*(ͷ 9s#r! 9^#V!  y|ʟ!  s`i#####!
 9! 9^#V!|~!  9^#Vs#r! 9^#Vs*DM`i|`i##! 9^#Vo| .9^#Vі`i`i^#VDM! 9^#VDM*s#r`i"##*DM`i|Lі`i^#VDM5!  "! 9^#V~DM|p!t`i! 9^#Vg	͇
!   ! 9n& A 	! 9n&  
! 9n& +++|! 9n& |!	 	! 9^#VJ	! 9^#Vbk|!	 	! 9^#V 
!; 	!	 	!: 	!
 	! 9^#V! 9^#V͍|B! 9^#V! 9^#V! 9n& tDM!  .9^#V4v!! 9n& !|ʒ!|ʖ! ! ! Out of Heap Out of heap ! 9^#V 
!J	! 9^#VF(! 9^#VZ(! 9^#Vn(͌*&DM!  "&.9^#VͲ`i"&:  ;  !  9s* ͍|6& 3!  55|O !  9s!*n& DM! Z( 9s`i!|@bk+|g!|g!|g!|!|!|9!|g!|ʟ!!|!|!|!|!|!!|!|!|!|!|k!|{!|ʓ!|ʋ!  F(++++|ʋ& 3! 9n& +++|#ͤb|ʋ! p+C!  F(!|ʰ!|ʰbk++|ʽ* ͍|ʠ& 3! E>|C!  g|C!  E>|CË!  ͔|CË! 9n& |! 9n& |!  p+!  ! .9n& | .#! !  n(*! 9C! 9n& |p+!  ! .2l*! 9C! 9n& |#.l*! ! .l*! 9C!  |CU#|C!  <R|CË!  F(||CË!  |C.9n& !|bk+|'Ë!  #ͤb|ʋ!  p+C`i|=`i|!  F(!I ln(*!  !  ͏0|CË!  |CË! IZ|ʋ!  p+C! 9n& |p+!  ! .A.*! 9C! E4|C#Z( 9s! Z( 9s!  Z(DM!|ʡ!|ʡbk+|<!|x!|ʈ!|!|ʮ!|!|c!|c!|s!  ;X|ʮ! 9n& |µ.9n& +|µ##F(++|µ##n( oø!  <|C* ͍|& 3! Z( 9s! Z( 9s!  Z(DMbk+|!|!|!  |C#3|C#K0|C##E>|C9n& 3!  F(!|c!|cbk++|sî!  g|Cî!  ͼ!|C3|CK0|Cn(|®.9n& ++++|®.9n& !|!|!|Dî!  p+!  ! .-l*! ! .	l*! 9C!  #.-l*! ! .	l*! ! .el*! 9C!  p+!  ! .
l*! ! .Hl*! 9C!  ͼ!|Cî! 9n& !|ʢ!|! 9n& |##n( ̓|! .A.n(++$!  p+C!  E4|Cî! F(++|®.9n& +|®.9n& |®##.A.*! ! ..n(*! ! .l*! 9C!  6|Cî! r\|ʮ! ̓]|ʮ! 9n& +++|®##ͤb|ʮ! p+C!  |ʮ! .1.n(*! 9C!  F(+++|!  F(|!  ͮV|C.9n& ++++|.9n& |E! 9n& |E! 9n& |!  n( y| ! 9s#r! Z(DM!|ʂ!|ʛ! n( 9s#rbk++|! +͓*! ! ))l*! ! ++n(!	 9^#V*! 9`i|##.A.9^#V$! 9/*
 *
 *		MACHINE  DEPENDENT  STUFF
 *
 *
 *		"run time" (for libc.rel)
 *
 *				C 1.2.0
 *
 */


/*	Bios entry points	*/
#define SELDSK		 9
#define SETTRK		10
#define SETSEC		11
#define SETDMA		12
#define READ		13
#define WRITE		14
#define SECTRAN		16

#define JMPLEN		 3		/* length of jmp instruction */

int *
bios(jmpnum,bc,de)	/* This version of bios() recognizes that SELDSK
			 * and SECTRAN return their values in HL not A and
			 * that SECTRAN is passed DE AND HL.
			 */
 char *jmpnum;
 int	bc,de;
{
	register int *p;

	p = JMPLEN * (jmpnum-1) + *(p = 1);

	return (jmpnum == SELDSK || jmpnum == SECTRAN)?
		ccall(p,0,0,bc,de):
		ccalla(p,0,0,bc,0);
}

/*
 * inp() and outp() are machine dependent. these are for 8080,Z80,8085 CPU'
 * They do not work in a split I&D enviornment, though they are ROMable.
 */
inp(port)
 char	port;
{
	char	a[3];

	a[0] = 0xDB;		/* 8080 in instr */
	a[1] = port;
	a[2] = 0xC9;		/* 8080 ret instr */
	return ccalla(a, 0, 0, 0, 0);
}

outp(port,c)
 char port, c;
{
	char	a[3];

	a[0] = 0xD3;		/* 8080 out instr */
	a[1] = port;
	a[2] = 0xC9;		/* 8080 ret */
	return ccall(a, 0, c, 0, 0);
}

#define	CLIB	1
#ifdef	CLIB
ccasl()
{
#asm
	XCHG
	MOV	A,E
	ORA	A
	RZ
C99:	DAD	H
	DCR	A
	JNZ	C99
#endasm
}

ccasr()
{
#asm
	XCHG		; rotate (not really asr)
	MOV	A,E
	ORA	A
	RZ
C99:	ORA	A
	MOV	A,H
	RAR
	MOV	H,A
	MOV	A,L
	RAR
	MOV	L,A
	DCR	E
	JNZ	C99
#endasm
}

ccneg()
{
#asm
	MOV	A,H
	CMA
	MOV	H,A
	MOV	A,L
	CMA
	MOV	L,A
	INX	H
#endasm
}

cccom()
{
#asm
	MOV	A,L
	CMA
	MOV	L,A
	MOV	A,H
	CMA
	MOV	H,A
#endasm
}

ccand()
{
#asm
	MOV	A,H
	ANA	D
	MOV	H,A
	MOV	A,L
	ANA	E
	MOV	L,A
#endasm
}

ccor()
{
#asm
	MOV	A,H
	ORA	D
	MOV	H,A
	MOV	A,L
	ORA	E
	MOV	L,A
#endasm
}

ccsub()
{
#asm
	MOV	A,E
	SUB	L
	MOV	L,A
	MOV	A,D
	SBB	H
	MOV	H,A
#endasm
}

ccxor()
{
#asm
	MOV	A,H
	XRA	D
	MOV	H,A
	MOV	A,L
	XRA	E
	MOV	L,A
#endasm
}

cceq()
{
#asm
	MOV	A,L
	SUB	E
	MOV	L,A
	MOV	A,H
	SBB	D
	ORA	L
	LXI	H,1
	RZ
	DCR	L
#endasm
}

ccne()
{
#asm
	MOV	A,L
	SUB	E
	MOV	L,A
	MOV	A,H
	SBB	D
	MOV	H,A
	ORA	L
	RZ
	LXI	H,1
#endasm
}

cclt()
{
#asm
	MOV	A,E
	SUB	L
	MOV	A,D
	SBB	H
	LXI	H,0
	RP
	INR	L
#endasm
}

ccgt()
{
#asm
	MOV	A,L
	SUB	E
	MOV	A,H
	SBB	D
	LXI	H,0
	RP
	INR	L
#endasm
}

ccge()
{
#asm
	MOV	A,E
	SUB	L
	MOV	A,D
	SBB	H
	LXI	H,1
	RP
	DCR	L
#endasm
}

ccle()
{
#asm
	MOV	A,L
	SUB	E
	MOV	A,H
	SBB	D
	LXI	H,1
	RP
	DCR	L
#endasm
}

ccult()
{
#asm
	MOV	A,E
	SUB	L
	MOV	A,D
	SBB	H
	LXI	H,1
	RC
	DCR	L
#endasm
}

ccugt()
{
#asm
	MOV	A,L
	SUB	E
	MOV	A,H
	SBB	D
	LXI	H,1
	RC
	DCX	H
#endasm
}

ccuge()
{
#asm
	MOV	A,E
	SUB	L
	MOV	A,D
	SBB	H
	LXI	H,0
	RC
	INR	L
#endasm
}

ccule()
{
#asm
	MOV	A,L
	SUB	E
	MOV	A,H
	SBB	D
	LXI	H,0
	RC
	INX	H
#endasm
}

brk()
{
#asm
EXT	CCNEG
EXT	EDATA
EXT	CCEDATA
	POP	D
	POP	H
	PUSH	D
	PUSH	H

	INR	H		; save 100h for misc
	CALL	CCNEG
	DAD	SP
	JNC	C1ERR

	POP	H
	PUSH	H
	LXI	D,EDATA
	MOV	A,L
	SUB	E
	MOV	L,A
	MOV	A,H
	SBB	D
	JC	C1ERR

	POP	H
	SHLD	CCEDATA
	POP	D
	PUSH	D
	PUSH	D
	LXI	H,0
	RET

C1ERR:	POP	D
	POP	D
	PUSH	D
	PUSH	D

CERROR: LXI	H,-1
#endasm
}

ccgint()
{
#asm
	MOV	E,M
	INX	H
	MOV	D,M
	XCHG
#endasm
}

ccpint()
{
#asm
	XCHG
	MOV	M,E
	INX	H
	MOV	M,D
	XCHG
#endasm
}

comlen()
{
#asm
	LHLD	80H	; Returns length of command line
	MVI	H,0
#endasm
}

ccudiv()
{
#asm
DIV0	EQU	0	; zero here turns off divide by 0 message

EXT	CCNEG


CCUDIV:	XRA	A	; clear S condition code
	JMP	CCDV9

PUBLIC	CCDIV
CCDIV:	CALL	CCDMSE	; de = de / hl; signed; S = f(de,hl)

CCDV9:	PUSH	B
	PUSH	PSW

	CALL	CCDV1
	XCHG
	POP	PSW
	POP	B
	RP
	CALL	CCNEG
	XCHG
	CALL	CCNEG
	XCHG
	RET

CCDV1:	MOV	A,H
	ORA	L
	JZ	CCDIV0

	MOV	A,H		; BC = -HL
	CMA
	MOV	B,A
	MOV	A,L
	CMA
	MOV	C,A
	INX	B
	LXI	H,0

	CALL	CCDV2
CCDV2:	MOV	A,D
	MOV	D,E
	MVI	E,8

CCDV3:	DAD	H
 C!  #+*! 9C! 9n& |.9n& ++++|.Z(|##++n(*! p+C;! 9^#VZ(!|bk+|!  3!|K!|S!  3! DM`ibk++|[!|`! 9^#Vp+! 9^#V 9n& ! 9^#Vn(*! 9! 3! 9^#VF(  9s!|$!|$!  3! 9^#VZ(!|ʥ!|.DMê! DMê! DMê! DM! 9^#V! .el*! 9! 9^#VDM#*͗|ʜ!  Z(!|ʹ!|b!  `i#[|! .l*! 9! `i#Z(!|J!|R`i#^|]`i#F(`i#Z(T^`i#n(*! 9`i#! .Nl*! 9! p+E`i#p+E!  `i#Z(!|`i##"Z|ʏp+p+ô!  ! 9^#VDM#*͗|ʱ!  Z(|!  `i#Y|p+! `i#Z(!|!|1!|i`i#^|¡`i#Z(@ Mäp+p+͔! ! .Gl*! 9`i#! .l*! 9`i#͔! ! .l*! 9`i#! .l*! 9`i#͔! ! |`i#F(`i#Z(T^`i#n(*! 9`i#! .l*! 9`i#͔! "|! `i##*͗|!  `i#Z(+|`i#F(++|`i##Z(|\`i###Z( M|ʟ`i#F(! `i#n(*! 9`i#! .l*! 9`i#͔! `i#IZ|ʺ`i##"Z|`i#"Z|`i##IZ|p+! !  ! 9^#VDM####*͗|!  n(`i##n($M|Z(|`i##Z(|`i#]|X`i#VY|]!  `i###Z(|u!  ! ͐Z|`i##`i#͓*`i#͓*! .	l*! 9`i###p+! !  ;!	 9^#VDM^c|	 <!    9sn( 9s#r^c|ʃ!  DM`i#)DM*͗||n(! 9^#VM|!= `i#(DM*͡||!  9! 9^#V5n& }& 3yb||!	 9^#V͵5 9s#r*͡||! 9^#VDM`i*͡||^c|ʷn(! 9^#VM|ʷ!  9! 9^#V5n& }÷! 9^#V^c| ! 9^#Vyb|i ! 9^#VZ(+|i ##9^#VF(++|i ##9^#V! yb|m !  ! 9^#V! 9^#V! ͤb| ! 9^#V! Z(| ! 9^#V! Z(| !  ! 9^#Vn(| ! 9^#V! Z(|!! 9^#Vn(|!##9^#V! Z(|!! 9^#V! 9^#V! ͓*! 9^#Vbk##! 9^#V͓*! 9^#Vbk#! 9^#V! ͓*! 9^#V! p+! 9^#V! p+! ! 9^#Vbk##! ..9^#V! n(*! 9! ;! 9^#VDMZ(  9s  9n& |!& +|!!  3F(++|"!  3`i#Z(|."`i#Z(|."!  3`i##Z(|X"`i##Z(|X"!  3! ##9n& n($*! 9`i#Z(|»"`i##`i##F(!, `i##Z(`i##n(*! 9`i#! .l*! 9! 3! 9^#VZ(|"!  ! 9^#Vs#rZ(DM͝X#|#! 9^#V! 9^#VF(͝X!
 9^#Vn(*! 9! 9^#Vp+! ! 9^#VDM#*͗|r#!  Z(|ʅ#!  n( e|ʚ#!  `i#Z(|T$`i##*͗|#!  `i#IZ|#`i#VY|#!  `i##Z(|#!  `i###*͡|$`i###͐Z|$`i##! .l*! 9F(Z(n(++$! 9! `i##*͡|ʢ$`i##͐Z|t$`i###*͡|ʢ$`i###Z(|¢$`i#E4F(Z(n(++$! 9! .l*! 9! ! 9^#Vbk|$.9^#Vp+!  ! 9^#V 9n& ! 9n& ! 9^#V*! 9! *8& |V%! 9n& ! 9n& ! 9^#V͌! 9n& !|&!|>&bk|h&!|h&bk++|j&!|v&!|ʱ&!|'!| '!|o'!|ʨ'!|'!|'!|'*C& |#(! 9n& ! 9n& ! 9^#Vo)D(*B& |%! .l'%! ! l'%! ! l'%*B& |%! .2l'%! ! l'% ! 9s%! 9^#Vbk++|ʑ&bk+|ʯ&% ! 9s ! 9s ! 9s#r%! 9^#Vbk+|'! .Hl'%! ! l'%! ! .9^#V'%! !l l'%! !
 l'%= ! 9s%! 9n& |%#}2o9))9^#V́~*>& |%*&DM!  "&.9^#VJ	!  	`i"&%*C& |%! 9n& ! 9n& ! 9^#Vo)! !c lo)! 9n& ! 9n& ! 9^#V
d ! 9s4 ! 9s  ! 9s#r%!  }2o9%*o9& |%.9n& ! 9n& ! 9^#V
d/! }2H! 9n& ! 9n& ! 9^#V
d/*! 9^#V))n& *! 9^#V))n& *I! 9^#V))^#V*! 9^#V))DM`in& ! 9n& Y|(! 9^#Vs#r*͡|(! `iDMÖ(! 9^#V! 9^#VDMZ(! 9n& M|	)`i*	JC	CCOVER
	ADD	A
	JNC	CCDV4
	INX	H

CCDV4:	PUSH	H
	DAD	B
	JC	CCDV5

		POP	H
		DCR	E
		JNZ	CCDV3
		MOV	E,A
		RET

CCDV5:	INX	SP
	INX	SP
	INR	A
	DCR	E
	JNZ	CCDV3
	MOV	E,A
	RET

CCOVER:	ADC	A
	JNC	CCOSUB
	INX	H

CCOSUB:	DAD	B
	DCR	E
	JNZ	CCDV3
	MOV	E,A
	RET

CCDMSE:	MOV	A,D
	XRA	H
	PUSH	PSW

	MOV	A,H
	RAL
	CC	CCNEG
	MOV	A,D
	RAL
	JNC	CCDMS1
	XCHG
	CALL	CCNEG
	XCHG
CCDMS1:	POP	PSW
	RET

CCDIV0	EQU	$
	IF DIV0
DIV0MSG:	DB	'Division by 0!',13,10,7,'$'
		LXI	D,DIV0MSG
		MVI	C,9		; Print string
		CALL	CCBDOS
	ENDIF
	LXI	D,0			; X / 0 == 0
	POP	B
#endasm
}

setexit()
{
#asm
EXT	CCEXPC

	LXI	H,2
	DAD	SP
	SHLD	CCEXPC+2
	POP	H
	SHLD	CCEXPC
	PUSH	H
	MOV	H,B
	MOV	L,C
	SHLD	CCEXPC+4
	LXI	H,0
#endasm
}

reset()
{
#asm
EXT	CCEXPC

	POP	D
	POP	D
	LHLD	CCEXPC+2	; could check for exitsp > current SP
	SPHL
	LHLD	CCEXPC
	PUSH	H
	LHLD	CCEXPC+4
	MOV	B,H
	MOV	C,L
	XCHG
#endasm
}

streq()
{
#asm
EXT	XXKLG

	PUSH	H
	MOV	H,B
	MOV	L,C
	SHLD	XXKLG	; bad kludge
	POP	H
	POP	B
	POP	D
	XTHL
	PUSH	B
	PUSH	B
	LXI	B,0
	JMP	CCLP

CCMORE:	INX	B
	INX	H
	INX	D

CCLP:	LDAX	D
	ORA	A
	JZ	CCOUT
	CMP	M
	JZ	CCMORE
	LXI	B,0

CCOUT:	PUSH	B
	LHLD	XXKLG
	MOV	B,H
	MOV	C,L
	POP	H
#endasm
}

bdos()
{
#asm
CCBDOS	EQU	5H

	MOV	H,B	; save b
	MOV	L,C
	POP	B	; pop return address
	POP	D	; pop new d value
	XTHL		; tos contains old b; h contains new b
	PUSH	B	; push return address
	MOV	B,H	; put b value where it belongs
	MOV	C,L
	PUSH	B

	CALL	CCBDOS
	POP	D
	POP	H
	POP	B

	PUSH	H	; restore stack for C
	PUSH	H
	PUSH	H

	MOV	D,A
	MOV	A,E
	CPI	12
	RZ
	CPI	24
	RZ
	CPI	27
	RZ
	CPI	29
	RZ
	CPI	31
	RZ

	MOV	L,D
	MVI	H,0	; should be a sign extend...
#endasm
}

cconst()
{
#asm
CCBDOS	EQU	5H

	PUSH	B	; save reg variable
	MVI	C,11	; bdos function number
	CALL	CCBDOS	; execute function
	MVI	H,0	; set up return value
	MOV	L,A
	POP	B	; restore register variable
#endasm
}

cconin()
{
#asm
CCBDOS	EQU	5H

	PUSH	B	; save reg variable
	MVI	C,1	; bdos function number
	CALL	CCBDOS	; execute function
	MVI	H,0	; set up retun value
	MOV	L,A
	POP	B	; restore register variable
#endasm
}

cconout()
{
#asm
CCBDOS	EQU	5H

	POP	H	; pop return addr
	POP	D	; pop parameter
	PUSH	D	; restore parameter
	PUSH	H	; and return address
	PUSH	B	; save register variable
	MVI	C,2	; bdos function number
	CALL	CCBDOS	; execute function
	POP	B	; restore register variable
#endasm
}

ccall()
{
#asm
	EXT	CCALLER

	PUSH	B
	CALL	CCALLER
	POP	B
#endasm
}

ccalla()
{
#asm
	EXT	CCALLER

	PUSH	B
	CALL	CCALLER
	POP	B
	MOV	L,A
	MVI	H,0
#endasm
}

ccaller()
{
#asm
	LXI	H,15	; get address to call
	DAD	SP
	MOV	B,M
	DCX	H
	MOV	C,M
	DCX	H
	PUSH	B	; and put on stack so we can ret to it.
	MOV	D,M	; move hl parm to de
	DCX	H
	MOV	E,M
	PUSH	D	; and push it
	DCX	H
			; blow off flags
	DCX	H
	MOV	A,M	; load a
	DCX	H
	MOV	B,M	; load bc
	DCX	H
	MOV	C,M
	DCX	H
	MOV	D,M	; load de
	DCX	H
	MOV	E,M
	POP	H	; pop hl off stack
;	RET		; jp *sp++
#endasm
}

setjmp()
{
#asm
EXT	CCLJRV
	POP	D
	POP	H
	PUSH	H
	PUSH	D

	MOV	M,C	; preserve reg var
	INX	H
	MOV	M,B
	INX	H

	XCHG		; preserve old sp
	LXI	H,2
	DAD	SP
	XCHG
	MOV	M,E
	INX	H
	MOV	M,D
	INX	H

	POP	D	; preserve ret addr
	PUSH	D
	MOV	M,E
	INX	H
	MOV	M,D
	LXI	H,0
#endasm
}

longjmp()
{
#asm
EXT	CCLJRV
	POP	PSW	; ret addr and we don't care
	POP	H	; state area
	POP	D	; return value
	SHLD	CCLJRV	; (kinda nasty)
	XCHG

	MOV	C,M	; fetch reg var
	INX	H
	MOV	B,M
	INX	H

	MOV	E,M	; fetch old sp
	INX	H
	MOV	D,M
	INX	H
	XCHG
	SPHL
	XCHG

	MOV	E,M	; fetch ret addr
	INX	H
	MOV	D,M
	PUSH	D
	LHLD	CCLJRV	; load return value from nasty place
#endasm
}

ccmult()
{
#asm
	PUSH	B
	XRA	A
	CMP	H
	JZ	CCEXCH
	CMP	L
	JZ	CCEXCH

CCM3:	MOV	B,H
	MOV	C,L
	MOV	A,E
	PUSH	D
	CALL	CCBMULT
	XTHL
	MOV	A,H
	CALL	CCBMULT
	MOV	H,L
	MVI	L,0
	POP	B
	DAD	B
	POP	B
	RET

CCEXCH:	XCHG
	JMP	CCM3
 ͡|(`i*! 9^#V))DM`in& |L).9^#VF(|L)! 9^#V! 9^#Vs#r*͗|B).`iDM )**))DM!
 9n& }`i! 9n& }! 9^#Vs#r 9n& |),*|)*÷)/!  }2H*#"*+͗| ***+͗| ***@& |7*!8J	!
 9^#V 
!8J	!
 9^#VͲ*! 9^#V))DM!
 9n& }`i! 9n& }! 9^#Vs#r*@& |ʑ*!8J	!
 9^#VͲ! 9^#V! 9^#VF(! 9^#VZ(! 9^#Vn(*! 9*|*!8g	*IDM*n& +|**n& |L+!  F(|+!  F(+++|L+! Z(|L+`i^#V! n(bx!  p+f+*n& *n& `i^#V
d!  p+! 9^#V*͗|ʵ+!8g	! 9^#V 
!8J	* 
*&ă*@& |+!8J	! 9^#V 
!8J	! 9^#VͲ!9J	*! 9^#V))DM####**+"#))`i####ͧ*@& |B,! 9^#VͲ! 9n& |W,**͗|q,!9g	,*! 9^#V))DM! *#"! 9^#V))ͧ`i!
 9n& }`i! 9n& }! 9^#Vs#r*H& |,*|,!  6b|,! Z(|-#p+eQ!  DMͬ.Q-/F.|L-`i ͡|-!!9	eQ;*@& |g-!)9J	  ! 9s#r!  9s! 9^#V*͡|?.! 9^#Vyb|-! 9^#Vn( 9s#r  DM*͗|-! 9^#Vp+ !  9s! 9^#Vs#rw-^c|9.n(! 9^#VM|9.! 9^#VM|-p+ !  9sDM! 9^#Vs#r`iô-& 3;*@& |Z.!;9J	!  DM  9s*͡|ʥ.^c|.yb|ʟ.!  9n& }`if.& 3;*@& |.!G9J	*|.!  F(|.*.  !  9s  ! 9s#r! 9^#V) 9s#r*͡|/! 9^#Vs#r! 9^#V*͡|.! 9^#Vyb|.! 9^#Vn( 9s#r !  9s  DM*͡|ʽ/n(! 9^#VM|ʷ/^c|ʷ/F(Z(! 9^#Vn(*! 9`ii/! 9^#Vp+$/& 3;*@& |/!U9J	*|(0  !  9s*+DM`i  ͡|(0!  9`i55n& }/& 3! 9^#V! 3& ! 9^#Vbk& ! 9^#VZ(+|0##9^#VF(++|0##9^#Vbk#! 9^#Vn(͏0!  ! 9^#V*͗|ʨ0!  ! 9^#VE4|0.9^#VE>|0! ! 9^#V]|0! 9^#VZ(+|1! 9^#Vbk#! 9^#V͏0! 9^#V*͗|&1!  ! 9^#Vn(DM!H .9^#VK e|ʞ1! 9!
 9^#Vbk#! .@.9^#V$! 9  M^#Vs#r2! 9^#V)`iM|1! 9^#V! ..*! 92! 9^#V))`iM|2! 9^#V! ..*! 92! 9^#V/0/0M||2! 9^#V/0?0M|Z2! 9^#V! .:l*! 92! 9^#V! .1?0*! 92! 9^#V?0?0M|3! 9^#V?0/0M|2! 9^#V! .;l*! 92! 9^#V! .4/0*! 9! 9^#V͏0! !  ! 9^#VDM##*͗|&3!  Z(|X3`i#͐Z|X3`i#[|X3p+! 4|4`i#4|4`i##Z(|4IZ|ʘ3`i#"Z|µ3"Z|ʭ3`i#IZð3!  |4F(Z(T^n(*! 9`i#`i#F(`i#Z(T^`i#n(*! 9`i##p+! !  ! 9^#VZ(+|44##9^#VF(++|A4! 9^#V^! ! 9^#VDM##*͗|c4!  Z(!|~4!|405`i#IZ|4`i#VY|4`i##Z(|4! .l*! 9`i##p+! !  `i#IZ|5`i#VY|5`i##Z(|5p+`i#p+! `i#"Z|5`i##Z(|ʪ4!  ! 9^#VDM#*͗|R5!  Z(!|j5!|°5`iZ(!|ʰ5!|ʰ5p+Z(!|ʫ5*͗|ʅ5! ! !  != .9^#V(DM*͡|5Z(!|5!|5*`i! 9^#VZ(!|6!|j6Û6! 9^#V! 9^#Vͤb|6##9^#V! 9^#VF(! 9^#VZ(!
 9^#Vn(*! 9! ! 9^#VZ(!|ʟ6!|ʾ6!|6!|6!  ! 9^#V! .l*! 9! ! 9^#V! .Kl*! 9! ! 9^#V! .Jl*! 9! ! 9^#VDMZ(!|"7!|77`i#Z(+++|7`i#n(!g9Hc|7`i##Z(|7n(`i##n(͝_|7! .Cn(`i##n($! 9  M`iDM##! .C`i##n($$! 9! n(!i9Hc|7`i#Z(!|7!|)8!  `i##͐Z|7p+! .l*! 9! `i##Z(|7`i##n(!k9Hc|7! .C`i#n(*! 9`i##p+`i#͐Z|ʍ8`i#p+ä8`i#! !m9*! 9! optrep( ) was	  is	 internal error: optout empty Internal error: optdel >= optdel( ) wa

CCBMULT:LXI	H,0
	MVI	E,7
	ADD	A
	JC	CCM6
	RZ

CCM2:	JNC	CCM4
CCM6:	DAD	B

CCM4:	DAD	H
	ADC	A
	DCR	E
	JNZ	CCM2
	RNC
	DAD	B
#endasm
}

comline()
{
#asm
	LXI	H,81H	; Returns address of command line.
#endasm
}
#endif
	XCHG
	MOV	M,sm
}

ccmult()
{
#asm
	PUSH	B
	XRA	A
	CMP	H
	JZ	CCEXCH
	CMP	L
	JZ	CCEXCH

CCM3:	MOV	B,H
	MOV	C,L
	MOV	A,E
	PUSH	D
	CALL	CCBMULT
	XTHL
	MOV	A,H
	CALL	CCBMULT
	MOV	H,L
	MVI	L,0
	POP	B
	DAD	B
	POP	B
	RET

CCEXCH:	XCHG
	JMP	CCM3
/*
 * sample 1
 */

#ifndef REL		/* not needed if linking assembler used */
#include "crunt2.c"	/* not needed if linking assembler used */
#include "func.c"	/* not needed if linking assembler used */
#endif			/* not needed if linking assembler used */

main()
{
	register char ch;
	char instring[80], secstr[80];
	int	isalnum()
		,isascii()
		,iscntrl()
		,ispunct()
		,isprint()
		,isspace()
		,isalpha()
		,isupper()
		,islower()
		,isdigit()
		,iswhite();

	puts("\nSample program 1: the string and character functions\n");
	puts("\n   The functions to be demonstrated include:\n\n");
	puts("   toupper   	tolower		isalpha		isdigit\n");
	puts("   gets		puts		strcpy		strcat\n");
	puts("   strcmp       isupper         islower\n");

	puts("\n\nEnter a string: ");	gets(instring);
	puts("Here is the string you entered: ");
	puts(instring);
	puts("\nEnter a second string to compare with the first: ");
	gets(secstr);
	puts(strcmp(secstr,instring)? "strings differ\n": "strings are equal\n");
	puts("\nNow let's put the first string together with the second\n");
	strcat(instring,secstr);
	puts(instring);
	puts("\n\nNext let's copy the second string into the first:\n");
	strcpy(instring,secstr);
	puts(instring);
	puts("\n\n");
	
	puts("Next we will demonstrate some character commands\n");
	do{
		puts("\ntype a 0 to move on: ");
		ch = getchar();
		if(islower(ch)) 
			dolower(ch);
		else if(isupper(ch))
			doupper(ch);
		else if(isdigit(ch))
			dodigit(ch);
	} while (ch!='0');

	for(puts("\n\nEnter a line, end with a return:");;) {
		puts("\n\n\t");
		gets(instring);
		if(instring[0]=='\0')
			break;

		str_tr(isascii,"isascii",instring);
		str_tr(isprint,"isprint",instring);
		str_tr(isalnum,"isalnum",instring);
		str_tr(isalpha,"isalpha",instring);
		str_tr(islower,"islower",instring);
		str_tr(isupper,"isupper",instring);
		str_tr(isdigit,"isdigit",instring);
		str_tr(ispunct,"ispunct",instring);
		str_tr(iswhite,"iswhite",instring);
		str_tr(isspace,"issp s	  is	 optimizer table overflow cnt>15
 del_useless_lab:
 doalljmps:
 del_eqv_lab:
 del_unreachable:
 0 0 0 0 ^;!  DM  9s*͡|ʩ9!  9`i͹9n& }~9& |r99n& 3!
 9^#VDMv_|9`i#Z(|9!  `i#F(|:!  `i#n(  9s#rZ(|?:n(M|?:p+! !  ...9^#VX<! 9 9s#r*͗|u:!  ! `i#̓( 9s#r*͗|ʽ:! `i#̓( 9s#r*͗|ʽ:!  ! 9^#V! 9^#VM|:!  `i#! 9^#V! 9^#V ;! *  9s#r! 9^#V! 9^#V#DM! 9^#V*!
 9^#V`i;! 9^#V! 9^#V͍|ʄ;!
 9`i^#Vs#r 9`i^#Vs#r!
 9^#V!
 9^#V!
 9^#V;! 9^#Vbk#*! 9^#V;"! 9^#V!
 9^#V#DM! 9^#V`i*͗|<!,>g	!*!
 9^#V))*! 9^#V))`i))ͧ! 9^#V`i*͍|S<! 9^#V`i"!  ! 9n& !
 9^#V̓( 9s#r! 9^#V*͗|¾<.9^#VF(! 9n& M|<! 9^#Vn(! 9^#VM|<! 9^#V! 9^#Vs#rX<;! 9^#VZ(DM!|=!|=!  3! 9^#VZ(|0=.9^#VF(|A=! 9^#V553! 9^#V!	 9^#Vͤb|a=3! 9^#VZ(!|ʄ=!|=%>!, `iDM! 9^#Vn(  9s#r! 9^#VF( 9s! 9^#Vp+! 9^#V 9n& ! 9^#V*! 9! 3`i!|>!|>>!J DM>!K DM  !  9s#r ! 9s!  3optimizer table overflow ! 9^#VDM*o|d>!  Z(bk+|{>!|]FF(!|ʓ>!|>`iZ(|¸>`iZ( Mû>>|>`ip+`i#! .@`in($! 9! !  bk++| ?	?!   ?`iZ(!|7?!|7?!|7?!|@n(|ʭ?p+`iZ(!|_?!|g?p+@!|?! .l*! 9@!|@! .n(*! 9@@p+`iZ(!|?!|?p+@!|?! .l*! 9@!|@! .n(*! 9@! !|?@!|?@!|?@bk+|J@p+! !|m@n(`in(&J!|@n(`in(C&J!|·@n(`in(=&J!|@n(`in(z&J!|An(`in(&J!|%A`in(n(@L! 9!|@An(,&J!|[An($&J!|A!H n(K! `i_o|ʑA!  `i! .@n($`i! `i_|A! A!N !  *! 9! !|B! +n($*`i#! .l*! 9! !|B`iZ(!|B`iͤb| J! .n(*`i#! .Nl*`i##! ))l*! 9!  J!| J! +n(`in(*`i##p+!  J!| C`iZ(͝X#| J`iZ(|:C.Hn(K ̓| J`ip+`i#! .@n($! 9ÃC`i! .n(*`i##`iF(`iZ(͝X`in(*! 9! .-l*! 9!  J!|C`in(`$WJ| J! .l*! 9!  J!|En(bk|D!cg	!  bk+|Dp+`ip+Dbk#|ADp+`i! .rl*! 9D`iZ(|Dn(`  9s#r!|ʂD`in(yÅDD|D`i! .`in(! 9^#V*`i#! .?l,! 9^#VC*`i! .l*! 9! !  AD! !|ºE`in(WJ|:E! .l*! 9! `iZ(|cE`in(n(ofEôE|ʴE`i! .`in(n(*`ip+`i! .l*! 9! !  !|E`in($WJ|F! .l*! 9! F!| Jn(|'Fp+`i! ++*! 9TF`i! .?n(*`i! .Nl*! 9!  J!| J`iZ(!|ʂF!|Fp+! !|Fn(  9s#r`iF(! `in(*`i#! ..9^#V*! 9! bk+|GF(++|Gn(`in(@L! 9!  %G!|G!H n(K e|bG`i! .@n($`ip+! `i###*o|yG!  `iZ(|G`i###Z( MâG J| J! .n(`in(*`i##p+`i##p+!  J!|Hn(bk|Hp+`i! ++*! 9ÔHbk#|:Hp+`i! .rl*! 9ÔHbk##|mH! ..*`i! .rl*! 9ÔHn(`$ͳJ|ʋH! !  mH! !|H!H n(K ̓|H!  `i! .@n($`i! .rl*! 9! !|I`iace",instring);
		str_tr(iscntrl,"iscntrl",instring);
	}
}

dolower(ch)
 char ch;
{
	puts(" lower case char --> upper: ");
	putchar(toupper(ch));
}

doupper(ch)
 char ch;
{
	puts(" upper case char --> lower: ");
	putchar(tolower(ch));
}

dodigit(ch)
 char ch;
{
	register int tt;

	puts(" squared is ");
	tt = ch-'0';
	putdec(tt*tt);
}

str_tr(fn,fnname,ss)
 char (*fn)();
 char *fnname;
 char *ss;
{
	register char *s;

	puts(fnname); putchar('\t');
	for(s=ss; *s; ++s)
		putchar((*fn)(*s)? 'X': ' ');

	puts("\n");
}
urn:");;) {
		puts("\n\n\t");
		gets(instring);
		if(instring[0]=='\0')
		);
	putchar(toupper(ch));
}

doupper(ch)
 char ch;
{
	puts(" upper case char --> lower: ");
	putchar(tolower(ch));
}

dodigit(ch)
 char ch;
{
	register int tt;

	puts(" squared is ");
	tt = ch-'0';
	putdec(tt*tt);
}

str_tr(fn,fnname,ss)
 char (*fn)();
 char *fnname;
 char *ss;
{
	register char *s;

	puts(fnname); putchar('\t');
	for(s=ss; *s; ++s)
		p/*
 *	WARNING: this file with its includes and with +ASM
 *		 on the compiler command line generate
 *		 a 128k .asm file... another good reason
 *		 for using a linking assembler.
 */


#ifndef REL			/* not needed if linking assembler used */
#include "crunt2.c"		/* not needed if linking assembler used */
#include "bcd80.c"		/* not needed if linking assembler used */
#include "double.c"		/* not needed if linking assembler used */
#include "long.c"		/* not needed if linking assembler used */
#endif				/* not needed if linking assembler used */

union ulong {
	long lng[1];
	int word[2];
};

#define	hi	word[0]
#define	lo	word[1]

main()
{
	register int t;
	char	q;
	int	r;
	int	cnt;
	union	ulong l, v;
	double	fl[1], fv[1], fi[1];

	puts("\n\nSample program 2: execution speed of variable types\n");
	puts("\n\nThis program will illustrate the speed differences\n");
	puts("between various data types. Nested FOR loops\n");
	puts("each counting down from 255 will be executed.\n");
	puts("In each case, the outer loop is controlled by\n");
	puts("type int and the inside loop is the type under study\n");
	puts("Try timing each loop. (Double is the slowest.)\n\n");

	start("register");
	for(cnt=255; cnt-->=0; )
		for(t=255; t<=0; --t)
			;
	bell();

	start("char");
	for(cnt=255; cnt-->=0; )
		for(q=255; q<=0; --q)
			;
	bell();


	start("int");
	for(cnt=255; cnt-->=0; )
		for(r=255; r<=0; --r)
			;
	bell();

	start("long");
	for(cnt=255; cnt-->=0; )
		for(l.lo=255, v.hi=l.hi=l.lo=0; cc2cmp(l.lng,v.lng)>=0; cc1dec(l.lng) )
			;
	bell();

	start("double");
	s2bcd(fi,"-1");
	t = 0;
	for(cnt=255; cnt-->=0; putchar('.') )
		for(s2bcd(fl,"255"); Bsign(fl)>=0; Badd(fl,fl,fi) )
			;
	bell();

	floating();
	puts("\nDONE\n");
}

floating()
{
	register int j;
	char line[200];
	char sn[200];
	double n[1], c[1], s[1], i[1], mone[1];
	double tmp[1];
	double tmp1[1];

	x("\nHit return to do some long float work: ");

	s2bcd(n,"0");	
	s2bcd(i, ".05");
 ! +n(*`i! .l*`i#E>|:I! ! .`in(*`i#! .l*! 9`iZ(bk+|ʠI!|ʠI!|ʠI!|ʠI!|®Ip+`ip+I!|I!|I`ip+`i! +n(*! 9I!  I! !| J! .?n(*`i#p+!  J!  ! 9^#Vp+! 9^#V! +.9^#V*! 9! ! 9^#V!|ʫJ!c |ʫJ! 9^#V!  y|ʯJ! 9^#V! ..9^#V$*! 9! !  !  ! 9^#V!|IK!c |IK! 9^#Vbk#! 9^#VWJ|J! 9^#Vp+! ! 9^#VZ(!|NK!|NK! 9^#V!  y|SK! 9^#V$ 9s#rq DMXK!  !  !p DM! 9^#V! ̓|L! 9^#VZ(+|K.9^#VF(++|K.9^#VZ(`iM|K! 9^#Vn(! 9^#VM|K!  ! 9^#V! +.
9^#V*! 9! 9^#V! l*! 9! `i|;L! 9^#Vp+! 9^#V! ++*! 9! !  ! 9^#V*o|XL!  ! 9^#VZ(!|L!|M!|1M!|UM!|zM!|ʞM!|M!|M!|N!|0N!|4N!|XN!||N!|ʠN!  ! 9^#V! 9^#V! 9^#VN! ! 9^#V! 9^#V! 9^#VNM! 9^#V! 9^#V! 9^#V=NM! 9^#V! 9^#V! 9^#VzNM! 9^#V! 9^#V! 9^#VNM! 9^#V! 9^#V! 9^#VNM! 9^#V! 9^#V! 9^#VNM! 9^#V! 9^#V! 9^#V3NM! 9^#V! 9^#V! 9^#VCNM!  ! 9^#V! 9^#V! 9^#VeNM! 9^#V! 9^#V! 9^#VoNM! 9^#V! 9^#V! 9^#V̓NM! 9^#V! 9^#V! 9^#VyNM! 9^#V! +.9^#V*! 9! 9^#Vp+! 9^#Vp+! *@& |GO!cJ	!
 9^#V!
 9^#V! 9^#V#RV!cJ	  ! 9s  !  9s!
 9^#VDM!
 9^#Vo|-P* 9s#r  9`E4`͔`<R`3`ͼ!`E>`6n& }! 9^#V*`iDM! 9! 9^#V*^#Vs#r`ibO! 9^#V`DM!
 9^#Ve|P! 9^#Vy|P* 9s#r  9`n& }! 9^#V*`iDM! 9! 9^#V*^#Vs#r`iMP& |3Q*@& |(Q!cJ	! 9Q!
 9^#V!
 9^#V! 9^#V#RVQ!cJ	!cJ	! 9n& ! 9^#V` 9s#r 9! 9n& n& }PO;  ! 9s#r*  9s#r! 9^#VDMF(|ʫQZ(|ʫQ`iÉQ! 9! 9^#VOn& }*o|Q! 9n& p93*`iDM  ̓|-RF(|-RZ(|-R!cg	`i# 9s#rtQ! 9^#VZ(!|ʃR!|S!|gT!|ʌU!|R!|V!  ! 9^#VZ(!|@S!|\S! 9^#VZ(+|R##9^#VF(++|R##9^#VZ(|R##9^#V! Z(|R##9^#Vp+! 9^#Vp+! ! 9^#VZ(!|ʽS!|S!|TR! 9^#Vp+! 9^#Vp+! ! 9^#Vn( y|ʣR! 9^#Vp+! 9^#V! 9^#VF(! 9^#VZ(! 9^#Vn(++$! 9! ! 9^#Vp+! 9^#V! .! d*! 9! ! 9^#Vp+! 9^#Vp+! ! 9^#Vn( y|R! 9^#Vp+! 9^#V! 9^#VF(! 9^#VZ(! 9^#Vn(++$! 9! ! 9^#VZ(!|T!|U!|+U! 9^#VZ(|R##9^#V`|R! 9^#Vp+! 9^#V! !d*! 9! ! 9^#Vp+! 9^#V! !d*! 9! ! 9^#Vp+! 9^#Vp+! ! 9^#Vn( y|ʐT! 9^#Vp+! 9^#V! 9^#VF(! 9^#VZ(! 9^#Vn(++$! 9! ! 9^#VZ(!|R##9! 9^#V! .A.9^#Vn(! 9^#Vn($! 9  M^#Vs#r! 9^#Vp+! ! 9^#Vn(!dHc|R! 9^#VZ(|R##9^#V! .	l*! 9! ! 9^#Vs#r!  ͍|! 9^#V*o||V! 9^#VͲ! 9^#Vs#r! z|ʨVRVRV! 9^#VDM##n( 9s#r! 9^#VͶaDM|ʼW! 9^#VͶaDM|ʼW! 9^#VͶa|ʼW! 9^#VDM! 9^#VͶaDM|bW`i! Z(|AW.JDW!K !  *! 9`i  9s#rW! .A.D,! 9! 9^#V! .	lD,! 9! 9^#V! ..9^#VD,! 9! !  ! 9^#VY! 9^#V*o|W!  ! 9^#VY|W! ! 9^#VZ(DM! 9^#VIZ|W`i|W! 9^#V"Z|W! 9^#VZ(!|ʙX!X!|!|!|!|!|!|!|!|!|!  ! ! 9^#V!|-Y!|1Y!|5Y!|9Y!|=Y!|AY!|EY!|IY!MY!|!|!	s2bcd(mone,"-1");
	for(j=100; --j; Badd(n,n,i)) {
		format(line,n);
		puts("\nn=="); puts(line);
		Bsin(s,n);
		Bcos(c,n);
		format(line,s);
		puts("\nsin(n)=="); puts(line);
		format(line,c);
		puts("\ncos(n)=="); puts(line);
		Badd(c, Bmul(tmp1,c,c), Bmul(tmp,s,s));
		Badd(c,c,mone);
		format(line,c);
		puts("\n\t\terror in sin(n)**2+cos(n)**2 is\t"); puts(line);
	}
}

printf(s)
 char *s;
{
	puts(s);
}

absval(a)
 int a;
{
	return a<0? -a: a;
}

start(s)
 char *s;
{
	puts("\nHit return to start "); puts(s); x(" loop: ");
}

x(s)
 char *s;
{
	puts(s);
	getchar();
	bell();
}

bell()
{
	puts("\007*");
}
0; putchar('.') )
		for(s2bcd(fl,"255"); Bsign(fl)>=0; Badd(fl,fl,fi) )
			;
	bell();

	floating();
	pu1,c,c), Bmul(tmp,s,s));
		Badd(c,c,mone);
		format(line,c);
		puts("\n\t\terror in sin(n)**2+cos(n)**2 is\t"); puts(line);
	}
}

printf(s)
 char *s;
{
	puts(s);
}

absval(a)
 int a;
{
	return a<0? -a: a;
}

start(s)
 char *s;
{
	puts(/*
 * sample 3
 */

#ifndef REL		/* not needed if linking assembler used */
#include "crunt2.c"	/* not needed if linking assembler used */
#include "func.c"	/* not needed if linking assembler used */
#endif			/* not needed if linking assembler used */


/*Eratosthenes Sieve Prime Number Program in C*/
#define true 1
#define false 0
#define size 8190
#define sizepl 8191

char flags[sizepl];

main() {
	register int i;
        int prime,k,count,iter;

	puts("\n\nSample Program #3 : A prime number sieve\n");
	puts("10 iterations\n");
        for(iter = 1;iter <= 10;iter ++) {
            count=0;
            for(i = 0;i <= size;i ++)
                flags[i] = true;
            for(i = 0;i <= size;i ++) {
                if(flags[i]) {
                    prime = i + i + 3;
                    k = i + prime;
                        while(k <= size) {
                            flags[k] = false;
                            k += prime;
                            }
                        count = count + 1;
                    }
                }
              }
		putchar('\n');
		putdec(count);
		puts(" primes");
}
ude "func.c"	/* not needed if linking assembler used */
#endif			/* not needed if linking assembler used  {
                    prime = i + i + 3;
                    k = i + prime;
                        while(k <= size) {
                            flags[k] = false;
                            k += prime;
                            }
              |!|!|!|!|!|!!v !w !t !u !z !{ !x !y ! 9^#V! 9^#VZ(!|Y!Y!|!|!|!|!|!|!|!|!|!|! 9^#V/_! ! 9^#VZ(|Y#! 9^#VZ(+|Z##9^#VZ(++++|Z##9^#VZ(|Z#!  ! 9^#VZ(!|EZ!|EZ!  ! ! 9^#VZ(!|ʌZbk+|ʌZ!Z!|!|!|!|!  ! ! 9^#VZ(!|Z!Z!|!|!|!|Z! 9^#V]|Z! 9^#V͐Z! ! 9^#V[! 9^#VIZ! 9^#VZ(!|f[!f[!|!|!|!|!|j[! 9^#Vͅ[|x[! 9^#V[! ! 9^#V͐Z! 9^#V"Z! 9^#VZ(!|n\!n\!|!|!|!|!|!|!|!|!|!|!|!|bk+|n\!n\!|!|!|!|!|!|!|!|bk++|n\!n\!|!|!|!|!|!  ! ! 9^#VZ(!|]!]!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!  ! ! 9^#VZ(!|]!]!|!|!|!|!|!|!|!|!|!|!|!|!  ! ! 9^#VZ(!|ʯ]!|ʯ]!|ʳ]! !  ! 9^#Vn(!dHc! 9^#VZ(!|P^!P^!|!|!|!|!|!|!|!|!|!|!|bk++|P^!|P^!|P^!  ! ! 9n& !|^!|^bk+|^!|^!|^!|^!|^!|^!|^!^!|!|!|!!B !@ ! !H !	 !- !
 ! ! ! 9n& ! 9^#VZ(!|+_bk+|+_! 9^#VZ(T^Y!  ! 9n& !|__!|__!|__!|c_!  ! ! 9n& n(  e! 9^#VZ(!|ʙ_!|ʙ_!  ! ! 9^#V! 9^#V! 9^#V̓! 9^#V*o|_!  ! 9^#V"Z|_##9^#VZ(
 M! ! 9^#Vbk+|ʚ`bk++|ʚ`!|ʤ`!|ʨ`!|ʬ`!|ʰ`!|ʴ`!|ʸ`bk%|ʼ`bk%%|`! |`! |`! |`! |`! |`! |`!c ! 9^#V! ! ! ! ! ! ! !	 !
 ! ! ! ! ! ! 9^#V*e|`*! 9^#V! 9^#VZ(!|ʲa!a!|!|!|!|!|!|!|!|!|!|!|bk+|ʲa!a!|!|!|!|!|bk++|ʲa!|ʲa!|ʲa!  ! ! 9^#VDMZ(+|aF(++|a!  `iZ(|a!  `in(! 9^#VY|b!  Z(|,bZ(|1b`i#!  ! 9^#VZ(|ub##9^#VF(+++|qb! 9^#VF( M! !  ! 9^#VF(| b##9^#VZ(= M!  ! 9^#VF(! 9^#VF(Y|b!  ! 9^#VF(!|c!|cbk++|+c!|+c!|+c!! 9^#Vn(! 9^#Vn(o  M! 9^#Vn(! 9^#Vn(M! 9^#V! 9^#V! 9^#VF(|c##9^#VZ(= Y!  divide by 0 ;Basic block (before): ;;;;;;;; ;Basic block (after): 	<no changes> ;;;;;;;; Internal warning: basic block 0 0 0 0 0 ! }2H))9^#VDM! 9n& bk+|zdbk++|ʫg!|7h!|7h!|k!|Sm!|m! 9n& ! 9n& yu! 9n& !|ʘe!|ʘe!|ʚe!|ʥe!|ʰe!|ʻe!|e!|e!|f!|3f!|]f!|hf!|sf!|~f!|ʉf!|ʔf!|ʟf!|ʪf!|ʵf!|f!|f!|f!|f!|g!|g!|g!|9g!|rg! 9n& ! 9n& yuxd!x 
xd!x 
xd!x 
xd!x 
xd!x 
xd! .Gl
d! !@ .
d! !^ l
dxd! .9l
d! !@ .
d! !8 l
dxd*:& |Rf*6& |Rf!x 
xd!x 
xd!x 
xd!x 
xd!x 
xd!x 
xd!x 
xd!x 
xd!x 
xd!x 
xd!x 
xd!x 
xd!y 
xd!y 
xd!y 
! ! l
d!y 
xd!y 
xd!'y 
xd! .El
d! !F l
dxd!/y 
!7y 
*:& |gg*6& |gg!=y 
xd!Ey 
xd!Hy 
!Py 
*:& |ʠg*6& | g!Vy 
xd!_y 
xd! 9n& bk+|h!|h!|h!|
i!|i!| i!|^i!|i!|i!|Gj!|ʠj!|j! 9n& ! 9n& yu! 9n& n|Lh! 9n& !|k!|k!|!kbk+|,k!|,k!|7k!|ʘk!|ʲk!|ʹk!|k!|kbk++|k!|k! 9n& ! 9n& yu!cy
 
xd!jy
h!/*
 * sample 4
 */

#ifndef REL		/* not needed if linking assembler used */
#include "crunt2.c"	/* not needed if linking assembler used */
#include "func.c"	/* not needed if linking assembler used */
#endif			/* not needed if linking assembler used */

#define COL 6

main()
{
	register int n;
	int i,j,space;
	int aa[30],bb[30];
	char instr[80];

	puts("\n\nSample program 4: Pascal's triangle\n");

	do {
		puts("Enter a number greater than zero but less than 16: ");
		gets(instr);
		n=atoi(instr);
	} while(n<0 || n>15);
	puts("\n");

	space = n*COL/2;
	aa[0]=0; aa[1]=1;
	for(j=1; j<=n; ++j) {
		space=space-COL/2;
		for(i=0; i<=space; ++i) putchar(' ');
		for(i=1; i<=j; ++i) {
			bb[i]=aa[i-1]+aa[i];
		}
		aa[j+1]=0;
		for(i=1; i<=j; ++i) {
			print(bb[i],COL);
			aa[i]=bb[i];
		}
		puts("\n");
	}
}

print(num,ic)
 int num, ic;
{
	register int i;
	int j;

	for(i=0,j=num; j!=0; ++i)
		j /= 10;

	if(i>ic)
		for(i=1; i++<=ic; ) putchar('*');
	else
		for(j=1; j++<=ic-i; ) putchar(' ');

	putdec(num);
}
d if linking assembler used */
#include "crunt2.c"	/* not needed if linking asce-COL/2;
		for(i=0; i<=space; ++i) putchar(' ');
		for(i=1; i<=j; ++i) {
			bb[i]=aa[i-1]+aa[i];
		}
		aa[j+1]=0;
		for(i=1; i<=j; ++i) {
			print(bb[i],COL);
			aa[i]=bb[i];
		}
		puts("\n");
	}
}

print(num,ic)
 int num, ic;
{
	register int i;
	int j;

	for(i=0,j=num; j!=0; ++i)
		j /= 10;

	if(i>ic)
		for(i=1; i++<=ic; ) putchar('*');
	else
		for(j=1; /*
 * sample 5
 */

#ifndef REL		/* not needed if linking assembler used */
#include "crunt2.c"	/* not needed if linking assembler used */
#include "func.c"	/* not needed if linking assembler used */
#include "stdio.c"	/* not needed if linking assembler used */
#include "alloc.c"	/* not needed if linking assembler used */
#include "formatio.c"	/* not needed if linking assembler used */
#endif			/* not needed if linking assembler used */

extern	int	errno;

#define	RECSIZ	128
#define	ERROR	(-1)

main(argc,argv)
 int argc;
 char **argv;
{
	register char *filename;
	int mode, fd, rec;
	char ch, instr[80], buffer[RECSIZ+1];

	if(argc==2)
		filename = argv[1];
	else {
		puts("Usage: samp5 filename");
		return 1;
	}

	if((fd=open(filename,2))==ERROR) {
		printf("\nCan't open file %s (errno is %d)\n",filename,errno);
		return 0;
	}

	for(;;) {
		printf("Enter %d byte sector number (RETURN to exit): ",RECSIZ);
		gets(instr);
		puts("\n");

		switch(*instr) {
		case 'C'-'@':
		case '\0':
			break;
		default:
			rec = atoi(instr);
			if(seek(fd, rec*RECSIZ, 0)==ERROR) {
				printf("No such place in this file\n\n");
				printf("(Errno is %d)\n", errno);
			} else {
				if(read(fd,buffer,RECSIZ)!=RECSIZ)
					printf("Can't read (errno is %d)\n",errno);

				buffer[RECSIZ]=0;
				puts("<<");
				puts(buffer);
				puts(">>\n\n");
			}
			continue;
		}
		break;
	}
}
eeded if linking assembler used */

extern	int	errno;

#define	RECSIZ	128
#define	ERROR	(-1 qy
h!xy
h!y
h! .Hl
d! ! 
d! !k .
d! !
 l
d`i  e|ui!yg	`i ̓|ʒi! ++
d`i y|i! .;l
d! !1 l
d! `iDM!yͫn`i#|i!L ͦu! 3!H ͦu!H 4x|Ej#.Hl
d! ! 
d! ! l
d! !
 l
d!D 4x|j#.	l
d! ! 
d! ! l
d! !
 l
d! ! l
d!B 4x|j!y
`i&  
!y 
!y 
!y
! 3&  
!y 
!y 
r!y
oxd!y
k!y
k!y
k*& |Tk!
oo!y|xk!y{k! }26|k*:& |ʓk^p*& |¤k!
kss!y
k!y
k!y
o!y 
J	! 9n& !|kl!|ʅl!|ʗl!|ʩl!|m!|m! .[.
9n& cq
d! ! .
9n& cq
dxd!y 
! !4 l
dxd!y 
!z 
xd! .4l
dxd*B& |l! .2l
d! ! l
dxd! .[.
9n& cq
d! ! .
9n& cq
dxd! .l
dxd*B& |8l! .l
d! ! l
d! ! l
dxd! 9n& !|m!|m!|m!n!|!|!|!|Fn!|Fnbk+|n! 9n& ! 9n& yu! 9n& !|ʊn! 9n& ! 9n& yus!z
sxd!z 
!z 
!!z
! 9n& |;n!N 	!#zJ	n!&z 
!,z 
!2z
! 9n& |tn!N 	!4zJ	n!7z
n!>z
! s!+ 	 
xd! 9^#VDM`i  ̓|n! 9^#V 
ún! 9^#Vbkn& |o##9^#Vbkn& |o! 9^#Vbk#o!  ! 9n& bk++|_o!|_o!|ʘo!|ʘo!|o!|o!zg	! ! 9^#Vbkn& |o!Ez 
!Mz 
[o!Uz 
!]z 
[o! 9^#Vbkn& |¿o!ez 
!mz 
[o!uz 
!}z 
[o!  ! 9^#VDM`ip`in& |p`i!$ 	o`in& 	o*E& |p͌*|Ap!z
* 
!gͼ*E& |Up!Uͼ!z 
!z
! 9^#VJ	!zJ	! 9 9s#r 9^#Vs#r! 9^#V^#V!  9s#r  DM`i*̓|p!  úp*#"믾p!  9^#Vs#rn& p! 9^#V! 9^#Vs#r! !
 !  DM`i*̓|Dq!  *q!) !
 ! *+"! 9n& !|Yr!|]r!|ar!|er!|ir!|mr!|qr!|ur!|yr!|}r!|ʁr!|ʅr!|ʉr!|ʍr!|ʑr!|ʕr!|ʙr!|ʝr!|ʡr!|ʥr!|ʩr!|ʭr!|ʱr!|ʵr!|ʹr!|ʽr!K{!z!z!z!z!z!z!z!z!z!z!z!z!z!z!{!{!{!{!{!{!"{!({!.{!4{!;{!C{! 9^#VDM  y|s`i e|s`i y|s!Q{ 
! `iDMr!Y{ͫnÿs`i  e|ds`i̓|ds`io|Ws! .l
d! `iDM/s!`{ͫnÿs`i  ̓|ʀs! .l
d! +
d! ! l
d!g{ 
`i  ̓|ʿs! .l
d!l{
! 9^#Vo!KJ	! 9^#V 
;!r{
 ! 9s  ! 9s!	 9^#VDM`in& !|rtbk|t!|t`in&  9s!  ̓  9s& |3u! 9u!v{J	  ! 9s$u !  9s  ! 9s! 9s`i`in& Q|Lt! 9n& #} o|Lt! 9n& 
 =`in&  9sËt! 9t!' 	3 !  9s`in&  9sLt! 9u!, 	$u  ! 9s! 9n&  
t! 9ju! 9Pu!, 	Yu  ! 9s!' 	 ! 9s! 9n& 	t!y{g	! 9n& ! 9n& ! 9^#V͌! 9 ^#Vs#rbk%#|bk|v!{
! 9n& 	!{
! 9^#V 
!{
! 9n& 	!{J	!{
! 9n& 	!{J	v!9! 9^#Vbk|Qv! 9! DM  .9s#r! 9^#V! z+ 9s#r! 9^#Vs#r! ̓|v! 9^#V! !! 9^#V!
 9^#Ve.  9s#r`i̓|v! 9^#VDM! 9^#V!  9s#r! 9^#Vs#rvv! 9w! 9n& ͡|w y|ww!{
! 9n& 	!{
bk&  
!{
! 9n& 	!{J	Ùw! 9n& ! 9^#V!{!{w! 9! 9n& ! 9^#V! 9^#Ve. !{!{w! 9`i! 9! 9^#VDM`i  ̓|2x! 9^#V!  e|x! 9^#Vx! 9^#V
!
 9n& 	w! 9n& tDM! 9n& ! 9^#V4v`i͡!{
! 9^#Vo!+ 	! 9^#V 
PUSH	H POP	B DAD	SP XCHG DAD	D JMP	TRET RET PUSH	D PUSH	B POP	H MOV	H,L MOV	L,H MOV	A,L POP	D MOV	M,E MOV	M,D MOV	E/*
 * sample 6
 */

#ifndef REL		/* not needed if linking assembler used */
#include "crunt2.c"	/* not needed if linking assembler used */
#include "func.c"	/* not needed if linking assembler used */
#include "stdio.c"	/* not needed if linking assembler used */
#include "alloc.c"	/* not needed if linking assembler used */
#include "formatio.c"	/* not needed if linking assembler used */
#endif			/* not needed if linking assembler used */

#include "stdio.h"

#define d1	10
#define d2	2*d1
int arr[d1][d2];

char *fmt[11];

int printf(.), execl(.);	/* declare as list functions */

main()
{
	printf("Sample program 6: array indexing,\n");
	printf("formatted input/output, exec, and execl .\n");
printf(
"\n\nTest A: test 2 dimensional arrays (silent unless it fails)\n");
	test_2d_arrays();
	init_fmt();

printf(
"\n\nTest B: prints two strings plus the value 1 in various ways:\n\n");
	testprintf("CON:",1);

printf(
"\n\nTest C: prints two strings plus the value -2 in various ways:\n\n");
	testprintf("CON:",-2);

printf(
"\n\nTest D: prints the same using the hex value 0x8000:\n\n");
	testprintf("CON:",0x8000);
printf(
"\n\nThese next set of tests demostrate the aspects of symmetry between\n");
printf(
"printf format strings and scanf format strings\n");
printf(
"\n\nTest E: is like Test B, except that it does formatted file output\n");
printf(
"on the value 1, formatted file input on it, and then prints the result\n");
printf(
"on the console:\n\n");
	testprintf("$$",1);
	testScanf("$$");

printf(
"\n\nTest F: is like test C, except that it does formatted file output\n");
printf(
"on the value -2, formatted file input on it, and then prints the result\n");
printf(
"on the console (only the numbers on the first line will be output as -2\n");
printf(
"in the appropriate base, because of imperfect symmetry between printf and scanf\n");
printf(
"format strings):\n\n");
	testprintf("$$",-2);
	testScanf("$$");

printf(
"\n\nTest G: is like test D, except that it does formatted file output\n");
printf(
"on the value 0x8000, formatted file input on it, and then prints the result\n");
printf(
"on the console (only the numbers on the first line will be output as 0x8000\n");
printf(
"in the appropriate base, because of imperfect symmetry between printf and scanf\n");
printf(
"format strings):\n\n");
	testprintf("$$",0x8000);	/* hex 8000 */
	testScanf("$$");

printf(
"\n\nTest H: ");
	testexec();
}

init_fmt()
{
	fmt[0]="This is a format with no arguments\n";
	fmt[1]="%s\n";
	fmt[2]="%%o\t%o\t%%d\t%d\t%%u\t%u\t%%x\t%x\n";
	fmt[3]="%%3o\t%3o\t%%3d\t%3d\t%%3u\t%3u\t%%3x\t%3x\n";
	fmt[4]="%%6o\t%6o\t%%6d\t%6d\t%%6u\t%6u\t%%6x\t%6x\n";
	fmt[5]="%%06o\t%06o\t%%06d\t%06d\t%%06u\t%06u\t%%06x\t%06x\n";
	fmt[6]="%%07o\t%07o\t%%07d\t%07d\t%%07u\t%07u\t%%07x\t%07x\n";
	fmt[7]="%%-6o\t%-6o\t%%-6d\t%-6d\t%%-6u\t%-6u\t%%-6x\t%-6x\n";
	fmt[8]="%%-7o\t%-7o\t%%-7d\t%-7d\t%%-7u\t%-7u\t%%-7x\t%-7x\n";
	fmt[9]="%%-06o\t%-06o\t%%-06d\t%-06d\t%%-06u\t%-06u\t%%-06x\t%-06x\n";
	fmt[10]="%%-07o\t%-07o\t%%-07d\t%-07d\t%%-07u\t%-07u\t%%-07x\t%-07x\n";
}

test_2d_arrays()
{
	register int i;
	int j;
	int *p;

	for(j=0; j<20; ++j)
		for(i=0; i<d1; ++i)
			arr[i][j] = -2;

	for(p=arr; p<=&arr[d1-1][d2-1]; ++p)
		*p = -1;

	for(i=0; i<d1; ++i)
		for(j=0; j<d2; ++j)
			arr[i][j] = (j<<8)|i;

	for(p=arr; p<=&arr[d1-1][d2-1]; ++p)
		if(*p==-1)
			puts("Bad array value\n");
}

testprintf(s,i)
 char *s;
 int i;
{
	register int fd;

	fd = fopen(s,"w",128);
	if(fd==NULL) {
		printf("Can't open %s\n",s);
		return;
	}

	fprintf(fd, fmt[0]);
	fprintf(fd, fmt[1],  "This is one string argument");
	fprintf(fd, fmt[2],  i, i, i, i);
	fprintf(fd, fmt[3],  i, i, i, i);
	fprintf(fd, fmt[4],  i, i, i, i);
	fprintf(fd, fmt[5],  i, i, i, i);
	fprintf(fd, fmt[6],  i, i, i, i);
	fprintf(fd, fmt[7],  i, i, i, i);
	fprintf(fd, fmt[8],  i, i, i, i);
	fprintf(fd, fmt[9],  i, i, i, i);
	fprintf(fd, fmt[10], i, i, i, i);

	if(isatty(fileno(fd)))
		fflush( ,M MOV	D,M XTHL LXI	H,$+5 PCHL MOV	H,D MOV	L,E MOV	A,H ORA	L JZ	TRET RZ MOV	A,H ORA	L JNZ	TRET RNZ LXI	H, LXI	D, MVI	L, MVI	H, DS	 shli error DAD	H MVI	A, ADD	C MOV	C,A MVI	A, ADC	B MOV	B,A LHLD	 STA	 SHLD	 LXI	H, trace tret CZ	 CNZ	 LDA	 MOV	L,A MOV	L,M MOV	A,L STAX	D JMP	 MOV	A,H ORA	L J Z	 XRA	A CMP	M J Z	 LXI	H, LXI	H, MOV	H,B MOV	L,C MOV	H,D MOV	L,E MOV	B,H MOV	C,L MOV	D,H MOV	E,L Bad register op ORG	 CALL	TRACE DB	' ',0 CCPINT CCGINT CCEQ CCNE CCSXT CCSUB CCMULT CCDIV CCOR CCXOR CCAND CCASR CCASL CCNEG CCCOM CCLT CCLE CCGT CCGE CCULT CCULE CCUGT CCUGE CCUDIV CCGCHAR CCPCHAR CCBAD POP	PSW INX	SP DCX	SP SPHL CALL	 DB	 ', Opcode error MVI	 ,0 MOV	A, ANI	 MOV	 ,A MOV	A, ADI	 MOV	 ,A INR DCR INX DCX LXI	H, !|9ݛDMכ  s 9  9s#r!  s`in& !|_|!|e|!|e|bk||`in& m|H|9^#Vs#r`in& }|«|!  9^#Vs#r!  s{`i{`i{`in& m|e|{!  s 9#/"! 9! 9`i|ݛDMכ  9s#r!  9^#Vs#r!  e|}  ! 9s#r!
 9^#V! 9^#VA}! 9^#Vn& m|-}.9-}! 9^#V:}! 9^#V=}!  !
 9^#V! 9^#Vn& ! 9^#Vn& Y|}!
 9^#V! 9^#Vn& ԗ|}!
 9^#V! 9^#Vn&   ! 9^#Vn&   Y|}! 9^#Vs#r|`i|!  !9*&|}!d 9*D& |~!  "&!d 9*& |~!/~!f 9^#V 91;~!f 9*<& |\~!IJ	! 9^#VJ	! 9^#V!U*͢"&|!Wg	!9**|~!" 9͇
! 9  9s#r!& 9^#VDM`in& |~!  9^#Vs#r`in& }`i±~! 9   s!d**@! 9**@!k**@! 9!m2! 9;~!$ 9! 9^#VDM! 9^#Vn&   Y.9^#Vn&   Y! 9^#Vn& . Y|ʙ`i! 9^#Vs#rn& }<`i. s*F& |ʶ`iU s`iA s`iS s`iM s!  }! 9^#V;!  "(*9& |³*(|*(/*n& |*#"**! }29ó*"DM*n& |S*S*#"2*n&   9s*  s!r*͢"(|¡!t		!	*! 9n& }}*! 9n& }*"3*A& |ˀ! 9^#V믾ۀ! 9^#V!*͢  9s#rbk|wDM|%`i#|%Ϳ/! 9^#V!  !  !  	Output is  w Open failure sh as  
 .mac r 	Can't open:  
 r 
!!6 ><ꚁ4* ! 9^#Vn& !|Ӂ!|%! D!  ! 9^#V!  $DM#|! 9^#V! 9^#V! 9^#Vbk#n& |%!  ! 9^#V!  DM#|! 9^#VDM`it`in& ! 9^#V#|n+`iK! 9^#V! 9^#VDMʹ|¡.D`i' n& |`i' ! )#|т+ă#|.
D/! 9n& |..9^#V)#|+! 9n& ! 9^#V)! 9^#V!' n& !|^!|^!|^! D! 9^#V!) ^#VDM##^#V`i####^#Vy|ʜ! 9^#V#|+`i##^#Vs#r`i^#Vs#r 9n& }! 9^#VDM' n& !|!|!|!|! D`i) ^#V!  s#r  ȍDM! 9^#V#|A+`i' ! 9^#Vs! e|f! D`in& ! ̐! #|і!! 9^#V! |ʾ`i	 n&  |ʾ/!`iȍDM! 9^#V#|߄+`i'  s`in& ! n! #|і!`i! 9^#V!) ^#VDM! 9^#V`i `i##^#VJ`i##^#VY|[!`i s#r`i##  s#r  ! 9^#V!' n& !|ʣ!|ʣ! D! 9^#V!) ^#VDM##^#V!  y|`i##! 9^#V`i `i####^#Vͱs#r!  y|! D`i s#r`i##^#Vs#r`i^#Vs#rn& ! 9^#VDMʹ|H`  9s#rі;! 9Ў  9s#r  9! ͙^#Vs#r! 9͵ݐ3! 9^#VDM#|̆`i|`i' n& bk|bk+|bk++|!!|!|!|!|!  ! ! 9^#VDM#|-+!/ lͥ! 9^#VC! 9^#VDM' n& bk+|ʑbk++|ʑ!!|!|!|! D! .
9^#V!
 9^#Va! 9! 9^#VDM' n& bk|bk++|!|!|! D! .
9^#V!
 9^#Va! 9! 9^#V! 9^#Vn%#|0!  ! ! 9^#VD!
 9^#VDMa! D! 9^#V! 9s#r! 9^#VA}|`i#n& |ʢ`i#n& |Ԉ! 9^#V`in& } ̓|! D! 9^#V!  s`in& |s`i  !  9s#r`infd);/* leaving this open for no particular good reason */
	else
		fclose(fd);
}

testScanf(s)
 char *s;
{
	register int fd;
	char str[100];
	int i, j, k, l;

	fd = fopen(s,"r",128);
	if(fd==NULL) {
		printf("Can't open %s\n",s);
		return;
	}

	if(fscanf(fd,"%[^\n]s",str)==ERROR)
		return;

	printf(   "%s\n",str);

	if(fscanf(fd,"%[^\n]s\n",str)==ERROR)
		return;

	printf(   "%s\n",str);

	do_one(fd,2);
	do_one(fd,3);
	do_one(fd,4);
	do_one(fd,5);
	do_one(fd,6);
	do_one(fd,7);
	do_one(fd,8);
	do_one(fd,9);
	do_one(fd,10);

#ifdef XXXX
	printf("\n---the following was not read from %s---\n",s);

	for(;;){
		i = getc(fd);
		if(i==-1 || i==0x1a)
			return;
		putchar(i);
	}
#endif
}

do_one(fd, n)
 int fd;
 int n;
{
	int i, j, k, l;

	i = j = k = l = -1;
	fscanf(fd,fmt[n], &i, &j, &k, &l);
	printf(   fmt[n],  i,  j,  k,  l);
}

testexec()
{
	puts("Now, test execl.  Look for samp5.com on this disk:\n");
	execl("samp5.com","samp5.hex",0);
	/*
	 * if we can't find samp5.com,
	 * try other programs:
	 */
	puts("Couldn't find samp5.com, try to find another sample program.\n");
	exec("samp4.com");
	exec("samp3.com");
	exec("samp2.com");
	exec("samp1.com");

	/*
	 * if we can't find samp?.com,
	 * try a few prime user numbers
	 * on the current drive:
	 */
	puts("Still can't find a sample program, try a different user no.\n");
	exec("/1:samp3.com");
	exec("/3:samp3.com");
	exec("/5:samp3.com");
	exec("/7:samp3.com");
	exec("/11:samp3.com");
	exec("/13:samp3.com");
	puts("Can't exec a sample program");
}
intf("\n---the following was not read from %s---\n",s);

	exec("samp4.com");
	exec("samp3.com");
	exec("samp2.com");
	exec("samp1.com");

	/*
	 * if we can't find samp?.com,
	 * try a few prime user numbers
	 * on the current drive:
	 */
	puts("Still can't find a sample program, try a different user no.\n");
	exec("/1:samp3.com");
	exec("/3:samp3.com");
	exec("/5:samp3.com");
	exec("/7:samp3.com");
	exec("/11:samp3.com");D!9! }2A!	9^#Vs#r!9^#Vs#r|!	9^#V^#V!ͩ'|²!	9^#Vbk##^#V!  X#|!!9^#Vbk##^#V! !!!9^#Vbk##^#V,!  !9!	9^#V^#V!ͩ'|}2A!!  X#|!DM!,!!!!!  DM!  "B!9^#V"?!	9^#V"=!  9!9^#Vs#r^#V'!  9!. ͹)|x9!l'!  9!! ͥ
9s#r!9^#Vbk|  bk9s  9! 9!.9^#V	& |i!9^#V͙`i| !  9!! ͧ! 9!  9!!! ͥ
9s#r!9^#Vbk|0!ͥ*B|*B##*B##! .!	9^#V)! 9*B^#V"B0!  9?!! 9;|! ! 9;|ʯ*?+"?+|*=##"=á& |*A& |¡!  9á!9^#V!9^#V͵!9! 9^#V*?͏)DM! 9^#V*?0|+*=`i)^#Vbk|0!,*=`i)^#V!9!  9DM!9^#V!9s#r!9^#Vn& bk|ʒ!|ʳ`i!9^#Vs#rn& }Z!  }!9^#V 9'!9!9^#Vs#rn& 9sbk|/!|@!|X!|X!|v!9^#V͟&9s#r`i!9^#Vs#rn& }|!9^#Vs#rZ!9^#Vs#rn& 9s!9^#Vs#r !9s#r!9^#V9s#r`i!9^#Vs#rn& }|`i!9^#Vs#r*?0|Z`i!9n& |.,!  }p`i!9^#Vs#rn& /|!9^#Vs#rZ! E.  9s#rbk#|4!-ͥ*Bs#r"Bbk#! 9^#V! .$ͫ.bk#! 9^#V! 9^#Vbk##! 9^#V -#! ͏)}((! 9! 9^#V! !   ! 9^#VDM`i! `in& ! 9^#Vs#rn& 0|!  !;! 9^#V)DM|,.9^#V! 9^#V -DM`i#0 ss`i#n& #}|h`in& #}|``i#0 s! 9^#V!  X#|7.9^#V-E Missing file: %s
 a:$$$.sub a:$$$.sub -I a:$$$.sub A:$XX.SUB a:$$$.sub $00.sub $01.sub $02.sub $03.sub .SUB r shift SHIFT sh -e %s a:$$$.sub w No room on disk
  Out of memory X 82G!216 ><P4* X!  9u! 9^#V  !9!  9!s#r  9DM! 9! 9 s0s0m0! 9`i͙0DM!  9! 9^#VH,s#rͭ-! 9^#V! 9/! 9 !
 9^#VDM & Q|3!
 .9^#V=`in&   9s#r!  e|N`in& |Z! D! 9^#V!& ! 9^#VsÃ! 9^#V!&  s`in& |`i! 9^#Vs#r! . ͥ  !  9s#r`in& |`i! 9^#V! 9^#V!	 ͍|! D! 9^#V!	  9s#r !  9s#r! 9^#Vs#r`in& }`i=!  !  9^#Vs#r! e|ʺ! D!9! 9^#VDM! 9  ! 9s#r! 9^#V|! 9^#V! `i$ n&  9s#r͡|Ɋ! 9^#Vъ! 9^#V 9s#r!|ʡ! 9n& |b! m#|! 9͵! 9^#V! 9! 9^#V`i- ^#V`i$ n& ! 9^#Vͧ`i%  n& }ދ! m#|`i- ^#V`i$ n& ! 9^#V! 9^#VͧދЎ#|`i% n& }! 9n& ! 9^#VX#|! 9! 9^#V^#Vs#r 9! 9^#V^#Vs#r 9! 9^#V^#Vs#r`i$ ! 9^#Vn& } y|ʇ`i! ^#Vs#r`i$   sÇ;!	 9^#VDM! 9! 9^#V 9s#r! 9͵! 9^#V3! 9^#VDM:|! 9^#Vbk#n& }! .9^#Vbkn& `i& n& %#|!  .9^#Vbk##n& ! 9^#VDM:|.9^#V! S}! .9^#Vbk#`in& }|c`in& +o! 9^#Vbkn& !  }`i&   sƍ`i& n& %#|ƍ! 9^#V!  .}!  `i& n& !/ ͋DM|܍`i! D! 9^#Vʹ|! 9^#V!) ! 9^#V! ͋s#rDM|:.9^#V/! D!  `i s#r`i##  s#r`i####! 9^#Vs#r! 9^#V!' ! 9^#Vn& }!|Ǝ!|Ǝ! 9^#V!' ! 9^#Vbk#n& |.XÎ!R }! 9^#V! 9^#VDM% n&  |f`i! ^#V! 9s#r`i! `i+ ^#Vs#r! `i- ^#VX  9s#rbk#|M`i% n& }`i! ! 9^#Vs#r!  ! 9^#VDM% n&  |ʦ`i! ^#V`i+ ^#VY|S`i- ^#Vbk|ڏ`i- ! ͋s#rbk|ڏ.DЎ#|+`i% n& }`i+ `i! ^#Vs#r! `i- ^#VX#|>.9^#V!|>+`i%  n& }!  ! 9^#VDM! 9^#V̐! 9^#V|×! !
 9^#VD! 9^#V! 9^#V%#|ʹ!  ! ! 9^#VD! .9^#V! 9^#VDMʹ|.D`i) ^#V|`i) ^#Vі`i- ^#V|5`i- ^#Vі!   & ! 9^#V"!! 9^#V!  ! 9^#Vs#rn& m|g.9^#Vs#rn& !|ʩ!|Ñё !  9s 9^#Vs#rڑ! 9^#Vs#r  !  9s!  DM! 9^#Vs#rn&  9sQ|`i
 =! 9n& DMߑ& |-`i$/`i! 9^#VDM`i=`i`i! 9^#Vs#rn& }|H.9^#V! 9^#VDM`in& ! 9^#Vs#rn& Y|ʴ`in& ! 9^#Vbk+n& `iz!  ! 9^#VDM`i! 9^#Vs#rn& }|̒`i! 9^#Vi  9s#r!
 9^#VDM^#Vs#r`i^#V! 9s#r^#Vbk}o& |T! 9^#V^#Vs#r#! 9^#V! 9^#V)͗|ʢ! 9^#V! 9^#V)"͖͍|*͖`i^#Vs#r! 9^#V*˖M|/!  ?*˖##M|/! 9^#V`i z)#|/! 9^#V)"˖"͖*ɖ s#r*͖ s#r!
 9^#V`i ^#Vs#r! 9^#V͋DM|l!
 9^#V! 9^#Vͧ!
 9^#Vі`i! 9^#V͋!9! 9^#Vi  9s#r*͖DM`i^#Vbk}o& |U`i^#V! 9s#r^#Vbk}o& |! 9^#V^#Vs#rý! 9^#V! 9^#V)͗|U! 9^#V! 9^#V)"͖͍|9*͖`i^#Vs#r*͖ s#r`i##! 9`i 9s#r`i^#Vbk}oDM! 9^#V*͖͗|«*͖͡|«9^#V! ) 9s#r! 9^#V 9s#rbk#|##9^#V ͗|ٕ!  ! 9! 9^#V! v}o 9s#rÞ*˖! 9^#V!
 9^#V*˖##Y|! !!  s#r! 9^#V! 9^#V! 9^#V! v+)"˖s#r*˖*ɖ s#rë!ȖDM³! }! "ɖ## s#r*ɖ##*ɖ s#r*ɖ##"͖"˖! 9^#V### v         ! 9^#V"͖^#Vs#r! 9^#V!  ?}o& ?! 9^#V!  ?  9s#r! 9^#Vbk|H9^#V! 9^#V! 3|gDM?#|k+! 9^#V`i?#|£`i 9s#r! 9^#V$?!! 9^#VDM`iʗ`in& õ! 9^#V! 9n& DMH|,! ! 9^#VDM`i ! 9^#V+! 9n& DMa y|D`iz o|D!  `i! 9n& DMA y|h`iZ ok!  ! 9n& !|ʣ!!|!|!|!|!  ! ! 9^#VDM!
 9^#VM|И.9^#Vbk|Ԙ`i!
 9^#V͍|!
 9^#V! 9^#V͝,!
 9^#V0|?	! 9! 9^#VC	s#r|?	`i^#Vn& `i`i!{9! 9^#V^#VDM! 9^#V1|t	!  ! 9`in& s-|	`in& !|	!|	  ! 9s! 9 9s#r !  9s#r! 9	`in& ! 9n& 0	`iW	`in&  9sä	`in& s-  ͸0|O
! 9^#V0|O
`in& |%
`i! 9^#Vs#r`in& }!  9^#Vs#rû	! 9^#V!  s 9! 9^#VE. 9s#r! 9^#Vͭ-! 9^#V`i#s#r! 9^#V! 9! 9^#Vn& C-!|
!|1!|L! &!  ! 9^#V!  DM#|! 9^#V! 9^#Vͭ! 9^#Vbk#n& C-|1!  ! 9^#V!  DM#|
! 9^#V! DM#|~! 9^#V!DM#|͵!  !  ##͈
! 9^#VDM:&|¹.&  !  9s#r`i' n& |`i' ! ]#|!  9s#r!  9^#V͒0s#r͵! 9^#V͒0! 9^#V!  9s#r|ʐ!
 9^#VDM`i|y! 9^#Vs#rn& ! 9^#V]#|!  9^#Vs#r:`iL! 9^#V! 9^#V͙0! 9^#V! 0|ʼ! 9EDM^#V`i##!|9! 9^#V! 0|!  ! 9!  9! 9E!  9,! 9!j9! 9^#Vs#r^#V! 9s#r! 9^#Vs#rn&  9s|! 9n& |ʉ! 9^#Vs#r 9n& }>! 9^#V! 9s#r 9DM ! 9s#r  ! 9s! 9s! 9^#Vn& - ͸0 9s|! 9^#Vs#r! 9^#Vn& |.0!   9s 9
 9s#r 9^#Vs#rn&  9s!|l.9 9s#r 9n& #}! 9^#Vs#rn&  9s! 9n& C- 9s!|ʟ!
 9^#V| !
 9s#r! 9n& !|!|$!|0!|<!|ʖ!|!|ʔâ! 9^#V^#V!  0|$ ! 9s! 9^#V! 9^#V^#V͠0s#r
 ! 9sE ! 9sE ! 9s`i  9s#r
 9! 9! 9^#Vs#r^#V 9n& ^#V͙0s#rDM`i! 9^#Vs#r^#Vs
 9^#Vs#r! 9! 9^#V! 0| ! 9s#r! 9^#Vs#r^#V! 9s#r! 9^#V믾3! 9! 9ʒ! 9n& 0 ͸0Õ! 9^#Vbk|! 9 1|e`i! 9^#Vn& }! 9^#Vs#r
 9^#Vs#r 9^#Vs#r!  |! 9^#Vs#r!- s  ! 9s
 9^#Vs#r!
 9^#Vs#r!  0|! 9^#Vs#r 9n& }! 9$! 9^#Vs#r!- s
 9^#Vs#r!  }! 9DM! 9^#Vs#r`in& }|1.9^#Vs#r 9>!
 9^#Vs#r!  0|>! 9^#Vs#r!  se! 9^#Vs#r! 9^#Vs#r!% s! 9^#V! 9s#r>! 9^#V!  s! 9!  DM.9^#V^#V!  9s#rn& /|-!
 `i/! 9^#Vs#rn& DM! 9^#V! 9^#Vs#r`i! 9^#VDM 9s#r`i^#V`i)DM! 9^#V1|ʹ`i^#V!  9s#r! 9^#V^#Vs#r 9^#Vs#r! 9^#Vs#r`ig! 9^#V! 9^#V! 9^#VDM1|!! 9^#V^#Vs#r! 9^#V!
 9^#V!
 1|!0 !7 }! ! 9^#V! 9^#V`i5/!
 9^#V!
 9^#V`i5/! 9^#V!' n& !|ʒ!|ʒ!|ʒ! &! 9^#V!) ^#VDM##^#V`i####^#V0|! 9^#V͕#|+`i##^#Vs#r`i^#Vs#r 9n& }! 9^#VDM' n& !|9!|9!|9!|@! &͕`i) ^#V!  s#r  ! 9^#V! ͋0|ʂ! 9 ^#V͒0s#r! 9^#V! 9^#V|ʮ! 9^#V! ͨ0 ͋0+ñ!    9s#rbk#|+! 9^#V! ͋0|! 9^#V!̀(|+͵.com ! 9^#V[DM#|+`i' ! 9^#Vs! 0|E! ͮ$`in& !||ʙ!|ʙ!|ʾ!}|!~|! ͝$! s#|(,!! 9^#V! ͋0|`i	 n&  ͋0! 9^#Vbk|ʙ!	 ͮ$! 9^#Vbk+|ʙ!	 ͮ$!  |͵!`i!
 9^#VDM! 9^#Vs#r|ʮ! 9^#V  9s#r!|g#|w!|ʜ! 9^#Vs`i! 9^#V͕"!  }!
 9^#V믾ʖ!
 9^#V!  !  }!
 9^#V!  }!
 9^#V! 9^#VDM|.9^#VDM|! 9^#V͕"! DM`i! 9^#V[DM#|+`i'  s`in& !|z!!||!|!}|!~|! ͮ ! s#|(,!!	 ͮ$`i(   s`i! 9^#V!) ^#VDM! 9^#V`i `i##^#Vͭ`i##^#V0|!`i s#r`i##  s#r  ! 9^#V!' n& !|!!|!! &! 9^#V!) ^#VDM##^#V!  0|ʍ`i##! 9^#V`i `i####^#Vs#r!  0|ʀ! &`i s#r`i##^#Vs#r`i^#Vs#rn& ! 9^#V$#|! 9^#V! 1| ! 9s#r! 9^#V!) ! 9^#V! )s#r ! 9^#V+!
 9^#V! 9^#V+! 9^#Vu! 9^#V! 9^#V*DM! 9^#V`i͍|q! 9^#V!  ̓|ʈ!! 9^#V!  e|ʈ!! 9^#V|ʡ!`i! 9^#V|ܙ! 9^#VDM! 9n& }`i#!
 9^#V͝! 9^#V! 9^#VDM  e|`i$`i! 9n& |.˛! 9n& ˛! 9n& DMa y|L`iz oO!  ! 9n& DM0 y|q`i9 ot!  ɯ}Ϛ͏$$||/G}/O!  ͡zS)ÚҮ#	ں¥_33<¥_ɏȚ#	¥_z|$z$  $$9}o|"!  !`i"  )#5&  *DMůZZDM{^|^e. 	G!  kl	)h	`i"xʵ:ʐõ~+xõ`i"xʵ:ʾ*DM~#x¾õ * & ! `iDM W{j& |g}o|g}o|g}o{ozg|/g}/o#}/o|/g{ȷ|g}o7{)=G}o|! -}o|g! }|!  ,{z! -}|! -{z!  ,}|! +{z!  ,{z! -                   7{)=G}o|! -}o|g! }|!  ,{z! -}|! ; Copyright (c) 1983 SuperSoft, Inc.
;
;	11/15/82 RB	Setup for C 1.2.0
;	9/15/82 RB	New exec
;	9/09/82 RB	New shift routines
;	9/03/82 RB	New div routine
;	8/25/82 RB	Various optimizations
;	4/7/82
;	8/13/82 mqh	replaced by setjmp/longjmp
;				Preserved BC in LDDR/LDIR

REL	EQU	0		; 1 creates a REL style source

;	In order to reassemble c2rt.rel do the following:
;
;	pip c2rt.mac=c2.rh,c2.rt
;	ed c2rt.mac
;	*#asREL EQU 0^ZREL EQU 1^Z
;	*e
;	m80 =c2rt
;

DIV0	EQU	0		; 0 supresses divide by 0 message

	IF	REL

	PUBLIC	CCSTAR		;	*leave in c2.rh*
	PUBLIC	EXIT		;
	EXT	XMAIN		;
	PUBLIC	CCEDATA		;

	PUBLIC	COMLINE		;
	PUBLIC	COMLEN		;
	PUBLIC	CCNEG		;
	PUBLIC	CCCOM		;
	PUBLIC	CCAND		;
	PUBLIC	CCXOR		;
	PUBLIC	CCOR		;
	PUBLIC	CCASL		;
	PUBLIC	CCASR		;
	PUBLIC	CCSUB		;

	PUBLIC	CCUDIV		;	*together*
	PUBLIC	CCDIV		;

	PUBLIC	CCMULT		;

	PUBLIC	CCEQ		;
	PUBLIC	CCLT		;
	PUBLIC	CCGT		;
	PUBLIC	CCGE		;
	PUBLIC	CCLE		;
	PUBLIC	CCNE		;
	PUBLIC	CCULT		;
	PUBLIC	CCUGT		;
	PUBLIC	CCUGE		;
	PUBLIC	CCULE		;

	PUBLIC	BRK		;	*uses CCEDATA*

	PUBLIC	CCGINT		;
	PUBLIC	CCPINT		;

	PUBLIC	SETEXIT		;	*together*
	PUBLIC	RESET		;

	PUBLIC	SETJMP		;	*together*
	PUBLIC	LONGJMP		;

	PUBLIC	STREQ		;

	PUBLIC	BDOS		;

	PUBLIC	CCONST		;
	PUBLIC	CCONIN		;
	PUBLIC	CCONOUT		;

	PUBLIC	CCLDIR		;
	PUBLIC	CCLDDR		;

	PUBLIC	CCALL		;
	PUBLIC	CCALLA		;

;	PUBLIC	CCSXT		;

	PUBLIC	XSTART		;	*together*
	PUBLIC	XFCB1		;
	PUBLIC	XFCB2		;
	PUBLIC	XEND		;

	ENDIF

CCBDOS		EQU	5
;
;	WHICH CPU?
CCSTAR: LXI	H,CCCPU
	MVI	M,0
	MVI	A,2
	INR	A
	JPE	CIS8080
	INR	M
CIS8080:LHLD	6
	SPHL
	LXI	D,CCIDSTR
	MVI	C,9
	CALL	CCBDOS
	CALL	XMAIN
	RST	0

CCEXIT	EQU	0	; EXIT() -- FOR C

;
; ****** READ IN USER CODE HERE *******
;

CC0ERR:	POP	D
	PUSH	B
	MVI	C,9
	CALL	CCBDOS
CC0EXIT: LXI	H,0
	POP	B
	RET

CCASL:	XCHG
	MOV	A,E
	ORA	A
	RZ
CCASL1:	DAD	H
	DCR	A
	JNZ	CCASL1
	RET

CCASR:	XCHG		; rotate (not really asr)
	MOV	A,E
	ORA	A
	RZ
CCARLP:	ORA	A
	MOV	DM|.9^#V͵! &!  `i s#r`i##  s#r`i####! 9^#Vs#r! 9^#V!' ! 9^#Vn& C-}!|ʫ!|ʫ! 9^#V!' ! 9^#Vbk#n& C-|¥.Xè!R }! 9^#V! 9^#VDM:&|  9s#r(,;!	 9^#VDM%|  !  9s#r! s  9s#r$3! 9^#V[ 9s#rbk#|P+!
 9^#V[DM#|v##9^#V$!`in& ! 9^#Vn& 0|±`i& n& ! 9^#V!& n& 0|! &  9s#r! 9^#V! ! ͭ-! ! 9^#Vs  9s#r$! 9^#V$! 9^#V[DM#|'+%|>!	 ͮ$! s  9s#r$!/ )DM|t.&!/ lͫ.`i(  s! 9^#Vͦ#|©(,!`i! 9^#VDM' n& bk+|bk++|!!|!|!|! &! .
9^#V!
 9^#V! 9! 9^#VDM' n& bk|Sbk++|S!|S!|S! &! .
9^#V!
 9^#V! 9! 9^#V! 9^#Vͮ %#|ʓ!  ! ! 9^#V&!
 9^#VDM! &! 9^#V! 9s#r! 9^#V }|`i#n& |`i#n& |7! 9^#V`in& C-} 0|D! &! 9^#V!  s`in& |`i  !  9s#r`in& /|ʖ!
 .9^#V/`in&   9s#r`!  0|±`in& |ʽ! &! 9^#V!& ! 9^#Vs! 9^#V!&  s`in& |`i! 9^#Vs#r! . ͫ.  !  9s#r`in& |t`i! 9^#V! 9^#V!	 0|V! &! 9^#V!	  9s#r !  9s#r! 9^#Vs#r`in& C-}`i !  !  9^#Vs#r! 0|! &!9! 9^#VDMn& !||A!|e!|ʲ!}|!~|! 9!! 9^#V! 5/! 9^#V! 5/| ! 9n&  ͸0 ! 9n& |T\! 9^#V! 9! 9n& |.9^#V! (&}! ! 9! .9^#V! 9^#Vs%! 9! 9^#V! (&}! ! 9! .9^#V! 9^#Vs%! 9! .9^#V! 9^#Vs%! 9!   9s#r  ! 9s#r! 9^#Vs#r|X ! 9n& ! 9^#V"#|t ! 9͂!! 9^#V! 9! 9 ^#Vs#r 9 ^#Vs#r`i! ^#Vs#r' ;!	 9^#VDM! 9!! 9^#Vw0 9s#r! 9͂!! 9^#V3!i!! 9^#VDM+%|!! !n!+%|(!! !s!+%|<!! !x!+%|P!! !}!+%|d!! !  CON: RDR: LST: PUN: NUL: ! 9^#VDMͺ%|¾!! 9^#Vbk#n& }! .9^#Vbkn& w0!`i& n& %#|!!  .9^#Vbk##n& w0! 9^#VDMͺ%|W".9^#V! (&}! .9^#Vbk#`in& }|0"`in& +<"! 9^#Vbkn& w0!  }`i&   sÓ"`i& n& %#|ʓ"! 9^#V!  .w0}!  `i& n& w0! 9^#V!' n& !|"!|"! &! 9^#V!) ^#VDM##^#Vs#r`i^#Vs#r 9n& }! 9^#VDMͺ%|#`i n& `i! ^#V! 9/0|# $`i `i! ^#V! 9/}! j$#|#.
9^#V!|y#.j$#|#!`i  `i! ^#V! 9/sï#!
 9 ^#Vs#r! 9^#V͝$!
 9^#Vw0|##! ! 9^#V&  9s#r`i n& `i( n& 0|$`i( `i n& }! ͝$! ! 9^#VDMw0`i `i! `i ͙0 9/!  ͫ.! 9^#V! 9^#Vw0%#|ʊ$!  ! ! 9^#V&! .9^#Vw0! 9^#V$! 9^#V&! 9^#V$#|$+! 9^#V(,!  ! 9^#VDM:&|	%.&`i) ^#V|&%`i) ^#V(,!  ! 9^#VDM`in%`in& ! 9^#Vs#rn& C-0|h%!  `i6%! !  DM`i! 9^#V1|ʰ%! 9n& ! 9^#Vs#rn& w0y%! ͙0 & ! 9^#V:&|%.&! 9^#Vn& !&!||!|!|!}|!~|!  ! ! 9^#V"(1!! 9^#V!  w0! 9^#VDM#|R&`i|ʕ&`i' n& bk|ʚ&bk+|ʚ&bk++|ʚ&!&!|!|!|!|!  ! ! 9^#Vs#rn& s-|¡&.9^#Vs#rn& !|&!|&' !  9s 9^#Vs#r'! 9^#Vs#r  !  9s!  DM! 9^#Vs#rn&  9s/|V'`i
 /! 9n& DM'& |g'`i͠0i'`i! 9^#VDM`iw'`i`i! 9^#Vs#rn& }|'.9^#V! 9^#VDM`in& ! 9^#Vs#rn& 0|'`in& ! 9^#Vbk+n& ͙0`i´'!  ! 9^#VDM`i! 9^#Vs#rn& }|(`i! 9^#VDM! 9^#Vs#r|v(`i! 9^#V믾m(! 9^#Vs#rn& p(!  }3(! 9^#V!
 9^#VDM! 9^#V! 9s#r!  9s#r`i±(! 9^#V믾(!  `in& C-! 9^#Vs#rn& C-0|ʣ(!
 9^#VDM! 9^# A,H
	RAR
	MOV	H,A
	MOV	A,L
	RAR
	MOV	L,A
	DCR	E
	JNZ	CCARLP
	RET

			; de = de / hl;	unsigned
CCUDIV:	XRA	A	; clear S condition code
	JMP	CCDV9

CCDIV:	CALL	CCDMSE	; de = de / hl; signed; S = f(de,hl)

CCDV9:	PUSH	B
	PUSH	PSW

	CALL	CCDV1
	XCHG
	POP	PSW
	POP	B
	RP
	CALL	CCNEG
	XCHG
	CALL	CCNEG
	XCHG
	RET

CCDV1:	MOV	A,H
	ORA	L
	JZ	CCDIV0

	MOV	A,H		; BC = -HL
	CMA
	MOV	B,A
	MOV	A,L
	CMA
	MOV	C,A
	INX	B
	LXI	H,0

	CALL	CCDV2
CCDV2:	MOV	A,D
	MOV	D,E
	MVI	E,8

CCDV3:	DAD	H
	JC	CCOVER
	ADD	A
	JNC	CCDV4
	INX	H

CCDV4:	PUSH	H
	DAD	B
	JC	CCDV5

		POP	H
		DCR	E
		JNZ	CCDV3
		MOV	E,A
		RET

CCDV5:	INX	SP
	INX	SP
	INR	A
	DCR	E
	JNZ	CCDV3
	MOV	E,A
	RET

CCOVER:	ADC	A
	JNC	CCOSUB
	INX	H

CCOSUB:	DAD	B
	DCR	E
	JNZ	CCDV3
	MOV	E,A
	RET

CCDMSE:	MOV	A,D
	XRA	H
	PUSH	PSW

	MOV	A,H
	ral
	cc	ccneg
	MOV	A,D
	ral
	jnc	ccdms1
	XCHG
	CALL	CCNEG
	XCHG
CCDMS1:	POP	PSW
	RET

CCDIV0	EQU	$
	IF DIV0
		LXI	D,DIV0MSG
		MVI	C,9		; Print string
		CALL	CCBDOS
	ENDIF
	LXI	D,0			; X / 0 == 0
	POP	B
	RET

CCEQ:	MOV	A,L
	SUB	E
	MOV	L,A
	MOV	A,H
	SBB	D
	ORA	L
	LXI	H,1
	RZ
	DCR	L
	RET

CCNE:	MOV	A,L
	SUB	E
	MOV	L,A
	MOV	A,H
	SBB	D
	MOV	H,A	; not needed if hl unused on return
	MOV	H,A
	ORA	L
	RZ
	LXI	H,1
	RET

CCLT:	MOV	A,E
	SUB	L
	MOV	A,D
	SBB	H
	LXI	H,0
	RP
	INR	L
	RET

CCGT:	MOV	A,L
	SUB	E
	MOV	A,H
	SBB	D
	LXI	H,0
	RP
	INR	L
	RET

CCGE:	MOV	A,E
	SUB	L
	MOV	A,D
	SBB	H
	LXI	H,1
	RP
	DCR	L
	RET

CCLE:	MOV	A,L
	SUB	E
	MOV	A,H
	SBB	D
	LXI	H,1
	RP
	DCR	L
	RET

CCEXCH:	XCHG
	JMP	CCM3

CCMULT:	PUSH	B
	XRA	A
	CMP	H
	JZ	CCEXCH
	CMP	L
	JZ	CCEXCH

CCM3:	MOV	B,H
	MOV	C,L
	MOV	A,E
	PUSH	D
	CALL	CCBMULT
	XTHL
	MOV	A,H
	CALL	CCBMULT
	MOV	H,L
	MVI	L,0
	POP	B
	DAD	B
	POP	B
	RET

CCBMULT:LXI	H,0
	MVI	E,7
	ADD	A
	JC	CCM6
	RZ

CCM2:	JNC	CCM4
CCM6:	DAD	B

CCM4:	DAD	H
	ADC	A
	DCR	E
	JNZ	CCM2
	RNC
	DAD	B
	RET

CCNEG:	MOV	A,H
	CMA
	MOV	H,A
	MOV	A,L
	CMA
	MOV	L,A
	INX	H
	RET

; check for program or stack overlap
BRK:	POP	D
	POP	H
	PUSH	D
	PUSH	H

	INR	H		; save 100h for misc
	CALL	CCNEG
	DAD	SP
	JNC	C1ERR

	POP	H
	PUSH	H
	LXI	D,EDATA
	MOV	A,L
	SUB	E
	MOV	L,A
	MOV	A,H
	SBB	D
	JC	C1ERR

	POP	H
	SHLD	CCEDATA
	POP	D
	PUSH	D
	PUSH	D
	LXI	H,0
	RET

C1ERR:	POP	D
	POP	D
	PUSH	D
	PUSH	D

CERROR: LXI	H,-1
	RET

CCCOM:	MOV	A,L
	CMA
	MOV	L,A
	MOV	A,H
	CMA
	MOV	H,A
	RET

CCAND:	MOV	A,H
	ANA	D
	MOV	H,A
	MOV	A,L
	ANA	E
	MOV	L,A
	RET

CCOR:	MOV	A,H
	ORA	D
	MOV	H,A
	MOV	A,L
	ORA	E
	MOV	L,A
	RET

CCGINT:	MOV	E,M
	INX	H
	MOV	D,M
	XCHG
	RET

CCPINT:	XCHG
	MOV	M,E
	INX	H
	MOV	M,D
	XCHG
	RET

;CCSXT:	MOV	A,L		; Sign extend anyone?
;	RAL
;	MVI	A,0
;	SBB	A
;	MOV	H,A
;	RET

;	HL = DE - HL
CCSUB:	MOV	A,E
	SUB	L
	MOV	L,A
	MOV	A,D
	SBB	H
	MOV	H,A
	RET

CCULT:	MOV	A,E
	SUB	L
	MOV	A,D
	SBB	H
	LXI	H,1
	RC
	DCR	L
	RET

CCUGT:	MOV	A,L
	SUB	E
	MOV	A,H
	SBB	D
	LXI	H,1
	RC
	DCX	H
	RET

CCUGE:	MOV	A,E
	SUB	L
	MOV	A,D
	SBB	H
	LXI	H,0
	RC
	INR	L
	RET

CCULE:	MOV	A,L
	SUB	E
	MOV	A,H
	SBB	D
	LXI	H,0
	RC
	INX	H
	RET

CCXOR:	MOV	A,H
	XRA	D
	MOV	H,A
	MOV	A,L
	XRA	E
	MOV	L,A
	RET

;setjmp(stateArea)
; char stateArea[/* at least 6 bytes */];
;{
SETJMP:
	POP	D
	POP	H
	PUSH	H
	PUSH	D

	MOV	M,C	; preserve reg var
	INX	H
	MOV	M,B
	INX	H

	XCHG		; preserve old sp
	LXI	H,2
	DAD	SP
	XCHG
	MOV	M,E
	INX	H
	MOV	M,D
	INX	H

	POP	D	; preserve ret addr
	PUSH	D
	MOV	M,E
	INX	H
	MOV	M,D
	LXI	H,0
	RET
;}

;longjmp(stateArea,value)
; char stateArea[/* at least 6 bytes*/];
; int value;
;{
LONGJMP:
	POP	PSW	; ret addr and we don't care
	POP	H	; state area
	POP	D	; return value
	SHLD	CCLJRV	; (kinda nasty)
	XCHG

	MOV	C,M	; fetch reg var
	INX	H
	MOV	B,M
	INX	H

	MOV	E,M	; fetch old sp
	INX	H
	MOV	D,M
	INX	H
	XCHG
	SPHL
	XCHG

	MOV	E,M	; fetch ret addr
	INX	H
	MOV	D,M
	PUSH	D
	LHLD	CCLJRV	; load return value from nasty place
	RET
;}

SETEXITV!  9s#rã(!
 9^#VDM! 9^#V! 9s#r!  9s#r`i=)! 9^#V믾Q)!  `in& ! 9^#Vs#rn& 0|/)!
 9^#VDM! 9^#V!  9s#r/)! 9^#V! 9^#V0|ʰ)! 9^#V! 9^#V! 9^#VDM`i)`in& ! 9n& ͸0|)! ͙0!  !9!,DMA*! }! H,DM" ,`i## ͒0s#r`i##`i ͒0s#r`i##"$,"",! 9^#V### 5/  9s#r*$,DM`i^#V! ͋0|	+`i^#V! 9s#r^#V! ͋0|¡*! 9^#V^#Vs#rr*! 9^#V! 9^#V)1|	+! 9^#V)"$,! 9^#V*$,0|**$,`i^#Vs#r*$, ͒0s#r`i##! 9`i 9s#r`i^#V!͋0DM! 9^#V*$,1|b**$,1|b*9^#V! ) 9s#r! 9^#VH, 9s#rbk#|¬+##9^#V 1|ʍ+!  ! 9! 9^#V! 5/͋0 9s#rR+*",! 9^#V!
 9^#V*",##0|+! +!  ͒0s#r! 9^#V! 9^#V! 9^#V! 5/+)"",s#r*",* , ͒0s#rb* ! ! ! 9^#V"$,^#V͋0s#r!  E. ͋0E.! 9^#Vh,!  E.  9s#r! 9^#Vbk|,9^#V! 9^#V! ͨ0͋0DME.#|·,+! 9^#V`i͙0E.#|,`i 9s#r! 9^#V͠0E.!! 9^#VDM`i-`in& .-! 9^#V! 9^#VDM`i+-! 9^#V͙0+! 9n& DMa 0|o-`iz 0|o-!  ͙0`i! 9n& !|ʩ-!-!|!|!|!|!  ! ! 9^#VDM!
 9^#V͸0|-.9^#Vbk|-`i!
 9^#V0|.!
 9^#V! 9^#V302.! 9^#V+!
 9^#V! 9^#V+! 9^#V0! 9^#V! 9^#V* 1DM! 9^#V`i0|w.! 9^#V!  0|ʎ.!! 9^#V!  0|ʎ.!! 9^#Vͧ/|ʧ.!`i! 9^#V|.! 9^#VDM! 9n& }`i#!
 9^#V30! 9^#V! 9n& |/.a0! 9n& a0! 9n& DM0 0|0/`i9 03/!  ɯ</͎/N/͠0͠0|ʢ/|/G}/O!  `/zS)ڂ/m/#	y/d/_33<d/_ɏ҇/#	d/_z|ܠ0zҠ/͠0  $͠09/51}o|/" 1!  !ů//DM{/|/e. 	/!  00	)/	`i"31xK0:21&0K0~+x&0K0`i"31xK0:21T0*31DM~#xT0K0 * & ! `iDM o& |g}o|g}o{ozg|/g}/o#{ȷ|g}o¬0}o|! -}o|g! }|!  ,{z! -}|! -{z!  ,}|! +{z!  ,}|!  #{z! -51               !0}o|! -}o|g! }|!  ,{z! -}|! -{z!  ,}|! _ɏ҇/#	d/_z|ܠ0zҠ/͠0  $͠09/51}o|/" 1!  !ů//DM{/|/e. 	/!  00	)/	`i"31xK0:21&0K0~+x&0K0`i"31xK0:21T0*31DM~#xT0K0 * & ! `iDM o& |g}o|g}o{ozg|/g}/o#{ȷ|g}o¬0}o|! -}o|g! }|!  ,{z! -}|! -{z!  ,}|!  : LXI	H,2
	DAD	SP
	SHLD	CCEXPC+2
	POP	H
	SHLD	CCEXPC
	PUSH	H
	MOV	H,B
	MOV	L,C
	SHLD	CCEXPC+4
	LXI	H,0
	RET

RESET:	POP	D
	POP	D
	LHLD	CCEXPC+2	; could check for exitsp > current SP
	SPHL
	LHLD	CCEXPC
	PUSH	H
	LHLD	CCEXPC+4
	MOV	B,H
	MOV	C,L
	XCHG
	RET

STREQ:	PUSH	H
	MOV	H,B
	MOV	L,C
	SHLD	XXKLG	; bad kludge
	POP	H
	POP	B
	POP	D
	XTHL
	PUSH	B
	PUSH	B
	LXI	B,0
	JMP	CCLP

CCMORE:	INX	B
	INX	H
	INX	D

CCLP:	LDAX	D
	ORA	A
	JZ	CCOUT
	CMP	M
	JZ	CCMORE
	LXI	B,0

CCOUT:	PUSH	B
	LHLD	XXKLG
	MOV	B,H
	MOV	C,L
	POP	H
	RET

BDOS:	MOV	H,B	; save b
	MOV	L,C
	POP	B	; pop return address
	POP	D	; pop new d value
	XTHL		; tos contains old b; h contains new b
	PUSH	B	; push return address
	MOV	B,H	; put b value where it belongs
	MOV	C,L

	CALL	CCBDOS
	POP	H
	POP	B

	PUSH	H	; restore stack for C
	PUSH	H
	PUSH	H
	MOV	L,A
	MVI	H,0	; should be a sign extend...
	RET


CCONST:
	PUSH	B	; save reg variable
	MVI	C,11	; bdos function number
	CALL	CCBDOS	; execute function
	MVI	H,0	; set up return value
	MOV	L,A
	POP	B	; restore register variable
	RET		

CCONIN:	PUSH	B	; save reg variable
	MVI	C,1	; bdos function number
	CALL	CCBDOS	; execute function
	MVI	H,0	; set up retun value
	MOV	L,A
	POP	B	; restore register variable
	RET		

CCONOUT: POP	H	; pop return addr
	POP	D	; pop parameter
	PUSH	D	; restore parameter
	PUSH	H	; and return address
	PUSH	B	; save register variable
	MVI	C,2	; bdos function number
	CALL	CCBDOS	; execute function
	POP	B	; restore register variable
	RET		
 
;call()
;{
;#asm	
CCALL:
	PUSH	B
	CALL	CCALLER
	POP	B
;#endasm
;}
	RET

;ccalla()
;{
;#asm
CCALLA:	PUSH	B
	CALL	CCALLER
	POP	B
	MOV	L,A
	MVI	H,0
;#endasm
;}
	RET

CCALLER:
	LXI	H,15	; get address to call
	DAD	SP
	MOV	B,M
	DCX	H
	MOV	C,M
	DCX	H
	PUSH	B	; and put on stack so we can ret to it.
	MOV	D,M	; move hl parm to de
	DCX	H
	MOV	E,M
	PUSH	D	; and push it
	DCX	H
			; blow off flags
	DCX	H
	MOV	A,M	; load a
	DCX	H
	MOV	B,M	; load bc
	DCX	H
	MOV	C,M
	DCX	H
	MOV	D,M	; load de
	DCX	H
	MOV	E,M
	POP	H	; pop hl off stack
	RET		; jp *sp++
;#endasm
;}


;	This is exec's driver return. To execute it should be movmem()'ed
;	to 0x0080. It should NEVER be executed at this location as it has
;	been assembled as if at 0x0080.






XTPA		EQU	0100H
XAREA		EQU	0080H

XSTART:	nop			; store a zero byte
				; in case $.$ doesn't exist
	LHLD	6		; initialize stack to (bdos+1)
	SPHL
	LXI	H,0		; Push address of boot
	PUSH	D	
	LXI	D,XTPA		; initial load address
XLOOP:
	PUSH	D		; preserve load address
	MVI	C,26		; setdma to load address
	CALL	CCBDOS
	LXI	D,XFCB1
	MVI	C,20		; seq read data to load address
	CALL	CCBDOS
	POP	D		; restore load address
	ORA	A		; test eof
	JNZ	XEOF-XSTART+XAREA	; load complete.
	LXI	H,080H		; next load
	DAD	D		; address
	XCHG			; to DE.
	JMP	XLOOP-XSTART+XAREA

XEOF:
	LXI	D,XTPA			; entry point of loaded program
	PUSH	D			; where bdos will return
	LXI	D,XAREA
	MVI	C,26			; set dma to overwrite me
	CALL	CCBDOS	
	LXI	D,XFCB2			; fcb of $.$
	MVI	C,20			; seq read
	JMP	CCBDOS			; overlay this code and return to tpa

XEND:
XFCB1	equ	$-XSTART+XAREA
XFCB2	equ	$-XSTART+XAREA+33

CCLDIR:
; Callable via ccldir(dest,source,count)
; CCLDIR mimics LDIR instruction for 8080, executes LDIR on Z80. 
; However count of zero performs nop.

	MOV	H,B	; Squirrel away BC
	MOV	L,C
	SHLD	XXKLG	

	POP	H	; Return address
	POP	B	; Count
	POP	D	; Source
	XTHL		; Dest->hl, return address to TOS
	XCHG		; srce->HL,dest->DE,count->BC 

	MOV	A,B
	ORA	C
	JZ	CCLDIX

	LDA	CCCPU	; Check CPU type
	ORA	A
	JZ	CCLDI8

CCLDIZ:				; Z80 CPU	*****
	DB	0EDH,0B0H	; Z80 ldir instruction

CCLDIX:	LHLD	XXKLG
	MOV	B,H
	MOV	C,L
	XTHL			; Ret addr -> HL
	PUSH	H		; Adjust SP 
	PUSH	H
	PCHL			; Ret

CCLDI8:				; 8080 CPU	*****
	MOV	A,M
	INX	H
	STAX	D
	INX	D
	DCX	B
	MOV	A,B
	ORA	C
	JNZ	CCLDI8
	JMP	CCLDIX

CCLDDR:
; Callable via cclddr(dest,source,count)
; CCLDDR mimics LDDR ins/* Copyright (c) by SuperSoft, Inc., 1982 */

/*	stdio.c
 *
 *	This version has:
 *	User codes in file specs (eg b/6:file)
 *	Serial devices CON, RDR, PUN, LST may be opened and treated as files.
 *	Structures
 *	Fix for execl done on 6 July 1982  MQH
 *	Fix to fclose 1982 July 9 RB
 *	Fix to getw 1982 July 9 RB
 *	Fix to exec 1982 Sept 19 RB
 *	Fix to cpmver, seek, and unlink 1982 Sept 29 RB
 *	Full setup for C 1.2.2
 *	Fix SET_DRIVE call in CP/M 1.4 code
 *	Added byte-wise-ness 1982 Dec 30 RV
 *
 */

#define	STDIOEDIT	38

/*
 *
 * open(filename, mode) mode = 0,1,2
 * creat(filename, prot)
 * close(fd)
 * fopen(filename, mode, buffer_size) mode = "r","w","a","rw"
 * write(fd, buffer, byte_count)
 * read(fd, buffer, byte_count)
 * cio(mode, fcb_pointer, buffer, byte_count)
 * cpmver()
 * seek(fd, offset, code)	code = 0,1,2,3,4,5
 * tell(fd)	tell returns bytes
 * otell(fd)	otell returns bytes % 512
 * rtell(fd)	rtell returns bytes / 512
 * fabort(fd)
 * exec(p)
 * execl(nargs)
 */

#include	"customiz.h"
#include	"stdio.h"

#ifdef	SEEK
#define	RANDIO
#ifdef	CPM1p4
#define	CPM1p4SEEK
#endif	CPM1p4
#else	SEEK
#ifdef	BYTEWISE
#define	RANDIO
#endif	BYTEWISE
#endif	SEEK

#define	RS	REC_SIZE

static unsigned serialout();
static unsigned xsize();

/* functions between ==== are machine dependent */
cpmver()
{
#ifdef	CPM1p4
#asm
	push	b
	mvi	c,12
	call	5
	mvi	h,0
	pop	b
#endasm
#else	CPM1p4
	return 0x20;
#endif	CPM1p4
}

FILE *
open(filename, mode)
 char	*filename;
 unsigned mode;
{
	register FILE *fd;

	if((fd = fillfcb(filename)) == ERROR)
		return ERROR;

	if((fd->fd_fm = mode) > FCB_R_W)
		return Xseterr(INVMODE,fd);

	switch(fd->fd_dc) {
#ifdef SERIAL
	case NUL:
	case CON:
		break;
	case RDR:
		if(mode != FCB_READ)
			return Xseterr(BADDEV,fd);
		break;
	case LST:
	case PUN:
		if(mode != FCB_WRITE)
			return Xseterr(BADDEV,fd);
		break;
#endif	SERIAL
	default:
		xsetdma(INIT_DMA);
		if(ybdos(CC_OPEN, fd) == ERROR) {
			free(fd);
			return ERROR;
		}
	}

	/* check to see if trying to write a read-only file */
	if( ((mode+1)&2) && (fd->fd_ext[0]&0x80) ) {
		close(fd);
		return ERROR;
	}
	return fd;
}

FILE *
creat(filename, mode)
 char	*filename;
 unsigned mode;
{
	register FILE *fd;

	if((fd = fillfcb(filename)) == ERROR)
		return ERROR;

	fd->fd_fm = FCB_WRITE;
	switch(fd->fd_dc)
	{
#ifdef SERIAL
	case RDR:
		return Xseterr(BADDEV,fd);
	case NUL:
	case CON:
	case LST:
	case PUN:
		break;
#endif SERIAL
	default:
		xbdos(CC_DELETE, fd);
		if(ybdos(CC_CREAT, fd) == ERROR) {
			free(fd);
			return ERROR;
		}
#ifdef	CPM1p4SEEK
		fd->fd_me = 0;
#endif	CPM1p4SEEK
	}
	return fd;
}

chmod(filename, mode)
 char *filename;
 unsigned mode;
{
	register FILE *fd;

	/* the only purpose of this function under CP/M is to
	 * disallow write to file "owner"
	 */
#ifdef	CPM1p4
	if((mode&0200) || cpmver()==0)
		return SUCCESS;
#endif	CPM1p4

	if((fd = fillfcb(filename)) == ERROR)
		return ERROR;

	switch(fd->fd_dc)
	{
#ifdef SERIAL
	case RDR:
	case CON:
	case LST:
	case PUN:
		break;
#endif SERIAL
	default:
		fd->fd_ext[0] |= 0x80;
		if(ybdos(CC_ATTRIBS,fd)==ERROR) {
			return Xseterr(NOFILE,fd);
		}
	}
	fabort(fd);
	return SUCCESS;
}

close(_fd)
 FILE	*_fd;
{
	register FILE	*fd;
	int	t;

	if(!isfd(fd = _fd))
		return SUCCESS;

	t = closeio(fd);
	free(fd);
	return t;
}

isfd(_fd)
 FILE *_fd;
{
	register FILE *fd;

	/* fd's should be linked together so that this is a
	 * algorithm instead of a heuristic.  Also so that
	 * exit can close all open fd's
	 */
	if((fd = _fd) != ERROR || fd!=NULL)
		switch(fd->fd_fm)
		{
		case 0:
		case 1:
		case 2:
		case 'R':
		case 'W':
		case 'A':
		case 'X':
			return TRUE;
		}

	return FALSE;
}

/* close fd without a free
 *	no call to isfd(fd):
 *	all callers should check
 */
static
closeio(_fd)
 FILE *_fd;
{
	register FILE *fd;
	char tmp[3];
	int t;

	fd = _fd;
#ifdef	SERIAL truction for 8080, executes LDDR on Z80. 
; However count of zero performs nop.

	MOV	H,B	; Squirrel away BC
	MOV	L,C
	SHLD	XXKLG	

	POP	H	; Return address
	POP	B	; Count
	POP	D	; Source
	XTHL		; Dest->hl, return address to TOS
	XCHG		; srce->HL,dest->DE,count->BC 

	MOV	A,B
	ORA	C
	JZ	CCLDIX

	LDA	CCCPU	; Check CPU type
	ORA	A
	JZ	CCLDD8

CCLDDZ:				; Z80 CPU	*****
	DB	0EDH,0B8H	; Z80 lddr instruction
	JMP	CCLDIX

CCLDD8:				; 8080 CPU	*****
	MOV	A,M
	DCX	H
	STAX	D
	DCX	D
	DCX	B
	MOV	A,B
	ORA	C
	JNZ	CCLDD8
	JMP	CCLDIX

COMLINE: LXI	H,81H	; Returns address of command line.
	RET

COMLEN: LHLD	80H	; Returns length of command line
	MVI	H,0
	RET
80 ldir instruction

CCLDIX:	LHLD	XXKLG
	MOV	B,H
	MOV	C,L
	XTHL			; Re,dest->DE,count->BC 

	MOV	A,B
	ORA	C
	JZ	CCLDIX

	LDA	CCCPU	; Check CPU type
	ORA	A
	JZ	CCLDD8

CCLDDZ:				; Z80 CPU	*****
	DB	0EDH,0B8H	; Z80 lddr instruction
	JMP	CCLDIX

CCLDD8:				; 8080 CPU	*****
	MOV	A,M
	DCX	H
	STAX	D
	DCX	D
	DCX; Copyright (c) by SuperSoft, Inc., 1983
;	for C 1.2.0

;		DSEG

		IF DIV0
DIV0MSG:	DB	'Division by 0!',13,10,7,'$'
		ENDIF

CCEDATA:	DW	EDATA

STDIN:		DW	0	; standard input stream pointer
STDOUT:		DW	0	; standard output stream pointer
STDERR:		DW	0	; standard error stream pointer

CCEXPC:		DW	0,0	; save area for setexit/reset
		DS	2	; saves: pc, sp, and bc

CCCPU:		DS	1	; 1 if Z80, 0 if 8080

CCLJRV		equ	$	; recycle XXKLG for longjmp()'s temp
XXKLG:		DS	2	; handy place to save bc when lazy
errno:		dw	0	; "stderr"
BERRFL:		dw	0	; float error values

	IF	REL
	PUBLIC	EDATA
	ENDIF
EDATA	EQU	$

CCIDSTR: DB	'C Run time V1.4.0',9,'SuperSoft Copyright 1983'
	DB	0DH,0AH,'$'

	END	CCSTAR	; Pad a little bit for effect -- Don't ask...
	END	CCSTAR	; Pad a little bit for effect -- Don't ask...
	END	CCSTAR	; Pad a little bit for effect -- Don't ask...
	END	CCSTAR	; Pad a little bit for effect -- Don't ask...
	END	CCSTAR	; Pad a little bit for effect -- Don't ask...
	END	CCSTAR	; Pad a little bit for effect -- Don't ask...

;	for C 1.2.0

;		DSEG

		IF DIV0
DIV0MSG:	DB	'Division by 0!',13,10,7,'$'
		END'C Run time V1.4.0',9,'SuperSoft Copyright 1983'
	DB	0DH,0AH,'$'

	END	CCSTAR	; Pad a little bit for effect -- Don't ask...
	END	CCSTAR	; Pad a little bit for effect -- Don't ask...
	END	CCSTAR	; Pad a little bit for effect -- Don't ask...
	END	CCSTAR	; Pad a little bit for effect -- Don't ask...
	END	CCSTAR	; Pad a little bit for effect -- Don't ask...
	END	CCSTAR	; Pad a 
	if(isserial(fd))
		t = SUCCESS;
	else
#endif	SERIAL
#ifdef	BYTEWISE
	{
		xselect(fd, tmp);
		t = xflush(fd);
		t |= zbdos(CC_CLOSE, fd);
		xrestore(fd, tmp);
	}
#else	BYTEWISE
		t = ybdos(CC_CLOSE, fd);
#endif	BYTEWISE

	ffabort(fd);
	return t;
}

fabort(fd)
 FILE	*fd;
{
	if(ffabort(fd)==ERROR)
		return ERROR;

	free(fd);
	return SUCCESS;
}

static
ffabort(_fd)
 FILE	*_fd;
{
	register FILE	*fd;

	if(!isfd(fd=_fd))
		return seterr(INVFD);

	if(fd->fd_ps)		/* free the buffered sub-field */
		free(fd->fd_ps);
#ifdef	BYTEWISE
	if(fd->fd_br)		/* free the bytewise sub-field */
		free(fd->fd_br);
#endif	BYTEWISE

	return SUCCESS;
}

isserial(_fd)
 FILE *_fd;
{
#ifdef	SERIAL
	if(!isfd(_fd))
		return seterr(INVFD);

	switch(_fd->fd_dc) {
	case NUL:
	case CON:
	case RDR:
	case LST:
	case PUN:
		return 1;
	}
#endif	SERIAL
	return 0;
}

isatty(fd)
 FILE *fd;
{
	return isfd(fd) && fd->fd_dc==CON;
}

unsigned cio();

/* currently does not check isfd(fd) */
read(_fd, buffer, byte_count)
 FILE *_fd;
 char *buffer;
 unsigned  byte_count;
{
	register FILE	*fd;

	switch((fd = _fd)->fd_fm) {
	case FCB_READ:
	case FCB_R_W:
	case 'R':
	case 'X':
		return cio(CC_READ, fd, buffer, byte_count);
	}
	return seterr(INVMODE);
}

/* currently does not check isfd(fd) */
write(_fd, buffer, byte_count)
 FILE *_fd;
 char *buffer;
 unsigned byte_count;
{
	register FILE	*fd;

	switch((fd = _fd)->fd_fm)
	{
	case FCB_WRITE:
	case FCB_R_W:
	case 'W':
	case 'A':
	case 'X':
		return cio(CC_WRITE, fd, buffer, byte_count);
	}
	return seterr(INVMODE);
}

static
unsigned
cio(mode, _fd, buffer, byte_count)
 FILE *_fd;
 char	mode, *buffer;
 unsigned byte_count;
{
	register FILE	*fd;
	unsigned bytes;
	int	bc;
	char	tmp[3];

	fd = _fd;
#ifdef SERIAL
	switch(fd->fd_dc) {
	case NUL:
		return (mode == CC_READ) ? 0 : byte_count;
	case CON:
		if(mode == CC_READ) {
			*buffer = bdos0(CC_CONIN);
			return 1;
		}
		return serialout(CC_CONOUT, buffer, byte_count);
	case RDR:
		*buffer = bdos0(CC_RDR);
		return 1;
	case LST:
		return serialout(CC_LST, buffer, byte_count);
	case PUN:
		return serialout(CC_PUN, buffer, byte_count);
	}
#endif	SERIAL
	xselect(fd, tmp);
#ifdef	BYTEWISE
	for(bytes = 0; byte_count; ) {
		if((bc = byte_count > (bc = RS - fd->fd_rbyt)
		   ? bc : byte_count) != RS) {
			if(mode == CC_WRITE) {
				if(xfill(fd, CC_WRITE) == ERROR)
					break;
				movmem(buffer, &fd->fd_br[fd->fd_rbyt], bc);
				fd->fd_st |= FS_DIRTY;
			} else {
				if(xfill(fd, CC_READ) == ERROR)
					break;
				movmem(&fd->fd_br[fd->fd_rbyt], buffer, bc);
			}
		} else {
			if(xflush(fd) == ERROR)
				break;
			fd->fd_st &= ~FS_VALID;
			if(xbio(mode, fd, buffer) == ERROR)
				break;
		}
		buffer += bc;
		bytes += bc;
		byte_count -= bc;
		if((fd->fd_rbyt += bc) >= RS) {
			++fd->fd_rrec;
			fd->fd_rbyt = 0;
		}
	}
#else	BYTEWISE
	bc = byte_count/RS + (byte_count%RS && mode == CC_WRITE);
	for(bytes = 0; bc--; ) {
		if(xbio(mode, fd, buffer) == ERROR)
			break;
		buffer += RS;
		bytes += RS;
#ifdef	RANDIO
		++fd->fd_rrec;
#endif	RANDIO
	}
#endif	BYTEWISE
	xrestore(fd, tmp);
	return bytes;
}

static
xfill(_fd, mode)
 FILE *_fd;
 int mode;
{
#ifdef	BYTEWISE
	register FILE	*fd;

	fd = _fd;
	if(!(fd->fd_st & FS_VALID) || (fd->fd_rrec != fd->fd_brec)) {
		if(!fd->fd_br)
			if(!(fd->fd_br = malloc(RS)))
				return seterr(NOMEM);
		if(xflush(fd) == ERROR)
			return ERROR;
		fd->fd_st &= ~FS_VALID;
		fd->fd_brec = fd->fd_rrec;
		if(xbio(CC_READ, fd, fd->fd_br) == ERROR && mode == CC_READ)
			return ERROR;
		fd->fd_st |= FS_VALID;
	}
	return SUCCESS;
#endif	BYTEWISE
}

static
xflush(_fd)
 FILE *_fd;
{
#ifdef	BYTEWISE
	register FILE	*fd;
	unsigned trec;
	int t;

	if((fd = _fd)->fd_st & FS_DIRTY) {
		trec = fd->fd_rrec;
		fd->fd_rrec = fd->fd_brec;
		if((t = xbio(CC_WRITE, fd, fd->fd_br)) != ERROR)
			fd->fd_st &= ~FS_DIRTY;
		fd->fd_rrec = trec;
		return t;
	}
	retur ; Copyrighted (c) by SuperSoft, Inc., 1982
;	for C 1.1.36

	END


		IF DIV0
DIV0MSG:	DB	'Division by 0!',13,10,7,'$'
		 C2RTM                           CC      COM  56789:;<=>?@ABCD CC      COM  !EFG              C2      COM  HIJKLMNOPQRSTUVW C2      COM  8XYZ[             C2      RTM                    ; Copyrighted (c) by SuperSoft, Inc., 1983
;		DSEG

	PUBLIC	CCEDATA
	PUBLIC	CCEXPC
	PUBLIC	CCCPU
	PUBLIC	CCLJRV
	PUBLIC	XXKLG
	PUBLIC	STDIN
	PUBLIC	STDOUT
	PUBLIC	STDERR
	PUBLIC	errno
	PUBLIC	BERRFL
	EXT	CCSTAR

;	EXTERN	CCSTAR	; for RMAC

CCEDATA:	DW	EDATA

STDIN:		DW	0	; standard input stream pointer
STDOUT:		DW	0	; standard output stream pointer
STDERR:		DW	0	; standard error stream pointer

errno:		dw	0	; "stderr" error values
BERRFL:		dw	0	; float error values

CCEXPC:		DW	0,0	; save area for setexit/reset
		DS	2	; saves: pc, sp, and bc

CCCPU:		DS	1	; 1 if Z80, 0 if 8080
CCLJRV		EQU	$	; recycle XXKLG for longjmp()'s temp
XXKLG:		DS	2	; handy place to save bc when lazy

	PUBLIC	EDATA
EDATA	EQU	$

	END CCSTAR
	Multip
CCEDATA:	DW	EDATA

STDIN:		DW	0	; standard input stream pointer
STDOUT:		DW	0	; standard output stream pointer
STDERR:		DW	0	; standard error stream pointer

errno:		dw	0	; "stderr" error values
BERRFL:		dw	0	; float error values

CCEXPC:		DW	0,0n SUCCESS;
#endif	BYTEWISE
}

static
xbio(mode, _fd, buf)
 int mode;
 FILE *_fd;
 char *buf;
{
	register FILE *fd;
#ifdef	CPM1p4SEEK
	int t1;
#endif	CPM1p4SEEK

	fd = _fd;
#ifdef	RANDIO
#ifdef	CPM1p4
	if(cpmver() == 0) {
		if(fd->fd_ex !=  fd->fd_rrec/EXT_SIZE) {
			xclose(fd);
			fd->fd_ex = fd->fd_rrec/EXT_SIZE;
			if(zbdos(CC_OPEN, fd) == ERROR) {
				if(mode != CC_WRITE
				   || zbdos(CC_CREAT, fd) == ERROR)
					return ERROR;
			}
		}
		fd->fd_nr = fd->fd_rrec%EXT_SIZE;
	} else
#endif	CPM1p4
	{
		mode += 13;
	}
#endif	RANDIO
	xsetdma(buf);
#ifdef	CPM1p4SEEK
	t1 = bdos(mode, fd) == 0? SUCCESS: seterr(0x200+mode);
	if(fd->fd_ex > fd->fd_me)
		fd->fd_me = fd->fd_ex;
	return t1;
#else	CPM1p4SEEK
	return bdos(mode, fd) == 0? SUCCESS: seterr(0x200+mode);
#endif	CPM1p4SEEK
}

static
unsigned
serialout(dev, bp, byte_count)
 char	dev, *bp;
 int	byte_count;
{
#ifdef SERIAL
	register unsigned bytes;

	for(bytes = 0; ++bytes <= byte_count; )
		bdos(dev, *bp++);
	return bytes-1;
#endif	SERIAL
}

static
cmpu(a0, b)
 char *a0, *b;
{
#ifdef	SERIAL
	register char *a;

	for(a = a0; *a; ++a)
		if(*a != toupper(*b++))
			return 0;
	return 1;
#endif	SERIAL
}

/*	This function predates structures. It should be modified to access
 *	file descriptors by member names, yet, as it works properly, we shall
 *	let it kludge along a little longer.
 */
static
fspec(fps, fcb)		/* parse fspec. if valid return SUCCESS and set up */
 char *fps, *fcb;	/* low 16 bytes of fcb, else return false.device*/
			/* codes CON..NUL reserved for serial devices.	*/
{
	register char *fp;
	FILE *xfcb;
	int c;

	if(*(fp = fps) == 0)
		return seterr(FSPECERR);

	xfcb = fcb;
	if((*fcb = chkserial(fp)) == 0) {
		if(fp[1] == ':' || fp[1] == '/') {
			if((*fcb = toupper(*fp++) - '@') > MAX_DRIVE)
				return seterr(FSPECERR);
		} else
			*fcb = 0;

		if(*fp == '/') {
			for(++fp, c = 0; isdigit(*fp); )
				c = (10 * c) + *fp++ - '0';

			if(c > MAX_USER || *fp != ':')
				return seterr(FSPECERR);

			xfcb->fd_user = c;
		}
		else
			xfcb->fd_user = DEF_USER;

		if(*fp == ':')
			++fp;
	}

	setmem(++fcb, 8 + 3, ' ');
	for(c = 0; ; ) {
		if(*fp == '.') {
			++fp;
			/* already started the ext? */
			if(fcb > xfcb->fd_ext)
				return seterr(FSPECERR);
			fcb = xfcb->fd_ext;
			c = 5;
		}
		*fcb++ = toupper(*fp++);
		if(*fp == '\0')
			break;
		if(++c > 8)
			return seterr(FSPECERR);
	}
	return SUCCESS;
}

static
chkserial(_fp)
 char *_fp;
{
#ifdef SERIAL
	register char *fp;

	if(cmpu("CON:", (fp = _fp)))	return CON;
	else if(cmpu("RDR:", fp))	return RDR;
	else if(cmpu("LST:", fp))	return LST;
	else if(cmpu("PUN:", fp))	return PUN;
	else if(cmpu("NUL:", fp))	return NUL;
	else
#endif	SERIAL
					return 0;
}

static
fillfcb(filename)
 char	*filename;
{
	register FILE	*fd;

	if((fd = malloc(SIZE_FD))==NULL)
		return seterr(NOMEM);

	setmem(fd, SIZE_FD, 0);
#ifdef	CPM1p4SEEK
	fd->fd_me = 255;
#endif	CPM1p4SEEK
	if(fspec(filename, fd)==ERROR) {
		free(fd);
		return ERROR;
	}
	return fd;
}
/* functions between ==== are machine dependent */
/* functions between ++++ are machine independent in the
 * sense that the source does not have to be altered for a
 * new machine--note that the operation of some of these
 * functions will still vary depending upon the machine,
 * however this variance is in some accepted way
 */

FILE *
fopen(filename, mode, buffer_size)
 char	*filename, *mode;
 unsigned buffer_size;
{
	register FILE	*fd;

	switch(toupper(*mode)) {
	case 'R':
		if((fd = open(filename, FCB_READ)) != ERROR)
			break;
		if(toupper(mode[1]) != 'W')
			return NULL;
	case 'W':
		if((fd = creat(filename, 0)) == ERROR)
			return NULL;
		break;
#ifdef APPENDMODE
	case 'A':
		if((fd = open(filename, FCB_WRITE)) == ERROR
		 || (fd = creat(filename, ~0))==ERROR) {
			close(fd);
			return NULL;
		}
		{
#ifdef	SEEK
			seek(fd, 0, LAST);
#else	SEEK
			char buf[RS];
			while(read(fd, buf, ; for RMAC:
;
;	EXTERN	CCCPU
;	EXTERN	XMAIN

	EXT	CCCPU
	EXT	XMAIN

	PUBLIC	CCSTAR
	PUBLIC	CCEXIT

CCBDOS	EQU	5
;
;	WHICH CPU?
;
CCSTAR: LXI	H,CCCPU
	MVI	M,0
	MVI	A,2
	INR	A
	JPE	CIS8080
	INR	M
CIS8080:LHLD	6
	SPHL
	CALL	XMAIN
	RST	0

CCEXIT	EQU	0	; EXIT() -- FOR C

;
; ****** READ IN USER CODE HERE *******
;

	END	CCSTAR
ef	CPM1p4SEEK	t1 = bdos(m/*
 * CBRACK.H
 *
 * DEFINES FOR SMALL CHARACTER SET INPUT DEVICES
 *
 *  FOR C 1.2.0
 *
 */

#DEFINE	BEGIN	{
#DEFINE	END	}
#DEFINE	RBR	[
#DEFINE	LBR	]

#DEFINE	COM	~
#DEFINE	AND	&
#DEFINE	OR	|
#DEFINE	NOT	!
#DEFINE	XOR	^
#DEFINE	OROR	||
#DEFINE	ANDAND	&&

#DEFINE	ACOM	~=
#DEFINE	AOR	|=
#DEFINE	AAND	&=
#DEFINE	ANOT	!=
#DEFINE	XOR	^=


	return sizeofbuf sizeof buf) > 0)
				;
#endif	SEEK
		}
		break;
#endif	APPENDMODE
	default:
		seterr(INVMODE);
		return NULL;
	}

	return fdopen(fd, mode, buffer_size);
}

/* fdopen destroys the old fd.  Is this ok? */
fdopen(fd, mode, buffer_size)
 FILE *fd;
 char *mode;
 unsigned buffer_size;
{
	register struct seq_buf *p;

	if(ffabort(fd)==ERROR)
		return NULL;

#ifdef	BYTEWISE
	if(buffer_size < 1)
		buffer_size = 1;
#else	BYTEWISE
	if(buffer_size < RS)
		buffer_size = RS;
#endif	BYTEWISE

	if( !(p = fd->fd_ps = malloc(buffer_size + SIZE_SB)) ) {
		close(fd);
		seterr(NOMEM);
		return NULL;
	}

	p->ap = &p->bu;
	p->ac = 0;
	p->bs = buffer_size;

	switch(fd->fd_fm = toupper(*mode)) {
	case 'A':
	case 'W':
		break;
	default:
		fd->fd_fm = toupper(mode[1]) == 'W'? 'X': 'R';
	}
	return fd;
}

freopen(filename, mode, fd, buf_size)
 char *filename;
 char *mode;
 unsigned buf_size;
 FILE *fd;
{
	register FILE *fd1;

	if(!isfd(fd) || closeio(fd)==ERROR)
		return NULL;

	if((fd1=fopen(filename, mode, buf_size))==NULL) {
		free(fd);
		return NULL;
	}

	/* substitute contents of fd1 for fd */
	movmem(fd1, fd, SIZE_FD);	/* sizeof FILE */
	free(fd1);

	return fd;
}

fclose(_fd)
 FILE	*_fd;
{
	register FILE	*fd;
	int stat;

	if(!isfd(fd = _fd))
		return seterr(INVFD);

	stat = 0;
	if(fd->fd_fm != 'R' && fd->fd_fm != FCB_READ) {
#ifdef	_EOF
		if(putc(_EOF,fd) == ERROR)
			stat = ERROR;
#endif	_EOF
		stat |= fflush(fd);

	}
	return close(fd) | stat;
}

/* currently does not check isfd(fd) */
getc(fd)
 FILE *fd;
{
	register struct seq_buf	*p;

	switch(fd->fd_fm) {
	case 'R':
	case 'X':
		p = fd->fd_ps;
		if(p->ac <= 0)
		{
			if((p->ac = read(fd, &p->bu, p->bs)) <= 0)
				return seterr(EOFERR);

			p->ap = &p->bu;
		}
		--(p->ac);
		return *p->ap++;
	}
	return seterr(INVFD);
}

fgetc(fd)
 FILE *fd;
{
	return getc(fd);
}

/* currently does not check isfd(fd) */
ungetc(c, fd)
 char	c;
 FILE *fd;
{
	register struct seq_buf	*p;

	switch(fd->fd_fm) {
	case 'R':
	case 'X':
		p = fd->fd_ps;
		++(p->ac);
		return *--(p->ap) = c;
	}
	return seterr(INVFD);
}

/* currently does not check isfd(fd) */
putc(c, fd)
 char	c;
 FILE *fd;
{
	register struct seq_buf *p;

	switch(fd->fd_fm) {
	case 'X':
	case 'W':
	case 'A':
		p = fd->fd_ps;
		if(p->ac >= p->bs && bufwrite(fd) == ERROR)
			return ERROR;
		++(p->ac);
		return *p->ap++ = c;
	}
	return seterr(INVFD);
}

/* currently does not check isfd(fd) */
fputc(c, fd)
 char c;
 FILE *fd;
{
	return putc(c, fd);
}

/* currently does not check isfd(fd) */
fflush(_fd)
 FILE	*_fd;
{
	register FILE	*fd;

	switch((fd = _fd)->fd_fm) {
	case 'X':
	case 'W':
	case 'A':
		return bufwrite(fd);
	case 'R':
		fd->fd_ps->ac = 0;
		return SUCCESS;
	}
	return seterr(INVFD);
}

/* machine independent */
/* currently does not check isfd(fd) */
static
bufwrite(fd)
 FILE	*fd;
{
	register struct seq_buf	*p;

	p = fd->fd_ps;
	/*
	 * test for write() < p->ac because
	 * sometimes CP/M write outputs extra bytes
	 * if the request is not a multiple of RS
	 */
	if(write(fd, &p->bu, p->ac) < p->ac)
		return ERROR;

	p->ap = &p->bu;
	p->ac = 0;
	return SUCCESS;
}

static
seterr(err)
 int err;
{
	errno = err;
	return ERROR;
}

/* really put two bytes out, machine independently */
/* currently does not check isfd(fd) */
put2b(i, fd)
 int	i, fd;
{
	if(putc((i>>8)&0xff, fd) == ERROR || putc(i, fd) == ERROR)
		return ERROR;
	return i;
}

/* currently does not check isfd(fd) */
putw(i, fd)
 int	i, fd;
{
	return fwrite(&i, sizeof i, 1, fd);
}

/* currently does not check isfd(fd) */
get2b(fd)
 FILE	*fd;
{
	register int r1;
	int r2;

	if((r1 = getc(fd)) == ERROR ||
	   (r2 = getc(fd)) == ERROR)
		return ERROR;
	return (r1<<8) | (r2&0xff);
}

/* currently does not check isfd(fd) */
getw(fd)
 FILE *fd;
{
	int i;

	i = 0;
	if(fread(&i, sizeof i, 1, fd)==0)
		return ERROR;
	return i;
}

/* machine indepe !a6 ><4* !
"!  "+"-"/!)"'!  ")!"!  "!  s#r  }2!  ""!Y!Y ss!Y!Y  ss  """""Y"5"7!  }2}2}2}2"+"1##}2JtE*& |Daw*& |! *& |7lDͳ*|*& |7l ͳ*& | *  *z!kx*|!kx*5z!9!!$!+7!  9!,!/7& |ʇ!0"!  9&!2}2!8}2!@}2!C}2!F}2!J}2!N}2!Q}2;!T  }2!]|!  }2#}2}2!b}2!e}2!j}2!o}2!r"!u|g!Wj!"!{"x|&"x!"x|*x"x!"|­##"!"|#"͵	"!|!|! "++"+}2/!|! "+"+}2/!|/! "+}2#"!x 9! 9^#V! .uDM|a!
 9^#Vxv! 9^#V! 9^#V.! 9^#VDM`iʴ`in& |ʴ! 9^#Vs#r`in& }Ã! 9^#V!  s! 9^#V!  .u  !9! 9^#V! .uDM|8! 9x! 9^#Vkx!kx!  9zͳ!  9! 9!  !
 9!kx! z!. ! z!. ! z!kx*DM!  ".9^#Vkx`i"!
 Ď! Ď*DM!  ".9^#Vz`i"*|*jyDM!  "`i#|!*& |! .clq*ͅm*DM`i|@`i##ͯm*& |5ً`i^#VDM! .a*g:*Ґq!"!  ""*-DM`i|ʣ`i ! 9^#V|ʘ`i`i^#VDMt!  *+DM`i|`i ! 9^#V|`i`i^#VDMî!  ! 9^#VnDM|.9^#Vͨ`i!3O,!n& !^#V*&*|2!*& |@<*& |*& |<!  }2;*x*& |x3!{ |ʋ?Eú!A|ʞͪ=ú!A|ʱ{Aú!5O,|!n&   9s!^#VDM 	|9n& 1!, |ͽú!A|aú!A|͗@ú!A|1Bú!A|GͰBͽú!A|]Bͽú!A|sBͽú!(A|ʆ)>ú!; |º!/A|ʦ5CúC|ʴaúlEͽ3*& |.;  |!4	
|	Ͳ*n& 	
|	*	Ͳ*n& 	
|	*n& !|@	bk|@	*& ! !@! 9^#V"  s*n& ͽ	|r	!  DM*#"+͚}*n& 	
|ʤ	`i  |w	*  s! 9^#V*#"! 9n& DMa |	`iz |
`iA |	`iZ |
`i_ 
! ! 9n& ͽ	|&
##9n& ! ! 9^#V!O*xxDM|i
!Qw! 9^#Vw͕!  *& |ʐ
! 9^#Vw!cw*7ͥ͕! 9^#Vӌ G:  9s#r*s#r! ! 9^#V.`i"s#r"! 9^#V\v!  "9"3*& |! .].
9^#Vq! ! 9%!  *|~! 9n& |T*& |T! *y! 9n& *y  	|ʫ!eë! 9n& |.Ď!
 Ďë! 9n& Ď! 9n& !
 !	 !! 9^#V7l*5|*9"5*#"! 9^#V!; &*DM!  ".9^#V!  &`i"!kxͳ! 9>7l!DM*E|p`in& |eͼC!  C!^ ͳ*|ʵ! 9ʏ7l*####*9s#r*ͷ! 9^#Vkxͳ! 9^#Vbk|! 9^#V^#Vͷ! 9^#V! kx!/ ! 9^#V! ^#Vz!kx*! 9^#VЏ! 9^#V! 9^#VЏDM|R! 9^#V`in& 	
|R`i!  ! 9^#V"! 9^#V"!  "*#"+n& DM*#"+n& |*+n& 	
|`i  ː*+n&   ː|!  `i|*`i|*#"t! 9n& *n& |*#"! !  *! 9^#VЏDM|<`i*"! !  **! 9^#V!]DM|u`i*"! !  ! 9^#V!  '|ʦ!- ! 9^#VِDMð! 9^#VDM!
 2  9s#r|z!
 2!0 ! 9^#V!    compilation errors --first error on line  -ofile  -d  1 +subm +silent +f +s +co +cr +l -g -listlno +pre +a +ddt +lno +j -n +case -bufsiz -wbufsiz -i -p +z8000 +z8001 +i8080 +z8002 == C Compiler V  SuperSoft Copyright (c) 1983 File close error Missing '}' if while register for do return break continue switch goto Missing ';' Must be lvalue r 	Can't open file  : Can't write to output file Internal error :  K2msbH r_2p  4 ͹`ū* @˔& 'А Օ~D!  #+5B prn !+B M`E7	mndent if you assume byte order is ok */
/* currently does not check isfd(fd) */
fwrite(buf, sizeofitem, nitems, fd)
 char *buf;
 unsigned sizeofitem;
 unsigned nitems;
 FILE *fd;
{
	register unsigned s;
	unsigned n;

	for(n = nitems; n; --n)
		for(s = sizeofitem; s; --s)
			if(putc(*buf++, fd) == ERROR)
				break;

	return nitems-n;
}

/* machine independent if you assume byte order is ok */
/* currently does not check isfd(fd) */
fread(buf, sizeofitem, nitems, fd)
 char *buf;
 unsigned sizeofitem;
 unsigned nitems;
 FILE *fd;
{
	register unsigned s;
	unsigned n;
	int i;

	for(n = nitems; n; --n)
		for(s = sizeofitem; s; --s) {
			if((i = getc(fd)) == ERROR)
				break;
			*buf++ = i;
		}

	return nitems-n;
}

/* machine independent, note: pputc!=putc */
/* currently does not check isfd(fd) */
fputs(s, stream)
 char *s;
 FILE *stream;
{
	register char *ss;

	for(ss=s; *ss; ++ss)
		if(pputc(*ss, stream)==ERROR)
			return ERROR;
	return ss-s;
}

/* machine independent, note: pgetc!=putc */
/* currently does not check isfd(fd) */
fgets(s, n, fd)
 char *s;
 unsigned n;
 FILE *fd;
{
	register char *cs;
	int c;

	for(cs=s; --n; ++cs) {
		switch(c = pgetc(fd)) {
#ifdef _EOF
		 case _EOF:
			ungetc(c, fd) ;
#endif
		 case ERROR:
			*cs = '\0';
			if(*s != '\0')
				return s;
			return NULL;
		 case '\n':
			*cs = '\0';
			return s;
		 default:
			*cs = c;
		}
	}
	*cs = '\0';
	return s;
}

/* machine independent */
/* currently does not check isfd(fd) */
ferror(fd)
 FILE *fd;
{
	return errno!=0;
}

/* machine independent */
/* currently does not check isfd(fd) */
clearerr(fd)
 FILE *fd;
{
	errno = 0;
}

/* machine independent */
fileno(fd)
 FILE *fd;
{
	if(!isfd(fd))
		return NULL;
	return fd;
}

mktemp(f)
 char *f;
{
	register char *p;

	if((p=substr("X", f))==NULL)
		p = f+strlen(f);

	for(p[0] = p[1] = '0';;) {
		if(++(p[1]) == '9'+1) {
			if(++(p[0])=='9'+1)
				return NULL;
			p[1] = '0';
		}
		if(access(f,0)==ERROR)
			return f;
	}
}
/* end of machine independent functions +++++ */

static
xselect(_fd, tmp)	/* preserve user and drive code, and select	*/
 FILE *_fd;		/* user & drive specified in fd			*/
 char *tmp;
{
	register FILE	*fd;

	fd = _fd;
#ifdef	CPM1p4
	if(cpmver() == 0) {
		tmp[0] = bdos0(GET_DRIVE);
		bdos(SET_DRIVE, (tmp[1] = fd->fd_dc)? fd->fd_dc-1: tmp[0]);

		fd->fd_dc = 0;
		fd->fd_user = 0;
	} else
#endif	CPM1p4
	{
		if(fd->fd_user != DEF_USER) {
			tmp[2] = bdos(CC_USER, 255);
			bdos(CC_USER, fd->fd_user);
		}
	}
}

static
xrestore(_fd, tmp)
 FILE *_fd;
 char *tmp;
{
	register FILE	*fd;

	fd = _fd;
#ifdef	CPM1p4
	if(cpmver() == 0) {
		fd->fd_dc = tmp[1];
		bdos(SET_DRIVE, tmp[0]);
	} else
#endif	CPM1p4
	{
		if(fd->fd_user != DEF_USER)
			bdos(CC_USER, tmp[2]);
	}
}

static
bdos0(fn)
 int fn;
{
	return bdos(fn, 0);
}

static
xbdos(fn, _fd)
 int fn;
 FILE *_fd;
{
	register FILE	*fd;
	int	t;
	char	tmp[3];

	xselect((fd = _fd), tmp);
	t = bdos(fn, fd);
	xrestore(fd, tmp);
	return t;
}

static
ybdos(fn, fd)
 int fn;
 FILE *fd;
{
	return xbdos(fn, fd) != BDOSERR? SUCCESS: seterr(0x200+fn);
}

static
zbdos(fn, fd)
 int fn;
 FILE *fd;
{
	return bdos(fn, fd) != BDOSERR? SUCCESS: seterr(0x200+fn);
}

static
xsetdma(buf)
 char *buf;
{
	bdos(SET_DMA, buf);
}

seek(_fd, off, code)
 FILE *_fd;
 int off, code;
{
#ifdef	SEEK
	register FILE *fd;
	unsigned uoff;
	int rbyt;

	if(isserial(fd = _fd))
		return 0;

	uoff = off;
	switch(code) {
	 case START:
		fd->fd_rrec = uoff/RS;
		rbyt = uoff%RS;
		break;
	 case CURRENT:
		fd->fd_rrec += off/RS;
		rbyt = fd->fd_rbyt + off%RS;
		break;
	 case LAST:
		fd->fd_rrec = xsize(fd) + off/RS;
		rbyt = off%RS;
		break;
	 case START+3:
		fd->fd_rrec = uoff*(512/RS);
		rbyt = 0;
		break;
	 case CURRENT+3:
		fd->fd_rrec += off*(512/RS);
		rbyt = fd->fd_rbyt;
		break;
	 case LAST+3:
		fd->fd_rrec = xsize(fd) + off*(512/RS);
		rbyt = 0;
 hBL:! %Yc)L O&ep )E-+& 4Y}	0p *`4  `D  ^eV@!@ 9/6  r`EI'АD   cp f >-XT"  @`4X!j'ū* 3p cUW ^'ū*4ZP  9D  & 4C!2  caP  ! '7XiaP! 9WTu@    g'X \*& |O  !  9s#r*-DM`i|`i##^#V! n& !!|!|!|!|`i n& }o& |`i##^#V9}o& |`i##^#Vͷ'|! ! ![ `i q`i##^#V9}o& |`i##^#Vͷ'|`i##^#Vs% 9s#r`i##^#V3|ʅg:! 9^#VҐ 9s#r|ʅ! .a.9^#Vqg:  9s#r! .=`i q! !a .9^#Vq!  9! 9^#V^#Vs#r`i n& Đ}`i##^#V9#### n& ː}`i^#VDMb! .a.9^#Vg:! 9^#VҐq! !c lq! 9*+DM`i|n!ً`i##^#V8$ً`i^#VDMF`i*|aw*& |ʊ*9#"9*7#"7*!|DM  	|»`i|t*jy#|!+*|1*ً*^#V"|1*####^#V"9*##^#V"*& |1* w!;w*7ͥ͕*  s*& |R! .clq*& |ʩ*& |ʩ*&   ì`i|ʛ`i|1**;|1*#"+`i}Û!  |*& |¾7l*& |*9z*& |!/ !  z*& |ͼ!kxͳ!*|s!"* |8!=! "!*#"+! 9n& }!9r*& |n!& 9  !% 9s*n& |##Î!   9s!  9s  "!"*n& !|!|!|D!|D!|Rbk|X*n& ͽ	|͚æͲ*n& !|3!|3!|9bk|ʦ!  æͲͪ|ʦ*n& æͪæ!  !"!.*& |x!% 9x*& {  ! 9s#r 9DM! 9^#Vs#r! '|`i*n& }Ͳ*n& 	
|!  }! 9-! 9n& |.9n& |.9  ! 9s$! 9n& +}! 9DMW! 9͚DM|Q`i= !% 9sW! 9DM`in& $ 9s|ʦ!$ 9n& W!  |ʕ7l!Kkx!kxͳ& |ʡ͏!& 9Ͳ*n& |!/ !  Ͳ*n& !|bk|ͲͲ*n& |Ͳ! *& |r! 9n& Ͳ*n& DM! 9n& |I`i|Z!NͲ! 9n& `i|p͚!͚͚*n& |p!!9!  9M	|µ!  9Ͳ*n& !|ʲ!|ʲ!  9͚DM|	`i*܈|!j!  9!  9&!" 9!  9! 9^#Vӌ*ӌ####!:DM*'`is#r`i"'`i  s#r*! 9^#V`i##!
 9^#Vӌ#ͅ*ӌ#ͅ*)DM`i|`i##! 9^#V|`i##`i^#VDMà!  !9!  9M	!" 9! 9^#V͚DM|`i`i  s!9!  9M	͚  !  9!9!" |R.<U! ! 9DM*n& |ʎ*n& |ʎ*ʎ`i͚}[!  }! 9DMw 9s#rbk|º!t8*& |w!w*7ͥ͕*####*9s#rӌ G:  9s#r*s#r! .bk##! 9^#V"s#r"!  "9!( 9!A|Y͒!A|l5!A|$!A|ʗͯ!A|ʵ  ͯ!A|!  9ͻfͯ!A|!A|!"9! DM+|!`i!A|H*+"  |A!  "! !A|\! !A|s*#"Ç!A|ʋ*#"! ! !# |D |!  ͯ*#"+DM! 9*n& |*& |Ͳbk++| !|r*`i#	|*`i	|!  }2#.Dlq*& |Rr!A|]! }2*& |8.D!_ zͼ!kxͳ8*!  *#n& *¦!  *#"+n& *#"+*+"!"  s**& |!  R͚*n& !|!|bk|Ͳ*& |%Rclose on bad fd : Line too long +	 Missing quote or apostrophe Redefined Can't open include file : define include asm ifdef ifndef if undef line Unrecognized '#' endif else ifdef if #endasm +!* | !  .*"!( |) !)  C !M	|: C !:!![ |ʊ !] |o !  .l"C !  .!"!]  C !( |!  *n& |­ .
ð !	 *"*n& | Ͳû !) C ! 9n& |!;7l! 9n& 		break;
	 default:
		return seterr(INVSEEK);
	}
#ifdef	BYTEWISE
	if(rbyt < 0) {
		--fd->fd_rrec;
		rbyt += RS;
	} else if(rbyt >= RS) {
		++fd->fd_rrec;
		rbyt -= RS;
	}
	fd->fd_rbyt = rbyt;
#else	BYTEWISE
	if(rbyt)
		return seterr(INVREC);
#endif	BYTEWISE
	return SUCCESS;
#endif	SEEK
}

unsigned
tell(_fd)		/* tell returns bytes. */
 FILE *_fd;
{
#ifdef	SEEK
	register FILE	*fd;

	fd = _fd;
	return fd->fd_rrec * 128 + fd->fd_rbyt;
#endif	SEEK
}

unsigned
rtell(_fd)		/* tell returns bytes / 512. */
 FILE *_fd;
{
#ifdef	SEEK
	return _fd->fd_rrec >> 2;
#endif	SEEK
}

unsigned
otell(_fd)		/* otell returns bytes % 512 */
 FILE *_fd;
{
#ifdef	SEEK
	register FILE	*fd;

	fd = _fd;
	return (fd->fd_rrec % 4) * 128 + fd->fd_rbyt;
#endif	SEEK
}

static
unsigned
xsize(_fd)
 FILE *_fd;
{
#ifdef	SEEK
	register FILE	*fd;
	FILE	tfd;
	char	tmp[3];

	xselect((fd = _fd), tmp);
#ifdef	BYTEWISE
	xflush(fd);
#endif	BYTEWISE
	movmem(_fd, (fd = &tfd), SIZE_FD);
#ifdef	CPM1p4
	if(cpmver() == 0) {
		if(fd->fd_me != fd->fd_ex) {
			xclose(fd);
			for(fd->fd_ex = fd->fd_me & 0x0f
			   ; bdos(CC_OPEN, fd) == BDOSERR
			   ; --fd->fd_ex) ;
			_fd->fd_me = fd->fd_ex;
		}
		fd->fd_rrec = fd->fd_ex * EXT_SIZE + fd->fd_rc;
	} else
#endif	CPM1p4
	{
		xclose(fd);
		bdos(CC_CFS, fd);
	}
	xrestore(_fd, tmp);
	return fd->fd_rrec;
#endif	SEEK
}

static
xclose(_fd)
 FILE	*_fd;
{
#ifdef	SEEK
	register FILE	*fd;

	xsetdma(INIT_DMA);
	bdos(CC_CLOSE, (fd = _fd));
	setmem(&fd->fd__fcbr1, &fd->fd_rrec - &fd->fd__fcbr1, 0);
#endif	SEEK
}

/* machine independent */
exec(p)
 char *p;
{
#ifdef	EXEC
	int execl(.);

	return execl(p, 0);
#endif	EXEC
}

#ifdef	CPM86

/*
 * These two functions should work under cpm-86 version 1.1.
 * However they have not been tested since we haven't recieved
 * our upgrade to 1.1 yet.
 */


#define EXECAREA	(0x0080)
#define EXEC_PROG	47

/* execl(progname, arg0, arg1, ... ) -- arg0 is ignored because of cp/m bug */

execl(nargs)	/* set up command line */
 int nargs;	/* then exec */
{
#ifdef	EXEC
	register char *l, *p;
	int *ip;

	if(nargs > 0) {
		ip = &nargs;
		/* construct progname line */
		for(p = ip[nargs]; *p; )
			*l++ = toupper(*p++);

		*l++ = ' ';

		--nargs;	/* skip over arg0, because of cp/m bug */

		/* construct command line */
		for(l = EXECAREA; --nargs>0; ) {
			if(nargs!=1) {	/* arg0 is ignored */
				for(p = ip[nargs]; *p; )
					*l++ = toupper(*p++);

				*l++ = ' ';
			}
		}
		*l = 0;

		xsetdma(EXECAREA);
		bdos0(EXEC_PROG);
	}

	return seterr(ENOEXEC);
#endif	EXEC
}
#else	CPM86

#define FCB_SIZE	33
#define EXECAREA	(0x0080)
#define DEF_FCB		0x005c

/* execl(progname, arg0, arg1, ... ) -- arg0 is ignored because of cp/m bug */

execl(nargs)	/* set up command line & default fcb just like cpm */
 int nargs;	/* then exec */
{
#ifdef	EXEC
	register int *ip;
	char *c, *l, *p, prog[30], hld80[128], tmp[3];
	FILE fcb;
	FILE *fd, *fd1;
	int (*fn)();	/* a coersion would be better */
	extern char xstart[], xfcb1[], xfcb2[], xend[];

	if(nargs < 1)
		return seterr(ENOEXEC);

	ip = &nargs;
	strcpy(prog, ip[nargs]);		/* get program name */
	/* if explicit extension missing, use ".COM" */
	for(c = prog; ; ++c)
	{
		switch(*c) {
		case 0:
			strcpy(c, ".COM");
			break;
		case '.':
			break;
		default:
			continue;
		}
		break;
	}

	/* Construct default fcb at DEF_FCB from args 3 & 4 */
	setmem(DEF_FCB, FCB_SIZE, 0);

	/* --nargs because arg0 can't exist: bug in cp/m */
	if(--nargs > 2) {
		fspec(ip[nargs - 1], &fcb);
		movmem(&fcb, DEF_FCB, 12);
		if(nargs > 3) {
			fspec(ip[nargs - 2], &fcb);
			movmem(fcb.fd_name, DEF_FCB + 16, 11);
		}
		else
			setmem(DEF_FCB + 16, 11, ' ');
	}

	/* construct command line */
	for(l = hld80 + 1; --nargs > 1; ) {
		for(p = ip[nargs]; *l++ = *p++; )
			;
		*l++ = ' ';
	}
	*--l = 0;
	hld80[0] = l-hld80-2;


	if(chkserial(prog) || (fd1 = open(prog, 0)) == ERROR)
		return seterr ͳ! 9^#V!  9ͻf|8!!3;!  9 s#r!/ |m!! 9ͻf!  9! 9^#V^#V6s#r8!!* |ʢ!! 9ͻf!  9! 9^#V^#Vs#rm!!+ |!! 9ͻf!  9! 9^#V^#Vs#râ!!- |
"! 9ͻf!  9! 9^#V^#VҐs#r!! G:DM####!
 9n& }`i ! 9n& }`i##! 9^#Vs#r`i  s#r!^#Vbk|p"!^#V`is#r{"!`is#r!`is#r*& |#! 9^#VDM!F;kx!I;kx!O;kxz!Q;kx`i####n& #!\;kx!^;kx`i n& z!i;kx`i##^#Vz!q;kx! 9^#VDM   9s#r|3#bk|g#! 2!0 g#! 9n& ! .9^#V"!ً!^#V8$!!  s#rs#r! 9^#Vbk|#! 9^#V !#DM#|+$bk|+$`i####! 9^#V! n& }`i ! 9^#V! n& }`i##! 9^#Vbk##^#Vs#r! 9^#V! 9^#V^#V͊#s#r`i!t;!  ! 9^#VDM`i|g$! 9^#V`i![$`i^#VDMC$! 9^#VDM! 9^#Vbk|$`i  `i|$! 9^#V`i! 9^#V!$|º$`i^#VDM! 9^#V^#V! 9s#rt$! 9^#VDM####n& ! 9^#V! n& |n%`i n& ! 9^#V! n& |n%`i##^#V! 9^#Vbk##^#V|h%`i##^#Vbk#|h%! 9^#Vbk##^#V!q%! q%!    !  9s#r! 9^#VDM`i|$&bk|«%`i##^#V!  9s#r%`i##^#Vbk|%!  9`i##^#V^#Vs#r`i n& !&!|!|!|!|&`i^#VDMÉ%`i##^#Vbk|&;!n&  9s!! 9n& } 	|°'.	9n& !	 9^#VG#!!^#Vs%s#r!^#Vͷ'|&!;|¤&*n& ͽ	|ʫ&B)3!^#V!  n& ː} ! 9s!nDM|D'`i##^#V9  9s#r! n& }o& |<'! 9<'!^#V! n& }o& |<'9^#V! n& Đ}i(ã'!^#V! n& }2! 9s'! n& ː}Û'!^#V! n& |'!n& Đ}!35!, |-&ͽ3! 9^#V! n& !|'!|'!  ! ! 9^#Vbk##^#Vbk#|(.9^#Vbk##! 9^#Vbk##^#Vs#r! ! 9^#Vbk##^#V! 9^#Vbk##^#VE|(!;! 9^#Vbk##! 9^#Vbk##^#Vs#r  ! 9^#Vbk##^#V9DM####n& }o& |(!^#V! n& }o& |(!n& Đ}!^#V! n& Đ}!'! 9^#Vbk##^#V!^#Vi$!$! 9^#Vbk##^#V!^#Vi$|8)! 9^#V! ^#V!^#V|8)!;!nDM|ʮ)`i##^#Vͷ'|ʁ)`i##^#V9####n& }o& |)!0ø)`i##^#V9####n& Đ}ø)!35DM! .=!q*& |)! .clq;  ! 9s#r!;|»*.)|»*!M	|o*!! 9^#Vs#rg#! *"!ͨ|N*!0V*!55! 9*^#Vs#rî**n& |£*`i##^#V! 
 sͲ*n& |ʎ*î*!;!) |2+! 9^#V|*! 9^#V"0`i"%!{ |+!;*+*n& |*! }2!<A|,!5O,|R+!n& U+!, |G+!; 	|»**!   9s 9n& !^#V! 9s#r1DM!  ͘n*ِ"! .lq 	|+.,|+! 9n& ! 9^#V1Ù+`i|,`i##^#V! n& bk+|+!|+!<`i##^#V9####@ n& ː}ͽ! }2?E!  ͘nEm! .clq@"+!  "}23;!!  s#rs#r!!  }2}  9s! 9^#V!5|ʐ,! Ó,!  DMW.ͳ.|,!ʴ, !  9s-*& |, !  9s`i ːDM-!,! }2  9s! 9^#V5-!-! }2  9s! 9^#V5!2- !  9s`i ːDM!O- !  9s`i ːDMt-!t- !  9s`i ːDM!`iĐDM!ʎ- !  9s`i ːDM!-!ʰ- !  9s`i ːDM!-!- !  9s`i  ːDM!`i}*& |O.!`i}o& |-! -*s#r`i} o& |%.! ^#Vs#r`i}o& |G.! ^#Vs#r& }2*& 3!!!!!!!!!!!!!!  sssssssssssss}2}!!<A|.! s/!%<A|.! }2/!*<A|.! s/!1<A|/! s/!7<A|*/! s/!@<A|B/! s/!F<A|Z/! s/!L<A|r/! s/!S<A|ʊ/! s/!X<A|ʢ/! s/!_<A|ʺ/! s/!h<A|/! s/!o<A|/! s/!w<A|0! s! !  !|<7l! 9^#Vkxͳ;!	 9^#V!  9s#r!5O,|~0!<*n& bk|g0!|y0ͲJ0R*& |J033!n&  9s!^#V! 9s#r! 9n& ! 9^#VG#!ͨDM|0!<! 	|1ͽ50!ً`i##^#V8$`i##!G:!^#V͊#s#r`i#(OPENERR);


	/* we endup with default drive and user specified by prog */
	xselect(fd1, tmp);
	if(hld80[0] != 0)	/* any args? */
	{
		if((fd = creat("$.$", 0)) == ERROR
		 || write(fd, hld80, sizeof hld80) != sizeof hld80
		 || seek(fd, 0, 0) == ERROR)
			return Xseterr(ENOSPC,fd);

		movmem(fd, xfcb2, FCB_SIZE);
	} else {
		setmem(xfcb2, FCB_SIZE, 0);
	}

	movmem(xstart, EXECAREA, xend-xstart);
	movmem(fd1, xfcb1, FCB_SIZE);

	(*(fn = EXECAREA))();
#endif	EXEC
}
#endif	CPM86

/*
 * rarely used buffered i/o routines
 */

#ifdef	DEBUG
dumpfcb(_fd)	/* This routine dumps a fd for debugging purposes */
 FILE	*_fd;
{
	register FILE	*fd;
	int i;

	printf("fcb @%x:\n", (fd = _fd));
	printf("dc %x\n", fd->fd_dc);
	puts("name.fd_ext : ");
	for(i = 0; i < 8; ++i)
		putchar(fd->fd_name[i]);
	putchar('.');
	for(i = 0; i < 3; ++i)
		putchar(fd->fd_ext[i]);
	putchar('\n');
	printf("ex %x\n", fd->fd_ex);
	printf("rc %x\n", fd->fd_rc);
	printf("nr %x\n", fd->fd_nr);
	printf("rrec %x\n", fd->fd_rrec);
	printf("rbyt %x\n", fd->fd_rbyt);
	printf("brec %x\n", fd->fd_brec);
	printf("user %x\n", fd->fd_user);
	printf("fm %x\n", fd->fd_fm);
#ifdef	CPM1p4SEEK
	printf("me %x\n", fd->fd_me);
#endif	CPM1p4SEEK
	printf("st %x\n", fd->fd_st);
	printf("ps %x\n", fd->fd_ps);
}
#endif	DEBUG

/* currently does not check isfd(fd) */
pgetc(fd)
 FILE	*fd;
{
	register char	c;

	if((c = getc(fd)) == '\r')
		if((c = getc(fd)) != '\n') {
			ungetc(c, fd);
			c = '\r';
		}
	return c;
}

/* currently does not check isfd(fd) */
pputc(c, fd)
 char	c;
 FILE	*fd;
{
	if(c == '\n')
		if(putc('\r', fd) == ERROR)
			return ERROR;
	return putc(c, fd);
}

/* Not strictly compatible with unix, except in the following sense:
 * under unix, a rename(f2, f1) would be link(f1, f2) unlink(f1).
 * This would work given link as below.
 * It is actually possible to simulate link
 * under CP/M, except that only open files would have their fcbs updated,
 * unopened links would have old file info in it.
 */
link(f1, f2)
 char *f1, *f2;
{
	return rename(f1, f2);
}

rename(f_new, f_old)
 char *f_new;
 char *f_old;
{
	register struct filedesc *new;
	struct filedesc *old;
	int i;

	if((old=fillfcb(f_old)) == ERROR )
		return ERROR;

	if((new=fillfcb(f_new)) == ERROR ) {
		fabort(old);
		return ERROR;
	}

	if(new->fd_dc != old->fd_dc || new->fd_user != old->fd_user) {
		i = seterr(ERLINK);
	} else {
						/* sizeof something */
		movmem(&new->fd_dc, &old->fd__fcbr2[0], 16);
		i = ybdos(CC_RENAME, old);
	}

	fabort(new);
	fabort(old);
	return i;
}

unlink(filename)
 char	*filename;
{
	register FILE *fd;
	int i;

	if((fd = fillfcb(filename)) == ERROR)
		return ERROR;

	if(isserial(fd))
		return Xseterr(BADDEV,fd);

	i = ybdos(CC_DELETE, fd);
	fabort(fd);
	return i;
}

/* machine dependent--a no-op under cp/m or mp/m */
lock(flag)
 int flag;
{
}

/* machine dependent--a no-op under cp/m or mp/m */
nice(incr)
 int incr;
{
}


/* machine dependent--a no-op under cp/m or mp/m */
wait(status)
 int status;
{
	return ERROR;
}

access(f, mode)
 char *f;
 unsigned mode;
{
	register unsigned m;
	FILE *i;

	if(mode&1)
		mode |= 4;	/* execute, under CP/M, implies read */

	/* set read/write bits */
	/* exists (mode==0), under CP/M, means read */

	if((i=open(f, mode? (((mode>>1)&3)-1): 0)) == ERROR)
		return ERROR;

	if((mode&1) && usubstr(f,".com")==NULL)	/* execute */
		return ERROR;

	return close(i);
}

Xseterr(eno,fd)
 int eno;
 FILE *fd;
{
	fabort(fd);
	return seterr(eno);
}

	return i;
}

unlink(filename)
 char	*filename;unsigned mode;
{
	register unsigned m;
	FILE *i;

	if(mode&1)
		mode |= 4;	/* execute, under CP/M, implies read */

	/* set read/write bits */
	/* exists (mode==0), under CP/M, means read */

	if((i=open(f, mode? (((mode>>1)&3)-1): 0)) == ERROR)
		return ERROR;

	if((mode&1) && usubstr(f,".com")==NULL)	/* execute */
		return ERROR;

	return close(i);
}

Xseterr( ###! 9^#V`i####^#VҐs#r!^#V! n& bk+|r1!|ʲ1!5\4!  9*^#VҐs#r!  |0ͽ3`i##^#V! n& }o& |>1*& |>1`i####*+^#Vs#r>1`i##^#V!  s`i##^#V*s#r>1!, |0!<Ø0! 9n& ! 9^#VG#!n&  9s!ͨ|)2!0!  !G2! 9 n& ː}2!^#Vͷ'|ʟ2! 9 n& ː}!^#V!  n& ː}!^#V! n& Đ}2!*!^#Vs%g:Ґ͘n"s#r! 9n& }o& |2!55DM3!DM|2i(3!35DM`i! 9^#VDM n& ++++|/3`i^#VDM`i####n& }o&   ! 9^#V!ӌ !b3DM####!^#Vs#r`i !.`i##! 9^#V!^#V͊#s#r`i   s! 9^#V^#Vs#r! 9^#V`is#r!!:!-F3*& |Z4! 9^#VDM|3!<kx!<kx!3`i^#V\4!<kx!"`i####^#V8$!<kx!"`i##^#V8$!<kx`i n& #ͳ*& |5!=kx! 9^#V!3|ʇ4!g Ê4!l !=kx! 9^#VDMz`i|5!, `i kx!=kx`i####^#Vz!=kx`i n& #!=kx!"`i##^#V8$5!!=kx!G:!+F3! 9^#V!)5DM##^#V! n& |5`i !$=Ox|5`i !+=Ox|5`i !3=Ox|5`i !;=Ox|5`i !A=Ox|5`i !H=Ox|5`i !O=Ox|5`i##^#V! 
 s! 9^#V\4`i!9*&  9s!n&   9s 9M	!{ |6! 9ʌ6!! 9.! }2!!s#rs#rg#!n& *& !"! 9|6.&9^#V5!9  ! 9s#r! 9s#r!  9s!} |´8.09^#VO,!n&  9s*& |t7!f=é8! 9DM|7!U=!$ 9!`i##^#Vs%s#r!`i####^#Vs#r!`i##^#V! n& }`i##^#V! n& }2g#!n& *& !^#V"!( 9!^#V! 9s#rg#! 9n& ! l"! 9n& ! .9^#V"!!^#Vs% 9s#rs#r!^#V! n& }2!^#V3|8! 9^#Vg: 9s#r !  9s!!
 9^#Vs#r!DM|48i(B8!0 9^#V5DM! 9n& |u8.9! 9^#V^#Vs#r! 9s#rÜ8! 9^#V! 9^#V1|ʜ8! 9^#V! 9s#r!, |7!; è6!! 9.! }2l98! 9^#Vg: 9s#r!!!
 9^#Vs#rs#r!! 9n& }!! 9n& }! 9n& ! .
9^#V"! 9F9!  !, 9! 9DM##^#Vbk##^#Vbk#|ʦ9`i##^#Vs%! 9^#V|ʦ9!=! 9^#Vzͳ!0 9^#V\4`i##^#Vbk##! 9^#Vs#r`i!, 9! 9^#Vbk|9! 9^#VDM`i^#Vbk|9`i^#VDM9`i! 9^#Vbk|:! 9^#V9####n& ! 9^#VDM#|C:.9^#VG:`i! 9^#V͆DM|c:!=`i*+|ʆ:! 9^#V*6DM|:! 9^#V! 9^#V*`iҐ! 9^#Vbk##^#V9DM####n& Đ}`i####! 9^#Vbk##^#V9}Co& n& ː}Missing name in declaration Missing bracketing symbol: Must be a constant 
; emit( @ ,attribs== , modifier== ,size== )
 No symbol table room { Array or pointer being lengthened Declaration mismatch { Expecting formal arg Expecting ',' or ')' Expecting function body register Bad register type int char struct union unsigned short float double long extern register static typedef auto Already defined A formal arg is not declared Not a formal arg Expecting ',' or ';' 
;ptr==0
 
;e_head:
 
;e_strt:
 
;e_nxt:
 
;e_stack== 
; (@ ,offset== ,flags== )
 )
 printf fprintf sprintf scanf fscanf sscanf execl Undefined struct Expecting type declaration Redeclaration of struct type Out of heap * 9s#r͵	DMAa! 9^#V͘n"!; |=!WA|=ͅm͵	  9s#rpmͅma! 9^#V͘n"ͅm!9* 9s#rEl! .Dlq!{  ͵	 9s#r͵	 9s#rDM	 9s#r  9D! 9!	 9^#Vs#r  9͘D  ! 9s!WA|?!: |?! 9>!Wç>! .##9^#Vq͵		 9s#rͅm ! 9sç>!WA|@! 98?! .++9^#Vq  ! 9s`i#|H?͵	DM[?! .͵	DMq! 9^#Vͅm! .Hlq**Ґ"E! .rlqm! .lq!:  ! .q! 9^#V͘n"!XA|g?..͵	 9s#rqͅm! 9^#V͘n"ç>!} |ʉ@! 95@! .++9^#Vq! 9^#Vͅm!	 9^#Vbk#|b@! .9^#Vq! 9^#VͅmD! 9^#V͘n"! 9C|§>aç>!9* 9s#r! bk9͵	s#r 9͵	s#r 9͘D!(  a͵	  9s#rͅm!; |Aa! 9^#/* Copyrighted (c) by SuperSoft, Inc., 1982 */

/*	stdio.h for stdio.c edit 38 and C 1.2.0
 *
 *	This file should be included by all programs that use stdio.c
 *	This file generates no code.
 */

#define	BOOLEAN		char	/* typdef char BOOLEAN; */
#define TRUE		1
#define FALSE		0

#define	RESULT		int	/* typedef int RESULT; */
#define	SUCCESS		0
#define	ERROR		(-1)

#define	BDOSERR		255

#define	CON		0x80
#define	RDR		0x81
#define	PUN		0x82
#define	LST		0x83
#define NUL		0x84

#define	BCE		1	/* Byte count error */
#define	NOFD		2	/* No open FD's */
#define	NOFILE		3	/* File not found */
#define	INVFD		4	/* Invalid FD, unopened file */
#define	INVMODE		5	/* IO type mismatch */
#define	OPENERR		6	/* Error on CC_OPEN */
#define	CREATERR	7	/* Error on CC_CREAT */
#define	FSPECERR	8	/* Invalid filename */
#define	BADDEV		9	/* Device out of range */
#define	CLOSEERR	10	/* bdos error in close */
#define	INVREC		11	/* Invalid record in seek */
#define	INVSEEK		12
#define	ENOEXEC		13
#define	ENOSPC		14
#define	ERLINK		15
#define	NOMEM		20	/* Memory allocation failure */
#define	INVBUF		21
#define	READERR		22
#define	EOFERR		23
#define	NOGETC		24

#define	INIT_DMA	0x80	/* Each open sets dma here */
#define	REC_SIZE	128	/* Byte count of a CP/M record */
#define	EXT_SIZE	128	/* Records in a extent 1..EXT_SIZE */
#define	MAX_DRIVE	15
#define	MAX_USER	32
#define	DEF_USER	255	/* Default user code */

#define	FCB_READ	0
#define	FCB_WRITE	1
#define	FCB_R_W		2

#define	START		0	/* Seek from beginning */
#define	CURRENT		1	/* Seek from current record */
#define	LAST		2	/* Seek from end */

struct filedesc
{
	char	fd_dc;		/* Drive Code of this file	*/
	char	fd_name[8];	/* File's name			*/
	char	fd_ext[3];	/* File's extension		*/
	char	fd_ex;		/* Extent number		*/
	char	fd__fcbr1[2];	/* Reserved for CP/M		*/
	char	fd_rc;		/* Record count in extent	*/
	char	fd__fcbr2[16];	/* Reserved for CP/M		*/
	char	fd_nr;		/* Next record number in extent	*/
	int	fd_rrec;	/* Random record number		*/
	char	fd_rreco;	/* rrec overflow, not yet used	*/
				/* End of CP/M FCB.		*/
	char	fd_rbyt;	/* Random byte number		*/
	char	fd_st;		/* Status byte			*/
	char	fd_user;	/* User code of this file	*/
	char	fd_fm;		/* File mode			*/
	char	fd_me;		/* Maximum extent		*/
	char	*fd_ps;		/* Pointer to seq buffer	*/
	int	fd_brec;	/* Buffered record number	*/
	char	*fd_br;		/* Buffered record		*/
};

#define	FILE		struct filedesc
#define	SIZE_FD		sizeof(filedesc)

#define	FS_VALID	1	/* Buffered record is valid	*/
#define	FS_DIRTY	2	/* Buffered record is dirty	*/

struct seq_buf
{
	char *ap;		/* Active pointer	*/
	int  ac;		/* Active count		*/
	int  bs;		/* Buffer size		*/
	char bu;		/* First byte of buffer	*/
				/* Buffer follows	*/
};

#define	SIZE_SB		(sizeof(seq_buf)-1)

/* BDOS calling codes */

#define	CC_CONIN	1
#define	CC_CONOUT	2
#define	CC_RDR		3
#define	CC_PUN		4
#define	CC_LST		5
#define	CC_CPMVER	12	/* Return cpm version # */
#define	SET_DRIVE	14	/* Select disk drive */
#define	CC_OPEN		15
#define	CC_CLOSE	16
#define	CC_FIND		17	/* Find first occurence */
#define	CC_NEXT		18	/* Find next occurence */
#define	CC_DELETE	19
#define	CC_READ		20	/* Read next CP/M record */
#define	CC_WRITE	21	/* Write next CP/M record */
#define	CC_CREAT	22
#define	CC_RENAME	23
#define	GET_DRIVE	25	/* Interrogate drive number */
#define	SET_DMA		26
#define	CC_ATTRIBS	30
#define	CC_USER		32	/* Set/Get user code		*/
#define	CC_RREAD	33	/* random read */
#define	CC_RWRITE	34	/* random write */
#define	CC_CFS		35	/* Compute file size (CPM 2.0 only ) */
#define	CC_SRR		36	/* set random record */

extern	int	errno;
extern	FILE	*stdin;
extern	FILE	*stdout;
extern	FILE	*stderr;

#define	ungetchar	ugetchar
#define	NULL		0	/* standard C NULL pointer */
buf)-1)

/* BDOS calling codes */

#define	CC_CONIN	1
#define	CC_CONOUT	2
#defi_DMA		26
#define	CC_ATTRIBS	30
#define	CC_USER		32	/* Set/Get user code		*/
#define	CC_RREAD	33	/* random read */
#define	CC V͚m͵	DMpm bk9^#Vͅm!) |6AlE!)  pmͅma bk9^#Vpm! 9^#Vͅm! 9^#V͘n"D! 9*  9s#r 9͵	s#r 9͵	s#r  9͘D! 9^#Vͅm! 9^#VAa! 9^#Vpm! 9^#Vͅm͘n"D!(  E!)  ! 9^#V͚m*  9s#r 9͵	s#r 9͵	s#r  9͘D͵	DMͅma! 9^#Vͅm!XA|uB!XE!; |xB..q! 9^#Vͅm͘n"D 	|»BE!  ͘nEmDDM|B!X`i^#V͘n`i####^#VpmDDM|C`i^#V͘n`i##^#Vbk#|'C!&X3C`i##^#Vpm!M	|[C! .dC####^#Vq!EX!DM|C!͵	s#rg#!  .}2l"!55`i##^#V! n& !|C!|C!SX`i*DMn& ͽ	|C`in& 	
|C`iC`in& |D`in& |D`iC`in& |,D!  !M	!: dCDM##^#V! n& !|dD!|oD! !_X_D`i##^#V!  s! .=`i####^#Vq_D! G:DM*/s#r`i"/! 9^#V`i##! ͅ*/|D*/ً*/^#V"/*/##*/|&E##9^#V*s#r! 9^#V!s#r! 9^#V! s#r*/##! 9^#V! ͅ*#"!} |dE*& |^EaFE*+"!9*Y  9s#r 9>F|ʔE! 9b! 9pe*Y'|ʵE!xXE*Y	|E!X!  !	 9!9*Y  9s#r 9{F|E! 9b! 9pe*Y'|F!X3F*Y	|3F!X!  !	 9! 9^#V{FDM!, |wF! 9^#Vpe! 9^#V{FDMMF`i!9! 9^#VͽI 9s!X|F! *Ґ"! 9n& ! 9^#V!pdH!  ! 9!X|G! *Ґ"! 9n& ! 9^#V!pdH!  ! 9͆|§G*n& !|G!|G!| H!|H!|H!|H!| H!|(H!|0H5H!KpDM! 9n& ! 9^#VdH!  ! 9!= |TH! 9EH! 9^#Vpb!  9{F|G!  9b!  9pe! 9^#V͒bHH![pDMÄG!kpDMÄG!lDMÄG!pDMÄG!pDMÄG!|pDMÄG!lDMÄG!pDM! 9n& ! 9D	!  ! 9! 9n& ! 9!9ͲͲ! 9HD	H! 9^#V@f|ʜH! 9^#Vc! 9^#Vpb! 9^#VpbDM!  9{F|H!  9b`i|Hm! 9^#Vpbl! 9^#Vb`i|Hml! 9^#V 9͙oDMc |~I! 9^#V!l|>I!l 9s#r~I! 9^#V!l|_I!l 9s#r~I! 9^#V![p|~I!X!DM! 9^#V!I`ic |ʠI!3 $p! 9^#V͒b!  9pe!	 9;! 9^#V͔J  9s!? |I9n& 3& |I! 9^#Vb! 9^#Vpe͵	DM͚m! 9^#VͽI|/J! 9^#Vb͵	 9s#rpmͅm! 9^#Vpe!: |dJ!X! 9^#VͽI|ʁJ! 9^#Vb! 9^#Vͅm!  3!9! 9^#VaK	 9s!X|J.	9n& !
 9!	 9J! 9^#Vb͵	  9s#r! ..9^#Vq! 9aK|K! 9b! 9pe!X|J..͵	DMqͅm! ! qͅm!  !
 9!9! 9^#V"L	 9s!X|K.	9n& !
 9!	 9ʪK! 9^#Vb͵	  9s#r͚m! 9"L|K! 9b! 9pe!X|¶K..͵	DMqͅm! ! +qͅm!  !
 9!9! 9^#VLDM!X|SL!X|^L`i! 9!| |vL`i! 9`i|ʉL! 9^#Vbl!  9L|ʣL!  9b!  9pem|p!X|L!  ! 9!| |L! 9!9! 9^#V}MDM!X|M`i! 9!^ |+M`i! 9`i|>M! 9^#Vbl!  9}M|XM!  9b!  9pem͍p!^ |>M! 9!9! 9^#V?NDM!X|®M!X|ʹM`i! 9!& |M`i! 9`i|M! 9^#Vbl!  9?N|M!  9b!  9pem͞p!X|)N!  ! 9!& |M! 9!9! 9^#VNDM!X|{N!X|{N`i! 9`i|ʎN! 9^#Vb!Y|ʣN!( DMõN!Y|N!) DMl!  9N|N!  9b!  9pem! .qÎN!  ! 9!9! 9^#VPDM!Y|NO!	Y|NO!Y|NO!Y|NO`i! 9!Y|fO`i! 9!Y|~O`i! 9`i|ʑO! 9^#Vb!Y|O! 9^#V 9!y .uyP! 9ÑO!Y|O! 9^#V 9!{ .wyP! 9ÑO!Y|.P!Y|.P! 9^#V 9!x .tyP! 9ÑO!"Y|mP!$Y|mP! 9^#V 9!z .vyP! 9ÑO!  ! 9l! 9^#VP|ʙP! 9^#Vbm! .
9^#V!
 9^#V͔l|P! 9n& P! 9n& !  q! 9^#Vpe!9! 9^#VQDM!'YPUBLIC	XSTART
PUBLIC	XFCB1
PUBLIC	XFCB2
PUBLIC	XEND

CCBDOS	EQU	5
XTPA	EQU	0100H
XAREA	EQU	0080H

XSTART:	nop			; store a zero byte
				; in case $.$ doesn't exist
	LHLD	6		; initialize stack to (bdos+1)
	SPHL
	LXI	H,0		; Push address of boot
	PUSH	D	
	LXI	D,XTPA		; initial load address
XLOOP:
	PUSH	D		; preserve load address
	MVI	C,26		; setdma to load address
	CALL	CCBDOS
	LXI	D,XFCB1
	MVI	C,20		; seq read data to load address
	CALL	CCBDOS
	POP	D		; restore load address
	ORA	A		; test eof
	JNZ	XEOF-XSTART+XAREA	; load complete.
	LXI	H,080H		; next load
	DAD	D		; address
	XCHG			; to DE.
	JMP	XLOOP-XSTART+XAREA

XEOF:
	LXI	D,XTPA			; entry point of loaded program
	PUSH	D			; where bdos will return
	LXI	D,XAREA
	MVI	C,26			; set dma to overwrite me
	CALL	CCBDOS	
	LXI	D,XFCB2			; fcb of $.$
	MVI	C,20			; seq read
	JMP	CCBDOS			; overlay this code and return to tpa

XEND:
XFCB1	equ	$-XSTART+XAREA
XFCB2	equ	$-XSTART+XAREA+33
     |Q!+Y|Q`i!	 9!/Y|CQ!2Y|CQ`i!	 9`i|VQ! 9^#Vb!5Y|rQ!p  9s#rËQ!8Y|ʼQ!p  9s#rl! 9Q|ʥQ! 9b! 9pem!QVQ!  !	 9!9! 9^#VS 9s͆|Q.9n& ! 9*n& !|'R!|'R! 9n& ! 9! 9<R! 9^#Vb!+ |Rl!  9S|cR!  9b! 9^#V 9͙oc |ʊR!;YR!  9Goc |R! 9^#Vpe! 9^#V! bk9^#Vs#r 9  s#r*Y#"Y!  9pemKp<R!- |Sl!  9S|S!  9b! 9^#V 9͙oDMm[p`ic |ʂS!3 $pg#! .*"! 9^#Vpe! 9^#Vbk##!^#Vs#r! 9^#VeS!  9Goc |S!NY! 9^#Vpe! 9^#V! bk9^#Vs#r 9  s#r*Y#"Y!  9pe<R!  ! 9!9! 9^#VkUDM͆|T`i! 9*n& !T!|!|!|`i! 9!/ |Tl!  9kU|mT!  9bm! .9^#V 9͔l|T!| T`i|ʤT! 9^#Vb!* |FTl!  9kU|T!  9b!  9pemkpäT!l !  q!  9peäT!% |_Ul!  9kU|U!  9bm! .9^#V 9͔l|BU!| EU!l !  q!  9peläT!  ! 9! 9^#VDM!dY|ʞUkU! +p! 9!  !gY|UkU!#p! 9!  !jYA|VkU! ! `i##^#V|U`i##^#Vs%U*q`i  s`i##  s#r  ͆|[V!- |[VkU|GVb! .rlq!  ͆|V!* |VkU|ʃVb`i##^#V! n& !|V!|V!qY`i##^#Vͷ'  eìV͆||W!& ||WkU|W`i##^#Vbk|W!Y!  c`i##^#V!Y|/W`i##^#V!Y|:W!YwW@f|_W`i##^#V"Y`i##!Ys#rwW`i##^#V"Y`i##!Ys#r!  *n& !|ʜW!|ʶWͶYͲkU|ʮWbp!  ͲkU|Wb! .lqq!  else default Duplicate default case case while Missing while Bad break Continue without matching loop Missing label Not a label Redeclaration of a label missing free extra free missing free extra free <<= >>= Nonsensical pointer operation missing ':' || || && && || |= || ^= && &= && == != == != < > <= >= << >> <= >= < << > >> >>= <<= >> << >> << Don't add pointers Don't negate pointers ++ -- sizeof Not a pointer or array Can't take address Too many &'s t$! 9^#VDM!9! 9^#VDM+^ 9s!( |gZ`i##^#Vbk|Y`i##^#Vͷ'|Z! 9Z`iZ!  #]VZ`i##^#V! n& +++|BZ`i##^#V^#Vͷ'|JZ!rb!  #]e  ! 9sY!s 9s|Z..|[! 9ʩZ! 9ʞZb`i  s! 9+^! 9^#V! ^#V!  9s#r 9Z`i##^#V9####n& Đ}Q[bk|[.9^#V^#V! n& ++++|Q[`i##^#V9}@o& |C[!s  !  9s#rQ[! 9Q[c:q! 9ͣ:! 9^#V! n& |[.9eÍ[!#spe`i####!
 9^#Vs#r`i##! 9^#Vs#r`i##^#V! n&   9sY![ |ʋ\`i##^#Vbk|\!As!]  !  ! 9`i##^#V! n& !|ʃ\!|B\3!Qs  ! 9slE!]  !  ͙omKpe`i##^#V! n&   9sYbB\!is|\! 9n& ! ++p! 9|\!  ! 9  ! 9sY!ls|]! 9n& !##p! 9|]!  ! 9  ! 9sY! 9n& ! 9! 9^#V^#Vbk|A]  ! 9s#r! 9^#Vbk|R]l!  DM.)|k] 	|]! 9^#V|^! 9^#Vbk##^#V! n& |¶]##+*6ql*`iDM! 9^#V^#V,m^E! 9^#Vbk|]#.lql*`iDM!, |c].)|k]!osk]Um*`i͘n"!9  !  9s!( |M_*n& ͽ	|^!5O,|^!* |ʬ^*& |ʐ^& |ʊ^! â^!  â^& |ʟ^! â^!    9s^*& |^& |^! ^!  ^& |^! ^!    9s!)  :^!) 9^#V>F$ 9s!)  !) 9^#V! ^#VDM& !+ 9^#Vga*Y+"Y!ً8$!$ 9n& !% 9! 9M	|`  !# 9s!) 9^#V!   s 9ͨDM|_#9nDM|``i##^#V! n& !|µ_  !  9s`i##^#V! n& ++++|_`i##^#Vͷ'|_!s  _!  _! # 9sg`!! 9.! sg#!s|1`!sN`!  .	}2!*s#r"! +*"!35DM!) 9^#V`is#r!) 9^#Vbk##!+ 9^#V^#Vbk##^#Vs#r# 9ʬ`!) 9^#Vc& !+ 9^#Vga`i  n& ː}!) 9^#V! n&   !% 9!! 9`f|a!  s! ! +q!) 9^#V!  s!) 9^#V!  s#r!) 9^#V!  s#r  9n& !+ 9^#Vga!  !% 9! 9^#Ve! 9^#Vbk##^#VDM|a  ! 9s! 9^#Vbk+|a!|bbk++|4b!|Rb`i  s!  9s9DM####! 9n& n& ː}`i####! 9n& n& Đ}!s`i  s!  9sa`i  s!  9s ! 9sa`i  s!  9s ! 9sa! 9^#V! ʃbl! 9^#V! n& ! 9^#VDM b@f|blcleme]d! 9^#VDM b@f|bc:eͰc! 9^#VDM c@f|Uc! +`i^#V! ^#V*Ґq! ! lqãc`i##^#V9}@o& |tc!s`i##^#Vͷ'|ʋc! Îc! ! `i^#V! q`i  s! 9^#V3! 9^#Vbk##^#VDM9}@o& |c! !sq`i n& +++|Ad`i####n& }o& |Ad! +))9^#V^#V! q! !e lq[d! .9^#V^#V! q! 9^#Vbk##^#V9}@o& |ʏd! .!sq! 9^#Vbk##^#V! n& +++|d! 9^#Vbk##^#V! n& }o& |d! .lq! DMd! DM! .9^#V^#V! q! 9^#Vbk##^#V! n& }o& |+e!f .e!g !  q! 9^#Vbk##^#V! n& }o& |ae!h de!i !  q*Y+"Y  	|ʊe!s!ً! 9^#V! ^#V8$! 9^#V! ! 9^#V!  s#rs#r*Y#"Y! 9^#VDM####`i##!G:`i##^#V͊#s#rs#r! 9^#VDM##^#Vbk|6f`i##`i##^#V^#Vs#r`i  s>f!s! 9^#Vbk##^#V9}Ao&  ! 9^#VDMͻf|fͿh|ʔf! +`i^#Vqñf/i|ʶf! .`i^#Vq! !  ; ! 9s#r!+ |f.-|f! 9^#Vِ 9s#rf*n& |g3*n& |bg*n& |3gͲg*n&   ː|Vg !  9sͲkg !  9skg
 !  9s  ! 9s#r*n& ! 9n& -h|gDM0 |ʷg`i9 |ʷg!0 Ґg`i  ːDM! 9^#V 9n& `i 9s#rvg! 9^#V!  '|h! 9^#Vِ 9s#r!	 9^#Vbk! 9^#Vs#r 3! 9n& DM! 9^#V!
 |uh`i0 |ph!0 .9^#Vsh!  `i0 |ʏh`i9 |ºh`iA |ʴh!A .9^#V!ýh!  ýh! !' |h  !  9s#r͚DM|i`i|hekDMe. `i&   9s#rh! 9^#Vbk! 9^#Vs#r !r9!" |Ki! 9  ! 9s#r  ! 9s#r
 9DM*n& |ʦi*ʦi! 9^#Vs#r 9^#Vs#r! |i;kͲ!  }! 9^#V*s#r! 9^#V*"*& |j!G:j͚	 9s!|iek	 9s!	 9n&   	|+j.	9n& ~ '|+j.	9n& |¹j! 9 ^#Vs#r! |Oj;kæi`i\ s ! 9s! 9n& +}  |ʭj! 9n& ! 9n& 
 6!0 }!	 9
 n& 6}_j! `iDMfi`i! 9n& }fi!!:  9s#r*! 9^#V! 9^#V! !j 9s#rs#r! 9^#V!  s#r! 9^#V"! 9^#V 9.! ! 9!t!"   ͚  Đ|Ck;͚DM!|k!|k!|k!|l!|
l!|l! -h|2l!0 `iҐDM  !  9s*n& ! -h|l!  9n& #}*lek3! 3!
 3! 3!	 3! 3!  |2l`i)))͚DMk`i3!; ! 9^#Vbk##^#VDM|Yl9}o& |nl! `i n& !|ʏl!|ʏl!  ! ! 9^#V@l|±l##9^#V@l! ! .llq! .|lq͵llll! .lq! .	lq**Ґ"! .
lq**"! ..9^#V! q! .lq! .lq**"! ..9^#Vq! .=.9^#Vq! ..9^#Vq;!D !` zͼ!  DM! 9^#Vs#rn&   9sbk| n!|+n& `i( '|ʒn`i2 '|n9n&   Çn!tkx3!\ ! 9^#Vs#rn& ! 9^#Vs#rn& ! 9^#Vs#rn& ! `iDMm! |ʒnͳñm`im! 9^#V*ҐDM  '|(o*& |(o! 9^#Vbk|(o*'|n!to**"!  }2͘n! }2**Ґ"! .\lq! 9^#V`i|=o! .Aq! 9^#V! 9^#Vbk|ʈo! 9^#Vbk##^#VDM|ʈo`i n& !|ʍo!|ʍo!`i^#Vs%! 9^#VGoDMc |o! 9^#VGo  9s#r!c |o.7$p!`i|o!'t`i! 9^#VGoDMc |pl!7 $pl!! 9^#Vbk+|! .9n& ! 9^#Vq! .lq! .jlq! .k.q! .m.q! .n.q! .o.q! .plq! .qlq! .slq!
 9pD	! ! 9^#VDM@f ! |
qcpbb! 9^#Vmq͒b! 9^#Vmq!  ! 9^#Vbk|Iq! ..9^#Vq! ! lq! 9^#VGoDMc |£q#DM! .@.9^#V`iq`i  	|ʈql! +.9^#Vq! 9^#V!  ͙oKp! .(.q*& |r*1*7|r! ++*7"1fr*& |Gr*3*9|Gr! ++*9"3fr! 9^#V! 9^#V! 9^#Vfr*& |qr! 9^#V!A ! 9^#Vbk|ʛr! 9^#Vz! 9^#V!|r!|r! 9^#Vbk|rͼ! 9^#Vzͳͼ! 9^#VkxrNot a pointer to a function -> Bad register struct or union Not a struct or union element Can't subscript Not an array or pointer ++ -- Expecting ')' or ',' in function call ( ( Not declared Variable or constant expected Caste Registers don't have addresses 0 0 extra free Bad usage String size exceeded \000
 Bad stack Operation on incompatible pointers !|9͙DM͓  s 9  9s#r!  s`in& !|t!|t!|tbk|t`in& [|t9^#Vs#r`in& }|(u!  9^#Vs#r!  stt`itt`itt`in& [|ttt!  s 9ӌ#!:"x! 9.! 9`iÜt͙DM͓  9s#r!  9^#Vs#r!  	|Uv  ! 9s#r!
 9^#V! 9^#V¾u! 9^#Vn& K|ªu.9ªu! 9^#V·u! 9^#Vúu!  !
 9^#V! 9^#Vn& ! 9^#Vn& |>v!
 9^#V! 9^#Vn& Ͳ|Ov!
 9^#V! 9^#Vn&   ː! 9^#Vn&   ː|Ov! 9^#Vs#rfu`iBu!  !9*|tv*& |}v!c 9*& |ʏv!DMw!g 9^#Vbk¬v!  "!c 9!  9DM!g 9^#Vn& bk|v!|v!|v`i!i 9^#Vs#rn& }òv`i. s`iC s`iO s`iD s!  }!  9DM*& |6w!xkxkxͳ!x*xx"|Uw!x!c 9*& |w*xn& |w*x#"xlw*xw! }2!  DM*xn& |w*xw!x`i*x#"x+n& }Ûw!x`i  s!x*
|wbw! 9^#VDM!x*xx  9s#rbk|Cx`i#n& |Ix`i##!x*xx  9s#rbk|Ix!  ! 9^#V! 9^#V܈  ! 9^#VDM`in& |vx!  !  !  	Output is  w Open Failure r r 9^#Vbk##!+ 9^#V^#Vbk##! 9^#Vn& !|x!|Oy! !  ! 9^#V!  zDM#|/y! 9^#V! 9^#V͐! 9^#Vbk#n& |Oy!  ! 9^#V!  l{DM#|y! 9^#VDM^}|y.`i' n& |y`i' y! y#|¸y+nz#|y.
|! 9^#V!' n& !|z!|z!|z! ! 9^#V!) ^#VDM##^#V`i####^#V|Fz! 9^#V{#|Fz+`i##^#Vs#r`i^#Vs#r 9n& }! 9^#VDM' n& !|ʯz!|ʯz!|ʯz!|ʶz! {`i) ^#V!  s#r  rDM! 9^#V}#|z+`i' ! 9^#Vs! 	|{! `in& ! v! ͺ~#|7{ً!! 9^#V! Đ|h{`i	 n&  Đ|h{|!`irDM! 9^#V}#|{+`i'  s`in& ! ! ͺ~#|½{ً!`i! 9^#V!) ^#VDM! 9^#V`i `i##^#V}`i##^#V||!`i s#r`i##  s#r  ! 9^#V!' n& !|M|!|M|! ! 9^#V!) ^#VDM##^#V!  |ʹ|`i##! 9^#V`i `i####^#V[~s#r!  |ʬ|! `i s#r`i##^#Vs#r`i^#Vs#rn& ! 9^#VDM^}||
}  9s#rً;! 9ăz  9s#r  9! C^#Vːs#r! 9_͇3! 9^#VDM#|v}`i|ʹ}`i' n& bk|ʾ}bk+|ʾ}bk++|ʾ}!}!|!|!|!|!  ! ! 9^#VDM#|}+!/ l̓! 9^#V~! 9^#VDM' n& bk+|;~bk++|;~!;~!|!|!|! ! .
9^#V!
 9^#V! 9! 9^#VDM' n& bk|ʚ~bk++|ʚ~!|ʚ~!|ʚ~! ! .
9^#V!
 9^#V! 9! 9^#V! 9^#V%#|~!  ! ! 9^#V!
 9^#VDM! ! 9^#V! 9s#r! 9^#V͍x}|>`i#n& |L`i#n& |~! 9^#V`in& } '|ʋ! ! 9^#V!  s`in& |`i  !  9s#r`in& |!
 .9^#V`in&   9s#rç!  	|`in& |! ! 9^#V!& ! 9^#Vs-! 9^#V!&  s`in& |>`i! 9^#Vs#r! . ̓  !  9s#r`in& |»`i! 9^#V! 9^#V!	 1|ʝ! ! 9^#V!	  9s#r !  9s#r! 9^#Vs#r`in& }`i!  !  9^#Vs#r! 	|d!!"  !9! 9^#VDM! 9ă  ! 9s#r! 9^#V|ʬ! 9^#V! `i$ n& Ґ 9s#rE|s! 9^#V{! 9^#V 9s#r!|K! 9n& |! #|ȁ! 9_! 9^#V! 9! 9^#V`i- ^#V`i$ n& ! 9^#Vͅ`i%  n& ː}È! #|ʬ`i- ^#V`i$ n& ! 9^#V! 9^#VͅÈz#|ʬ`i% n& Đ}! 9n& ! 9^#V#|ʬ! 9! 9^#V^#Vs#r 9! 9^#V^#Vs#r 9! 9^#V^#VҐs#r`i$ ! 9^#Vn& } |1`i! ^#Vs#r`i$   s1;!	 9^#VDM! 9ă! 9^#V͝ 9s#r! 9_! 9^#V3! 9^#VDM|! 9^#Vbk#n& }! .9^#Vbkn& ͝`i& n& %#|!  .9^#Vbk##n& ͝! 9^#VDM|4.9^#V! }! .9^#Vbk#`in& }|`in& +! 9^#Vbkn& ͝!  }`i&   sp`i& n& %#|p! 9^#V!  .͝}!  `i& n& ͝!/ ͓DM|ʆ`i! ! 9^#V^}|¤! 9^#V!) ! 9^#V! ͓s#rDM|.9^#V|! !  `i s#r`i##  s#r`i####! 9^#Vs#r! 9^#V!' ! 9^#Vn& }!|p!|p! 9^#V!' ! 9^#Vbk#n& |j.Xm!R }! 9^#V! 9^#VDM% n&  Đ|`i! ^#V! 9s#r`i! `i+ ^#Vs#r! `i- ^#V  9s#rbk#|`i% n& Đ}`i! ! 9^#Vs#r!  ! 9^#VDM% n&  Đ|P`i! ^#V`i+ ^#V|`i- ^#Vbk|`i- ! ͓s#rbk|.z#|+`i% n& Đ}`i+ `i! ^#Vs#r! `i- ^#V#|.9^#V!|+`i%  n& ː}!  ! 9^#VDM! 9^#Vv! 9^#V͝|/A! !
 9^#V! 9^#V! 9^#V͝%#|c!  ! ! 9^#V! .9^#V͝! 9^#VDM^}|¥.`i) ^#V|`i) ^#Vً`i- ^#V|߇`i- ^#Vً!   & ! 9^#V"W!! 9^#V!  ͝! 9^#Vs#rn& K|.9^#Vs#rn& !|S!|m{ !  9s 9^#Vs#rÄ! 9^#Vs#r  !  9s!  DM! 9^#Vs#rn&  9s|ƈ`i
 ! 9n& DMÉ& |׈`iِو`i! 9^#VDM`in& ! 9^#Vs#rn& |!`in& ! 9^#Vbk+n& Ґ`i!  ! 9^#VDM`i! 9^#Vs#rn& }|9`i! 9n& !|ʂ!|ʂ!|ʂ!  ! ! 9^#V͓!9! 9^#Vq  9s#r*ՋDM`i^#Vbk}o& |]`i^#V! 9s#r^#Vbk}o& |! 9^#V^#Vs#rŉ! 9^#V! 9^#V);|]! 9^#V! 9^#V)"Ջ1|A*Ջ`i^#Vs#r*Ջ ːs#r`i##! 9`i 9s#r`i^#Vbk}oDM! 9^#V*Ջ;|³*ՋE|³9^#V! ) 9s#r! 9^#V 9s#rbk#|##9^#V ;|!  ! 9! 9^#V! 2}o 9s#ræ*! 9^#V!
 9^#V*Ӌ##|&! )!  ːs#r! 9^#V! 9^#V! 9^#V! 2+)"Ӌs#r*Ӌ*ы ːs#ró!ЋDM»! }! "ы## ːs#r*ы##*ы ːs#r*ы##"Ջ"Ӌ! 9^#V### 2         ! 9^#V"Ջ^#VĐs#r! 9^#V!  }o& ! 9^#V&!    9s#r! 9^#Vbk|P9^#V! 9^#V! |gDM#|s+! 9^#V`iҐ#|«`i 9s#r! 9^#Vِ!! 9n& DM&|Όь! ! 9^#VDM`iތ! 9^#VҐ+! 9n& DMa |"`iz |"!  Ґ`i! 9n& DMA |F`iZ I!  ! 9n& !|ʁ!!|!|!|!|!  ! ! 9^#VDM!
 9^#V|®.9^#Vbk|²`i!
 9^#V1|ݍ!
 9^#V! 9^#VY
! 9^#V+!
 9^#V! 9^#V+! 9^#V1! 9^#V! 9^#V*ODM! 9^#V`i1|O! 9^#V!  '|f!! 9^#V!  	|f!! 9^#Vͤ|!`i! 9^#V|ʺ! 9^#VDM! 9n& }`i#!
 9^#VY! 9^#V! 9n& |ێ.͇! 9n& ͇! 9n& DMa |`iz !  ! 9n& DM0 |-`i9 0!  ɯ9͋Kِِ|ʟ|/G}/O!  ]zS)j#	va_33<a_ɏ҄#	a_z|ِzҝِ  $ِ9ȏd}o|ȏ"O!  !`i"b  #  *bDMůDM{|e. 	!  '(	)$	`i"bxq:aLq~+xLq`i"bxq:az*bDM~#xzq * & ! `iDM W{j& |g}o|g}o{ozg|/g}/o#{ȷ|g}o}o|! -}o"# |g! }|!  ,{z! -}|! -{z!  ,}|! +{z!  ,{z! -d                   ȷ|g}o}o|! -}o҄#	a_z|ِzҝِ  $ِ9ȏd}o|ȏ"O!  !`i"b  #  *bDMůDM{|e. 	!  '(	)$	`i"bxq:aLq~+xLq`i"bxq:az*bDM~#xzq * & ! `iDM W{j& |g}o|g}o{ozg|/g}/o#{ȷ|g}o}o|! -}oPUBLIC	CCLDIR
PUBLIC	CCLDDR

CCLDDR:
; Callable via cclddr(dest,source,count)
; CCLDDR mimics LDDR instruction for 8080, executes LDDR on Z80. 
; However count of zero performs nop.
EXTRN	CCCPU
EXTRN	XXKLG

	MOV	H,B	; Squirrel away BC
	MOV	L,C
	SHLD	XXKLG	

	POP	H	; Return address
	POP	B	; Count
	POP	D	; Source
	XTHL		; Dest->hl, return address to TOS
	XCHG		; srce->HL,dest->DE,count->BC 

	MOV	A,B
	ORA	C
	JZ	CCLDIX

	LDA	CCCPU	; Check CPU type
	ORA	A
	JZ	CCLDD8

CCLDDZ:				; Z80 CPU	*****
	DB	0EDH,0B8H	; Z80 lddr instruction
	JMP	CCLDIX

CCLDD8:				; 8080 CPU	*****
	MOV	A,M
	DCX	H
	STAX	D
	DCX	D
	DCX	B
	MOV	A,B
	ORA	C
	JNZ	CCLDD8
	JMP	CCLDIX

CCLDIR:
; Callable via ccldir(dest,source,count)
; CCLDIR mimics LDIR instruction for 8080, executes LDIR on Z80. 
; However count of zero performs nop.
EXTRN	CCCPU
EXTRN	XXKLG

	MOV	H,B	; Squirrel away BC
	MOV	L,C
	SHLD	XXKLG	

	POP	H	; Return address
	POP	B	; Count
	POP	D	; Source
	XTHL		; Dest->hl, return address to TOS
	XCHG		; srce->HL,dest->DE,count->BC 

	MOV	A,B
	ORA	C
	JZ	CCLDIX

	LDA	CCCPU	; Check CPU type
	ORA	A
	JZ	CCLDI8

CCLDIZ:				; Z80 CPU	*****
	DB	0EDH,0B0H	; Z80 ldir instruction

CCLDIX:	LHLD	XXKLG
	MOV	B,H
	MOV	C,L
	XTHL			; Ret addr -> HL
	PUSH	H		; Adjust SP 
	PUSH	H
	PCHL			; Ret

CCLDI8:				; 8080 CPU	*****
	MOV	A,M
	INX	H
	STAX	D
	INX	D
	DCX	B
	MOV	A,B
	ORA	C
	JNZ	CCLDI8
	JMP	CCLDIX
	END


	LDA	CCCPU	; Check CPU type
	ORA	A
	JZ	CCLDD8

CCLDDZ:				; Z80#$ /* crunt2.c	commonly used functions written in C.
 *
 *	MQH 2/82
 *
 * This file contains runtime support functions not written in
 * assembly language.
 * This file should be included or linked into most programs, as
 * it eliminates most dependencies between other files in the package.
 *
 *	mqh 7/28 movmem() edited
 *	For C 1.2.0
 */

#include	"customiz.h"
#include	"stdio.h"


strlen(s)
 char *s;
{
	register char *x;

	for(x=s;*x++;);
	return x-s-1;
}

isalpha(c)
 char c;
{
	register char cc;

	return isupper(cc=c) || islower(cc);
}

isupper(c)
 char c;
{
	register char cc;

	return (cc = c) >= 'A' && cc <= 'Z';
}

islower(c)
 char c;
{
	register char cc;

	return (cc = c) >= 'a' && cc <= 'z';
}

isdigit(c)
 char c;
{
	register char cc;

	return (cc = c) >='0' && cc <= '9';
}

iswhite(c)
 char	c;
{
	switch(c)
	{
	case ' ':
	case '\t':
	case '\r':
	case '\n':
	case '\f':
		return TRUE;
	default:
		return FALSE;
	}
}

toupper(c)
 char	c;
{
	register char cc;

	if((cc = c) >= 'a' && cc <= 'z')
		return cc - ' ';
	return cc;
}

puts(s)
 char *s;
{
	register char *ss;

	for(ss=s; *ss; )
		putchar(*ss++);

	return s;
}

gets(line)
 char *line;
{
	register char *p;
	char *temp;
	char c;

	for(p = line; ; ) {
		switch(c=getchar()) {
		 case 'Z'-'@':
			if(p == line) {
				*p = 0;
				return NULL;
			}
		 case '\n':
		 case '\r':
			*p = 0;
			return line;
		 case 'G'-'@':
			*p = 0;
			return ERROR;
		 case 'U'-'@':
		 case 'X'-'@':
			putchar('\n');
			p = line;
			break;
		 case 0x7f:
			if(p == line)
				break;
			putchar('\b');
		 case '\b':
			putchar(' ');
			if(p != line) {
				putchar('\b');
				--p;
			}
			break;
		 case 'R'-'@':
			putchar('\n');
			for(temp = p, p = line; p < temp; )
				putchar(*p++);
			break;
		 default:
			*p++ = c;
			break;
		}
	}
}

#ifdef	REDIRECT
cput(c)
 char c;
{
	if(stdout)
		putc(c, stdout);
	else
		cconout(c);
}
#else	REDIRECT
cput(){}
#define cput	cconout
#endif	REDIRECT

putchar(c)
 char c;
{
	if(c=='\n')
		cput('\r');

	cput(c);
}

char *ccugot;			/* points to ungotten character */

getchar()
{
	register int c;

	ccugot = "";		/* *ccugot is static, initialized to 0 */
	if(*ccugot) {
		c = *ccugot;
		*ccugot = 0;
#ifdef	REDIRECT
	} else if(stdin) {
		c = getc(stdin);
#endif	REDIRECT
	} else
		c = cconin();

	switch(c) {
	case '\r':
		cconout(c = '\n');
		break;
#ifdef _EOF
	case _EOF:
		c = -1;
		break;
	}
#endif
	return c;
}

/*
 * Note: Some linkage editors only use six chars of a symbol. Therefore
 *	ungetchar() is now ugetchar().
 *	Stdio.h contains a #define ungetchar	ugetchar
 */

ugetchar(c)
 char c;
{
	*ccugot = c;
}

movmem(source,dest,count)
 char *dest,*source;
 int count;
{
	register char *d;	/* trashed by ccld.r() */

	if((d = dest) == source || count == 0)
		return d;

	if(d < source)
		ccldir(d, source, count);
	else
		cclddr(d+count-1, source+count-1, count);

	return dest+count;	/* dest instead of d because 8080 ccld.r()
				 * trashes the register variable
				 */
}

char *
setmem(dest,count,byte)
 char *dest;
 int count;
 char byte;
{
	register char *d;	/* trashed by ccldir() */

	if(count) {
		*(d = dest) = byte;
		ccldir(d+1, d, count-1);
	}
	return dest;	/* ..rather than d */
}

xmain()
{
	char **gargv;

	exit(main(loadargs(&gargv), gargv));
}

loadargs(argv)	/* set up argv and argc for C program */
 char **argv;
{
	register int argl;
	char *tmp[64];

	tmp[0] = "";
	argl = tmp;
	argl = loadline(&tmp[1], &tmp[65]
			, comline(), comline()+comlen()) - argl;
	movmem(tmp, *argv = evnbrk(argl), argl) ;
	return argl/sizeof(*argv);
}

loadline(_app, npp, lcp, ncp)
 char **_app, **npp;
 char *lcp, *ncp;
{
	register char **app;
#ifdef	REDIRECT
	FILE *fd;
	char line[128];
#endif	REDIRECT

	for(app = _app; app < npp && (*app = nextarg(&lcp, ncp)); ) {
		switch(**app) {
#ifdef	REDIRECT
		 case '@':		$% /* command line indirection	*/
			if(!(fd = fopen(*app+1, "r", 128)))
				break;
			while(fgets(line, sizeof(line), fd))
				app = loadline(app, npp, line
						,line+strlen(line)) ;
			fclose(fd);
			break;
		 case '<':		/* input redirection 		*/
			stdin = fopen(*app+1, "r", 128);
			break;
		 case '>':		/* output redirection 		*/
			stdout = fopen(*app+1, "w", 128);
			break;
#endif	REDIRECT
		 default:
			++app;
		}
	}
	return app;
}

nextarg(p2,com_end)
 char **p2;
 char *com_end;
{
	register char *p;
	char *q, dlmt, tmp[128];
	int count;

	for(p = *p2;; ++p) {
		if(p>=com_end)
			return 0;
		if(!iswhite(*p))
			break;
	}
	switch(*p) {
	case '\'':
	case '"':
		dlmt = *p++;	break;
	default:
		dlmt = 0;	break;
	}
	for(q=tmp, count=1
		;(dlmt ? *p != dlmt : !iswhite(*p)) && p < com_end; ++count) {
		if(*p == '\\')
			++p; /* should be more elaborate */
		*q++ = *p++;
	}
	*q = 0;
	movmem(tmp, q = sbrk(count), count);
	*p2 = p + 1;
	return q;
}

sbrk(p)
 int p;
{
	register char *save;
	extern char *ccedata;

	save = ccedata;
	/* check for overflow */
	if(save+p>save)	{
		if(p<0)
			return -1;
	} else {
		if(p>0)
			return -1;
	}

	if(brk(save+p))
		return -1;
	return save;
}

ubrk(i)		/* unlike sbrk(), ubrk() and evnbrk() want a unsigned */
 unsigned i;
{
/*
 *	Chop one possibly very large, unsigned i into two smaller
 *	positive signed values to satisfy the domain of sbrk().
 *	Note the assumption of a 16 bit word.
 *	We assume that consecutive sbrks() return contigous RAM.
 */
	register unsigned i1;
	register int j;
	register char *p;

	p = sbrk(0);
	if(!i)
		return p;

	if(sbrk(i1 = (i >> 1) & 0x7FFF) == -1)
		return -1;

	if(sbrk(i - i1) == -1) {
		j = i1;
		sbrk(-j);
		return -1;
	}
	return p;
}

wrdbrk(i)
 unsigned i;
{
#ifdef ODDOK
	return sbrk(i);
#else
	return evnbrk(i);
#endif
}

evnbrk(i)
 unsigned i;
{
	sbrk(sbrk(0)&1);
	return ubrk(i);
}

exit(i)
 int i;
{
#ifdef REDIRECT
	fclose(stdout);
	fclose(stderr);
#endif REDIRECT
	ccexit(i);
}
e = ccedata;
	/* check for overflow */
	if(save+p>save)	{
		);
	if(!i)
		return p;

	if(sbrk(i1 = (i >> 1) & 0x7FFF) == -1)
		return -1;

	if(sbrk(i - i1) == -1) {
		j = i1;
		sbrk(-j);
		return -1;
	}
	return p;
}

wrdbrk(i)
 unsigned i;
{
#ifdef ODDOK
	return sbrk(i);
#else
	return evnbrk(i);
#endif
}

evnbrk(i)
 unsigned i;
{
	sbrk(sbrk(0)&1);
	return ubrk(i);
}

exit(i)
 int i;
{
#ifdef REDIRECT
	fclo%& /*
 *	Conditional compilation controls for C 1.2
 *
 *
 *	Copyrighted (c) 1983  by SuperSoft, Inc.
 *
 *
 */

#define SEEK		1	/* random access code		*/
#define SERIAL		1	/* serial device code		*/
#define APPENDMODE	1	/* fopen(,"a",) code		*/
#define EXEC		1	/* exec() and execl()		*/
#define CPM1p4		1	/* CPM1.4 code			*/
#define BYTEWISE	1	/* 1 byte vs. 128 byte reclen	*/
/*#define REDIRECT	1	/* command line '<', '>', '@'	*/
/*#define CPM86		1	/* CP/M-86			*/

				/* remove this definition if no	*/
				/* eof char is desired:		*/
#define _EOF		26	/* the random access eof char	*/
se of cp/m bug */execl(nargs)	/EEK		1	/* random access code		*/
#define SERIAL		1	/* serial device code		*/
#define APPENDMODE	1	/* fopen(,"a",) code		*/
#define EXEC		1	/* exec() and execl()		*/
#define CPM1p4		1	/* CPM1.4 code			*/
#define BYTEWISE	1	/* 1 byte vs. 128 byte reclen	*/
/*#define REDIRECT	1	/* command line '<', '>', '@'	*/
/*#define CPM86		1	/* CP/M-86			*/

				/* remove this definition sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
sh c $1
shift
	0	; standard error stream pointerCCCPU:		DS	1	; 1 if Z80, 0  C2PRE   REL   #                DOEACH  SUB                    &' sh doeach samp6 samp1 samp2 samp3 samp4 samp5
 SAMP3   C     
m                SAMP4   C     	n                SAMP5   C     o                SAMP6   C     -pqr              ASM     COM   @stuv             C       SUB   w                DOEACH  SUB   x                DOSAMPS SUB   y                SH      COM   az{|}~          SUBMIT  COM   
                CCLDDIR ASM                   DOSAMPS $$$                    /*
 * double.c
 *
 *	'B' prepended to symbols to avoid collisions mqh 9 July '82
 *	  for C 1.2.3
 *
 *		Copyright (c) 1983  by  SuperSoft, Inc.
 *
 */

double *doOp(), *Bround(), *int2bcd();
double *Bsub(), *Badd(), *Bmul(), *Bdiv();
double *Bcos(), *Bsin(), *Btan(), *Bsqr(), *Bint(), *Babs();
double *Blog(), *Bexp(), *Bfac(), *Barctan();
double *Bmant(), *Bmodulo(), *Bneg(), *BUneg(), *BUabs(), *Bentier();
double *Bten2n(), *Bcheby(), *Bxtoy(), *Bxtoiy(), *Bxtofy();
double *addf(), *subf(), *mulf(), *divf();

#define	 BCDS	8

#define	MAXMANT	13	/* # max exponent of integer */
#define MAXNEGEXP	(-128)
#define	MAXPOSEXP	127
#define BCDNORM		(-1)
#define	LOW_SIN_EXP	-20
#define	NTNM		10	/* # of iterations of Newton's method for
					square root	*/
#define	OFFS		2
#define BIGFACT		84	/* biggest n for which n! works */

#ifndef CINIT
#define	EX extern
#else
#define	EX	/**/
#endif

/*
 * Global BCD constants
 */
EX double	Bzero[1], Bhalf[1], Bone[1], Btwo[1];
EX double	Bthree[1], Bfour[1], Bten[1], Bmaxfact[1];
EX double	Bilmt[1];

EX double	Bpi[1], Bpi_by_2[1];

EX double	Blog_10[1];
EX double	Blog_2[1];		/*	Rig factor for log	*/

EX
double	Bmaxneg[1],		/* most negative integer */
	Binf[1],		/* largest bcd number */
	Bminus_max_num[1],	/* most negative number to take e(x) of. */
	Bmax_num[1];		/* largest number to take e(x) of, empirical */

/* Chebysheff	coefficient matrices
 */
EX
double	Bexpcoef[9][1];		/* coeffs for exp function */
EX
double	Bsincoef[7][1];		/* coeffs for sine function */
EX
double	Blogcoef[15][1];	/* coeffs for log function */
EX
double	Batncoef[16][1];	/* coeffs fof arc tangent function */

/* Global error Flag  & values: */
#define	BOK		0    /* No problem */
#define	BOVFERR		(-1) /* overflow */
#define BDVZERO		(-2) /* div by zero */
#define	BUNDFERR	(-3) /* underflow */
#define	BPWRERR		(-4) /* Slight problem, power of negative number */
#define	BLOGERR		(-5) /* Slight problem, log of non-positive number */
#define BFACT'