{
File name : fptdiag.mc
Author : Gunawan Santosa
Created : 17-Dec-84 13:00:40

=========================================================================
FPTDIAG.MC
=========================================================================

This program test the floating point circuit board for Xerox
1100 series workstation.

Registers :

REGA:	Mostly used for scratch pad
REGB:	Mostly used for scratch pad
RESM:	To store MS byte of result
RESL:	To store LS byte of result
REFREG:	To store expected value
STATUS:	To store status of floating point chip
FLTCNT:	To store total fault count

At DONE :
If FLTCNT = 0, no error, else errors have been detected.





First, perform A+B, there are 4 cases.
In this test, we test input and output buses of the floating point chip,
F2 input line, and status line.
}

START:	Q ← 0,				c1;	{Load Q with 0}
	PPort ← Q,			c2;	{set port direction to read status}
	COUNTER ← n04,			c3;	{There are 4 cases for A+B}
	
	FLTCNT ← n00,			c1;	{Initialize fault counter}
LOP1:	Xbus ← COUNTER LRot0, XDisp,	c2;	{Check which case}
	DISP4[ADDAB, 0C],		c3;
	
{First case, A+B, where A=AAAAAAAA, B=00000000}

CASE1:	REGA ← n00,			c1, at[0C,10,ADDAB];
	UREGA ← REGA,			c2;	{Load UREGA with 0000}
	REGA ← nAA,			c3;	{Load REGA with 00AA}
	
	REGA ← (REGA LRot8) or REGA,	c1;	{REGA contains AAAA}
	UREGADD ← REGA,			c2;	{UREGADD contains AAAA}
	GOTO[APLB],			c3;	{Perform A+B}
	
{Second case, A+B, where A=55555555, B=00000000}	
	
CASE2:	REGA ← n55,			c1, at[0F,10,ADDAB];
	REGA ← (REGA LRot8) or REGA,	c2;	{REGA contains 5555}
	UREGADD ← REGA, GOTO[APLB],	c3;	{UREGADD contains 5555}
	
{Third case, A+B, where A=00000000, B=55555555}

CASE3:	UREGA ← REGA,			c1, at[0E,10,ADDAB];
	REGA ← n00,			c2;	{UREGA contains 5555}
	UREGADD ← REGA, GOTO[APLB],	c3;	{UREGADD contains 0000}
	
{Fourth case, A+B, where A=00000000, B=AAAAAAAA}	
	
CASE4:	REGA ← nAA,			c1, at[0D,10,ADDAB];	
	REGA ← (REGA LRot8) or REGA,	c2;	{REGA contains AAAA}
	UREGA ← REGA, 			c3;	{UREGA contains AAAA}
	
{Perform A+B}	
	
APLB:	FloatMode, FloatFLOW,		c1;	{load flow thru mode}	
	FloatAB ← UREGA,		c2;	{load AB}
	FloatAB ← UREGA, 		c3;	
		
	FloatA ← UREGADD,	FLPlus,	c1;	{load A}	
	FloatA ← UREGADD,		c2;	{and perform A+B}
	FloatNop,			c3;
		
	FloatNop,			c1;	
	Noop,				c2;
	Noop,				c3;
		
	Noop,				c1;		
	FloatUnloadS,	Float.M,	c2;	{unload MS word}
	FloatUnloadS,	Float.L,	c3;	{unload LS word}
	
	STATUS ← PPort,			c1;	{read status}	
	RESM ← FloatResult,		c2;	{store MS word in RESM}
	RESL ← FloatResult,		c3;	{LS word in RESL}
	
	Noop,				c1;
	Xbus ← COUNTER LRot0, XDisp,	c2;	{Calculate expected values}
	DISP4[ADDRS, 0C],		c3;

{Expected value for case 1}
	
CS1:	REFREG ← nAA, 						c1, at[0C,10,ADDRS];
	REFREG ← (REFREG LRot8) or REFREG, GOTO[MERGE],		c2;	{Must be AAAAAAAA}

