//**************************************************************************************
//MEMB1.TST
//By B. Rosen and M. Thomson  						January 31, 1979
//Sub Test Program for D0 MEM Module
//**************************************************************************************
get "memb.d"

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

//{StorEcIn: StorEcIn.0,StorEcIn.1,  StorEcIn.2,StorEcIn.3,StorEcIn.4,  StorEcIn.5,StorEcIn.6,StorEcIn.7}

//**************************************************************************************
//Test 1: Check assorted logic indicated by the sub-titles

let Test1() be
[
	SpeakTest(1) //set initial conditions (see notes at end of MEMB.TEST)

//Check for shorts in the tri-state signals accessed by new test clips

//{t1bus1: MC2Next.4,  MC2Next.5,MC2Next.6,preMC2Next.7,  MC2TestSE,MC2TestDE,MC1Ftype.0,  MC1Ftype.1,NewPipe,MC1Pipe.0,  Refresh',Refresh'b,PStore12',  EnInputParChk,MC2SE,MC2DE}

//{Disablebus: Disablee2,Disableb9,Disablef14,  Disableh2,DisableMC1,DisableMC2}

	//Verify the state of the tri-state disable terms
	WCompare({Disablebus},#37,1000)

	for i = 0 to 15 do
	[
		{t1bus1} = 1 lshift i
		WCompare({t1bus1},1 lshift i,1001,i)
	]

//Test the f14 prom (page 19)

	let t1tab1 = table [
		0;2;2;1;2;1;1;2; 2;1;1;2;1;2;2;1; 2;1;1;1;1;1;2;1; 1;1;2;1;2;1;1;2;
		2;1;1;1;1;1;2;1; 1;1;2;1;2;1;1;2; 1;1;1;1;1;1;1;2; 1;1;1;2;1;2;2;1;
		2;1;1;1;1;1;2;1; 1;1;2;1;2;1;1;2; 1;1;1;1;1;1;1;2; 1;1;1;2;1;2;2;1;
		1;1;1;1;1;1;1;2; 1;1;1;2;1;2;2;1; 1;1;1;1;1;1;2;1; 1;1;2;1;2;1;1;2;

		2;1;1;1;1;1;2;1; 1;1;2;1;2;1;1;2; 1;1;1;1;1;1;1;2; 1;1;1;2;1;2;2;1;
		1;1;1;1;1;1;1;2; 1;1;1;2;1;2;2;1; 1;1;1;1;1;1;2;1; 1;1;2;1;2;1;1;2;
		1;1;1;1;1;1;1;2; 1;1;1;2;1;2;2;1; 1;1;1;1;1;1;2;1; 1;1;2;1;2;1;1;2;
		1;1;1;1;1;1;2;1; 1;1;2;1;2;1;1;2; 1;1;1;1;1;1;1;2; 1;1;1;2;1;2;2;1 ]

	//{MC2SEDE: MC2SE,MC2DE}

	{MC2SEDE}=###; //disconnect tester drivers from the f14 prom outputs
	{Disablef14}=0; //enable the f14 prom outputs for this test

	for i = 0 to 255 do
	[
		{StorEcIn}=i
		EClock() //ChkSyn[0:7]←(StorEcIn[0:7]=i)
		EClock() //CrctSyn[0:7]←(ChkSyn[0:7]=i)
		WCompare({MC2SEDE},t1tab1!i,1100,i)
	]

	{Disablef14}=1; //disable the f14 prom outputs for next test

//Check the MC2Next.7' and OFault' logic (page 20)

	//Check gates a and b of MC2Next.7'; check OFault'
	//(Gate a can only be partially checked since MC2LogSE is not tester-controllable)

	//Gate c is disqualified since MC2HoldIfSNE0=0 from SpeakTest
	{preMC2Next.7}=0; //disqualify gate d

	//{t1bus2: MC2TestSE,  MC2SE,MC2TestDE,MC2DE}

	for i = 0 to 8 do
	[
		{t1bus2}=i
		let sb = (#567 rshift i)&1
		WCompare({MC2Next.7'},sb,1200,i)
		WCompare({OFault'},sb,1201,i)
	]

	//Check gates c and d of MC2Next.7'
	//Gates a and b are rendered disqualified by the loop above

	{StorEcIn}=0; //Clear so that StorEcIn.7 can control SNE0

	//{t1bus3: preMC2Next.7,MC2HoldIfSNE0,StorEcIn.7}

	for i = 0 to 4 do
	[
		{t1bus3}=i
		EClock() //ChkSyn7←(StorEcIn.7=i[15])
		EClock() //CrctSyn7←(ChkSyn7=i[15]) for SNE0←i[15]
		WCompare({MC2Next.7'},(7 rshift i)&1,1202,i)
	]

//Check the OValid' logic (page 20)

	//{t1bus4: preLoadOdata',MC2WriteCdat,MC2Next.4}

	for i = 0 to 8 do
	[
		{t1bus4}=i
		EClock() //e2d ff ←(preLoadOdata'=i[13])
		EClock() //Odata←Cdat' ←(e2d ff =i[13])
		WCompare({Odata←Cdat'},i<<w.b13,1300,i)

		EClock() //e2f ff ← gate f1d output
		WCompare({OValid'},(#160 rshift i)&1,1301,i)
	]

//Check the EmRef logic (pages 15,16)

	{preMC1Next.6}=0; //MC1Next.6'←1 for MC1Active' control

	//{t1bus5: CTask.0,CTask.1,  CTask.2,MC1Next.4,MC1StartMC2}

	for i = 0 to 16 do
	[
		{t1bus5} = i xor 1
		EClock() //ClockAd': MC1Task[0:2]←(CTask[0:2]=i[11:13]) (MC1Task.3←0)

		//MC1Active' inputs: MC1Next[0:3]=0 from SpeakTest, MC1Next.6'=1
		//	hence, MC1Active'←(MC1StartMC2'=i[15]) (page 16)
		WCompare({MC1Active'},i&1,1400,i)

		WCompare({EmRef},1 rshift i,1401,i) //rev. J boards will fail when i=2
	]
]

//**************************************************************************************
//Test 2: Test the Pipe Data logic (pages 7,11,15)
//        Test the b11 prom and the b9 flip-flops (page 15)

and Test2() be
[
//[ // test loop
	SpeakTest(2) //set initial conditions (see notes at end of MEMB.TEST)

//Test the Pipe Data logic (pages 7,11,15)

	//{CTaskALUF: CTask.0,CTask.1,  CTask.2,CTask.3,ALUF.0,  ALUF.1,ALUF.2,ALUF.3}
	//{MC1Pipe.0003: MC1Pipe.0,  MC1Pipe.1,MC1Pipe.2,MC1Pipe.3}
	//{R.0815: R.08,R.09,  R.10,R.11,R.12,  R.13,R.14,R.15}
	//{StorA: StorA0,  StorA1,StorA2,StorA3,  StorA4,StorA5,StorA6}

	//Set up initial conditions:

	{R←Pipe'}=0; //for R[8:15]←d14 ff's←RAM outputs (page 11)
	{LoadPipe}=1; //for WritePipe" active when RamClock (page 14)
	//EnRowAd'=1 from SpeakTest to disable the a17 StorA drivers (page 7)

	//Check the RAM data paths using adresses 0 and 1 only

	{MC1Pipe.0003}=0
	//[// test loop

	for i = 0 to 7 do
	[
		let a = 1 lshift i

		//Set up data (a[9:15]') to be stored in address 0
		{StorA}=a; //for IStorA=a' (page 7)
		RClock() //a12 ff's ←(IStorA[0:6]=a[9:15]') (page 11)
		         //(a12f ff←(Map.8=?) - cannot be tested)

		//Set up data (a[8:15]) to be stored in address 1
		{CTaskALUF}=a
		EClock() //MC1Task[0:3]←(CTask[0:3]=a[8:11]) (page 15)
		         //MC1Type[0:3]←(ALUF[0:3]=a[12:15]) (page 15)

		//Store into and read from address 0
		{MC1Pipe.3}=0
		RClock() //WritePipe': RAM(0)←(a12 ff's=IStorA[0:6]=a[9:15]')
		EClock() //R[8:15]←d14 ff's←RAM(0)'
		WCompare({R.0815}&#177,a&#177,2000,i) //exclude R.08
		//WCompare({R.0815}&#177,0,2000,i) //exclude R.08  test wait only

		//Store into and read from address 1
		{MC1Pipe.3}=1
		RClock() //WritePipe': RAM(1)←(c9,c10 mux's=MC1Task[0:3],,MC1Type[0:3]=a[8:15])
		EClock() //R[8:15]←d14 ff's←RAM(1)'
		WCompare({R.0815},a xor #377,2001,i)
	] 
	//] repeat // test loop
	//Check all the testable addresses of the RAM using both 1's and 0's in each cell
	//(excludes 3,7,#13,#17 since their data inputs involve Map outputs)

	for i = 0 to 1 do
	[
		for j = 0 to 7 do //Write pattern into even addresses (0,2,...#16)
		[
			let a = 1 lshift j
			let b = a xor (-i) //a inverted if i=1
			{MC1Pipe.0003} = 2*j; //even addresses (0,2,...#16)
			{StorA} = not b; //for IStorA[0:6]=b[9:15]
			RClock() //a12 ff's←(IStorA[0:6]=b[9:15])
			         //(a12f ff←(Map.8=?) - cannot be tested)
			RClock() //WritePipe': RAM←(a12 ff's=b[9:15])
		]

		for j = 0 to 7 do //Read pattern from even addresses (0,2,...#16)
		[
			let a = 1 lshift j
			let b = a xor (-i) //a inverted if i=1
			{MC1Pipe.0003} = 2*j; //even addresses (0,2,...#16)
			EClock() //R[8:15]←d14 ff's←RAM'
			WCompare({R.0815}&#177,(not b)&#177,2010+i,j) //exclude R.08
		]

		for j = 0 to 3 do //Write pattern into addr. 1,5,#11,#15
		[
			let a = 3 lshift (2*j) //3,#14,#60,#300
			let b = a xor (-i) //a inverted if i=1
			{MC1Pipe.0003} = (4*j) % 1; //addr. 1,5,#11,#15
			{CTaskALUF}=b
			EClock() //MC1Task[0:3]←(CTask[0:3]=b[8:11]) (page 15)
			         //MC1Type[0:3]←(ALUF[0:3]=b[12:15]) (page 15)
			RClock() //WritePipe': RAM←(c9,c10 mux's=b[8:15])
		]

		for j = 0 to 3 do //Read pattern from addr. 1,5,#11,#15
		[
			let a = 3 lshift (2*j) //3,#14,#60,#300
			let b = a xor (-i) //a inverted if i=1
			{MC1Pipe.0003} = (4*j) % 1; //addr. 1,5,#11,#15
			EClock() //R[8:15]←d14 ff's←RAM'
			WCompare({R.0815},(not b)&#377,2020+i,j)
		]
	]

	//Check that LoadPipe=0 inhibits WritePipe'
	{ALUF.3}=0
	EClock() //Change write data from #177 to #176
	{LoadPipe}=0; //inhibit WritePipe'
	RClock() //don't change RAM(#16) from #177 to #176
	EClock() //R[8:15]←d14 ff's←RAM(#16)'
	WCompare({R.15},0,2030) //if result =1, check gate a11b, page 14

//Check the b11 prom and the b9 flip-flops (page 15)

	let t2tab1 = table [
	#034;#074;#174;#114; #034;#074;#024;#064; #174;#114;#174;#114; #174;#114;#076;#016
	#270;#210;#270;#210; #274;#214;#030;#070; #174;#114;#276;#216; #074;#014;#276;#216 ]

	//{t2bus1: ResetMemErrs',ALUF.0,ALUF.1,  ALUF.2,ALUF.3,NewPipe}

	//{t2bus2: MC1Ftype.0,MC1Ftype.1,  NewPipe,MC1Pipe.0,Refresh',  Refresh'b,PStore12',EnInputParChk}

	for i = 0 to 63 do
	[
		{t2bus1}=i; //ResetMemErrs'←i[10], b11 prom addr.←i[11:15]
		EClock() //ClockAd': b9 ff's ← (prom b11, gate a11a)

		{t2bus2}=###; //Disconnect tester drivers from b9 flip-flop outputs
		{Disableb9}=0; //Enable b9 flip-flop outputs

		//b11 prom outputs with address = i[11:15]
		let a = t2tab1!(i&#37)

		//b11 prom output code adjusted to match b9 ff inputs (MC1Pipe.0 excluded)
		let b = (a&#350) % ((a rshift 1)&#7)

		//Define gate a11a output (MC1Pipe.0 input) = (a[11] & i[10])'
		let c = (not (a & (i rshift 1)))&#20

		WCompare({t2bus2},b % c,2100,i)

		{Disableb9}=1; //Disable b9 flip-flop outputs
	]

//Check that LoadAd=0 disqualifies ClockAd'

	{PAbort}=1; //for LDisableMC1'=0, hence LoadAd=0
	WCompare({LoadAd'},1,2110) //confirm LoadAd=0

	{t2bus1}=0; //Change b11 prom address from #37 to 0
	EClock() //ClockAd' is inactive, so b11 ff's should retain old data

	{t2bus2}=###; //Disconnect tester drivers from b9 flip-flop outputs
	{Disableb9}=0; //Enable b9 flip-flop outputs

	WCompare({MC1Ftype.0},1,2111) //should stay =1 from address #37
]