{File name TripleCheck.mc
Description:  DandeLion InterLisp Emulator TripleCheck
Charnley  15-Jan-85 10:29:44  Created
}

{	uses opcode 373'b  alpha = 5  ( FLOATARRAY2 5)
}

{	called   (TRIPLECHECK Src1 Src2 Src3 WCount)

	if WCount = 0 then return( NIL )
	loop:	if NOT( [Src1 + WCount - 1] = [Src2 + WCount - 1] = [Src3 + WCount - 1] ) then WCount ← WCount - 1, loop
	return( WCount )
}

{Set[L2.Triple, 5];

Set[L0.trS2i, 1];
Set[L0.trS1i, 2];
Set[L0.trDi, 3];
Set[L0.trS2, 4];
Set[L0.trS1, 5];
Set[L0.trD, 6];
}

	GOTO[FLOATARRAYPREP],	c3, at[L2.Triple, 10, FOP2Disp];{Triple}

{
	has already saved
		uTOSH ← TOSH
		uTOS ← TOS
	saves regs:
		uS ← S
		uPVx ← PV
		uPC ← PC
		urhS ← rhS
		urhPV ← rhPV

	gets stk-1, stk-2, stk-3
		stk-3 (first arg)
			uS2Hi, uS2Lo
		stk-2 (second arg)
			uS1Hi, uS1Lo
		stk-1 (third arg)
			uDHi, uDLo
}
	
	at[L2.Triple, 10, LFAop],{FOP2 = Triple}
	Q ← TOS - 1, L1 ← L1.RestoreTosB2,	c1;
	TT ← uS2Lo,	c2;
	TT ← TT + Q, CarryBr,	c3;

	uS2Lo ← TT, BRANCH[$, trfixS2hi],	c1;
trS2:	TT ← uS1Lo,	c2;
	TT ← TT + Q, CarryBr,	c3;

	uS1Lo ← TT, BRANCH[$, trfixS1hi],	c1;
trS1:	TT ← uDLo,	c2;
	TT ← TT + Q, CarryBr,	c3;

	uDLo ← TT, BRANCH[$, trfixDhi],	c1;
trD:	,	c2;
	GOTO[TrMapInit],	c3;

trfixS2hi:
	TT ← uS2Hi,	c2;
	TT ← TT + 1,	c3;

	uS2Hi ← TT, GOTO[trS2],	c1;

trfixS1hi:
	TT ← uS1Hi,	c2;
	TT ← TT + 1,	c3;

	uS1Hi ← TT, GOTO[trS1],	c1;

trfixDhi:
	TT ← uDHi,	c2;
	TT ← TT + 1,	c3;

	uDHi ← TT, GOTO[trD],	c1;

TrMapInit:
	TT ← uS2Hi, L0 ← L0.trS2i,	c1;
	rhTT ← TT LRot0,	c2;
	TT ← uS2Lo, CALL[TrMap],	c3;

	at[L0.trS2i, 10, TrMapRet],
	Q ← rhRx,	c1;
	rhS2 ← Q LRot0,	c2;
	S2 ← Rx,	c3;

	MAR ← S2 ← [rhS2, TT + 0],	c1;
	,	c2;
	Q ← MD,	c3;

	UQSave ← Q,	c1;
	,	c2;
	,	c3;

	TT ← uS1Hi, L0 ← L0.trS1i,	c1;
	rhTT ← TT LRot0,	c2;
	TT ← uS1Lo, CALL[TrMap],	c3;

	at[L0.trS1i, 10, TrMapRet],
	Q ← rhRx,	c1;
	rhS1 ← Q LRot0,	c2;
	S1 ← Rx,	c3;

	MAR ← S1 ← [rhS1, TT + 0],	c1;
	Q ← UQSave,	c2;
	Q ←MD xor Q,	c3;

	,	c1;
	Ybus ← Q, ZeroBr,	c2;
	BRANCH[TrEarlya, $],	c3;

	TT ← uDHi, L0 ← L0.trDi,	c1;
	rhTT ← TT LRot0,	c2;
	TT ← uDLo, CALL[TrMap],	c3;

	at[L0.trDi, 10, TrMapRet],
	Q ← rhRx,	c1;
	rhD ← Q LRot0,	c2;
	D ← Rx,	c3;

	MAR ← D ← [rhD, TT + 0],	c1;
	Q ← UQSave,	c2;
	Q ←MD xor Q, GOTO[TrLoopDec],	c3;

