{
File name TrapzSubs.mc
Last edited by MRR: 13-Oct-86 12:53:51: updated BumpBitAddress label to reference current version.
Last edited by JPM: 8-Aug-86 16:24:13: Hacked SaveStack.
Last edited by CRF: 4-Aug-86 12:36:57:  Deleted code that saves working copy of xMin.val.frac in the stack.  Fixes to BumpVars.  Changes for second bank operation:  changed LSEPReturn1 to LSEPReturn.  
Last edited by MRR: 18-Jun-86  8:52:12: changed some prefixes from 'bb' to 'tzb'. Removed the Src and Dst LRemap routines, since BltLineGray is called instead of using a version of bbLoops.mc.

	Description: relative to BitBlt op-code version, modified for TrapezoidBlt to reside in control store bank 1.

	This file contains the following subroutines:
	
		Subroutine		Page #
		-----------		-------
		BumpVars		-  2
		MovrhVToStkandRestore	-  4
		RestoreRandRHRegs	-  4
		SaveStack		-  5
		SavetzbRegs		-  6

	this file was printed with the following XDE Executive command:
	
		>print gacha8/f /-a TrapzSubs.mc
}

{ 	Copyright (C) 1986 by Xerox Corporation.  All rights reserved.}

{************************************************************************************************

	Bump TrapezoidBlt Variables  SUBROUTINE
	first cycle = c1, last cycle = c2, length = 18 2/3 - 19 2/3 clicks

This subroutine is used to increment the working registers per Trapezoid Item transfered.

	EXITS TO BumpVarsRet
	
 ************************************************************************************************}

BumpVars:
	VD ← UdstBpl						,c1; {bump Dst Bit Address by dstBpl}
	dstWidth ← UWrkrhVD					,c2;
	srcWrdOffset ← UDtzVALo					,c3;

	Tzbtmp ← UtzDstBit					,c1;
	L4 ← L4.TrapzBump					,c2;
	CALL[BBASubEntry]					,c3;

	{ BumpBitAddress subroutine here {7, or 8 clicks}	,c1-c2;}

	Noop						,c3, at[L4.TrapzBump,10,BumpBitAddressRet];

	UWrkrhVD ← dstWidth					,c1;
	UDtzVALo ← srcWrdOffset				,c2; {save new Dst hi & lo addrs}
	UtzDstBit ← Tzbtmp					,c3;

	Q ← UXMinValFrac					,c1;
	Tzbtmp ← UXMindValFrac					,c2; {add XMindVal.li to XMinVal.li}
	TzbAnother ← Tzbtmp + Q, CarryBr			,c3;

	Q ← UXMinValInt, BRANCH[$, MinValCary]			,c1;
	Tzbtmp ← UXMindValInt					,c2;
	Rbb1 ← Tzbtmp + Q, GOTO[StashMinVal]			,c3;
MinValCary:
	Tzbtmp ← UXMindValInt					,c2;
	Rbb1 ← Tzbtmp + Q + 1					,c3;
StashMinVal:
	UXMinValFrac ← TzbAnother				,c1; {save new XMinVal.li}
	Tzbtmp ← Rbb1 - Q					,c2;
	Q ← UtzSrcBit						,c3;

	Q ← Q + Tzbtmp						,c1;
	Q ← Q and 0F						,c2;
	UtzSrcBit ← Q						,c3;

	UXMinValInt ← Rbb1					,c1;
	Q ← UXMaxValFrac					,c2;
	Tzbtmp ← UXMaxdValFrac					,c3;

	TzbAnother ← Tzbtmp + Q, CarryBr			,c1; {add XMaxdVal.li to XMaxVal.li}
	Q ← UXMaxValInt, BRANCH[$, MaxValCary]			,c2;
	Tzbtmp ← UXMaxdValInt					,c3;

	Rbb1 ← Tzbtmp + Q, GOTO[StashMaxVal]			,c1;
MaxValCary:
	Tzbtmp ← UXMaxdValInt					,c3;

	Rbb1 ← Tzbtmp + Q + 1					,c1;
StashMaxVal:
	UXMaxValFrac ← TzbAnother				,c2; {save new XMaxVal.li}
	UXMaxValInt ← Rbb1					,c3;

	Tzbtmp ← UyOffset					,c1; {load yOffset}
	TzbAnother ← UTzbFlags					,c2;
	TzbAnother ← TzbAnother and 0F				,c3; {look at Height-1}

	Q ← TzbAnother - Tzbtmp, ZeroBr				,c1;
	Rbb1 ← UStzVALo, BRANCH[lessthan, equals]		,c2;

equals:
	Rbb1 ← Rbb1 - TzbAnother, CarryBr			,c3; {reset back to top of brick}

	UyOffset ← 0, BRANCH[decRH, $]				,c1; {reset yOffset to 0}
	L2Disp, GOTO[rhOK]					,c2;
decRH:
	TzbAnother ← UWrkrhVS, 					,c2;
	TzbAnother ← TzbAnother - 1				,c3;

	Noop, GOTO[rhNowOK]					,c1;

lessthan:
	Q ← Tzbtmp + 1						,c3; {increment yOffset}

	Rbb1 ← Rbb1 + 1, CarryBr				,c1; {increment source VA}
	UyOffset ← Q, L2Disp, BRANCH[rhOK, $]			,c2;
	TzbAnother ← UWrkrhVS, CANCELBR[$, 0F]			,c3;

	TzbAnother ← TzbAnother + 1				,c1;