{Expected value for case 2}
	
CS2:	REFREG ← n55,						c1, at[0F,10,ADDRS];
	REFREG ← (REFREG LRot8) or REFREG, GOTO[MERGE],		c2;	{Must be 55555555}
	
{Expected value for case 3}	

CS3:	Noop,							c1, at[0E,10,ADDRS];
	GOTO[MERGE],						c2;	{Must be 55555555}
	
{Expected value for case 4}	

CS4:	REFREG ← nAA, 						c1,at[0D,10,ADDRS];
	REFREG ← (REFREG LRot8) or REFREG, GOTO[MERGE],		c2;	{Must be AAAAAAAAA}
	
{Test the result}	

MERGE:	RESM ← RESM - REFREG, ZeroBr,				c3;	{Test MS byte}	

	RESL ← RESL - REFREG, ZeroBr, BRANCH[FLS1,TRUE1],	c1;	{Test LS byte}
	
FLS1:	FLTCNT ← FLTCNT + n01, CANCELBR[$],			c2;	{MS byte is wrong}
									{Increment}
									{fault count}								
	Xbus ← FLTCNT LRot0, ZeroBr,				c3;	{Check if}

	BRANCH[TRUE3,DDCT],					c1;	{fault count}
									{overflow}



TRUE1:  BRANCH[FLS3,TRUE2],			c2;	{MS byte is OK, check LS byte}

FLS3:	FLTCNT ← FLTCNT + n01, ZeroBr,		c3;	{wrong, increment fault count}
	
	BRANCH[TRUE3,DDCT],			c1;	{Check if fault count overflow}
	
TRUE3:	GOTO[TRUE2],				c2;	{not overflow, check STATUS}
		
DDCT:	FLTCNT ← FLTCNT - n01,			c2;	{Else, decrement fault count}

TRUE2:  STATUS ← STATUS and n0F,		c3;	{Get status, mask off unwanted}
							{bits}

TP01:	REGB ← n0E,				c1;	{Use REGB as a reference}
	Noop,					c2;
	Noop,					c3;
	
	STATUS ← STATUS - REGB,	ZeroBr,		c1;	{Test STATUS}
	BRANCH[W000,T000],			c2;
	
W000:	FLTCNT ← FLTCNT + n01, ZeroBr,		c3;	{wrong, increment fault count}

	BRANCH[FCNOV,FCOV],			c1;	{Check if fault count}
							{overflow}

FCOV:	FLTCNT ← FLTCNT - n01,	GOTO[T000],	c2;	{overflow, decrement count}

FCNOV:	Noop,					c2;	{Else, noop}	

T000:	COUNTER ← COUNTER - n01, ZeroBr,	c3;	{Decrement pattern count}

	BRANCH[	LOP1,ASUBB],			c1;	{Check if completed A+B}
				
 
{ 
==========================================================================
A-B
==========================================================================

In this test, we check input line F0.

}

ASUBB:	REGA ← n55,			c2;	{Load REGA with 0055}
	REGA ← (REGA LRot8) or REGA,	c3;	{REGA contains 5555}
	
	UREGA ← REGA,			c1;	{UREGA contains 5555}
	UREGSUB ← REGA,			c2;	{load UREGSUB with 5555}
	FloatAB ← UREGA,		c3;	{load AB each with 55555555}
	
	FloatAB ← UREGA,			c1;
	FloatA ← UREGSUB,	FLAMinusB,	c2;	{load A with 55555555}
	FloatA ← UREGSUB,			c3;	{and perform A-B}
		
	FloatNop,			c1;
	Noop,				c2;
	Noop,				c3;
	
	Noop,				c1;
	FloatUnloadS,	Float.M,	c2;	{unload MS word of result}
	FloatUnloadS,	Float.L,	c3;	{unload MS word of result}
	
	STATUS ← PPort,			c1;	{load the status}
	RESM ← FloatResult,		c2;
	RESL ← FloatResult,		c3;
	
	RESM ← RESM or RESL, ZeroBr,	c1;	{Test results, must be 00000000}
	BRANCH[FLS5,AMULB],		c2;
	
