{File name NewLFAB2.mc
Description:  DandeLion InterLisp Emulator LispFloatArray
Author: Charnley
Last modified: Charnley                11-Jul-84 15:42:40
Created:   8-Jun-84 10:04:55
}


{- - - - - - - - - - - - - - - - - - - - - - - - - -
372      FLOATARRAY1
	called with      Source  Dest  Count
	all operations performed for n = 0 to Count-1
	  0  EXP   dest[n] ← Exp[Source[n]] {3 clicks per}
	  1  MAG  Dest[i] ← #Source[2*n]↑2 + #Source[(2*n)+1]↑2 {10 clicks per}{pipe}
	  2  FLOAT  Dest[i] ← Float[source[n]] {5 clicks per}
	  3  COMPLEX  #Dest[2 * n] ← Source[n], #Dest[(2 * n) + 1] ← 0.0 {6 clicks per}
	 return[Count = 0]
		# means quadword alligned {actually, a complex array}
		Source means 32 bit quantity, source means 16 bit quantity
		Dest means 32 bit quantity, dest means 16 bit quantity

 373      FLOATARRAY2
	called with      Source2  Source1  Dest  Count
	all operations performed for n = 0 to Count-1
	  0  TIMES   Dest[n] ← Source1[n] * Source2[n] {7 clicks per}
	  1  PERM  dest[n] ← source2[source1[n] ] {6 clicks per}
	  2  PLUS   Dest[n] ← Source1[n] + Source2[n] {7 clicks per}
	  3  DIFFERENCE   Dest[n] ← Source1[n] - Source2[n] {7 clicks per}
	 return[Count = 0]
	  4  MAGIC    {16 clicks per}  all numbers below are floating point
		D(n.0)  ←  S1(n.0) + S2(-n.0)  {alpha + beta}
		D(n.1)  ←  S1(n.1) - S2(-n.1)    {gamma - delta}
		D(n.2)  ←  S1(n.1) + S2(-n.1)  {gamma + delta}
		D(n.3)  ←  S1(n.0) - S2(-n.0)    {alpha - beta}

- - - - - - - - - - - - - - - - - - - - - - - - - -}



