{Xufn.mc
last edit by cal:  31-Aug-83 10:13:58
}

{**************************}
{caution some opcodes abort to ufn after ←ib}
{MacroDef[ufn,  (  Rx ← #1'b, GOTO[ufn2], c1, at[Add[#1'b, OpcodeBase]])];}

ufnX1:	c1;
ufnX2:	c2;
ufnX3:	S ← S + 1,	c3;

	MAR ← [rhPC, PC + 0], XC2npcDisp,	c1;
	Rx ← 0FF, BRANCH[ufnLoByte, ufnHiByte, 0E],	c2;
ufnLoByte:
	Rx ← MD and Rx, GOTO[UFN],	c3;
ufnHiByte:
	TT ← MD,	c3;

	TT ← TT and ~Rx,	c1;
	Rx ← TT LRot8,	c2;
	GOTO[UFN],	c3;

ufn1:	Noop, CANCELBR[ufn2, 0F],	c1;
ufn2:	Noop, CANCELBR[ufn3, 0F],	c2;
ufn2incS:	S ← S + 1, CANCELBR[ufn3],	c2;
ufn2inc2S:	S ← S + 2, CANCELBR[ufn3],	c2;
ufn2inc3S:	S ← S + 3, CANCELBR[ufn3],	c2;
ufn3:	S ← S + 1,	c3;

UFN: {(S) Flush top of  stack}	{S:evenEmpty}
	MAR ← [rhS, S], S ← S + 1,	c1;
	MDR ← TOSH,  rhTT ← UFNspace{STATSspaceReal}, CANCELBR[$, 2], WriteOK,	c2;
	TT ← (uUFNTableBaseHalf or Rx) LShift1,	c3;

	Map ← Q ← [rhTT, TT + 0],	c1;
	Noop,	c2;
	rhTT ← TT ← MD, {RefBr,}	c3;

	MAR ← [rhS, S + 0],	c1;
	MDR ← TOS, TOS ← ib,	c2;
	S ← S + 2,	c3;

fnUT: {fetch from ufnTable}	{S:oddEmpty}

	MAR ← [rhTT, Q + 1],	c1;
	Rx ← smallpl, CANCELBR[$, 2],	c2;
	TOSH{ibs} ← rhTOSH{args} ← MD,	c3;

	MAR ← [rhTT, Q + 0],	c1;
	S ← S, Xbus ← TOSH{ibs} LRot8, XDisp,	c2;
	TT{deflo} ← MD, DISP4[ufns, 0C], L3{ibs} ← 0C,	c3;

ufnIB: {optionally, push ib or ib,ib;  TOS{ib}, Rx{smallpl}}	{S:oddEmpty}

	MAR ← [rhS, S - 1], GOTO[ufn12],	c1, at[0D, 10, ufns];
	MAR ← [rhS, S - 1], GOTO[ufn12],	c1, at[0E, 10, ufns];
ufn12:	MDR ← Rx{smallpl}, PC ← PC, CANCELBR[$, 2],	WriteOK, c2;
	Rx ← TOS LRot8, L3Disp,	c3;

	MAR ← S ← [rhS, S + 0], BRANCH[ufn1ib, ufn2ib, 0D],	c1;
ufn1ib:	MDR ← TOS, WriteOK, CANCELBR[ufnJoin, 2],	c2;
ufn2ib:	MDR ← Rx or ib, WriteOK, CANCELBR[ufnJoin, 2],	c2;{%%}
ufnJoin:	S ← S + 2,	c3;

ufnIV: {iVar (new) stored as end of old frame}	{S:oddEmpty}

apply1:	Noop,	c1, at[0C, 10, ufns];
	Noop,	c2;
	TOSH{args2} ← rhTOSH{args} LShift1,	c3;

apply2:	MAR ← [rhPV, PV - 6],	c1;
	MDR ← TOSH{iVar} ← S - TOSH{arg2} - 1, BRANCH[$, SCar9, 1],	c2;
SC9Cont:	TT ← TT + TT, rhTT ← DEFspace, GOTO[fnMD],	c3;

{except}	Q ← 51'd, CANCELBR[sink2, 3],	c1, at[0F, 10, ufns];{MP9051}

	{ E N D }