DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T i

⟦5550c1654⟧ TextFile

    Length: 6270 (0x187e)
    Types: TextFile
    Names: »instructions.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/asm/instructions.c« 

TextFile

#include "asm.h"

int choiceinstr (ins)
	int ins;
{
	choicedef *chpt;
	int num, i, fits;
	Long value;
	static char *opdpt;

	if (label && *label)
		insert (label, (long) lc, &o_none, curseg, NO);
	chpt = (choicedef *)optab[ins].class;
	num = chpt->field;
	for (opdpt = opd; num > 1; num --) {
		opdpt = index (opdpt, ',');
		if (opdpt == NULL) {
			reporterr (E_NOPS);
			return (0);
		}
		opdpt++;
	}
	value = expr (&opdpt, &i, YES);
	fits = i ? NO :
		(value >= chpt->lorange &&
		 value <= chpt->hirange &&
		 curseg == exprseg);
	if ((i = opsrch ((fits ? chpt->rname : chpt->nname),
					     optab, instrlen)) >= 0) {
		(optab[i].action) (i);
	} else {
		reporterr (E_ILLOP);
	}
	return (0);
}


int geninstr (ins)
	int ins;
{
	static Acc cons = ~0L;
	int nargs, length, i, j, k;
	opdclass *oclass;
	insclass *iclass;
	Word itemtemp, obuf[MAXBYTPERINS];
	Acc mask;
	char *nextopd;
	itemu item;

	if (label && *label)
		insert (label, (long) lc, &o_none, curseg, NO);
	iclass = optab[ins].class;
	length = iclass->length;
	if (pass == 2) {
		nargs = iclass->mopds;
		for (i = 0; i < MAXBYTPERINS; i++)
			obuf[i] = 0;
		item.l = optab[ins].mask;
		for (i = 0; i < MINBYTES; i++)
			obuf[i] = item.s[i];
		item.l = 0L;
		nextopd = opd;
		for (j = 0; j < nargs; j++) {
			if (j != 0) {
				if (*nextopd != ',') {
					reporterr (E_NOPS);
				} else {
					nextopd++;
				}
			}
			oclass = iclass->type[j];
			item.l = expr (&nextopd, &ignerr, NO) + oclass->offset -
				(oclass->relative ? lc : 0);
			mask = cons >> (LONGLEN - oclass->length);
			if (item.l < 0L && !oclass->signed)
				reporterr (E_NEG);
			if (((item.ls < 0L && oclass->signed) ? -item.ls : item.ls) & ~mask)
				reporterr (E_TOOBIG);
			item.l &= mask;
			if (oclass->byteswapped) {
				itemtemp = item.s[BYTPERLONG - 2];
				item.s[BYTPERLONG - 2] = item.s[BYTPERLONG - 1];
				item.s[BYTPERLONG - 1] = itemtemp;
			}
			i = LONGLEN - 8 - iclass->offset[j];
			item.l <<= (i % 8);
			i /= 8;
			k = 0;
			if (i < 0)
				k = -i, i = 0;
			for (; k < MAXBYTPERINS && i < BYTPERLONG; k++, i++)
#ifdef NORMBYTE
				obuf[k] |= item.s[i];
#else
				obuf[k] |= item.s[BYTPERLONG-1-i];
#endif
		}
		if (optop) {
			optional (optop, obuf);
			free (optop);
		}
		putoutbin (obuf, length);
		listit (linecopy, lc, obuf, length);
	}
	lc += length;
	return (0);
}

