//**************************************************************************************
//ALU9.TST
//By F. Itami and M. Thomson  							January 24, 1979
//Sub Test Program for D0 ALU Module
//**************************************************************************************
get "alu.d"

//Edge pin signal busses used by ALU module:

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

//{aluf: ALUF.0,  ALUF.1,ALUF.2,ALUF.3}

//{clkbus: LT,LR,  Abort',LoadMIR,Cycle0Feed'}

//{CTask: CTask.0,  CTask.1,CTask.2,CTask.3}

//{F1F2: F1.0,F1.1,  F1.2,F1.3,F2.0,  F2.1,F2.2,F2.3}

//{H2: H2.08,H2.09,  H2.10,H2.11,H2.12,  H2.13,H2.14,H2.15}

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

//{MC1SA: BSEL.0,BSEL.1,  F1.0,F1.1,F1.2,  F1.3,LR,LT}

//{mcbus: MC1WriteR,  MC2AllowWrite,MC1NeedsR,MC2WillGetR}

//{mirbus: MemInst/d,MemInst/d',  RMOD/d,RMOD/d',RSEL.0/d',  RSEL.1/d',RSEL.2/d,RSEL.3/d,  RSEL.4/d,RSEL4and5/d,RSEL.5/d}

//{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}

//{TA: TA.0,  TA.1,TA.2,TA.3}

//**************************************************************************************
//Test 22: Check the ProcCycleS logic (pages 13,14) and clkH2' (pages 6,15)
//         Check the RUN=0 initialization of certain MIR bits  (page 19)

