//**************************************************************************************
//MEMA2.TST
//By B. Rosen and M. Thomson  						October 18, 1978
//Sub Test Program for D0 MEM Module
//**************************************************************************************
get "mema.d"

//Edge pin and test connector signal busses available to this sub-test:

//{Idata: Idata.00,  Idata.01,Idata.02,Idata.03,  Idata.04,Idata.05,Idata.06,  Idata.07,Idata.08,Idata.09,  Idata.10,Idata.11,Idata.12,  Idata.13,Idata.14,Idata.15}

//{Odata: Odata.00,  Odata.01,Odata.02,Odata.03,  Odata.04,Odata.05,Odata.06,  Odata.07,Odata.08,Odata.09,  Odata.10,Odata.11,Odata.12,  Odata.13,Odata.14,Odata.15}

//{rbus: R.00,  R.01,R.02,R.03,  R.04,R.05,R.06,  R.07,R.08,R.09,  R.10,R.11,R.12,  R.13,R.14,R.15}

//{StorDin: StorDin.00,  StorDin.01,StorDin.02,StorDin.03,  StorDin.04,StorDin.05,StorDin.06,  StorDin.07,StorDin.08,StorDin.09,  StorDin.10,StorDin.11,StorDin.12,  StorDin.13,StorDin.14,StorDin.15}

//{StorOut': StorOut.00',  StorOut.01',StorOut.02',StorOut.03',  StorOut.04',StorOut.05',StorOut.06',  StorOut.07',StorOut.08',StorOut.09',  StorOut.10',StorOut.11',StorOut.12',  StorOut.13',StorOut.14',StorOut.15'}

//**************************************************************************************
//Test 3: Test the EC Output generator (page 1)