long expr (string, errind, test)
	char **string;
	int *errind;
	int test;
{
	long exp, val;
	int op, err;
	int uniop = 0;
	segmnt *seg1, *seg2;

	*errind = NO;
	if (**string == '-')
		uniop = 1;
	else if (**string == '~')
		uniop = 2;
	if (uniop)
		(*string)++;
	exp = getval(string, &err, test, &seg1);
	if (err) goto errorexit;
	if (uniop == 2)
		exp = ~exp;
	else if (uniop == 1)
		exp = -exp;
	while (!isdelim(**string)) {
		if ((op = getop (string)) == NOOP) {
			if (!test) reporterr (E_EXPR);
errorexit:              for (; !isdelim (**string); *string++)  ;
			*errind = YES;
			return (0);
		}
		val = getval (string, &err, test, &seg2);
		if (err) goto errorexit;
		if (seg1 && seg2 && seg1 != seg2 && pass == 1)
			reporterr (E_SEG);
		switch (op) {
		case PLUS:
			exp += val;
			break;
		case MINUS:
			exp -= val;
			break;
		case MULT:
			exp *= val;
			break;
		case DIV:
			exp /= val;
			break;
		case MOD:
			exp %= val;
			break;
		case OR:
			exp |= val;
			break;
		case AND:
			exp &= val;
			break;
		case EXOR:
			exp ^= val;
			break;
		case SHLF:
			exp <<= val;
			break;
		case SHRT:
			exp >>= val;
			break;
		default:
			if (!test) reporterr (E_EXPR);
		}
		seg1 = seg2;
	}
	exprseg = seg1;
	return (exp);
}


/*      Snag literals and variable names. The literal classes are:

	[digit]....[digit]      unsigned decimal number
	0[hexdigit]...[hexdigit]unsigned hexadecimal number
	$                       current location counter
	'[char]                 single character, right just, zero fill
	"[char][char]           character pair

	Returns a 16 bit value. Unary operations taken care of in expr;
	byte swapping done if required by geninstr.
*/
long getval (strpt, errorret, test, segment)
	segmnt **segment;
	char **strpt;
	int *errorret;
	int test;
{
	long total;
	char name[33], *npt;
	int i;

	*segment = (segmnt *) 0;
	*errorret = 0;
	total = 0L;
	if (isdigit (**strpt)) {
		if (**strpt == '0') {
			while (isxdigit (**strpt)) {
				total *= 16;
				total += xtod (**strpt);
				(*strpt)++;
			}
		} else {
			while (isdigit (**strpt)) {
				total *= 10;
				total += (Long)(**strpt - '0');
				(*strpt)++;
			}
		}
	} else if (islabel (**strpt)) {
		npt = name;
		while (islabel (**strpt)) {
			*npt++ = **strpt;
			(*strpt)++;
		}
		*npt = '\0';
		if ((i = lookup (name)) == -1) {
			if (pass == 2)
				if (!test) reporterr (E_UNDEF);
			*errorret = 1;
			total = 0L;
		} else {
			total = symtab[i].value;
			if (pass == 2 && symtab[i].segp)
				total += (symtab[i].segp)->start;
			*segment = symtab[i].segp;
		}
	} else if (**strpt == '\'') {
		(*strpt)++;
		if (**strpt == '\\') {
			(*strpt)++;
			total = escape (strpt);
		} else {
			total = **strpt;
			(*strpt)++;
		}
	} else if (**strpt == '"') {
		(*strpt)++;
		if (**strpt == '\\') {
			(*strpt)++;
			total = escape (strpt);
		} else {
			total = **strpt;
			(*strpt)++;
		}
		total <<= 8;
		if (**strpt == '\\') {
			(*strpt)++;
			total |= escape (strpt);
		} else {
			total |= **strpt;
			(*strpt)++;
		}
	} else if (**strpt == '$') {
		total = lc;
		*segment = curseg;
		(*strpt)++;
	} else {
		if (!test) reporterr (E_EXPR);
		*errorret = 1;
	}
	return (total);
}


char escape (st)
	char **st;
{
	switch (*((*st)++)) {
	case 'b':
		return ('\b');
	case 'n':
		return ('\n');
	case 'r':
		return ('\r');
	case '^':
		return ('\033');
	case 'f':
		return ('\f');
	case 't':
		return ('\t');
	case '?':
		return ('\177');
	case '\\':
		return ('\\');
	default:
		(*st)--;
		if (isxdigit (**st) && isxdigit (*(*st + 1))) {
			*st += 2;
			return (xtod (*(*st - 2)) << 4 | xtod (*(*st - 1)));
		} else {
			return (*(*st++));
		}
	}
}


int xtod (c)
	char c;
{
	return ((int) c - (c > '9' ? (c > 'F' ? 'W' : '7') : '0'));
}


int getop (string)
	char **string;
{
	static char ops[] = OPSTRING;
	char *k;

	for (k = ops; *k; k++)
		if (*k == **string) {
			(*string)++;
			return ((int) (k - ops));
		}
	(*string)++;
	return (NOOP);
}