FLS5:	FLTCNT ← FLTCNT + n01, ZeroBr,	c3;	{wrong, increment fault count}

	BRANCH[AMULB1,DCT1],		c1;	{Check for fault count overflow}
	
AMULB1:	GOTO[AMULB],			c2;	{no overflow, continue}
	
DCT1:	FLTCNT ← FLTCNT - n01,		c2;	{Else, decrement count}
		
{
==========================================================================
A.B
==========================================================================

In this test, we check the multiplier chip.

Case 1: A=AAAAAAAA, B=1
Case 2: A=55555555, B=1

}
	
AMULB:	REGA ← nAA,			c3;	{Load REGA with 00AA}

	REGA ← (REGA LRot8) or REGA,	c1;	{REGA contains AAAA}
	UREGMUL ← REGA,			c2;	{load UREGMUL with AAAAAAAA}
	REGA ← n00,			c3;
	
	UREGA ← REGA,			c1;	{UREGA contains 0000}	
	REGA ← n3F,			c2;	{load 3F into REGA}
	REGB ← n80,			c3;	{load 80 into REGB}
	
	REGA ← (REGA LRot8) ,		c1;
	REGA ← REGA or REGB,		c2;	{REGA now contains 3F80(f)=1.0}	
	UREGB ← REGA,			c3;	{load UREGB with 3F80(f)=1.0}
	
	COUNTER ← n02,			c1;	{Initialize counter}
	Noop,				c2;
	Noop,				c3;
	
	FloatMode,	FloatFLOW,	c1;	{load flow thru mode}
	FloatAB ← UREGB,		c2;	{load AB each with 3F800000}
	FloatAB ← UREGA,		c3;
	
FEDA4:	FloatA ← UREGMUL,	FLTimes.A.B,	c1;	{load A with AAAAAAAA or 55555555}
	FloatA ← UREGMUL,			c2;	{and perform A.B}
	FloatNop,				c3;	
	
	Noop,					c1;
	Noop,					c2;
	Noop,					c3;
	
	FloatUnloadP,	Float.M,		c1;
	FloatUnloadP,	Float.L,		c2;
	STATUS ← PPort,				c3;	{load status}
	
	RESM ← FloatResult,			c1;
	RESL ← FloatResult,			c2;
	RESM ← RESM - REFREG, ZeroBr,		c3;	{Check MS word of result}
	
	RESL ← RESL - REFREG, ZeroBr, BRANCH[FL01,TR01],	c1;	{Check LS byte}
FL01:	FLTCNT ← FLTCNT + n01, CANCELBR[$],			c2;	{MS byte}
									{is wrong,}
									{increment fault}
									{count}												
	Xbus ← FLTCNT LRot0, ZeroBr,				c3;	{Check if overflow}

	BRANCH[TR04,DCT],			c1;

TR01:  	BRANCH[FL02,TR03],			c2;	{MS word is OK, check LS byte}

FL02:	FLTCNT ← FLTCNT + n01, ZeroBr,		c3;	{LS word is wrong, increment}
							{fault count}
	
	BRANCH[TR04,DCT],			c1;	{Check if fault count overflow}
	
TR04:	GOTO[TR03],				c2;	{not overflow, continue}	
	
DCT:	FLTCNT ← FLTCNT - n01,			c2;	{Else, decrement count}

TR03:   COUNTER ← COUNTER - n01, ZeroBr,	c3;	{Decrement test counter}

	BRANCH[SCPS,SWAB],			c1;	{Second pass or swap AB}

SCPS:	REGA ← n55,				c2;	{Second pass, use 55555555}
	REGA ← (REGA LRot8) or REGA,		c3;
	
	UREGMUL ← REGA,				c1;	
	REFREG ← REGA,				c2;	{Expected value is 55555555}	
	GOTO[FEDA4],				c3;

{	
Case 3: A=1, B=AAAAAAAA	
Case 4: A=1, B=55555555
}

