{
File : Pseudo8bitColorB0.mc
Author : Gwan Santosa
Date : 17-Sep-85 17:22:39


This program converts certain colors of an 8 bits per pixel bitmap into other colors

The parameters are :

	S - 10	Pointer to color array, page aligned
	S - 8	Bitmap
	S - 6	X (Left)
	S - 4	Y (Bottom)
	S - 2	Transfer width
	S - 0	Untransfered width (0 on initial call)
	TOS	Transfer height
	
The algorithm :

1. Fetch pixel value.
2. Use that value as a pointer to color array.
3. Replace that pixel with the value of that color array's entry.



@PSCLROP:	opcode[305'b],
	Bank ← PSCLRBank, 		c1; {This section is in LispPixelBltB1.mc}
	uTOS ← TOS,			c2;
	uTOSH ← TOSH, CROSS[PSCLR],	c3;
	
	at[PSCLR],
	Xbus ← ibNA, XDisp,		c1; {This section is in LispPixelBltB0.mc}
	DISP4[PSEUDOCLRDISP], 		c2;

}

{

Set[L2PSRET0, 08];

RegDef[rPSCArray, R, 4]; {=S}
RegDef[rhPSCArray, RH, 4]; {=rhS}
RegDef[rPS, R, 3]; {=PV}
RegDef[rhPS, RH, 3]; {=rhPV}
RegDef[urhPS, U, 38];
RegDef[urPS, U, 41];
RegDef[uPSXLo, U, 43];
RegDef[uPSYLo, U, 19];
RegDef[Data88, R, 6]; {=Rx}
RegDef[PSCOUNT, R, 1]; {=TOSH}
RegDef[PSTMP, R, 0]; {=TOS}

RegDef[urSAddr, U, 38]; {tmp, used in PixelBlt}
RegDef[urhSAddr, U, 41]; {tmp, used in PixelBlt}
RegDef[urDAddr, U, 43]; {tmp, used in PixelBlt}
RegDef[urhDAddr, U, 19]; {tmp, used in PixelBlt}
RegDef[upixelcount, U, 45]; {tmp, used in PixelBlt}
RegDef[uXoffset, U, 46]; {tmp, used in PixelBlt}
{RegDef[uSrcflag, U, 47]; {tmp, used in PixelBlt}
RegDef[uDstflag, U, 0C]; {tmp, used in PixelBlt}}

RegDef[uSrcBITMAPLo, U, 5D]; {tmp, used in PixelBlt}
RegDef[uSrcBITMAPHi, U, 19]; {tmp, used in PixelBlt}
RegDef[uSrcXLo, U,57]; {tmp, used in PixelBlt}
RegDef[uSrcYLo, U,05]; {tmp, used in PixelBlt}
RegDef[uDstBITMAPHi, U, 35]; {tmp, used in PixelBlt}
RegDef[uDstBITMAPLo, U, 04]; {tmp, used in PixelBlt}
RegDef[uDstXLo, U, 26]; {tmp, used in PixelBlt}
RegDef[uDstYLo, U, 31]; {tmp, used in PixelBlt}
RegDef[uTrnWidthLo, U, 3A]; {tmp, used in PixelBlt}
RegDef[uUnTrnWidthLo, U, 5C]; {tmp, used in PixelBlt}
RegDef[uTrnHeightLo, U, 0D]; {= uTOS, used in PixelBlt}

Stored in NewFuncDef.dfn

}

	uS ← S,				c3, at[00, 10, PSEUDOCLRDISP];
	
PSBK1:	MAR ← [rhS, S - 1],					c1; {Point to UnTrnWidthHi}
	Ybus ← TOSH xor smallpl, CANCELBR[$, 2], ZeroBr,	c2; {Check TrnHeight}
	Q ← MD, BRANCH[BTER0, $],				c3;
	
	MAR ← [rhS, S + 0],		c1; {Point to UnTrnWidthLo}
	S ← S-2, L1 ← L1.NoFixesB0,	c2;
	TT ← MD,			c3;
	
	MAR ← [rhS, S - 1],				c1; {Point to TrnWidthHi}
	Ybus ← Q xor smallpl, CANCELBR[$, 2], ZeroBr,	c2; {Check UnTrnWidth}
	Q ← MD, BRANCH[BTER1, $],			c3;
	
	MAR ← [rhS, S + 0],		c1; {Point to TrnWidthLo}
	S ← S-2, L3 ← 0,		c2;
	Rx ← MD,			c3;

	Ybus ← Q xor smallpl, ZeroBr,			c1; {Check TrnWidth}
	uUnTrnWidthLo ← TT, ZeroBr, BRANCH[BTER2, $],	c2; {Check UnTrnWidth}
	uTrnWidthLo ← Rx, ZeroBr, BRANCH[PWNZ, PWZ],	c3; {Check TrnWidth}
	
PWZ:	BRANCH[GPTR1, PNOTR1],				c1; {In between lines case}
GPTR1:	upixelcount ← Rx,				c2; {Load number of pixel per line}
	uXoffset ← 0, GOTO[PNFM],			c3; {X offset = 0}			
	
PWNZ:	upixelcount ← TT, BRANCH[GPTR2, PNOTR2],	c1; {Load number of pixel left}
GPTR2:	Rx ← Rx - TT, CarryBr,				c2; {Calculate X offset}
	uXoffset ← Rx, BRANCH[PNOTR3, $],      		c3; 
	
PNFM:	MAR ← [rhS, S - 1],				c1; {Point to YHi}
	uTrnHeightLo ← TOS, CANCELBR[$, 2], ZeroBr,	c2; {Check if transfer height is 0}
	Q ← MD, BRANCH[$, PNOTR4],			c3;
	
	MAR ← [rhS, S + 0],				c1; {Point to YLo}
	S ← S - 2, L2 ← L2PSRET0,			c2;
	Rx ← MD, 					c3;
	
	MAR ← [rhS, S - 1], 				c1; {Point to XHi}
	Ybus ← Q xor smallpl, CANCELBR[$, 2], ZeroBr,	c2; {Check Y}
	Q ← MD,	BRANCH[PSYE1, $],			c3;
	
	MAR ← [rhS, S + 0], 				c1; {Point to XLo}
	Ybus ← Q xor smallpl, CANCELBR[$, 2], ZeroBr,	c2; {Check X}
	TT ← MD, BRANCH[PSXE1, $],			c3;
	
	,						c1;
	S ← S - 2,					c2;
	uPSXLo ← TT,					c3;
	
	MAR ← [rhS, S - 1], 				c1; {Point to BITMAPHi}
	uPSYLo ← Rx, CANCELBR[$, 2],			c2;
	Rx ← MD,					c3;
	
PSBK5:	MAR ← [rhS, S + 0],				c1; {Point to BITMAPLo}
	S ← S + 8, 					c2;
	TT ← MD, CALL[GetTestBMParamsB0],		c3;
	
	S ← S - 10'd,					c3, at[L2PSRET0, 10, GetTestBMParamsB0Ret];
	
	MAR ← [rhS, S - 1], 				c1; {Point to ClrArrayHi}
	Ybus ← Q xor 8, CANCELBR[$, 2], ZeroBr,		c2; {Check if 8 bits per pixel bitmap}
	Q ← MD,	 BRANCH[PSE00, $],			c3;
	
	MAR ← [rhS, S + 0],				c1; {Point to ClrArrayLo}
	rhTT ← Q LRot0, 				c2; {Set up high VA of color table}
	TT ← MD,					c3; {Set up low VA of color table}
	
PSBK6:	Map ← [rhTT, TT + 0], L1 ← L1.NoFixesB0,	c1;
	S ← S + 10'd, L0 ← L0.RMAPB0.0,			c2;
	rhRx ← Rx ← MD, XRefBr,				c3;
	
	BRANCH[PSCH0, $],				c1, at[L0.RMAPB0.0, 10, RMapFixCallerB0];
	Q ← uBITMAPHEIGHT, L1 ← L1.RegSaveRet.0,	c2; {Save registers}	
	rhPSCArray ← Rx LRot0, CALL[SaveAllRegsB0],	c3; {Load the real address of color table}

{
==============================================================================================
Check boundaries
==============================================================================================
}

PSBK2:	rPSCArray ← Rx,			c1, at[L1.RegSaveRet.0, 10, SaveRegsB0Ret];
	TT ← uPSYLo, 			c2; {Check 1st Y}	
	Ybus ← Q - TT - 1, CarryBr,	c3;

	TT ← TOS + TT, BRANCH[PSE01, $],	c1; {TOS = TrnHeight}
	Ybus ← Q - TT, CarryBr,			c2; {Check 2nd Y}
	Q ← uPSXLo, BRANCH[PSE02, $],		c3; {Load X}	

	TT ← RShift1 uBITMAPWIDTH, SE ← 0, 	c1; {Divide Bitmapwidth by 8}
	TT ← RShift1 TT, SE ← 0,		c2;
	TT ← RShift1 TT, SE ← 0,		c3;

	Ybus ← TT - Q - 1, CarryBr,		c1; {Check 1st X}	
	Rx ← uTrnWidthLo, BRANCH[PSE03, $],	c2;	
	Q ← Q + Rx,				c3;
	
	Ybus ← TT - Q, CarryBr,		c1; {Check 2nd X}
	Q ← uPSYLo, BRANCH[PSE04, $],	c2;	
PSOLP:	Q ← Q + TOS,			c3;

PSBK3:	Rx ← uBITMAPHEIGHT,			c1;
	Q ← Rx - Q, L0 ← L0.MUL.00,		c2;	
	TOS ← uBITMAPRASTERWIDTH, CALL[MTPLB0],	c3; {Calculate Y*Bitmaprasterwidth}

	TOS ← uXoffset,			c2, at[L0.MUL.00 , 10, MULCALLERB0];
	Rx ← uPSXLo,			c3;
	
	TOS ← Rx + TOS,			c1;
	Rx ← RShift1 TOS, SE ← 0,	c2;
	Q ← Q + Rx, CarryBr, 		c3;
	
	Rx ← uBITMAPBASELO, BRANCH[PSNA1, PSA1],	c1;
	
PSA1:	TT ← TT + 1, GOTO[PSMG1],	c2;

PSNA1:	Noop,				c2;

PSMG1:	Rx ← Rx + Q, CarryBr,		c3;

	Q ← uBITMAPBASEHI, BRANCH[PSNA2, PSA2],	c1;
	
PSA2:	TT ← TT + 1, GOTO[PSMG2],		c2;

PSNA2:	Noop,					c2;

PSMG2:	Q ← TT + Q,				c3;

	PSCOUNT ← upixelcount, 		c1;
	urhPS ← Q, L0 ← L1.WMAPB0.5,	c2;
	rhTT ← Q LRot0,			c3;
	
	Map ← TT ← [rhTT, Rx],			c1;
	urPS ← Rx, L1 ← L1.TrapFixesB0.2,	c2;
	rhRx ← Rx ← MD, XwdDisp,		c3;
	
	MAR ← Q ← [rhRx, TT + 0], DISP2[PSCH11],	c1, at[L0.WMAPB0.5, 10, WMapFixCallerB0];
	rhPS ← Rx LRot0,				c2, at[1, 4, PSCH11];
	Data88 ← MD,					c3;
	
	Ybus ← TOS, YDisp,		c1;
	rPS ← Q, DISP4[PSODDEVEN, 0E],	c2;
	
	GOTO[PSMG4],			c3, at[0E, 10, PSODDEVEN];
	
	PSTMP ← Data88 and 0FF,		c3, at[0F, 10, PSODDEVEN];
	
	MAR ← [rhPSCArray, PSTMP + 0],	c1;
	Data88 ← Data88 and ~0FF,	c2;
	Q ← MD or Data88, GOTO[PSIL2],	c3;


PSILP:	MAR ← rPS ← [rhPS, rPS + 1], BRANCH[$, PSO2],	c1;
	BRANCH[$, FXPSA1, 1],				c2;
	Data88 ← MD,					c3;
	
PSMG4:	TT ← Data88  LRot8,		c1;
	Q ← TT and 0FF,			c2;
	Data88 ← Data88 and 0FF,	c3;	

PSIL1:	MAR ← [rhPSCArray, Q + 0],	c1;
	PSCOUNT ← PSCOUNT - 1, ZeroBr, 	c2;
	PSTMP ← MD, BRANCH[$, PSO1],	c3;
	
	MAR ← [rhPSCArray, Data88 + 0],	c1;
	PSTMP ← PSTMP LRot8, 		c2;
	Q ← MD or PSTMP,		c3;
	
PSIL2:	MAR ← [rhPS, rPS + 0],				c1;
	MDR ← Q,					c2;
	PSCOUNT ← PSCOUNT - 1, ZeroBr, GOTO[PSILP],	c3;

PSO2:	TOSH ← uTOSH, CANCELBR[PSO3, 3],		c2;

PSO1:	PSTMP ← PSTMP LRot8,		c1;
	TOSH ← uTOSH,			c2;
	Data88 ← Data88 or PSTMP,	c3;	
	
	MAR ← [rhPS, rPS + 0],	c1;
	MDR ← Data88,		c2;
PSO3:	Q ← uTrnHeightLo,	c3;	
	
	Q ← Q - 1, ZeroBr,			c1;
	uTrnHeightLo ← Q, BRANCH[$, PSEX],	c2;
	
	uXoffset ← 0, MesaIntBr,		c3;
	
	Ybus ← uWDC, NZeroBr, BRANCH[PSNI1, $],	c1;
	Ybus ← uWP, ZeroBr, BRANCH[$, PSNI2],	c2;
	
	uWP ← 0, BRANCH[PSIN, PSNI3],		c3;
	
PSIN:	Q ← 0,			c1;
	S ← uS,			c2;
	rhS ← nRhS,		c3;
	
	MAR ← [rhS, S + 0],	c1;		       
	MDR ← Q, 		c2;
	TOS ← uTrnHeightLo,	c3;
		
	Bank ← EmuBank,			c1;
	PV ← uPVx,			c2;
	rhPV ← nRhS, CROSS[EmuInt],	c3;

PSNI1:	Q ← uTrnWidthLo, CANCELBR[$],	c2;	
	TOS ← uTrnHeightLo,		c3;
	
	upixelcount ← Q, 		c1;
	Q ← uPSYLo, GOTO[PSOLP],	c2;
	
PSNI2:	CANCELBR[$],			c3;	

PSNI3:	Q ← uTrnWidthLo,  		c1;
	TOS ← uTrnHeightLo,		c2;
	Noop,				c3;
	
	upixelcount ← Q, 		c1;
	Q ← uPSYLo, GOTO[PSOLP],	c2;

FXPSA1:	TT ← urPS,				c3; {Retrieve original rPS}
		
	Q ← 0FF + 1,				c1; {Load Q with 100}
	TT ← TT + Q, CarryBr,			c2; {Add with 100}	
	Q ← urhPS, BRANCH[PSND1, PSAD1],	c3;
	
PSAD1:	Q ← Q + 1,				c1;
	urhPS ← Q,				c2;	
	rhTT ← Q LRot0,	GOTO[PSMP1],		c3;
		
PSND1:	rhTT ← Q LRot0,				c1;
	urhPS ← Q,				c2;
	Noop,					c3;
	
PSMP1:	Map ← [rhTT, TT + 0], L1 ← L1.TrapFixesB0.2,	c1;
	urPS ← TT, L0 ← L0.WMAPB0.6,			c2;
	rhRx ← Rx ← MD, XwdDisp,			c3;
	
	MAR ← Q ← [rhRx, rPS + 0], DISP2[PSMAP11],	c1, at[L0.WMAPB0.6, 10, WMapFixCallerB0];
	rPS ← Q, 					c2, at[1, 4, PSMAP11];
	Data88 ← MD,					c3;
	
	Q ← rhRx,		c1;
	rhPS ← Q LRot0,		c2;
	GOTO[PSMG4],		c3;

	S ← uS,			c1, at[L1.TrapFixesB0.2, 10, TrapFixesB0];
	rhS ← nRhS,		c2;
	Noop,			c3;
	
	MAR ← [rhS, S + 0],	c1;
	MDR ← PSCOUNT,		c2;
	Q ← 0,			c3;
	
	GOTO[RestoreAllRegsAndPFB0],	c1;

PSCH0:	CALL[RLMapFixB0],	c2;
	
	GOTO[WLMapFixB0],		c2, at[0, 4, PSMAP11];
	GOTO[WLMapFixB0],		c2, at[2, 4, PSMAP11];
	GOTO[WLMapFixB0],		c2, at[3, 4, PSMAP11];

	GOTO[WLMapFixB0],		c2, at[0, 4, PSCH11];
	GOTO[WLMapFixB0],		c2, at[2, 4, PSCH11];
	GOTO[WLMapFixB0],		c2, at[3, 4, PSCH11];


{
==============================================================================================
Exit point
==============================================================================================
}

PSEX:	Q ← 12'd,					c3;

PSBK4:	Xbus ← ib, GOTO[RestoreAllRegsAndExitB0],	c1;

{
==============================================================================================
Error cases
==============================================================================================
}

BTER0:	S ← uS, GOTO[ufnX20],		c1;

BTER1:	S ← uS, GOTO[ufnX20],		c1;

BTER2:	S ← uS, CANCELBR[ufnX10, 3],	c3;

PNOTR1:	S ← uS, GOTO[ufnX30],		c2;

PNOTR2:	S ← uS, GOTO[ufnX30],		c2;

PNOTR3:	S ← uS, GOTO[ufnX20],		c1;

PNOTR4: S ← uS, GOTO[ufnX20],		c1;

PSYE1:	S ← uS, GOTO[ufnX20],		c1;

PSXE1:	S ← uS, GOTO[ufnX20],		c1;

PSE00:	S ← uS, GOTO[ufnX20],		c1;

PSE01:	S ← uS,				c2;
	rhS ← nRhS, GOTO[ufnX10],	c3;

PSE02:	S ← uS,				c1;
	rhS ← nRhS, GOTO[ufnX30],	c2;

PSE03:	S ← uS,				c3;

	rhS ← nRhS, GOTO[ufnX20],	c1;

PSE04:	S ← uS,				c3;

	rhS ← nRhS, GOTO[ufnX20],	c1;

{
=======================================================================
Multiplier subroutine
=======================================================================

Q = multiplicand
TOS = multiplier
Rx = counter
(TT Q) contains the result, Q is least significant word.
}


MTPLB0:	Rx ← 10,					c*{c1};
	TT ← 0,						c*{c2};
MLLPB0:	Ybus ← Q and 1, NZeroBr, 			c*{c3};

	Rx ← Rx - 1, ZeroBr, BRANCH[MPL0B0, MPL1B0],		c*{c1};
	
MPL0B0:	TT ← DARShift1 (TT + 0), BRANCH[MLLPB0, MLPEB0],	c*{c2};

MPL1B0:	TT ← DARShift1 (TT + TOS), BRANCH[MLLPB0, MLPEB0],	c*{c2};

MLPEB0:	Q ← ~Q, L0Disp,						c*{c3};

	RET[MULCALLERB0],					c*{c1};

	{END}