AUSAM/source/mac/mac/mac33.c

#include	"mac.h"
#include	"mac.x"

/*
 *   Auxilliary routines 3 (for pass 2)
 */


/*
 *   Assemble binary object in a field 'width' bits,
 *   having a value of 'value'.
 *
 *   The value is checked to fit into the space and
 *   truncation errors will result if it overflows.
 *   If the host machine has generated a negative
 *   number as the result of an expression -
 *   check this also by complementing the number,
 *   and then checking it.
 */
assemble(value, width)
register int value;
register int width;
{
	register int mask;
	register int free;
	register int r;
	static	 int	used;
	static	 int	buf;



	/*
	 *   Check for overflow errors.
	 *   (a value too large to fit in
	 *   the desired space.)
	 */
	if (value >= 0)  {
		mask = (-1) << width;
		if (value & mask)
			warning("assemble overflow");
		}
	else  {
		mask = (-1) << (width - 1);
		if (value < mask)
			warning("assemble overflow");
		}


	free = head.h_bu_len - used;			/* free bits in buf */
	while (width && width >= free)  {
		r = width - free;			/* remainder can't use yet */
		mask = BITMASK(free);
		buf = (buf << free) | ((value >> r) & mask);
		mask = BITMASK(r);			/* remainder mask */
		value =& mask;
		width =- free;
		*locn[lcntr].l_next++ = buf;		/* push out to core */
		buf  = 0;
		used = 0;				/* none of buf used */
		free = head.h_bu_len;
		}

	if (!width)
		return;

	/*
	 *   Take care of remainder.
	 */
	used =+ width;
	mask = BITMASK(width);
	buf = (buf << width) | (value & mask);

	if (used >= head.h_bu_len)
		used = 0;

	return;
}


/*
 *   Code formatter.
 *
 *   Decode and assemble binary data in memory
 *   according to the selected format descriptor.
 */
format(fmt, op)
register struct fd *fmt;
register int op;
{
	register int pr;
	register int rf;
	register int n;
	register int mask;
	register int i;

	if (op == head.h_ii)  {
		synerr("illegal instruction");
		return;
		}


	/*
	 *   Format descriptor loop.
	 *
	 *   Get each sub-section, decode it,
	 *   and assemble it's value into the instruction.
	 */
	for (i=0; fmt->f_desc[i] != 0; i++)  {

		pr = fmt->f_desc[i] & (RMODE | PMODE);
		n  = fmt->f_desc[i] & 0xff;

						/* opcode field */
		if (n == 'o')  {
			reloc = RABS;
			rf = fmt->f_width[i];
			mask = BITMASK(rf);
			assemble(op & mask, rf);
			continue;
			}

							/* pc field */
		if (n == '!')  {
			reloc = RREL;
			assemble(locn[lcntr].l_value, fmt->f_width[i]);
			continue;
			}

							/* arg field */
		if (n >= 'a' && n <= 'm')  {
			n = n - 'a' + 1;
			reloc = relstac[n];
			n = oprstac[n];
			if (pr & PMODE)  {
				/* pc relative */
				n =- locn[lcntr].l_value;
				}

			if (pr & RMODE)  {
				/* byte relocation */
				rf = fmt->f_value[i];
				mask = BITMASK(rf);
				n = ((n & mask) << rf) | ((n >> rf) & mask);
				}

			assemble(n, fmt->f_width[i]);
			continue;
			}

							/* constant field */
		if (n == '#')  {
			reloc = RABS;
			assemble(fmt->f_value[i], fmt->f_width[i]);
			continue;
			}

			/* next n bits of opcode */
		if (n == 'n')  {
			reloc = RABS;
			rf = fmt->f_width[i];
			mask = BITMASK(rf);
			assemble(op & mask, rf);
			op =>> rf;
			continue;
			}



		/*  should never happen - but ... */

		printf("corrupted format descriptor %c\n", n);
		exit(1);

		}

	return;
}