let Test3() be
[
	SpeakTest(3) //set initial conditions (see notes at end of MEMA.TEST)

	{H4←IMux}=0; //for H4←R


//PART 1: Test all possible input configurations to the S280 parity generators (page 1)

	for i = 1 to 2 do
	[
		//i=1 => GenSyn0,1,2,3,x will =1 (independent of S374 latch logic)
		//i=2 => GenSyn0,1,2,3,x will =0 (dependent on S374 latch logic)

		for j = 0 to 255 do
		[
			let par = j<<w.b8  xor j<<w.b9  xor j<<w.b10 xor
			          j<<w.b11 xor j<<w.b12 xor j<<w.b13 xor
			          j<<w.b14 xor j<<w.b15 xor i<<w.b15

		//Check the b16,b17,b18,c17 parity generators and GenSyn0,1,2,3

			//{b16con: R.01,R.03,  R.05,R.07,R.09,  R.11,R.13,R.15}
			GenSynCon() //set up for GenSyn0←i[15]
			{b16con}=j
			EClock() //GenSyn0(S374 latch)←0, H4←(selected R bits =j)
			{GenPhase0}=i; //GenSyn0(S374 output)←i[15]
			WCompare({StorEcOut.0'},par,3000+i,j)

			//{b17con: R.02,R.03,  R.06,R.07,R.10,  R.11,R.14,R.15}
			GenSynCon() //set up for GenSyn1←i[15]
			{b17con}=j
			EClock() //GenSyn1(S374 latch)←0, H4←(selected R bits =j)
			{GenPhase0}=i; //GenSyn1(S374 output)←i[15]
			WCompare({StorEcOut.1'},par,3010+i,j)

			//{b18con: R.04,R.05,  R.06,R.07,R.12,  R.13,R.14,R.15}
			GenSynCon() //set up for GenSyn2←i[15]
			{b18con}=j
			EClock() //GenSyn2(S374 latch)←0, H4←(selected R bits =j)
			{GenPhase0}=i; //GenSyn2(S374 output)←i[15]
			WCompare({StorEcOut.2'},par,3020+i,j)

			//{c17con: R.08,R.09,  R.10,R.11,R.12,  R.13,R.14,R.15}
			GenSynCon() //set up for GenSyn3←i[15]
			{c17con}=j
			EClock() //GenSyn3(S374 latch)←0, H4←(selected R bits =j)
			{GenPhase0}=i; //GenSyn3(S374 output)←i[15]
			WCompare({StorEcOut.3'},par,3030+i,j)

		//Check the c18 parity generator via StorEcOut.7', with GenSynX=i[15]

			//{c18con: R.01,R.02,  R.04,R.07,R.08,  R.11,R.13,R.14}
			GenSynCon() //set up for GenSynX←i[15]
			{c18con}=j
			EClock() //GenSynX(S374 latch)←0, H4←(selected R bits =j)
			{GenPhase0}=i; //GenSynX(S374 output)←i[15]
			WCompare({StorEcOut.7'},par,3040+i,j) //GenY xor (GenSynX=i[15])

		//Check the c19 parity generator and GenSynX via StorEcOut.7', keeping GenY=0

			//{c19con: R.00,R.03,  R.05,R.06,R.09,  R.10,R.12,R.15}
			GenSynCon() //set up for GenSynX←i[15], c18 inputs ←0
			{c19con}=j
			EClock() //GenSynX(S374 latch)←0, H4←(selected R bits =j)
			         //c18 inputs stay =0 for GenY=0
			{GenPhase0}=i; //GenSynX(S374 output)←i[15]

			EClock() //GenSynX(S374 latch)←(GenX xor (GenSynX=i[15]))
			{GenPhase0}=0; //GenSynX(S374 output)←GenSynX(S374 latch)
			WCompare({StorEcOut.7'},par,3050+i,j) //GenSynX xor (GenY=0)
		]
	]


//PART 2: Check GenSyn0,1,2,3(S374 outputs)←(GenSyn0,1,2,3(S374 latches)=1111)
//        Start initialization for PART 3

	{rbus}=0
	EClock() //H4←(rbus=0), (GenX←0, GenY←0 for PART 3)
	{GenPhase0}=1; //GenSyn0,1,2,3(S374 outputs)←1111
	EClock() //GenSyn0,1,2,3(S374 latches)←1111, LastPar(c15f)←0 for PART 3
	{GenPhase0}=0; //GenSyn0,1,2,3(S374 outputs)←(GenSyn0,1,2,3(S374 latches)=1111)
	               //Enables all c15 ff outputs for PART 3

	//{StorEcOut.0003': StorEcOut.0',  StorEcOut.1',StorEcOut.2',StorEcOut.3'}
	WCompare({StorEcOut.0003'},#17,3100)


//PART 3: Test the StorEcOut[4:6]' logic

	//{StorEcOut.0406': StorEcOut.4',StorEcOut.5',StorEcOut.6'}

	//Continue initialization of c13 and c15 flip-flops (started in PART 2)
	EClock() //LastXP(c13b)←0, LastLastPar(c15g)←0
	EClock() //LastXQ(c13c)←0, LastLastXP(c15h)←0

	//Check initialization (GenX, GenY, and the flip-flops should =0)
	WCompare({StorEcOut.4'},1,3200) //(GenY'=1) xor (GenX=0) xor (LastXP=0)
	WCompare({StorEcOut.5'},1,3201) //(GenY'=1) xor (GenX=0) xor (LastXQ=0)
	WCompare({StorEcOut.6'},1,3202) //(GenY'=1) xor (GenX=0) xor (LastLastXP=0)

	//Define the five flip-flops related to StorEcOut[4:6]'
	let LastLastXP=0 //c15h ff
	let LastXP=0 //c13b ff
	let LastXQ=0 //c13c ff
	let LastLastPar=0 //c15g ff
	let LastPar=0 //c15f ff

	//Run all possible configurations through the StorEcOut[4:7] logic

	for i = 0 to 31 do
	[
		{R.15} = i<<w.b11; //for GenX=i[11]

		for j = 0 to 3 do
		[
			{R.14} = (i rshift j)&1; //for GenY=i[15-14-13-12]
			EClock() //Clock the c13 and c15 ff's to their new states
 			         //H4[0:13]←(R[0:13]=0)
 			         //H4.15←(R.15=i[11]), hence GenX←i[11]
			         //H4.14←(R.14=i[15-14-13-12]), hence GenY←i[15-14-13-12]


			let GenX = {R.15} //i[11]
			let GenY = {R.14} //i[15-14-13-12]
			let Par  = GenX xor GenY //gate c16a

			let a = (LastXP lshift 2) % (LastXQ lshift 1) % LastLastXP
			let b = (-(Par xor 1))&7 //b=7 if GenX=GenY, else 0

			let sb = a xor b
			let was = {StorEcOut.0406'}

			WCompt3(was,sb,i,j,GenX,GenY,Par,LastPar,LastLastPar,LastXQ,LastXP,LastLastXP)

			//Up-date the flip-flops for next pass through the loop
			LastLastXP = LastXP //c15h ff
			LastXP = LastPar xor Par //c13b ff
			LastXQ = LastLastPar xor Par //c13c ff
			LastLastPar = LastPar //c15g ff
			LastPar = Par //c15f ff
		]
	]
]


//Routine to input odd H4 parity to b16,b17,b18,c17,c19 and even parity to c18

and GenSynCon() be
[
	{rbus}=1
	{EdgeClockFeed'}=0
	{EdgeClockFeed'}=1; //H4←(rbus=1)
	{GenPhase0}=1; //GenSyn0,1,2,3,X(S374 outputs)←11111
	//The next EClock will cause GenSyn0,1,2,3,X(S374 latches)←00000
]


//Special Wait-Comparison routine peculiar to this test

and WCompt3(was,sb,i,j,GenX,GenY,Par,LastPar,LastLastPar,LastXQ,LastXP,LastLastXP) be
[
	if was eq sb then return

	Ws(FORMATN("*nTest 3300: StorEcOut.0406' was=<B>, should be=<B>, i=<B>, j=<B>",was,sb,i,j))

	//The next two lines are "should be" states of internal signals
	Ws(FORMATN("*nGenX=<B>, GenY=<B>, Par=<B>, LastPar=<B>",GenX,GenY,Par,LastPar))
	Ws(FORMATN("*nLastLastPar=<B>, LastXQ=<B>, LastXP=<B>, LastLastXP=<B>",LastLastPar,LastXQ,LastXP,LastLastXP))

	while Endofs(keys) do [  ]  
	Gets(keys)
	Ws("*nRunning...")
]

//**************************************************************************************
//Test 4: Test the EC Input checker (pages 2,6)

and Test4() be
[
	SpeakTest(4) //set initial conditions (see notes at end of MEMA.TEST)

	//LoadSyndrome=1 from SpeakTest to enable ClkSyndrome': CrctSyn[0:7]←ChkSyn[0:7]


//PART 1: Test all possible input configurations to the S280 parity generators (page 2)

	for i = 0 to 511 do
	[
		let par = i<<w.b7  xor i<<w.b8  xor i<<w.b9  xor
		          i<<w.b10 xor i<<w.b11 xor i<<w.b12 xor
		          i<<w.b13 xor i<<w.b14 xor i<<w.b15

		{ChkPhase0'}=0; //for flip-flops i16 and b15 ← StorEcIn[0:7] (pages 2,6)

	//Check the h19,h18,h17,i19 parity generators

		//{h19con: StorDin.01,StorDin.03,StorDin.05,  StorDin.07,StorDin.09,StorDin.11,  StorDin.13,StorDin.15,StorEcIn.0}
		{h19con}=i
		EClock() //H5(Udat)←(selected StorDin bits =i[7:14])
		         //i16b ff ←(StorEcIn.0=i[15])
		EClock() //CrctSyn0←(ChkSyn0=par)
		WCompare({CrctSyn0},par,4000,i)

		//{h18con: StorDin.02,StorDin.03,StorDin.06,  StorDin.07,StorDin.10,StorDin.11,  StorDin.14,StorDin.15,StorEcIn.1}
		{h18con}=i
		EClock() //H5(Udat)←(selected StorDin bits =i[7:14])
		         //i16c ff ←(StorEcIn.1=i[15])
		EClock() //CrctSyn1←(ChkSyn1=par)
		WCompare({CrctSyn1},par,4001,i)

		//{h17con: StorDin.04,StorDin.05,StorDin.06,  StorDin.07,StorDin.12,StorDin.13,  StorDin.14,StorDin.15,StorEcIn.2}
		{h17con}=i
		EClock() //H5(Udat)←(selected StorDin bits =i[7:14])
		         //i16d ff ←(StorEcIn.2=i[15])
		EClock() //CrctSyn2←(ChkSyn2=par)
		WCompare({CrctSyn2},par,4002,i)

		//{i19con: StorDin.08,StorDin.09,StorDin.10,  StorDin.11,StorDin.12,StorDin.13,  StorDin.14,StorDin.15,StorEcIn.3}
		{i19con}=i
		EClock() //H5(Udat)←(selected StorDin bits =i[7:14])
		         //i16e ff ←(StorEcIn.3=i[15])
		EClock() //CrctSyn3←(ChkSyn3=par)
		WCompare({CrctSyn3},par,4003,i)

	//Check the i17 (ChkY) parity generator via ChkSyn7 (page 6), with Partial7=i[15]

		//{i17con: StorDin.01,StorDin.02,StorDin.04,  StorDin.07,StorDin.08,StorDin.11,  StorDin.13,StorDin.14,StorEcIn.7}
		{i17con}=i
		EClock() //H5(Udat)←(selected StorDin bits =i[7:14])
		         //Partial7←(StorEcIn.7=i[15])
		EClock() //CrctSyn7←(ChkSyn7=(ChkY xor (Partial7=i[15])=par)
		WCompare({CrctSyn7},par,4004,i)

	//Check the i18 (ChkX) parity generator via ChkSyn7 (page 6), keeping ChkY=0

		//{i18con: StorDin.00,StorDin.03,StorDin.05,  StorDin.06,StorDin.09,StorDin.10,  StorDin.12,StorDin.15,StorEcIn.7}
		{i17con}=0; //for ChkY←0
		{i18con}=i
		EClock() //H5(Udat)←(selected StorDin bits =i[7:14])
		         //Partial7←(StorEcIn.7=i[15]), ChkY←0

		{ChkPhase0'}=1; //for Partial7←(ChkX xor Partial7)
		EClock() //Partial7←((ChkX xor (Partial7=i[15]))=par) 
		EClock() //CrctSyn7←(ChkSyn7=(Partial7 xor (ChkY=0))=par)
		         //(Partial7←(ChkX xor Partial7) - don't care)
		WCompare({CrctSyn7},par,4005,i)
	]


//PART 2: Test the ChkSyn[4:6] logic (page 6)

	//{StorEcIn.0406: StorEcIn.4,StorEcIn.5,StorEcIn.6}
	//{CrctSyn.0406: CrctSyn4,CrctSyn5,CrctSyn6}

	//Preliminary test of ChkSyn[4:6] with CW[0:2]'=0

	{ChkPhase0'}=0
	for i = 0 to 2 do EClock() //CW2'←CW1'←CW0'←(ChkPhase0'=0)

	for i = 0 to 1 do
	[
		let a = (-i)&7 //7 if i=1, else 0
		{StorEcIn.0406}=a
		EClock() //Partial[4:6]←(StorEcIn[4:6]=a)
		EClock() //CrctSyn[4:6]←(ChkSyn[4:6]=Partial[4:6]=a) (S64 b gates)
		WCompare({CrctSyn.0406},a,4100+i)
	]

	//Test ChkSyn[4:6] controlling all inputs

	{StorDin}=0
	{ChkPhase0'}=1
	for i = 0 to 2 do EClock() //CW2'←CW1'←CW0'←(ChkPhase0'=1)
	                           //Udat[0:15]←(StorDin[0:15]=0)

	for i = 0 to 7 do
	[
		let a = (-i<<w.b13)&7 //7 if i>3, else 0
		let UdatParity = i<<w.b14 xor i<<w.b15 //ChkX xor ChkY (page 2)
		let sb = i<<w.b13 xor UdatParity

		{StorEcIn.0406}=a
		{StorDin.00} = i<<w.b14; //for ChkX←i[14]
		{StorDin.01} = i<<w.b15; //for ChkY←i[15]

		{ChkPhase0'}=0
		EClock() //Partial[4:6]←(StorEcIn[4:6]=a)
		         //Udat[0:1]←(StorDin[0:1]=i[14:15]) for UdatParity = (i[14] xor i[15])
		         //CW[0:2]←011

		{ChkPhase0'}=1
		EClock() //CrctSyn[5:6],Partial[5:6]←(ChkSyn[5:6]=(Partial[5:6] xor UdatParity))
		         //Partial4←(ChkSyn4=Partial4) since CW0'=0
		         //CW[0:2]←101
		WCompare({CrctSyn5},sb,4200+i)
		WCompare({CrctSyn6},sb,4300+i)

		EClock() //CrctSyn[4,6],Partial[4,6]←(ChkSyn[4,6]=(Partial[4,6] xor UdatParity))
		         //Partial5←(ChkSyn5=Partial5) since CW1'=0
		         //CW[0:2]←110
		WCompare({CrctSyn4},sb,4400+i)

		EClock() //CrctSyn[4:5],Partial[4:5]←(ChkSyn[4:5]=(Partial[4:5] xor UdatParity))
		         //Partial6←(ChkSyn6=Partial6) since CW2'=0
		         //CW[0:2]←111

		//At this point CrctSyn[4:6] should = Partial[4:6]=a since Partial[4:6] will
		//have toggled twice if UdatParity=1; UdatParity=0 => Partial[4:6] regenerate
		WCompare({CrctSyn.0406},a,4500+i)
	]
]