SWAB:	REGA ← n3F,				c2;	{Load REGA with 003F}
	REGA ← REGA LRot8,			c3;	{REGA contains 3F00}
	
	REGA ← REGA or REGB,			c1;	{REGA contains 3F80}
	UREGMUL ← REGA,				c2;	{UREGMUL  now contains 3F80}
	REGA ← nAA,				c3;	{REGA contains 00AA}
	
	REGA ← (REGA LRot8) or REGA,		c1;	{REGA contains AAAA}
	UREGB ← REGA,				c2;	{load REGB with AAAA}
	COUNTER ← n02,				c3;	{load counter}
	
	REFREG ← REGA,				c1;	{REFREG contains AAAA}
FEDB1:	FloatMode,	FloatFLOW,		c2;	{load flow mode}
	FloatAB ← UREGB,			c3;	{load A,B with AAAAAAAA or 55555555}
	
	FloatAB ← UREGB,			c1;	
	FloatA ← UREGMUL,	FLTimes.A.B,	c2;	{load A with 3F800000}
	FloatA ← UREGA,				c3;	{and perform A.B}
	
	FloatNop,				c1;	
	Noop,					c2;
	Noop,					c3;
	
	Noop,					c1;	
	Noop,					c2;
	Noop,					c3;
	
	FloatUnloadP,	Float.M,		c1;	
	FloatUnloadP,	Float.L,		c2;
	STATUS ← PPort,				c3;	{Read status}
	
	RESM ← FloatResult,			c1;	
	RESL ← FloatResult,			c2;
	RESM ← RESM - REFREG, ZeroBr,		c3;	{Check MS word of result}
	
	RESL ← RESL - REFREG, ZeroBr, BRANCH[FL011,TR011],	c1;	{Check LS byte}
FL011:	FLTCNT ← FLTCNT + n01, CANCELBR[$],			c2;	{MS byte}
									{is wrong,}
									{increment fault}
									{count}
	Xbus ← FLTCNT LRot0, ZeroBr,				c3;	{Check if}

	BRANCH[TR041,DCT11],			c1;			{overflow}

TR011:  BRANCH[FL021,TR031],			c2;	{If MS word OK, check LS byte}

FL021:	FLTCNT ← FLTCNT + n01, ZeroBr,		c3;	{LS word wrong,}
							{increment fault count}
	
	BRANCH[TR041,DCT11],			c1;	{Check if fault count overflow}
	
TR041:	GOTO[TR031],				c2;	{no overflow, continue}	
	
DCT11:	FLTCNT ← FLTCNT - n01,			c2;	{Else, decrement count}

TR031:  COUNTER ← COUNTER - n01, ZeroBr,	c3;	{Decrement test count}

	BRANCH[SCPS1,STTS],			c1;	{Do second pass or next test}
SCPS1:	REGA ← n55,				c2;	{Second pass, use 55555555}
	REGA ← (REGA LRot8) or REGA,		c3;
	
	UREGB ← REGA,				c1;
	REFREG ← REGA, 				c2;	{Load expected value of 55555555}
	Noop,					c3;
	
	GOTO[FEDB1],				c1;
	
STTS:	STATUS ← STATUS and n0F,		c2;     {Test status line of multiplier}
	REFREG ← n0E,				c3;	{Load expected value}
	
	STATUS ← STATUS - REFREG, ZeroBr,	c1;
	BRANCH[STNPA,STPA],			c2;
	
STNPA:	FLTCNT ← FLTCNT + n01, ZeroBr,		c3;	{STATUS is wrong}
							{Increment fault count}
								
	BRANCH[SFCRC,SFNCR],			c1;	{Check if overflow}
	
SFNCR:	FLTCNT ← FLTCNT - n01,			c2;	{Overflow, decrement count}
	
STPA:	Noop,					c3;		
		
{
==========================================================================
Test status signals of the adder (1033)
==========================================================================

This is done by adding invalid numbers

}

	Noop,					c1;