@NOLABEL:
{@FLOATARRAY1:	{opcode[372'b],}
	Bank ← FAOPBank, L1 ← 4{L1.LFA1prep},,	c1;
	uTOS ← TOS,	c2;
	uTOSH ← TOSH, CROSS[FOP1],	c3;}

	at[FOP1],

	Xbus ← ibNA, XDisp,	c1;
	DISP4[FOP1Disp],	c2;
	
	L2 ← 08,			c3, at[0, 10, FOP1Disp];{EXP}
	
	GOTO[FLOATARRAYPREP1],		c1;
	
	L2 ← 0B,			c3, at[3, 10, FOP1Disp];{COMPLEX}
	
	GOTO[FLOATARRAYPREP1],		c1;

	L2 ← 0A,			c3, at[2, 10, FOP1Disp];{FLOAT}
	
	GOTO[FLOATARRAYPREP1],		c1;

	L2 ← 09,			c3, at[1, 10, FOP1Disp];{MAG}
	
	GOTO[FLOATARRAYPREP1],		c1;


{@FLOATARRAY2:	opcode[373'b],
	Bank ← FAOPBank, L1 ← 3{L1.LFA2prep},	c1;
	uTOS ← TOS,	c2;
	uTOSH ← TOSH, CROSS[FOP2],	c3;}

	at[FOP2],
	Xbus ← ibNA, XDisp,	c1;
	DISP4[FOP2Disp], L2 ← 0,	c2;

	GOTO[FLOATARRAYPREP],	c3, at[L2.perm, 10, FOP2Disp];{PERM}
	GOTO[FLOATARRAYPREP],	c3, at[L2.Xplus, 10, FOP2Disp];{PLUS}
	GOTO[FLOATARRAYPREP],	c3, at[L2.minus, 10, FOP2Disp];{MINUS}
	GOTO[FLOATARRAYPREP],	c3, at[L2.Xtimes, 10, FOP2Disp];{TIMES}

FLOATufn:	GOTO[ufnX22],	c1;

FLOATARRAYPREP:
	,	c1;
	{save regs}
FLOATARRAYPREP1:

	CALL[LFASaveRegsHere],	c2;

LFASaveRegsHere:
	uS ← S, S ← rhS,	c*;{c3}
	urhS ← S,	c*;{c1}
	uPVx ← PV, PV ← rhPV,	c*;{c2}
	urhPV ← PV,	c*;{c3}
	uPC ← PC,	c*;{c1}
	S ← uS, L1Disp,	c2;

	S ← S - 4, DISP4[LFASaveRegsRet]	c3;

	{fetch second source addr}
	MAR ← [rhS, S + 0],	c1, at[L1.LFA2prep, 10, LFASaveRegsRet];
	,	c2;
	Stemp{S2Lo} ← MD,	c3;

	MAR ← [rhS, S - 1],	c1;
	uS2Lo ← Stemp, CANCELBR[$ ,2]	c2;
	Stemp{S2Hi} ← MD,	c3;

	{fetch first source addr}
	MAR ← S ← [rhS, S + 2],	c1, at[L1.LFA1prep, 10, LFASaveRegsRet];
fixSAret:
	uS2Hi ← Stemp, BRANCH[$, fixSA, 1],	c2;
	Stemp{S1Lo} ← MD,	c3;

	MAR ← [rhS, S - 1],	c1;
	uS1Lo{S1Lo} ← Stemp, CANCELBR[$, 2],	c2;
	Stemp{S1Hi} ← MD,	c3;

	{fetch dest addr}
	MAR ← S ← [rhS, S + 2],	c1;
fixSBret:
	uS1Hi{S1Hi} ← Stemp, BRANCH[$, fixSB, 1],	c2;
	Stemp{DLo} ← MD,	c3;

	MAR ← [rhS, S - 1],	c1;
	uDLo{DLo} ← Stemp, CANCELBR[$, 2],	c2;
	Stemp{DHi} ← MD,	c3;

	uDHi{DHi} ← Stemp,	c1;
	L2Disp, FloatNop,	c2;{clear any pending floating unloads}
	DISP4[LFAop], FloatNop,	c3;

fixSA:
	S ← S + 0FF + 1,	c3;

	MAR ← S ← [rhS, S + 0], GOTO[fixSAret],	c1;

fixSB:
	S ← S + 0FF + 1,	c3;

	MAR ← S ← [rhS, S + 0], GOTO[fixSBret],	c1;


{	TIMES
}

	at[L2.Xtimes, 10, LFAop],{FOP2 = TIMES}
	GOTO[LFA2genl],	c1;

	at[L2.Xplus, 10, LFAop],{FOP2 = PLUS}
	GOTO[LFA2genl],	c1;

	at[L2.minus, 10, LFAop],{FOP2 = MINUS}
	GOTO[LFA2genl],	c1;

LFA2genl:
	D ← 0{cause immediate remap}, L0 ← L0.S1init2,	c2;

	{map S1}
	{S1 even, init at Kount}
	Zimph ← LShift1 (Kount - 1), SE ← 0, CALL[LFAremapS1],	c3;

	at[L0.S1init2, 10, LFAremapS1ret],
	FloatMode.RN.AI.FAST, FloatFLOW, 	c2;
	FloatAB{S1Hi} ← MD,	c3;

	MAR ← [rhS1, S1 + 1], 	c1;
	S2 ← 0{cause immediate remap}, CANCELBR[$, 2], L2Disp,	c2;
	FloatAB{S1Lo} ← MD, DISP2[TIMESop],	c3;

{TIMESloop:}
	at[L2.Xtimes, 4, TIMESop],
	MAR ← S2 ← [rhS2, S2 - Q{2}], L0 ← L0.S2timeslooptimes, LOOPHOLE[pci],	c1;
	BRANCH[TIMEStimesS2Remap, $, 1],	c2;
TIMEStimesS2cont:
	FloatA{S2Hi} ← MD, FLTimes.A.B, GOTO[TIMESnext],	c3;

	at[L2.Xplus, 4, TIMESop],
	MAR ← S2 ← [rhS2, S2 - Q{2}], L0 ← L0.S2timesloopplus, LOOPHOLE[pci],	c1;
	BRANCH[TIMESplusS2Remap, $, 1],	c2;
TIMESplusS2cont:
	FloatA{S2Hi} ← MD, FLPlus, GOTO[TIMESnext],	c3;

	at[L2.minus, 4, TIMESop],
	MAR ← S2 ← [rhS2, S2 - Q{2}], L0 ← L0.S2timesloopminus, LOOPHOLE[pci],	c1;
	BRANCH[TIMESminusS2Remap, $, 1],	c2;
TIMESminusS2cont:
	FloatA{S2Hi} ← MD, FLAMinusB, GOTO[TIMESnext],	c3;


TIMESnext:
	MAR ← [rhS2, S2 + 1],	c1;
	CANCELBR[$, 2],  L0 ← L0.S1timesloop,	c2;
	FloatA{S2Lo} ← MD,	c3;

	MAR ← S1 ← [rhS1, S1 - Q{2}], FloatStartFlow, LOOPHOLE[pci],	c1;
	BRANCH[TIMESS1Remap, $, 1], 	c2;
TIMESS1cont:
	Stemp{S1Hi} ← MD, L2Disp,	c3;

	MAR ← [rhS1, S1 + 1], DISP2[TIMESunload],	c1;
	uStemp{S1Hi} ← Stemp, CANCELBR[$, 2],	c2, at[L2.Xtimes, 4, TIMESunload];
	Stemp{S1Lo} ← MD, FloatUnloadP, Float.M, L0 ← L0.Dtimesloop,	c3;

	uXdisp ← Stemp{S1Lo},	c1;
	,	c2;
	FloatUnloadP, Float.L, GOTO[BOTHnext],	c3;

	uStemp{S1Hi} ← Stemp, CANCELBR[TIMESpluscomm, 2],	c2, at[L2.minus, 4, TIMESunload];
	uStemp{S1Hi} ← Stemp, CANCELBR[TIMESpluscomm, 2],	c2, at[L2.Xplus, 4, TIMESunload];
TIMESpluscomm:
	Stemp{S1Lo} ← MD, FloatUnloadS, Float.M, L0 ← L0.Dtimesloop,	c3;

	uXdisp ← Stemp{S1Lo},	c1;
	,	c2;
	FloatUnloadS, Float.L, GOTO[BOTHnext],	c3;

BOTHnext:
	MAR ← D ← [rhD, D - 2], 	c1;
	MDR ← Stemp ← FloatResult{DHi}, BRANCH[$, TIMESDRemap, 1],	c2;
TIMESDcont:
	,	c3;

	MAR ← [rhD, D + 1],	c1;
	MDR ← FloatResult{DLo}, CANCELBR[$, 2], LOOPHOLE[wok],	c2;
	FloatAB{S1Hi} ← uStemp,	c3;

	Kount ← Kount - 1, ZeroBr,	c1;
	{uStemp{S1Lo} ← Stemp, }BRANCH[$, TIMESend], L2Disp,	c2;
	FloatAB{S1Lo} ← uXdisp{uStemp}, DISP2[TIMESop],	c3;

TIMEStimesS2Remap:
	{S2 even, at Kount}
	Zimph ← LShift1 Kount - 1, SE ← 0, CALL[LFAremapS2],	c3;

	GOTO[TIMEStimesS2cont],	c2, at[L0.S2timeslooptimes, 10, LFAremapS2ret];

TIMESplusS2Remap:
	{S2 even, at Kount}
	Zimph ← LShift1 Kount - 1, SE ← 0, CALL[LFAremapS2],	c3;

	GOTO[TIMESplusS2cont],	c2, at[L0.S2timesloopplus, 10, LFAremapS2ret];

TIMESminusS2Remap:
	{S2 even, at Kount}
	Zimph ← LShift1 Kount - 1, SE ← 0, CALL[LFAremapS2],	c3;

	GOTO[TIMESminusS2cont],	c2, at[L0.S2timesloopminus, 10, LFAremapS2ret];

TIMESS1Remap:
	{S1 even, at Kount - 1}
	,	c3;

	Zimph ← Kount - 2, CarryBr, L0 ← L0.S1timesloop,	c1;
	Zimph ← LShift1 Zimph, BRANCH[TIMESS1dontremap, $],	c2;
	CALL[LFAremapS1],	c3;

TIMESS1dontremap:
	Q ← 2,	c3;
	MAR ← S1 ← [rhS1, 8 + 0],	c1;{redo mem ref and smash S1}
	GOTO[TIMESS1cont],	c2;

	GOTO[TIMESS1cont],	c2, at[L0.S1timesloop, 10, LFAremapS1ret];

TIMESDRemap:
	{D even, at Kount}
	Zimph ← LShift1 Kount - 1, SE ← 0, CALL[LFAremapD],	c3;

	MDR ← Stemp{FloatResult{DHi}}, GOTO[TIMESDcont],	c2, at[L0.Dtimesloop, 10, LFAremapDret];

TIMESend:
	Q ← 6,{ L1 = L1.LFAexit,} CANCELBR[$, 3],	c3;

	GOTO[LFACommonExit],	c1;

LFACommonExit:
	{restore regs}
	rhS ← urhS, GOTO[RestoreRegsHere1],	c2;
RestoreRegsHere:
	rhS ← urhS,	c*;{c2}
RestoreRegsHere1:
	rhPV ← urhPV,	c*;{c3}
	PV ← uPVx,	c*;{c1}
	S ←uS,	c*;{c2}
	PC ← uPC,	c*;{c3}
	{fix stack depth}
	S ← S - Q, L1Disp,	c*;{c1}
	TOSH ← uTOSH, DISP4[RestoreRegsRet],	c*;{c2}

	{remove ib byte}
	Xbus ← ib,	c3, at[L1.LFAexit, 10, RestoreRegsRet];
	{instruction dispatch}

	Bank ← EmuBank,	c1;
	PC ← PC + 1, L2 ← L2.0, IBDisp,	c2;
	L2 ← L2.0, DISPNI[OpTableB2],	c3;

LFApagefault:
	Q ← 0, L1 ← L1.LFApf, CALL[RestoreRegsHere],	c3;

	at[L1.LFApf, 10, RestoreRegsRet],
	GOTO[TrapFixesDoneB2c3],	c2;

{	end TIMES }


{	start PERM}
PERMc1:
	at[L2.perm, 10, LFAop],{FOP2 = PERM}
	S1 ← 0{cause immediate remap}, L0 ← L0.PERM,	c1;
	D ← 0{cause immediate remap}, L1 ← L1.LFAexit,	c2;
	,	c3;

{	PERM INNER LOOP
}
	{fetch offset}
PERMloop:
	MAR ← S1 ← [rhS1, S1 - 1], BRANCH[$, endPERM],	c1;
	BRANCH[$, PERMS1Remap, 1],	c2;
PERMS1cont:
	Zimph ← MD, CALL[LFAremapS2],	c3;

	,	c2, at[L0.PERM, 10, LFAremapS2ret];
	Stemp{data} ← MD,	c3;

	{store to dest}
	MAR ← D ← [rhD, D - 1],	c1;
	MDR ← Stemp, BRANCH[$, PERMDRemap, 1],	c2;
PERMDcont:
	Kount ← Kount - 1, ZeroBr, GOTO[PERMloop],	c3;

	{end PERM INNER LOOP }

PERMS1Remap:
	Zimph ← Kount - 1, SE ← 0, CALL[LFAremapS1],	c3;

	GOTO[PERMS1cont],	c2, at[L0.PERM, 10, LFAremapS1ret];

PERMDRemap:
	Zimph ← Kount - 1, SE ← 0, CALL[LFAremapD],	c3;

	MDR ← Stemp, GOTO[PERMDcont],	c2, at[L0.PERM, 10, LFAremapDret];

endPERM:
	CANCELBR[$, 3],	c2;
	Q ← 6,	c3;

	GOTO[LFACommonExit],	c1;

{	start EXP}
EXPc1:
	at[L2.exp, 10, LFAop],{FOP1 = EXP}
	S1 ← 0{cause immediate remap}, L0 ← L0.EXP,	c1;
	D ← 0{cause immediate remap}, L1 ← L1.LFAexit,	c2;
	Q ← 2,	c3;

{	EXP INNER LOOP
}

	{fetch source Hi and save}
EXPloop:
	MAR ← S1 ← [rhS1, S1 - Q{2}], BRANCH[$, EXPend], LOOPHOLE[pci],	c1;
	BRANCH[EXPS1Remap, $, 1],	c2;
EXPS1cont:
	Stemp{SHi} ← MD,	c3;

	Stemp ← LShift1 Stemp,	c1;
	Stemp ← Stemp LRot8,	c2;
	Stemp ← Stemp and 0FF,	c3;

	{store value}
	MAR ← D ← [rhD, D - 1],	c1;
	MDR ← Stemp, BRANCH[$, EXPDRemap, 1], LOOPHOLE[natc],	c2, at[L0.EXP, 10, LFAremapDret];
	Kount ← Kount - 1, ZeroBr, GOTO[EXPloop],	c3;

	{end EXP INNER LOOP}

EXPS1Remap:
	Zimph ← LShift1 Kount - 1, SE ← 0, CALL[LFAremapS1],	c3;

	GOTO[EXPS1cont],	c2, at[L0.EXP, 10, LFAremapS1ret];

EXPDRemap:
	Zimph ← Kount - 1, SE ← 0, CALL[LFAremapD],	c3;

EXPend:
	CANCELBR[$, 3],	c2;
	Q ← 4,	c3;

	GOTO[LFACommonExit],	c1;

{	start COMPLEX}
COMPLEXc1:
	at[L2.complex, 10, LFAop],{FOP1 = COMPLEX}
	S1 ← 0{cause immediate remap}, L0 ← L0.COMPLEX,	c1;
	D ← 0{cause immediate remap}, L1 ← L1.LFAexit,	c2;
	Q ← 2,	c3;


{	COMPLEX INNER LOOP
}

	{fetch source and save}
COMPLEXloop:
	MAR ← S1 ← [rhS1, S1 - Q{2}], BRANCH[$, COMPLEXend], LOOPHOLE[pci],	c1;
	BRANCH[COMPLEXS1Remap, $, 1],	c2;
COMPLEXS1cont:
	Stemp{SHi} ← MD,	c3;

	MAR ← [rhS1, S1 + 1],	c1;
	uStemp ← Stemp, CANCELBR[$, 2],	c2;
	Stemp{SLo} ← MD,	c3;

	{store into dest imaginary}
	MAR ← D ← [rhD, D - 2],	c1;
	MDR ← 0, BRANCH[$, COMPLEXDRemap, 1],	c2;
COMPLEXDcont:
	,	c3;

	MAR ← [rhD, D + 1], L0 ← L0.COMPLEXx,	c1;
	MDR ← 0, CANCELBR[$, 2], LOOPHOLE[wok],	c2;
	,	c3;

	{store into dest real}
	MAR ← D ← [rhD, D - 2],	c1;
	MDR ← uStemp, BRANCH[$, COMPLEXDxRemap, 1],	c2;
COMPLEXDxcont:
	,	c3;

	MAR ← [rhD, D + 1], L0 ← L0.COMPLEX,	c1;
	MDR ← Stemp, CANCELBR[$, 2], LOOPHOLE[wok],	c2;
	Kount ← Kount - 1, ZeroBr, GOTO[COMPLEXloop],	c3;

	{end COMPLEX INNER LOOP}
COMPLEXS1Remap:
	Zimph ← LShift1 Kount - 1, SE ← 0, CALL[LFAremapS1],	c3;

	GOTO[COMPLEXS1cont],	c2, at[L0.COMPLEX, 10, LFAremapS1ret];

COMPLEXDRemap:
	Zimph ← LShift1 Kount, SE ← 0,	c3;

	Zimph ← LShift1 Zimph - 1, SE ← 0,	c1;
	,	c2;
	CALL[LFAremapD],	c3;

	MDR ← 0, GOTO[COMPLEXDcont],	c2, at[L0.COMPLEX, 10, LFAremapDret];

	{only necessary if array not quad alligned!!}
COMPLEXDxRemap:
	Zimph ← LShift1 Kount - 1, SE ← 0,	c3;

	Zimph ← LShift1 Zimph, SE ← 0,	c1;
	,	c2;
	CALL[LFAremapD],	c3;

	MDR ← uStemp, GOTO[COMPLEXDxcont],	c2, at[L0.COMPLEXx, 10, LFAremapDret];


COMPLEXend:
	CANCELBR[$, 3],	c2;
	Q ← 4,	c3;

	GOTO[LFACommonExit],	c1;

{	start MAG}
MAGc1:
	at[L2.mag, 10, LFAop],{FOP1 = MAG}
	L0 ← L0.MAGx, FloatMode.RN.AI.FAST, FloatPIPE,	c1;
	Zimph ← LShift1 Kount, SE ← 0,	c2;
	Zimph ← LShift1 Zimph - 1, SE ← 0, CALL[LFAremapS1],	c3;

	L1 ← L1.LFAexit,	c2, at[L0.MAGx, 10, LFAremapS1ret];
	FloatAB{IHi} ← MD, FLTimes.A.B,	c3;

	MAR ← [rhS1, S1 + 1],	c1;
	CANCELBR[$, 2],	c2;
	FloatAB{ILo} ← MD,	c3;

	MAR ← S1 ← [rhS1, S1 - Q{2}], LOOPHOLE[pci],	c1;
	CANCELBR[$, 2],	c2;
	FloatAB{RHi} ← MD, FLTimes.A.B,	c3;

	MAR ← [rhS1, S1 + 1],	c1;
	CANCELBR[$, 2],	c2;
	FloatAB{RLo} ← MD,	c3;

	D ← 0, FloatPump,	c1;
	L0 ← L0.MAG, FloatPump,	c2;
	FloatPump,	c3;

	FloatPump,	c1;
	FloatPump, FloatUnloadP, Float.M, GOTO[MAGstart],	c2;


{	MAG INNER LOOP
}

MAGloop:
	{get imaginary and put to chip}
	MAR ← S1 ← [rhS1, S1 - Q{2}], BRANCH[$, MAGend], LOOPHOLE[pci],	c1;
	Stemp ← FloatResult, BRANCH[MAGS1Remap, $, 1],	c2;
MAGS1cont:
	FloatAB{IHi} ← MD, FLTimes.A.B,	c3;

	MAR ← [rhS1, S1 + 1],	c1;
	CANCELBR[$, 2],	c2;
	FloatAB{ILo} ← MD, 	c3;

	{get real and put to chip}
	MAR ← S1 ← [rhS1, S1 - Q{2}], LOOPHOLE[pci],	c1;
	CANCELBR[$, 2],	c2;
	FloatAB{RHi} ← MD, FLTimes.A.B,	c3;

	MAR ← [rhS1, S1 + 1],	c1;
	CANCELBR[$, 2],	c2;
	FloatAB{RLo} ← MD,	c3;

	,	c1;
	,	c2;
	FloatPump,	c3;

	MAR ←D ← [rhD, D - 2],	c1;
	MDR ← uStemp, BRANCH[$, MAGDRemap, 1], FloatPump,	c2;
MAGDcont:
	FloatPump,	c3;

	MAR ← [rhD, D + 1], FloatPump,	c1;
	MDR ← Stemp, CANCELBR[$, 2], LOOPHOLE[wok], FloatPump, FloatUnloadP, Float.M,	c2;
MAGstart:
	FloatPump, FloatUnloadP, Float.L,	c3;

	FloatAB ← FloatResult, FloatUnloadP, Float.M,	c1;
	FloatAB ← FloatResult, FloatUnloadP, Float.L,	c2;
	FloatA ← FloatResult, FLPlus,	c3;

	FloatA ← FloatResult,	c1;
	FloatPump,	c2;
	FloatPump,	c3;

	FloatPump,	c1;
	FloatPump,	c2;
	FloatPump,	c3;

	FloatPump,	c1;
	FloatUnloadS, Float.M,	c2;
	FloatUnloadS, Float.L,	c3;

	Stemp ← FloatResult,	c1;
	uStemp ← Stemp,	c2;
	Kount ← Kount - 1, ZeroBr, GOTO[MAGloop],	c3;

	{end MAG INNER LOOP}
MAGS1Remap:
	Zimph ← LShift1 Kount,	c3;

	Zimph ← LShift1 Zimph - 1,	c1;
	,	c2;
	CALL[LFAremapS1],	c3;

	GOTO[MAGS1cont],	c2, at[L0.MAG, 10, LFAremapS1ret];

MAGDRemap:
	Zimph ← LShift1 Kount, SE ← 0, CALL[LFAremapD],	c3;

	MDR ← uStemp, GOTO[MAGDcont],	c2, at[L0.MAG, 10, LFAremapDret];

MAGDxRemap:
	{D even, at Kount}
	Zimph ← 0, SE ← 0, CALL[LFAremapD],	c3;

	MDR ← uStemp, GOTO[MAGDxcont],	c2, at[L0.MAGx, 10, LFAremapDret];

MAGend:
	Stemp ← FloatResult, CANCELBR[$, 3],	c2;
	L0 ← L0.MAGx,	c3;

	MAR ← D ← [rhD, D - 2],	c1;
	MDR ← uStemp, BRANCH[$, MAGDxRemap, 1],	c2;
MAGDxcont:
	,	c3;

	MAR ← [rhD, D + 1],	c1;
	MDR ← Stemp, CANCELBR[$, 2], LOOPHOLE[wok],	c2;
	,	c3;

	Q ← 4, GOTO[LFACommonExit],	c1;



{	start FLOAT}
FLOATc1:
	at[L2.float, 10, LFAop],{FOP1 = FLOAT}
	L0 ← L0.FLOATx, FloatMode.RN.AI.FAST, FloatFLOW,	c1;
	ufloat ← 0, L1 ← L1.LFAexit,	c2;
	Zimph ← Kount - 1, SE ← 0, CALL[LFAremapS1],	c3;

	FloatAB{Hi} ← ufloat, FLFloatA,	c2, at[L0.FLOATx, 10, LFAremapS1ret];
	FloatAB{Lo} ← MD,	c3;

	FloatStartFlow,	c1;
	D ← 0,	c2;
	L0 ← L0.FLOAT,	c3;

	,	c1;{pause to allow chips to calc}
	,	c2;
	,	c3;


{	FLOAT INNER LOOP
}

FLOATloop:
	FloatUnloadS, Float.M, BRANCH[$, FLOATend],	c1;
	FloatUnloadS, Float.L,	c2;
	Stemp ← FloatResult,	c3;

	uS2Hi ← Stemp,	c1;
	Stemp ← FloatResult,	c2;
	uS2Lo ← Stemp, 	c3;

	MAR ← S1 ← [rhS1, S1 - 1],	c1;
	FloatAB ← ufloat, FLFloatA, BRANCH[$, FLOATS1Remap, 1],	c2;
FLOATS1cont:
	FloatAB{Lo} ← MD,	c3;

	MAR ← D ← [rhD, D - 2],	c1;
	MDR ← uS2Hi, BRANCH[$, FLOATDRemap, 1],	c2;
FLOATDcont:
	FloatStartFlow,	c3;

	MAR ← [rhD, D + 1],	c1;
	MDR ← uS2Lo, CANCELBR[$, 2], LOOPHOLE[wok],	c2;
	Kount ← Kount - 1, ZeroBr, GOTO[FLOATloop],	c3;

	{end FLOAT INNER LOOP}

FLOATS1Remap:
	,	c3;

	Zimph ← Kount - 2, CarryBr,	c1;
	BRANCH[FLOATS1dontremap, $],	c2;
	CALL[LFAremapS1],	c3;

FLOATS1dontremap:
	Q ← 2,	c3;
	MAR ← S1 ← [rhS1, 8 + 0],	c1;{redo mem ref and smash S1}
	GOTO[FLOATS1cont],	c2;

	GOTO[FLOATS1cont],	c2, at[L0.FLOAT, 10, LFAremapS1ret];

FLOATDRemap:
	Zimph ← LShift1 Kount - 1, SE ← 0, CALL[LFAremapD],	c3;

	MDR ← uS2Hi, GOTO[FLOATDcont],	c2, at[L0.FLOAT, 10, LFAremapDret];

FLOATend:
	Q ← 4, CANCELBR[$, 3],	c2;
	,	c3;

	GOTO[LFACommonExit],	c1;

	{remapping common code}

	{
	assumes offset in Zimph
	trashes Zorch, rhZorch,
	sets Q to 2
	loads appropriate r and rh
	goes to pagefault if need be
	returns through L0
	}

{----	S2 REMAP   ----}
LFAremapS2:
	Zorch ← uS2Lo,	c1;
	Zorch ← Zorch + Zimph, CarryBr,	c2;
	rhZorch ← uS2Hi, BRANCH[LFAS2nocar, LFAS2car],	c3;

LFAS2car:
	Q ← rhZorch,	c1;
	Q ← Q + 1,	c2;
	rhZorch ← Q LRot0,	c3;

LFAS2nocar:
	{map S2}
	Map ← [rhZorch, Zorch],	c1;
lfa.S2map:
	,	c2;
	rhS2 ← S2 ← MD, XwdDisp,	c3;

	Map ← [rhZorch, Zorch], DISP2[LFAmapS2],	c1;
	MDR ← S2 or 10, GOTO[LFAS2ok],	c2, at[0, 4, LFAmapS2];
	MDR ← S2 or 10, GOTO[LFAS2ok],	c2, at[1, 4, LFAmapS2];
	MDR ← S2 or 10, GOTO[LFAS2ok],	c2, at[2, 4, LFAmapS2];
	Rx ← S2, GOTO[LFApagefault],	c2, at[3, 4, LFAmapS2];

LFAS2ok:
	Q ← 2, L0Disp,	c3;

	MAR ← S2 ← [rhS2, Zorch + 0], RET[LFAremapS2ret]	c1;

{----	S1 REMAP   ----}
LFAremapS1:
	Zorch ← uS1Lo,	c1;
	Zorch ← Zorch + Zimph, CarryBr,	c2;
	rhZorch ← uS1Hi, BRANCH[LFAS1nocar, LFAS1car],	c3;

LFAS1car:
	Q ← rhZorch,	c1;
	Q ← Q + 1,	c2;
	rhZorch ← Q LRot0,	c3;

LFAS1nocar:
	{map S1}
	Map ← [rhZorch, Zorch],	c1;
	,	c2;
	rhS1 ← S1 ← MD, XwdDisp,	c3;

	Map ← [rhZorch, Zorch], DISP2[LFAmapS1],	c1;
	MDR ← S1 or 10, GOTO[LFAS1ok],	c2, at[0, 4, LFAmapS1];
	MDR ← S1 or 10, GOTO[LFAS1ok],	c2, at[1, 4, LFAmapS1];
	MDR ← S1 or 10, GOTO[LFAS1ok],	c2, at[2, 4, LFAmapS1];
	Rx ← S1, GOTO[LFApagefault],	c2, at[3, 4, LFAmapS1];

LFAS1ok:
	Q ← 2, L0Disp,	c3;

	MAR ← S1 ← [rhS1, Zorch + 0], DISP4[LFAremapS1ret]	c1;


{----	D REMAP   ----}
LFAremapD:
	Zorch ← uDLo,	c1;
	Zorch ← Zorch + Zimph, CarryBr,	c2;
	rhZorch ← uDHi, BRANCH[LFADnocar, LFADcar],	c3;

LFADcar:
	Q ← rhZorch,	c1;
	Q ← Q + 1,	c2;
	rhZorch ← Q LRot0,	c3;

LFADnocar:
	{map D}
	Map ← [rhZorch, Zorch],	c1;
	,	c2;
	rhD ← D ← MD, XwdDisp,	c3;

	Map ← [rhZorch, Zorch], DISP2[LFAmapD],	c1;
	MDR ← D or 30, GOTO[LFADok],	c2, at[0, 4, LFAmapD];
	MDR ← D or 30, GOTO[LFADok],	c2, at[1, 4, LFAmapD];
	Rx ← D, GOTO[LFApagefault],	c2, at[2, 4, LFAmapD];
	Rx ← D, GOTO[LFApagefault],	c2, at[3, 4, LFAmapD];

LFADok:
	Q ← 2, L0Disp,	c3;

	MAR ← D ← [rhD, Zorch + 0], DISP4[LFAremapDret]	c1;

	{ E N D }