{ChipTest.mc, HGM, 4-Nov-84 2:29:05}
{Chip Tester for Dicentra memory. See FTCS-7 pg 81.}
Reserve[0F5F, 0FFF]; {section used by the CP Kernel }
SetTask[0]; StartAddress[Go];
RegDef[bank, R, 0]; {Current bank}
RegDef[highBank, U, 0]; {Highest bank to test}
RegDef[lowBank, U, 1]; {Lowest bank to test}
RegDef[address, R, 1]; {Word within bank}
RegDef[rhAddr, RH, 1];
RegDef[addres2, R, 2];
RegDef[rhAdr2, RH, 2];
RegDef[expected, R, 3];
RegDef[rhEx, RH, 3];
RegDef[found, R, 4];
RegDef[found2, R, 5];
RegDef[found3, R, 6];
RegDef[diff, U, 10];
RegDef[picked, U, 11];
RegDef[dropped, U, 12];
RegDef[rA, R, 0A];
RegDef[rB, R, 0B];
RegDef[rC, R, 0C];
RegDef[passCount, R, 0E]; {number of good passes}
RegDef[test, RH, 0E]; {current test}
Set[Test.Zero, 0];
Set[Test.One, 1];
Set[Test.Two, 2];
Set[Test.Three, 3];
Set[Test.Four, 4];
Trap: rA ← RRot1 ErrnIBnStkp, ClrIntErr, CANCELBR[$, 0F], c1, at[0];
Xbus ← rA LRot0, XwdDisp, c2;
DISP2[TrapType], c3;
Parity: GOTO[GoToGo], c1, at[0,4,TrapType];
Init: GOTO[GoToGo], c1, at[1,4,TrapType];
Stack: GOTO[GoToGo], c1, at[2,4,TrapType];
IB: GOTO[GoToGo], c1, at[3,4,TrapType];
GoToGo:
Noop, c2;
Noop, GOTO[Go], c3;
Go: rhAdr2 ← 0, c1;
Noop, c2;
Noop, c3;
addres2 ← 010, c1;
addres2 ← addres2 LRot8, c2;
addres2 ← addres2 + 018, c3;
IO ← [rhAdr2, addres2 + 0], c1;
MDR ← 0A, {Disarm 40.96ms int and Watchdog} c2;
Noop, c3;
IO ← [rhAdr2, addres2 + 0], c1;
MDR ← 040, {Ack it (in case)} c2;
Noop, c3;
{Give interrupt time to go away.}
Noop, c1;
Noop, c2;
Noop, c3;
Noop, c1;
Noop, c2;
Noop, c3;
passCount ← 0, test ← Test.Zero, ClrIntErr, c1;
ExtCtrl ← 5, {Init Incr, Zero, UnBlank} c2;
addres2 ← 0, GOTO[MainLoop], c3;
{------------------------------------------------------------------------------------}
MainLoop:
Noop, c1;
MainLoop2:
Noop, c2;
MainLoop3:
bank ← lowBank, c3;
NewBank:
Noop, c1;
rhAddr ← bank LRot0, MesaIntBr, c2;
rhAdr2 ← bank LRot0, BRANCH[$, MesaInt], c3;
Noop, c1;
Xbus ← test, XDisp, c2;
DISP4[DoIt], c3;
NextBank:
Noop, c2;
bank ← bank + 1, c3;
Q ← highBank, c1;
Q ← Q - bank, NegBr, c2;
BRANCH[NewBank, NextTest], c3;
NextTest:
ExtCtrl ← 3, {Gets Bumped on rising edge} c1;
ExtCtrl ← 7 c2;
Xbus ← test, XDisp, c3;
RET[NewTest], c1;
{------------------------------------------------------------------------------------}
ZeroFinished:
addres2 ← 0, c2, at [Test.Zero, 10, NewTest];
test ← Test.One, GOTO[MainLoop], c3;
OneFinished:
addres2 ← addres2 + 1, CarryBr, c2, at [Test.One, 10, NewTest];
BRANCH[$, DoTestTwo], c3;
GOTO[MainLoop2], c1;
DoTestTwo:
addres2 ← 0, c1;
test ← Test.Two, GOTO[MainLoop3], c2;
TwoFinished:
addres2 ← addres2 + 1, CarryBr, c2, at [Test.Two, 10, NewTest];
BRANCH[$, DoTestThree], c3;
GOTO[MainLoop2], c1;
DoTestThree:
addres2 ← addres2 xor ~addres2, c1;
test ← Test.Three, GOTO[MainLoop3], c2;
ThreeFinished:
addres2 ← addres2 - 1, CarryBr, c2, at [Test.Three, 10, NewTest];
BRANCH[DoTestFour, $], c3;
GOTO[MainLoop2], c1;
DoTestFour:
addres2 ← addres2 xor ~addres2, c1;
test ← Test.Four, GOTO[MainLoop3], c2;
FourFinished:
addres2 ← addres2 - 1, CarryBr, c2, at [Test.Four, 10, NewTest];
BRANCH[DoTestOne, $], c3;
GOTO[MainLoop2], c1;
DoTestOne:
passCount ← passCount + 1, c1;
addres2 ← 0, c2;
test ← Test.One, GOTO[MainLoop] c3;
{------------------------------------------------------------------------------------}
{Initialize whole world to 0.}
WriteZeros:
expected ← 0, c1, at[Test.Zero,10,DoIt];
address ← 0, c2;
Noop, c3;
WriteZeroLoop:
MAR ← [rhAddr, address + 0], c1;
MDR ← expected, address ← address + 1, CarryBr, c2;
BRANCH[WriteZeroLoop, $], c3;
GOTO[NextBank], c1;
{------------------------------------------------------------------------------------}
{Do Up transition in forward scan.}
PassOne:
expected ← 0, GOTO[Forward], c1, at[Test.One,10,DoIt];
{Do Down transition in forward scan.}
PassTwo:
expected ← expected xor ~expected, GOTO[Forward], c1, at[Test.Two,10,DoIt];
Forward:
address ← addres2, c2;
[] ← 0, ZeroBr, c3;
{Check [addres2..FFFF].}
ForwardA:
MAR ← [rhAddr, address + 0], BRANCH[BugFA1, $], c1;
address ← address + 1, CarryBr, c2;
found ← expected xor MD, ZeroBr, BRANCH[ForwardA, $], c3, LOOPHOLE[stw];
BRANCH[BugFA2, $], c1;
expected ← ~expected, c2;
Noop, c3;
ForwardStore:
MAR ← [rhAdr2, addres2 + 0], c1;
MDR ← expected, c2;
Noop, c3;
address ← addres2, c1;
Noop, c2;
[] ← 0, ZeroBr, c3;
{Check [0..addres2] (scanning backwards).}
ForwardB:
MAR ← [rhAddr, address + 0], BRANCH[BugFB1, $], c1;
address ← address - 1, CarryBr, c2;
found ← expected xor MD, ZeroBr, BRANCH[$, ForwardB], c3, LOOPHOLE[stw];
ForwardEnd:
BRANCH[BugFB2, $], c1;
Noop, c2;
Noop, c3;
GOTO[NextBank], c1;
{------------------------------------------------------------------------------------}
{Do Up transition in reverse scan.}
PassThree:
expected ← 0, GOTO[Reverse], c1, at[Test.Three,10,DoIt];
{Do Down transition in reverse scan.}
PassFour:
expected ← ~expected xor expected, GOTO[Reverse], c1, at[Test.Four,10,DoIt];
Reverse:
address ← addres2, c2;
[] ← 0, ZeroBr, c3;
{Check [0..addres2] (scanning backwards).}
ReverseA:
MAR ← [rhAddr, address + 0], BRANCH[BugRA1, $], c1;
address ← address - 1, CarryBr, c2;
found ← expected xor MD, ZeroBr, BRANCH[$, ReverseA], c3, LOOPHOLE[stw];
BRANCH[BugRA2, $], c1;
expected ← ~expected, c2;
Noop, c3;
ReverseStore:
MAR ← [rhAdr2, addres2 + 0], c1;
MDR ← expected, c2;
Noop, c3;
address ← addres2, c1;
Noop, c2;
[] ← 0, ZeroBr, c3;
{Check [addres2..FFFF].}
ReverseB:
MAR ← [rhAddr, address + 0], BRANCH[BugRB1, $], c1;
address ← address + 1, CarryBr, c2;
found ← expected xor MD, ZeroBr, BRANCH[ReverseB, $], c3, LOOPHOLE[stw];
ReverseEnd:
BRANCH[BugRB2, $], c1;
Noop, c2;
ReverseEnd3:
Noop, c3;
GOTO[NextBank], c1;
{------------------------------------------------------------------------------------}
BugFA1: found ← found xor expected, CANCELBR[Retreat], c2;
BugFA2: found ← found xor expected, CANCELBR[Retreat], c2;
BugFB1: found ← found xor expected, CANCELBR[Advance], c2;
BugFB2: found ← found xor expected, CANCELBR[Advance], c2;
BugRA1: found ← found xor expected, CANCELBR[Advance], c2;
BugRA2: found ← found xor expected, CANCELBR[Advance], c2;
BugRB1: found ← found xor expected, CANCELBR[Retreat], c2;
BugRB2: found ← found xor expected, CANCELBR[Retreat], c2;
Advance: address ← address + 1, GOTO[Error], c3;
Retreat: address ← address - 1, GOTO[Error], c3;
Error: Noop, c1;
Noop, c2;
found2 ← MD, c3, LOOPHOLE[mdok];
MAR← [rhAddr, address + 0], c1;
Noop, c2;
found3 ← MD, c3;
Q ← found xor expected, c1;
diff ← Q, c2;
Noop, c3;
rA ← Q and ~expected, c1;
picked ← rA, c2;
Noop, c3;
rA ← Q and expected, c1;
dropped ← rA, c2;
Noop, c3;
DataMismatch:
Noop, c1;
Noop, c2;
GOTO[Go], c3;
{------------------------------------------------------------------------------------}
MesaInt:
addres2 ← 010, c1;
addres2 ← addres2 LRot8, c2;
addres2 ← addres2 + 018, c3;
IO ← [rhAdr2, addres2 + 0], c1;
rB ← ExtStat, c2;
rA ← MD, c3;
MesaIntIsProbablyAParityError:
Noop, c1;
Noop, c2;
GOTO[Go], c3;
{------------------------------------------------------------------------------------}