SFCRC:	REGA ← nFF,				c2;	{REGA contains 00FF}
	REGA ← (REGA LRot8) or REGA,		c3;	{REGA contains FFFF}
	
	UREGADD ← REGA,				c1;	{UREGADD contains FFFF}
	UREGB ← REGA,				c2;	{UREGB contains FFFF}
	REFREG ← n02,				c3;	{Expected value is 02}
	
	FloatAB ← UREGB,			c1;	{Load FFFFFFFF into A & B}
	FloatAB ← UREGB,			c2;
	FloatA ← UREGADD,	FLPlus,		c3;	{Perform A+B}
	
	FloatA ← UREGADD,			c1;	
	FloatNop,				c2;
	Noop,					c3;
	
	Noop,					c1;
	Noop,					c2;
	Noop,					c3;
	
	FloatUnloadS,	Float.M,		c1;	{unload MS word}
	FloatUnloadS,	Float.L,		c2;	{unload LS word}
	STATUS ← PPort,				c3;	{read status}
	
	RESM ← FloatResult,			c1;	{store MS word of result in REGCM}
	RESL ← FloatResult,			c2;	{LS word in REGCL}
	STATUS ← STATUS and n0F,		c3;	{Mask off unwanted bits}
	
	STATUS ← STATUS - REFREG, ZeroBr,	c1;	{Check STATUS}
	BRANCH[STER,STCR],			c2;
	
STCR:	GOTO[STCH],				c3;	{If OK, continue}

STER:	FLTCNT ← FLTCNT + n01, ZeroBr,		c3;	{Else, increment fault count}

	BRANCH[FCCR,DFCT],			c1;	{Check for overflow}

FCCR:	Noop,					c2;	{no overflow, continue}
	GOTO[STCH],				c3;
	
DFCT:	FLTCNT ←  FLTCNT - n01,			c2;	{Else, decrement fault count}
	GOTO[STCH],				c3;						
{
==========================================================================
Test Funtion input, F1
==========================================================================

This is done by converting 24 bits integer to 32 bits floating point.

}

STCH:	REGA ← n02,				c1;	{Load 02 into REGA}
	UREGB ← REGA,				c2;	{Load it into UREGB}
	REGA ← n00,				c3;	{REGA contains 0000}
	
	UREGFL ← REGA,				c1;	{Load 0000 into UREGFL}
	FloatAB ← UREGFL,			c2;
	FloatAB ← UREGB,			c3;
	
	FloatA ← UREGFL,	FLFloatA,	c1;	
	FloatA ← UREGB,				c2;	
	FloatNop,				c3;
	
	Noop,					c1;	
	Noop,					c2;
	Noop,					c3;
	
	Noop,					c1;	
	FloatUnloadS,	Float.M,		c2;	{unload MS word}
	FloatUnloadS,	Float.L,		c3;	{unload LS word}
	
	STATUS ← PPort,				c1;	{read status}
	RESM ← FloatResult,			c2;	{store MS word of result in REGCM}
	RESL ← FloatResult,			c3;	{LS word in REGCL}
	
							{Expected value is 40000000}  
	
	REFREG ← n40,				c1;	
	REFREG ← REFREG LRot8,			c2;	{REFREG contains 4000}
	REFREG ← RESM - REFREG, ZeroBr,		c3;	{Check MS byte}
	
	Xbus ← RESL LRot0, ZeroBr, BRANCH[FL012,TR012],		c1;	{Check LS byte}	
FL012:	FLTCNT ← FLTCNT + n01, CANCELBR[$],			c2;	{MS byte}
									{is wrong,}
									{increment fault}
									{count}
	Xbus ← FLTCNT LRot0, ZeroBr,		c3;	{Check if}
							{fault count}
	BRANCH[F3TS,DCT2],			c1;	{overflow}

TR012:  BRANCH[FL022,TR032],			c2;	{MS word OK,Check LS byte}		FL022:	FLTCNT ← FLTCNT + n01, ZeroBr,		c3;	{LS byte wrong}
							{increment fault,count}

	BRANCH[F3TS,DCT2],			c1;	{Check if overflow}
	