{	inner loop}
TrLoop:
	MAR ← S2 ← [rhS2, S2 - 1], L0 ← L0.trS2,	c1;
TrMapS2RetX:
	Ybus ← Q, ZeroBr, BRANCH[$, TrfixS2, 1],	c2;
	Q ← MD, BRANCH[TrEarly2, $],	c3;

	MAR ← S1 ← [rhS1, S1 - 1], L0 ← L0.trS1,	c1;
TrMapS1RetX:
	BRANCH[$, TrfixS1, 1],	c2;
	Q ← MD xor Q,	c3;

	MAR ← D ← [rhD, D - 1], L0 ← L0.trD,	c1;
TrMapDRetX:
	Ybus ← Q, ZeroBr, BRANCH[$, TrfixD, 1],	c2;
	Q ← MD xor Q, BRANCH[TrEarly1, TrLoop],	c3;

TrLoopDec:
	TOS ← TOS - 1, ZeroBr,	c1;
	uTOS ← TOS, BRANCH[$, TrDone],	c2;
	GOTO[TrLoop],	c3;

	{Early (mismatch) exits here}
TrEarly1:
	TOS ← TOS,	c1;
	Q ← smallpl,	c2;
	uTOSH ← Q, L1 ← L1.LFAexit, GOTO[TrExit],	c3;

TrEarly2:
	TOS ← TOS + 1,	c1;
	Q ← smallpl,	c2;
	uTOSH ← Q, L1 ← L1.LFAexit, GOTO[TrExit],	c3;

TrEarlya:
	TOS ← TOS,	c1;
	Q ← smallpl,	c2;
	uTOSH ← Q, L1 ← L1.LFAexit, GOTO[TrExit],	c3;

TrEarlyc:
	,	c3;

	TOS ← TOS + 1,	c1;
	Q ← smallpl,	c2;
	uTOSH ← Q, L1 ← L1.LFAexit, GOTO[TrExit],	c3;

TrDone:
	,	c3;

	Ybus ← Q, ZeroBr,	c1;
	BRANCH[TrEarlyc, $],	c2;
	uTOSH ← 0, L1 ← L1.LFAexit, GOTO[TrExit],	c3;

TrfixS2:
	S2 ← rhS2, CANCELBR[$],	c3;

	TT ← uS2Lo,	c1;
	rhTT ← S2 LRot0,	c2;
	CALL[TrMap],	c3;

	at[L0.trS2, 10, TrMapRet],
	MAR ← S2 ← [rhS2, 0FF + 0], GOTO[TrMapS2RetX],	c1;

TrfixS1:
	S1 ← rhS1, CANCELBR[$],	c3;

	TT ← uS1Lo,	c1;
	rhTT ← S1 LRot0,	c2;
	CALL[TrMap],	c3;

	at[L0.trS1, 10, TrMapRet],
	MAR ← S1 ← [rhS1, 0FF + 0], GOTO[TrMapS1RetX],	c1;

TrfixD:
	D ← rhD, CANCELBR[$],	c3;

	TT ← uDLo,	c1;
	rhTT ← D LRot0,	c2;
	CALL[TrMap],	c3;

	at[L0.trD, 10, TrMapRet],
	MAR ← D ← [rhD, 0FF + 0], GOTO[TrMapDRetX],	c1;

TrMap:
	Map ← [rhTT, TT],	c1;
	,	c2;
	Rx ← rhRx ← MD, XwdDisp,	c3;

	Map ← [rhTT,TT], DISP2[TrFixRFlags],	c1;

	MDR ← Rx or 10, L0Disp, GOTO[TrReRead],	c2, at[0, 4, TrFixRFlags];
	MDR ← Rx or 10, L0Disp, GOTO[TrReRead],	c2, at[1, 4, TrFixRFlags];
	MDR ← Rx or 10, L0Disp, GOTO[TrReRead],	c2, at[2, 4, TrFixRFlags];
	GOTO[RWTrapB2],	c2, at[3, 4, TrFixRFlags];

TrReRead:	RET[TrMapRet],	c3;

	{when completed come here for restoring regs}
	{set uTOSH to value desired in TOSH}
	{set TOS to value desired in TOS}
	{when completed, set L1 = L1.LFAexit}

TrExit:
	Q ← 6{delta stk}, GOTO[LFACommonExit],	c1;


	{ E N D }