rhNowOK:
	UWrkrhVS ← TzbAnother, L2Disp				,c2;
rhOK:	UStzVALo ← Rbb1, DISP4[BumpVarsRet]			,c3;


{************************************************************************************************

	MoverhVToStkandRestore  SUBROUTINE
	length = 3 clicks
This subroutine is used to move the rhV registers into the stack.
	USES
L0	caller
	MOVES
Rbb1	to UDstBit
Q	to USrcBit
	EXITS TO RestoreRandRHRegs  SUBROUTINE
	
 ************************************************************************************************}

MovrhVToStkandRestore:
	rhL ← UrhLsave, GOTO[RestoreBlkRegsC3],	,c*{c1};

{
	RestoreRandRHRegs  SUBROUTINE
	length = 2 1/3 clicks
This subroutine is used to restore the R registers and rh registers which were saved at the entry into BitBlt.
	USES
L0	caller
	RESTORES
L	from ULsave
G	from UGsave
PC	from UPCsave
rhMDS	from UrhMDSsave
rhPC	from UrhPCsave
rhG	from UrhGsave
rhL	from UrhLsave
	RETURNS THRU
tzbRestoreCallers
RestoreBlkRegs entries are used by Block.mc in order to end up on the right cycle. 
Block.mc saves all registers but does not use them all.
}

RstrRandRHRegs:
	rhL ← UrhLsave				,c*{c1}, at[Type.normal,10, LSEPReturn];
RestoreBlkRegsC3:
	rhPC ← UrhPCsave			,c*{c2};
RestoreBlkRegsC2:
	rhMDS ← UrhMDSsave			,c*{c3};

RestoreBlkRegsC1:
	rhG ← UrhGsave				,c*{c1};
RestoreBlkRegsC3Initial:
	{This entry can be used from Block only if rhG has not yet been modified.}
	PC ← UPCsave				,c*{c2};
	G ← UGsave, L0Disp			,c*{c3};

	L ← ULsave, RET[tzbRestoreCallers]	,c*{c1};

{************************************************************************************************

	SaveStack SUBROUTINE
	length = 
This subroutine staches working loop variables from their proper stack elements. The variables are dstBpl, yOffset, SrcBitOffset, and Source Address. The elements touched are as follows:

	o fold source and destination rh components into the stack,
	o merge destination bit offset into the Min and Max Val interpolators,
	o place yOffset and source bit offset into flags word.

	USES
rhWho	caller

 ************************************************************************************************}

SaveStack:
	Tzbtmp ← UWrkrhVS					,c*{c1}; {UrhTzbVS Ustk←Uwork}
	Tzbtmp ← Tzbtmp LRot8					,c*{c2};
	Q ← UWrkrhVD						,c*{c3}; {UrhTzbVD Ustk←Uwork}

	Tzbtmp ← Tzbtmp or Q					,c*{c1};
	UrhTzbVSD ← Tzbtmp 					,c*{c2};
	Q ← UtzDstBit						,c*{c3}; {Add dstbit to interp vals}

	Tzbtmp ← UXMinValInt					,c*{c1};
	Tzbtmp ← Tzbtmp + Q					,c*{c2};
	UXMinValInt ← Tzbtmp					,c*{c3};

	Tzbtmp ← UXMaxValInt					,c*{c1};
	Tzbtmp ← Tzbtmp + Q					,c*{c2};
	UXMaxValInt ← Tzbtmp					,c*{c3};

	TzbAnother ← UyOffset					,c*{c1};
	Q ← UTzbFlags						,c*{c2};
	Tzbtmp ← TzbAnother LRot8 or Q				,c*{c3}; {merge yOffset into Flags}

	TzbAnother ← UtzSrcBit					,c*{c1};
	TzbAnother ← TzbAnother LRot4				,c*{c2};
	Tzbtmp ← Tzbtmp or TzbAnother 				,c*{c3}; {merge srcBit into Flags}

	UTzbFlags ← Tzbtmp					,c*{c1};
	[] ← rhWho, XDisp					,c*{c2};
	DISP4[SaveStackRet,0E]					,c*{c3}; {return to caller}


{************************************************************************************************

	SavetzbRegs  SUBROUTINE
	length = 2 2/3 clicks
This subroutine is used to move the rh registers in U.
Note that the caller MUST save L before calling.
	MOVES
TOS	STK
G	to UGsave
rhG	UrhGsave
PC	to UPCsave
rhPC	UrhPCsave
L	UrhLsave
rhL	UrhLsave
rhMDS	UrhMDSsave
	EXITS TO SavetzbRegsRet
	
 ************************************************************************************************}

SavetzbRegs:	
	L ← rhL					,c2, at[0,10,SavetzbRegs];
SaveBlkRegs::	
	PC ← PC - 1				,c3;

SaveBlkRegsx:	{Radr same as Ublock containing following Uregs}
	UPCsave ← PC				,c1;

	{the following Uregs are at "xB" to allow "← rh"}
	UGsave ← G				,c2;
	UrhLsave ← L, G ← rhG 			,c3;

	UrhGsave ← G, PC ← rhPC		,c1;
	UrhPCsave ← PC, TOS ← rhMDS, pRet2,	,c2;
	UrhMDSsave ← TOS, RET[SavetzbRegsRet],	,c3;

	{END}