{ 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;