{LispCADR.mc
cal:  18-Dec-84 10:12:24
}

{
	SUBROUTINE: takes VA of CONS cell, returns CAR and CDR of cell
	Rx has lo bits of VA of cell
	TT has hi bits of VA of cell
	L3 used for return thru CADRret
	trashes Q, L0, L1, rhRx, rhTT
	trashes uRx, uhiVA, UQSave
	returns:
		TT has hi bits of CDR of cell
		Rx has lo bits of CDR of cell
		uCARlo has lo bits of CAR of cell
		uCARhi has hi bits of CAR of cell
	will ufnX if VA not type list
	will pagefault {NoFixes} if cell page faults

}
CADR:
	uRx ← Rx,	c1;{uRx ← lo bits of cell VA}
	Ybus ← TT or Rx, NZeroBr,	c2;
	rhRx ← crhTypeTable, BRANCH[lccellnil, $],	c3;

	MAR ← Rx ← [Rx, TT + 0],	c1;{byte merge}
	Rx ← Rx LRot8,	c2;
	Rx ← Rx RShift1, getTypemsBit,	c3;

	MAR ← [rhRx, Rx + 0], L1 ← L1.NoFixes,	c1;{type table fetch}
	Rx ← ListType,	c2;
	Rx ← MD xor Rx, L0 ← L0.RedoCADR,	c3;

	Ybus ← Rx - 1, PgCarryBr,	c1;{test if tos is type list}
	rhTT ← TT LRot0, BRANCH[$, lcnotlist],	c2;
	TT ← uRx,	c3;{lo bits of cell VA}

lcmapagain:
	Map ← [rhTT, TT],	c1;
	uRx ← TT,	c2;{uRx ← lo bits of cell VA}
	rhRx ← Rx ← MD, XRefBr,	c3;

	BRANCH[lcremap, $],	c1, at[L0.RedoCADR, 10, RxMapFixCaller];
	Q ← rhTT,	c2;
	uhiVA ← Q,	c3;{uhiVA ← hi bits of cell VA}

	MAR ← Q ← [rhRx, TT + 0],	c1;
	UQSave ← Q,	c2;{UQSave ← low 16 bits cell RA}
	rhTT ← TT ← MD,	c3;{high 16 bits cell contents}

	MAR ← [rhRx, Q + 1],	c1;
	Rx ← TT LRot8, CANCELBR[$, 2],	c2;{low 8 bits of Rx are cell cdrcode}
	Q ← MD,	c3;{low 16 bits cell contents}

	Ybus ← Rx - 1, PgCarryBr,	c1;{test if cdrcode = 0 : indirect}
	BRANCH[lcindir, lcdir],	c2;
lcindir:
	TT ← Q, GOTO[lcmapagain],	c3;
lcdir:
	uCARlo ← Q,	c3;

	Q ← rhTT,	c1;
	uCARhi ← Q,	c2;
	Xbus ← Rx LRot0, XLDisp,	c3;{test 200'b bit of cdrcode}

	Rx ← LShift1 (Rx and 07F), BRANCH[lcsmallcdrcode, lcbigcdrcode, 1],	c1;

		{cdr code >= 200'b}
lcbigcdrcode:
	Ybus ← Rx, ZeroBr,	c2;{test for cdrcode nil}
	TT ← uRx, BRANCH[$, lccdrnil],	c3;{low 16 bits cell VA}

	MAR ← TT ← [TT, Rx + 0],	c1;{byte merge}
	Rx ← TT, L3Disp,	c2;{lo bits of CDR}
	TT ← uhiVA, RET[CADRret],	c3;{hi bits of CDR}

		{cdr code < 200'b}
lcsmallcdrcode:
	,	c2;
	TT ← UQSave,	c3;{low 16 bits cell RA}

	MAR ← TT ← [TT, Rx + 0],	c1;{byte merge}
	Rx ← TT,	c2;
	,	c3;

	MAR ← [rhRx, Rx + 0], L2 ← 3,	c1;{fetch contents of cdrcoded cell}
	,	c2;
	TT ← MD,	c3;{hi bits of CDR}

	MAR ← [rhRx, Rx + 1],	c1;
	TT ← TT and 0FF, L3Disp, CANCELBR[$, 2],	c2;
	Rx ← MD, RET[CADRret],	c3;{lo bits of CDR}

lccellnil:
	TT ← 0, uCARlo ← 0,	c1;
	Rx ← 0, uCARhi ← 0, L3Disp,	c2;
	RET[CADRret],	c3;

lccdrnil:
	Rx ← 0,	c1;
	TT ← 0, L3Disp,	c2;
	RET[CADRret],	c3;

lcremap:
	GOTO[RLxMapFix],	c2;

lcnotlist:
	GOTO[ufnX1],	c3;

	{ E N D }