DCT2:	FLTCNT ← FLTCNT - n01,			c2;	{overflow, decrement count}
										

TR032:  Noop,					c3;

	Noop,					c1;
F3TS:	Noop,					c2;
	Noop,					c3;

	
			
{	
==========================================================================
Test Function input, F3
==========================================================================

This is done by doing Abs(A-b) twice, 
first : A= 00005555, B=0000AAAA,
then  : A= 0000AAAA, B=00005555.
}

	

	COUNTER ← n02,				c1;	{Load 02 into test counter}
	REGA ← n00,				c2;	{REGA contains 0000}
	UREGSBA ← REGA				c3;	{UREGSBA contains 0000}
	
	REGA ← n55,				c1;	{REGA contains 0055}
	REGA ← (REGA LRot8) or REGA,		c2;	{REGA contains 5555}
	REFREG ← REGA,				c3;	{Load REFREG with 5555}
							{Expected value is 00005555}	
	
	UREGB ← REGA,				c1;	{UREGB contains 5555}
	REGA ← REGA LRot1,			c2;	{REGA contains AAAA}
	UREGA ← REGA,				c3;	{UREGA contains AAAA}

{Perform Abs(A-b), the exponents are 0000}
	
F3T1:	FloatAB ← UREGSBA,			c1;	{Load AB each with 00005555}
	FloatAB ← UREGA,			c2;	{or 0000AAAA}
	FloatA ← UREGSBA,	FLAbsOfAMinusB,	c3;
	
	FloatA ← UREGB,				c1;	
	FloatNop,				c2;
	Noop,					c3;
	
	Noop,					c1;
	Noop,					c2;
	Noop,					c3;
	
	FloatUnloadS,	Float.M,		c1;	{unload MS word}
	FloatUnloadS,	Float.L,		c2;	{unload LS word}
	STATUS ← PPort,				c3;	{read status}
	
	RESM ← FloatResult,			c1;	{store MS word of result in REGCM}
	RESL ← FloatResult,			c2;	{LS word in REGCL}
	Xbus ← RESM LRot0, ZeroBr,		c3;	{Check MS byte}
	
	RESL ← RESL - REFREG, ZeroBr, BRANCH[NPS,PASS],		c1;	{Check LS byte}
NPS:	FLTCNT ← FLTCNT + n01, ZeroBr, CANCELBR[$],		c2;	{MS byte is}
									{wrong,}
									{increment}
									{fault count}						
	BRANCH[FCNTOK,FCNTWR],			c3;	{Check if fault count overflow}
	
PASS:	BRANCH[NPS1,PASS1],			c2;	{MS word OK, check LS byte}

FCNTWR:	FLTCNT ← FLTCNT - n01, GOTO[FLTDT1],	c1;	{fault count overflow}
							{decrement count}

FCNTOK:	Noop,					c1;
FLTDT1:	GOTO[PASS1],				c2;


NPS1:	FLTCNT ← FLTCNT + n01, ZeroBr,		c3;	{LS word is wrong, increment}
							{fault count}

	BRANCH[FCPS1,FCWR1],			c1;	{Check for overflow}
	
FCWR1:	FLTCNT ← FLTCNT - n01, GOTO[PASS1],	c2;	{overflow, decrement count}	
	
FCPS1:	Noop,					c2;	


PASS1:	COUNTER ← COUNTER - n01, ZeroBr,	c3;	{Decrement test count}

	BRANCH[ONEMR,DONE],			c1;	{Check if test completed}

ONEMR:	UREGB ← REGA,				c2;	{One more test, UREGB contains}
							{AAAA}

	REGA ← REGA LRot1,			c3;	{REGA contains 5555}
	
	UREGA ← REGA,				c1;	{UREGA contains 5555}
	Noop,					c2;
	GOTO[F3T1],				c3;
	
DONE:	Noop,					c2;
	GOTO[START],				c3;