let Test22() be
[
	SpeakTest(22) //set initial conditions (see notes at end of ALU.TST)

let t22sb = table [

	#210;#060;#210;#020; #210;#040;#210;#060; #210;#061;#210;#021; #210;#041;#210;#061;
	#210;#062;#210;#022; #210;#042;#210;#062; #210;#063;#210;#023; #210;#043;#210;#063;
	#210;#060;#210;#020; #210;#040;#210;#060; #210;#061;#210;#021; #210;#041;#210;#061;
	#210;#062;#210;#022; #210;#042;#210;#062; #210;#104;#210;#104; #210;#104;#210;#104;

	#060;#060;#020;#020; #040;#040;#060;#060; #061;#061;#021;#021; #041;#041;#061;#061;
	#062;#062;#022;#022; #042;#042;#062;#062; #063;#063;#023;#023; #043;#043;#063;#063;
	#060;#060;#020;#020; #040;#040;#060;#060; #061;#061;#021;#021; #041;#041;#061;#061;
	#062;#062;#022;#022; #042;#042;#062;#062; #063;#063;#023;#023; #043;#043;#063;#063;

	#060;#210;#020;#210; #040;#210;#060;#210; #061;#210;#021;#210; #041;#210;#061;#210;
	#062;#210;#022;#210; #042;#210;#062;#210; #063;#210;#023;#210; #043;#210;#063;#210;
	#060;#210;#020;#210; #040;#210;#060;#210; #061;#210;#021;#210; #041;#210;#061;#210;
	#062;#210;#022;#210; #042;#210;#062;#210; #104;#210;#104;#210; #104;#210;#104;#210;

	#060;#061;#020;#021; #040;#041;#060;#061; #061;#061;#021;#021; #041;#041;#061;#061;
	#062;#063;#022;#023; #042;#043;#062;#063; #063;#063;#023;#023; #043;#043;#063;#063;
	#060;#061;#020;#021; #040;#041;#060;#061; #061;#061;#021;#021; #041;#041;#061;#061;
	#062;#063;#022;#023; #042;#043;#062;#063; #063;#063;#023;#023; #043;#043;#063;#063 ]

	{NewInst}=0; //keep SStkp=0 for test 22401
	{ALUF.2}=1; //for prom f2 address = xxxx x1x0 and outputs = 1111 (page 16)
	            //to keep MC1XferWord=1 when ClockAd (for Suspend←MC1NeedsR)

//Write all R locations with their own addresses as data:

	{Stkp←ALUA'}=1; //keep Stkp=0
	{MemInst/d}=1; //enable b13 prom (page 11) for MC1Ad←Stkp+0 when SRC/DEST=0 (i.e. when i=0)
	{mcbus}=#12; //write into R (address from MC1Ad)
	ClockMIR() //MemInst←1, Suspend←1, RSA,B←4,6

	for i = 0 to 255 do 
	[
		{MC1SA}=i
		{rbus}=i
		ClockAd()  //MC1Ad←i
		RClock()
		ClockMC2() //MC2Ad←(MC1Ad=i)
		           //reset EnMapRow (avoid StorA bus conflict)
	]

//Set up constants in registers for remainder of test:

	//MC2Ad=#377 from the loop above (for error indication in case RSA,B←6,7 during loop later)
	{MC1SA}=#074; //for H2←#360 (BSEL=0, F1=#17)
	{rbus}=###
	{mcbus}=0
	{MemInst/d}=0
	ClockMIR() //load MIR: MemInst=0, RMOD=1, RSEL=01 11 11 (open rbus)
	           //reset Suspend

	{Stkp←ALUA'}=0; //for load Stkp
	{rbus}=#210
	EClock() //H1←#210, H2←(0,0,F1,F2=#360)
	{rbus}=###
	ClockCycle1() //Stkp←(ALUA=#210), RSA,B←3,3(Stkp)

	{rbus}=#104
	EClock() //H1←#104, RASAVE←(RA=Stkp=#210)
	{rbus}=###
	ClockCycle1() //Stkp←(ALUA=#104), WA←(RASAVE=#210)

	//Set up: PCF[1:2]=0, SBX[0:1]=1, DBX[0:1]=2
	{SBX.1}=1
	{DBX.0}=1

	//Set up CTask[0:3]=3 to distinguish between RSA[0:2] = 0 and 1
	{CTask}=3

//Abort'←0 for remainder of test
	//it is required for ProcCycleS = (Abort.Cycle0'+Suspend).MemNeedsR'
	//it resets AbortDly' (page 6) on the next Cycle1 clock (ClockMIR)
	//it conveniently inhibits the GoCycle1 input to clkCycle1' and clkWA', hence
	//Stkp remains =#104 and WA remains =#210
	{Abort'}=0

	{mirbus}=#1540; //MemInst=0, RMOD=0, RSEL=00 00 00
	{MC1SA}=#356; //for MC1Ad←#356 in the loop to follow

//{t22drive: Cycle0Feed',MemInst/d,  RMOD/d',RSEL.4/d,RSEL.5/d,  RSEL.0/d',RSEL.1/d',MC1NeedsR}

	for i = 0 to 255 do
	[
		{t22drive} = i xor #247
		           //Cycle0←i[8]

		ClockMIR() //selected MIR bits ← i[9:14], (RSEL4and5 flip-flop stays =0)
		           //Suspend' ←i[15] (MC1XferWord is kept =1)
		           //reset AbortDly' (inhibits clkH2' (page 15), keeping H2=#260)
		           //reset i1 flip-flop (page 14), hence RAD7=RSEL.5 unless
		           //conditions set i1 on the following clock
 
		{MC1NeedsR}=0; //enable ProcCycleS if Cycle0=0 or Suspend=1
		               //MemNeedsR←0 for Suspend←0 on next clock

		ClockAd()  //The b2 prom (page 13) address bits now = i

		           //RSA,B←x,x if Cycle0=0 or  Suspend=1 (i.e. ProcCycleS=1), or
  		           //RSA,B←2,5 if Cycle0=1 and Suspend=0 and MemInst=0, or
		           //RSA,B←0,4 if Cycle0=1 and Suspend=0 and MemInst=1 and RSEL[0:1]#0, or
		           //RSA,B←1,4 if Cycle0=1 and Suspend=0 and MemInst=1 and RSEL[0:1]=0, or

		           //MC1Ad←(MC1SA=#356), for error indication if RSA,B←4,6)
		           //Suspend←0
		           //set i1 flip-flop if Cycle0=1 and Suspend=0
		           //if i1 is set, RAD7=1 (otherwise RAD7=RSEL.5)

		{Cycle0Feed'}=0; //for rbus←R when MemInst=0
		WCompare({rbus},t22sb!i,22000,i) //fails when i = #3x1 if no rev. L
	]


//Check that AbortDly'=0 inhibited clkH2'
//and prevented H2←(0,0,0,F2=0) at the end of the above loop

	WCompare({H2},#360,22300)


//Check that RUN=0 DC resets MemInst, MemInstFast,
//and DC sets RMOD, RSEL.0, and RSEL.1 (page 19)

	{mirbus}=#2377; //MemInst=1, RMOD=0, RSEL=00 11 11
	ClockMIR() //Load MIR (all bits except RSEL[2:5] will be reversed by RUN=0

	{RUN}=0; //MemInst←0, RMOD←1, RSEL[0:1]←11, (RSEL[2:5] stay =11 11)
	{RUN}=1; //return to normal
	WCompare({MemInst-a},0,22400) //MemInst-a is an inverter on MemInstFast'

	//The MIR configuration established by RUN=0 should cause Stkp←Stkp-2
	//Stkp=#104 from prior logic, SStkp=0 since NewInst=0 from start of test
	//StackShift'=1 from SpeakTest initialization

	{Abort'}=1; //return to normal so Stkp gets ClockCycle1
	{Stkp←ALUA'}=1; //enable Stkp count

	{mirbus}=#1547; //MemInst=0, RMOD=1, RSEL=00 00 11
	ClockMIR() //Stkp←Stkp-2 (#104-2), rbus←SStkp,Stkp'
	WCompare(not {rbus},#177502,22401) //test fails if I revision not installed
]

//**************************************************************************************
//Test 23: Test the MC1Ad, MC2Ad, and MC2CAd functions not tested elsewhere (pages 16,20)

let Test23() be
[
	SpeakTest(23) //set initial conditions (see notes at end of ALU.TST)

	//NOTE: Each address of the R file contains its own address as data
	//      (This was established in Test 22)

	//Set up initial conditions:

	{Cycle0Feed'}=1; //keep H1[14:15]=3 and H2[14:15]=0 for prom f2 addressing (page 16)
	{Stkp←ALUA'}=1;  //keep Stkp=0


//PART 1: Check that MC1Ad[4:7] and MC2Ad[4:7] increment properly

	{ALUF.2}=1; //for prom f2 address = xxxx x1x0 and ouput = 1111
	            //for MC1XferWord←1 and MC1XWdly←1 when ClockAd (page 16)

	{MC1SA}=#23
	ClockAd()  //MC1Ad←(MC1SA=#23), MC1XferWord←1, MC1XWdly←1
	ClockMC2() //MC2Ad←(MC1Ad=#23), MC2XferWord←(MC1XferWord=1)

	{MC1SA}=#20; //make MC1Ad different from MC2Ad
	ClockAd()  //MC1Ad←(MC1SA=#20), MC2XWdly←(MC2XferWord=1)

	for i = 0 to 16 do
	[
		{MC1NeedsR}=1
		EClock() //(no incrementing since MC1HasR=MC2HasR=0)
		         //MC1HasR←1, MC2HasR←0, Suspend←1
		         //RSA,B←4,6 (RA←MC1Ad)
		WCompare({rbus},#20 % i,23100,i) //rbus=RA=MC1Ad

		{MC1NeedsR}=0
		{MC2WillGetR}=1
		EClock() //MC1Ad[4:7] increments since MC1HasR=1 and MC1XWdly=1
		         //MC1HasR←0, MC2HasR←1, Suspend←1
		         //RSA,B←6,7 (RA←MC2Ad)
		WCompare({rbus},#20 % (i+3),23101,i) //rbus=RA=MC2Ad

		{MC2WillGetR}=0
		EClock() //MC2Ad[4:7] increments since MC2HasR=1 and MC2XWdly=1
		         //MC1HasR←0, MC2HasR←0, Suspend←0
	]


//PART 2: Check that MC1Ad[4:7] does not increment when MC1XWdly=0

	{aluf}=0; //for prom f2 address = 1100 1000 and outputs = 0001 (page 16)
	ClockAd() //MC1Ad←(MC1SA=#20)
	          //g2 ff's ← (prom f2 =0001) (MC1XferWord←0, MC1XWdly←1) (page 16)

	{MC1NeedsR}=1

	for i = 0 to 3 do
	[
		EClock() //g2 ff's left-cycle since ShiftMC1XW'=0 (page 16):
		         //    i=0 => g2's ← 0010 (MC1XferWord←0, MC1XWdly←0)
		         //           MC1HasR←1 
		         //    i=1 => g2's ← 0100 (MC1XferWord←0, MC1XWdly←0)
		         //    i=2 => g2's ← 1000 (MC1XferWord←1, MC1XWdly←0)
		         //    i=3 => Suspend←1, RSA,B←4,6 (RA←MC1Ad) (since MC1XferWord=1)
		         //           g2's ← 0001 (MC1XferWord←0, MC1XWdly←1)
	]

	WCompare({rbus},#20,23200) //rbus=RA=(MC1Ad still =#20)


//PART 3: Check that MC2Ad[4:7] does not increment when MC2XWdly=0

	{MC1NeedsR}=0
	ClockMC2() //MC2Ad←(MC1Ad=#20)
	           //MC2CAd[4:7]←(MC1Ad[4:7]=0) 
	           //h2 ff's ← (g2 ff's =0001) (MC2XferWord←0), MC2XWdly←(MC2XferWord=1)
	           //(MC1Ad increments to #21 since MC1HasR=1 and MC1XWdly=1)
	           //MC1HasR←0 
 
	{MC2WillGetR}=1

	for i = 0 to 3 do
	[
		EClock() //h2 ff's left-cycle since MC2WillGetR'=0 (page 16):
		         //    i=0 => h2's ← 0010 (MC2XferWord←0), MC2XWdly←(MC2XferWord=0)
		         //           MC2HasR←1 
		         //    i=1 => h2's ← 0100 (MC2XferWord←0), MC2XWdly←(MC2XferWord=0)
		         //    i=2 => h2's ← 1000 (MC2XferWord←1), MC2XWdly←(MC2XferWord=0)
		         //    i=3 => Suspend←1, RSA,B←6,7 (RA←MC2Ad) (since MC2XferWord=1)
		         //           h2's ← 0001 (MC2XferWord←0), MC2XWdly←(MC2XferWord=1)
	]

	WCompare({rbus},#20,23300) //rbus=RA=(MC2Ad still =#20)


//PART 4: Check that the MC2Compb comparator (page 20) compares MC2CAd[4:7] with RA[4:7]
//        (instead of MC2Ad[4:7] as in un-modified rev. J boards)

	//Status: MC2Ad[4:7]=0, MC2CAd[4:7]=0, Stkp=0
	//        MC2HasR=1, MC2XWdly=1, MC2XferWord=0, MC2WillGetR=1

	EClock() //MC2Ad[4:7] increments from 0 to 1 since MC2HasR=1 and MC2XWdly=1
	         //MC2CAd[4:7] remains =0
	         //(RSA,B←(ProcCycleS data) since Suspend=1 and MemNeedsR=0)
	         //Suspend←0 (since MC2XferWord=0)
	         //h2 ff's left-cycle (MC2XferWord←0), MC2XWdly←(MC2XferWord=0)
	EClock() //RSA,B←3,3 (RA←(Stkp=0)) for MC2Compb input

	//Check that (MC2CAd[4:7]=0) = (RA[4:7]=Stkp[4:7]=0)
	//This will fail in unmodified rev. J boards since
	//            (MC2Ad[4:7]=1) # (RA[4:7]=Stkp[4:7]=0)
	WCompare({MC2Compb},1,23400) //if stop, check "blue-wire" change to location a10


//PART 5: Check the MC2Ad[4:7]←MC2CAd[4:7] logic (page 20)

	{ALUF.2}=1; //for prom f2 address = xxxx x1x0 and ouput = 1111
	            //for MC1XferWord←1 and MC1XWdly←1 when ClockAd (page 16)
	{MC2HoldIfSNE0}=1; //for MC2Ad[4:7]←MC2CAd[4:7] (b9 mux. - page 20)
	//MC2WillGetR still =1

	for i = 0 to 15 do
	[
		{MC1SA} = #20 % i
		ClockAd()  //MC1Ad←(MC1SA=#20%i), MC1XferWord←1, MC1XWdly←1
		ClockMC2() //MC2Ad←(MC1Ad=#20%i), MC2XferWord←(MC1XferWord=1)

		{MC1SA}=#20; //make MC1Ad[4:7] # MC2CAd[4:7] for failure detection
		ClockAd() //MC1Ad←(MC1SA=#20), MC2XWdly←(MC2XferWord=1)
		EClock()  //MC2Ad←(MC1Ad[0:3]=1),,(MC2CAd[4:7]=i)
		          //RSA,B←6,7 (RA←MC2Ad) (MC2WillGetR=1 and MC2XferWord=1)
		WCompare({rbus},#20 % i,23500,i) //rbus=RA=MC2Ad
	]
]

//**************************************************************************************
//Test 24: Check that RUN=0 DC resets the g2 and h2 flip-flops (page 16)
//         (This feature was added by revision L)

let Test24() be
[
	SpeakTest(24) //set initial conditions (see notes at end of ALU.TST)

	//the g2 and h2 ff's contain all 1's from SpeakTest initialization

	{MC2WillGetR}=1; //enable left-cycle h2 ff's

	for i = 1 to 2 do
	[
		{RUN}=i; //DC reset g2 and h2 ff's when i=2
		{RUN}=1; //restore to normal

		for j = 0 to 3 do //check state of h2 ff's
		[
			WCompare({MC2XferWord},i&1,24000+i,j)
			EClock() //left-cycle h2 ff's
		]

		ClockMC2() //h2 ff's ← g2 ff's

		for j = 0 to 3 do //check state of g2 ff's via the h2 ff's
		[
			WCompare({MC2XferWord},i&1,24010+i,j)
			EClock() //left-cycle h2 ff's
		]
	]
]