{MemTest.mc, HGM, 14-Apr-85 4:03:57 Dicentra memory test. From Cucinitti's Syzygy of November 14, 1979 7:22 AM, The random number generator was supplied by Bob Garner} Reserve[0F5F, 0FFF]; {section used by the CP Kernel } SetTask[0]; StartAddress[Go]; RegDef[bank, R, 0]; {Current bank} 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[toAddr, R, 5]; RegDef[toAddrHi, RH, 5]; RegDef[highBank, U, 0]; {Highest bank to test} RegDef[lowBank, U, 1]; {Lowest bank to test} RegDef[errorCount, U, 10]; {Zeroed by Burdock.} RegDef[diff, U, 11]; RegDef[picked, U, 12]; RegDef[dropped, U, 13]; RegDef[sticky, U, 20]; {Stick to this test. Neg to ingore.} RegDef[cc, R, 7]; {index for current constant} RegDef[const, R, 8]; {value of current constant} RegDef[oldConst, R, 9]; {value of constant on previous pass} RegDef[rA, R, 0A]; RegDef[rB, R, 0B]; RegDef[rC, R, 0C]; RegDef[r3619, R, 0D]; RegDef[passCount, R, 0E]; {number of good passes} RegDef[test, RH, 0E]; {test=passCount, current test} RegDef[toData, U, 40]; RegDef[toCommand, U, 41]; RegDef[found2, U, 42]; RegDef[found3, U, 43]; RegDef[goodPasses, U, 44]; RegDef[reason, U, 45]; {Tell command file what's going on} Set[Test.Write, 0]; Set[Test.Read, 1]; Set[Test.WriteC, 2]; Set[Test.ReadC, 3]; Set[Test.FlipC, 4]; Set[Test.WriteA, 5]; Set[Test.ReadA, 6]; Set[Test.WriteRot, 7]; Set[Test.ReadRot, 8]; Set[Test.WriteRead, 9]; Set[Test.Scan, 0A]; Set[Test.Flap, 0B]; Set[Test.MapWrite, 0D]; Set[Test.MapRead, 0E]; Set[Test.MapVerify, 0F]; Set[Test.WriteRef, 10]; Set[Test.WriteRefx, 00]; Set[Test.ReadRef, 11]; Set[Test.ReadRefx, 01]; Set[cc.First, 0]; Set[cc.0000, 00]; Set[cc.FFFF, 01]; Set[cc.5555, 02]; Set[cc.AAAA, 03]; Set[cc.3333, 04]; Set[cc.6666, 05]; Set[cc.CCCC, 06]; Set[cc.9999, 07]; Set[cc.000F, 08]; Set[cc.00F0, 09]; Set[cc.0F00, 0A]; Set[cc.F000, 0B]; Set[cc.00FF, 0C]; Set[cc.0FF0, 0D]; Set[cc.FF00, 0E]; Set[cc.F00F, 0F]; Set[cc.0101, 00]; Set[cc.0202, 01]; Set[cc.0404, 02]; Set[cc.0808, 03]; Set[cc.1010, 04]; Set[cc.2020, 05]; Set[cc.4040, 06]; Set[cc.8080, 07]; Set[cc.FEFE, 08]; Set[cc.FDFD, 09]; Set[cc.FBFB, 0A]; Set[cc.F7F7, 0B]; Set[cc.EFEF, 0C]; Set[cc.DFDF, 0D]; Set[cc.BFBF, 0E]; Set[cc.7F7F, 0F]; Set[cc.0303, 00]; Set[cc.0606, 01]; Set[cc.0C0C, 02]; Set[cc.1818, 03]; Set[cc.3030, 04]; Set[cc.6060, 05]; Set[cc.C0C0, 06]; Set[cc.8181, 07]; Set[cc.FCFC, 08]; Set[cc.F9F9, 09]; Set[cc.F3F3, 0A]; Set[cc.E7E7, 0B]; Set[cc.CFCF, 0C]; Set[cc.9F9F, 0D]; Set[cc.3F3F, 0E]; Set[cc.7E7E, 0F]; Set[cc.1111, 00]; Set[cc.2222, 01]; Set[cc.4444, 02]; Set[cc.8888, 03]; Set[cc.EEEE, 04]; Set[cc.DDDD, 05]; Set[cc.BBBB, 06]; Set[cc.7777, 07]; Set[cc.Last, 37]; Set[Setup0, 0]; Set[Setup1, 1]; Set[Setup2, 2]; Set[Setup3, 3]; Set[Setup4, 4]; Set[Setup5, 5]; Set[Setup6, 6]; Set[Setup7, 7]; Set[Setup8, 8]; Set[Setup9, 9]; Set[SetupA, 0A]; Set[SetupB, 0B]; Set[SetupC, 0C]; Set[SetupD, 0D]; Set[Fetch0, 0]; Set[Fetch1, 1]; Set[Fetch2, 2]; Set[Fetch3, 3]; Set[Fetch4, 4]; Set[Fetch5, 5]; Set[Info0, 0]; Set[Info1, 1]; 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: r3619 ← 36, c1; r3619 ← r3619 LRot8, c2; r3619 ← r3619 or 19, {r3619 ← 3619} c3; rhAddr ← 0, c1; Noop, c2; Noop, c3; {Setup Misc Board to Interrupt on XACK Timeout} rhAdr2 ← 4, {Misc CIO Chip} c1; addres2 ← 090, c2; addres2 ← addres2 LRot8, {9000} c3; rA ← addres2 + 0, L0 ← Setup0, {Master Control} c1; Q ← 1, CALL[Setup], {Reset} c2; Noop, c3, at[Setup0, 10, SetupRet]; rA ← addres2 + 0, L0 ← Setup1, {Master Control} c1; Q ← 00, CALL[Setup], {Clear Reset} c2; Noop, c3, at[Setup1, 10, SetupRet]; rA ← addres2 + 0, L0 ← Setup2, {Master Control} c1; Q ← 080, CALL[Setup], {MIE} c2; Noop, c3, at[Setup2, 10, SetupRet]; rA ← addres2 + 20, L0 ← Setup3, {Port A Mode} c1; Q ← 0, CALL[Setup], {Bit Port} c2; Noop, c3, at[Setup3, 10, SetupRet]; rA ← addres2 + 23, L0 ← Setup5, {Port A Direction} c1; Q ← 0FF, CALL[Setup], {All Bits Input} c2; Noop, c3, at[Setup5, 10, SetupRet]; rA ← addres2 + 0E, L0 ← Setup6, {Port B Data} c1; Q ← 0F, CALL[Setup], {Disable all outputs} c2; Noop, c3, at[Setup6, 10, SetupRet]; rA ← addres2 + 2B, L0 ← Setup7, {Port B Direction} c1; Q ← 0F0, CALL[Setup], {Output on low 4 bits} c2; Noop, c3, at[Setup7, 10, SetupRet]; rA ← addres2 + 1, L0 ← Setup8, {Master Config Control} c1; Q ← 084, CALL[Setup], {Enable Ports A+B} c2; Noop, c3, at[Setup8, 10, SetupRet]; rA ← addres2 + 2C, L0 ← Setup9, {Port B Special IO} c1; Q ← 40, CALL[Setup], {ONEs Catcher for TOXack} c2; Noop, c3, at[Setup9, 10, SetupRet]; rA ← addres2 + 2D, L0 ← SetupA, {Port B Polarity} c1; Q ← 40, CALL[Setup], c2; Noop, c3, at[SetupA, 10, SetupRet]; rA ← addres2 + 2F, L0 ← SetupB, {Port B Mask} c1; Q ← 40, CALL[Setup], c2; Noop, c3, at[SetupB, 10, SetupRet]; rA ← addres2 + 09, L0 ← SetupC, {Port B Command} c1; Q ← 0C0, CALL[Setup], {Set Interrupt Enable} c2; Noop, c3, at[SetupC, 10, SetupRet]; rA ← addres2 + 28, L0 ← Setup4, {Port B Mode} c1; Q ← 4, CALL[Setup], {Bit Port, OR Matcher} c2; Noop, c3, at[Setup4, 10, SetupRet]; ExtCtrl ← 5, {Init Incr, Zero, UnBlank} c1; Noop, c2; Noop, c3; passCount ← 0, test ← Test.Write, ClrIntErr, c1; goodPasses ← 0, c2; reason ← 0, GOTO[MainLoop], c3; {------------------------------------------------------------------------------------} MainLoop: Q ← sticky, c1; [] ← Q, NegBr, c2; BRANCH[$, MainLoopNext], c3; test ← Q LRot0, c1; Noop, c2; Noop, c3; MainLoopNext: bank ← lowBank, c1; expected ← passCount LRot8, c2; expected ← expected + passCount, c3; NewBank: {Put current bank number in decimal points.} Q ← bank, c1; rA ← Q, c2; rA ← rA LRot4, c3; ExtCtrl ← rA or 7, c1; Noop, c2; Noop, c3; rhAddr ← bank LRot0, c1; address ← 0, c2; expected ← (expected + bank) LRot1, c3; rA ← LShift1 expected, c1; Random: rB ← expected and 0FF, c2; rB ← rB LRot12, c3; rB ← rB RRot1, c1; expected ← expected + rA, MesaIntBr, c2; expected ← expected + rB, BRANCH[$, MesaInt], c3; expected ← expected + r3619, c1; Noop, c2; Q ← test, c3; Xbus ← Q LRot12, XDisp, c1; Xbus ← test, XDisp, DISP4[DoWordHigh], c2; DoWordHigh: DISP4[DoWord0], c3, at[0, 10, DoWordHigh]; DISP4[DoWord1], c3, at[1, 10, DoWordHigh]; NextWord: address ← address + 1, CarryBr, c3; rA ← LShift1 expected, BRANCH[Random, $], c1; NextBank: MesaIntBr, c2; BRANCH[$, MesaIntBank], c3; Noop, c1; 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; Noop, c3; Q ← test, c1; Xbus ← Q LRot12, XDisp, c2; Xbus ← test, XDisp, DISP4[NewTestHigh], c3; NewTestHigh: DISP4[NewTest0], c1, at[0, 10, NewTestHigh]; DISP4[NewTest1], c1, at[1, 10, NewTestHigh]; {------------------------------------------------------------------------------------} WriteFinished: test ← Test.Read, c2, at [Test.Write, 10, NewTest0]; GOTO[MainLoopNext], c3; ReadFinished: test ← Test.WriteC, c2, at [Test.Read, 10, NewTest0]; cc ← cc.First, GOTO[MainLoop], c3; WriteCFinished: test ← Test.ReadC, c2, at [Test.WriteC, 10, NewTest0]; oldConst ← const, GOTO[MainLoopNext], c3; ReadCFinished: test ← Test.FlipC, c2, at [Test.ReadC, 10, NewTest0]; oldConst ← const, GOTO[MainLoopNext], c3; FlipCFinished: {check for another constant} Q ← cc.Last, c2, at [Test.FlipC, 10, NewTest0]; [] ← cc xor Q, ZeroBr, c3; cc ← cc + 1, BRANCH[NextConst, $], c1; test ← Test.WriteA, c2; GOTO[MainLoop], c3; NextConst: test ← Test.ReadC, c2; oldConst ← const, GOTO[MainLoop], c3; WriteAFinished: test ← Test.ReadA, c2, at [Test.WriteA, 10, NewTest0]; GOTO[MainLoopNext], c3; ReadAFinished: test ← Test.WriteRot, c2, at [Test.ReadA, 10, NewTest0]; const ← 1, c3; RotThisConst: Noop, c1; Noop, c2; oldConst ← const, GOTO[MainLoop], c3; WriteRotFinished: test ← Test.ReadRot, c2, at [Test.WriteRot, 10, NewTest0]; const ← oldConst, GOTO[MainLoopNext], c3; ReadRotFinished: const ← LRot1 oldConst, c2, at [Test.ReadRot, 10, NewTest0]; [] ← const xor 1, ZeroBr, c3; [] ← const xor ~1, NZeroBr, BRANCH[$, RotHole], c1; BRANCH[$, RotNext], c2; test ← Test.WriteRead, GOTO[MainLoop], c3; RotHole: const ← ~1, CANCELBR[$], c2; RotNext: test ← Test.WriteRot, GOTO[RotThisConst], c3; WriteReadFinished: test ← Test.Scan, c2, at [Test.WriteRead, 10, NewTest0]; GOTO[MainLoop], c3; ScanFinished: test ← Test.Flap, c2, at [Test.Scan, 10, NewTest0]; GOTO[MainLoop], c3; FlapFinished: test ← Test.MapWrite, c2, at [Test.Flap, 10, NewTest0]; GOTO[MainLoop], c3; SkipMapWrite2: Noop, c3; SkipMapWrite1: GOTO[MapVerifyFinished], c1; MapWriteFinished: test ← Test.MapRead, c2, at [Test.MapWrite, 10, NewTest0]; GOTO[MainLoop], c3; MapReadFinished: test ← Test.MapVerify, c2, at [Test.MapRead, 10, NewTest0]; GOTO[MainLoop], c3; MapVerifyFinished: test ← Test.WriteRef, c2, at [Test.MapVerify, 10, NewTest0]; GOTO[MainLoop], c3; WriteRefFinished: test ← Test.ReadRef, c2, at [Test.WriteRefx, 10, NewTest1]; rB ← 200'd, c3; {I've got a board that only dies when running a real program. Try waiting longer.} rB ← LShift1 rB, c1; rB ← LShift1 rB, c2; rB ← LShift1 rB, c3; { Don't touch memory for a while to give the bits a chance to fall through the cracks in case refresh is broken. With a 16MHz clock, an instruction takes 125 ns. 3*125ns*65000 => 25ms. 5sec/25ms => 200} Dally: Noop, c1; rA ← rA - 1, ZeroBr, c2; Dally3: BRANCH[Dally, $], c3; Noop, c1; rA ← rB and 0F0, c2; ExtCtrl ← rA or 7, c3; rB ← rB - 1, ZeroBr, c1; rA ← 0, BRANCH[Dally3, $], c2; GOTO[MainLoop], c3; ReadRefFinished: test ← Test.Write, c2, at [Test.ReadRefx, 10, NewTest1]; GOTO[PassFinished], c3; PassFinished: passCount ← passCount + 1, c1; Q ← 1, c2; reason ← Q, c3; Q ← goodPasses, c1; Q ← Q + 1, c2; goodPasses ← Q, c3; AnotherGoodPass: Q ← Q - 100'd, c1; [] ← Q, ZeroBr, c2; reason ← 0, BRANCH[MainLoop, $], c3; Noop, c1; Q ← 2, c2; reason ← Q, c3; AnotherHundredGoodPasses: Noop, c1; goodPasses ← 0, c2; reason ← 0, GOTO[MainLoop], c3; {------------------------------------------------------------------------------------} {Write random data} WriteRef: MAR ← [rhAddr, address + 0], RawRef, GOTO[Writex], c1, at[Test.WriteRefx, 10, DoWord1]; Write: MAR ← [rhAddr, address + 0], RawRef, c1, at[Test.Write, 10, DoWord0]; Writex: MDR ← expected, GOTO[NextWord], c2; {Read and compare with random data} ReadRef: MAR ← [rhAddr, address + 0], RawRef, GOTO[Readx], c1, at[Test.ReadRefx, 10, DoWord1]; Read: MAR ← [rhAddr, address + 0], RawRef, c1, at[Test.Read, 10, DoWord0]; Readx: Noop, c2; found ← MD, c3; ReadCompare: [] ← found xor expected, ZeroBr, c1; BRANCH[BugR, NextWord], c2; {------------------------------------------------------------------------------------} {Write constant.} WriteC: CALL[GetConstant], c1, at[Test.WriteC, 10, DoWord0]; WriteCConst: Noop, c1, at[Test.WriteC, 10, ConstRet]; Noop, c2; Noop, c3; WriteCLoop: MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← const, address ← address + 1, CarryBr, c2; BRANCH[WriteCLoop, $], c3; GOTO[NextBank], c1; {Read and compare with constant} ReadC: expected ← oldConst, c1, at[Test.ReadC, 10, DoWord0]; Noop, c2; Ybus ← 0, ZeroBr, c3; ReadCLoop: MAR ← [rhAddr, address + 0], RawRef, BRANCH[BugC, $], c1; address ← address + 1, CarryBr, c2; found ← expected xor MD, ZeroBr, BRANCH[ReadCLoop, $], c3, LOOPHOLE[stw]; BRANCH[BugC2, $], c1; Noop, c2; Noop, c3; GOTO[NextBank], c1; {Compare old value and write new value: Catches addressing troubles} FlipC: expected ← oldConst, CALL[GetConstant], c1, at[Test.FlipC, 10, DoWord0]; FlipCConst: Noop, c1, at[Test.FlipC, 10, ConstRet]; Noop, c2; Noop, c3; FlipCLoop: MAR ← [rhAddr, address + 0], RawRef, c1; Noop, c2; found ← MD, c3; [] ← found xor expected, ZeroBr, c1; BRANCH[BugF, $], c2; Noop, c3; MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← const, address ← address + 1, CarryBr, c2; BRANCH[FlipCLoop, $], c3; GOTO[NextBank], c1; {Setup the right constant.} GetConstant: Noop, c2; Xbus ← cc LRot12, XDisp, c3; Ybus ← cc, YDisp, DISP4[ConstHigh], c1; ConstHigh: DISP4[Const0], c2, at[0, 10, ConstHigh]; DISP4[Const1], c2, at[1, 10, ConstHigh]; DISP4[Const2], c2, at[2, 10, ConstHigh]; DISP4[Const3], c2, at[3, 10, ConstHigh]; Const0: const ← 0, GOTO[ConstDone], c3, at[cc.0000, 10, Const0]; const ← const xor ~const, GOTO[ConstDone], c3, at[cc.FFFF, 10, Const0]; const ← 055, GOTO[ConstBoth], c3, at[cc.5555, 10, Const0]; const ← 0AA, GOTO[ConstBoth], c3, at[cc.AAAA, 10, Const0]; const ← 033, GOTO[ConstBoth], c3, at[cc.3333, 10, Const0]; const ← 066, GOTO[ConstBoth], c3, at[cc.6666, 10, Const0]; const ← 0CC, GOTO[ConstBoth], c3, at[cc.CCCC, 10, Const0]; const ← 099, GOTO[ConstBoth], c3, at[cc.9999, 10, Const0]; const ← 014, GOTO[ConstDone], c3, at[cc.000F, 10, Const0]; const ← 028, GOTO[ConstDone], c3, at[cc.00F0, 10, Const0]; const ← 050, GOTO[ConstLeft], c3, at[cc.0F00, 10, Const0]; const ← 0A0, GOTO[ConstLeft], c3, at[cc.F000, 10, Const0]; const ← 0FF, GOTO[ConstDone], c3, at[cc.00FF, 10, Const0]; const ← 00F, GOTO[Const0FF0], c3, at[cc.0FF0, 10, Const0]; const ← 0FF, GOTO[ConstLeft], c3, at[cc.FF00, 10, Const0]; const ← 0F0, GOTO[ConstF00F], c3, at[cc.F00F, 10, Const0]; Const1: const ← 001, GOTO[ConstBoth], c3, at[cc.0101, 10, Const1]; const ← 002, GOTO[ConstBoth], c3, at[cc.0202, 10, Const1]; const ← 004, GOTO[ConstBoth], c3, at[cc.0404, 10, Const1]; const ← 008, GOTO[ConstBoth], c3, at[cc.0808, 10, Const1]; const ← 010, GOTO[ConstBoth], c3, at[cc.1010, 10, Const1]; const ← 020, GOTO[ConstBoth], c3, at[cc.2020, 10, Const1]; const ← 040, GOTO[ConstBoth], c3, at[cc.4040, 10, Const1]; const ← 080, GOTO[ConstBoth], c3, at[cc.8080, 10, Const1]; const ← 0FE, GOTO[ConstBoth], c3, at[cc.FEFE, 10, Const1]; const ← 0FD, GOTO[ConstBoth], c3, at[cc.FDFD, 10, Const1]; const ← 0FB, GOTO[ConstBoth], c3, at[cc.FBFB, 10, Const1]; const ← 0F7, GOTO[ConstBoth], c3, at[cc.F7F7, 10, Const1]; const ← 0EF, GOTO[ConstBoth], c3, at[cc.EFEF, 10, Const1]; const ← 0DF, GOTO[ConstBoth], c3, at[cc.DFDF, 10, Const1]; const ← 0BF, GOTO[ConstBoth], c3, at[cc.BFBF, 10, Const1]; const ← 07F, GOTO[ConstBoth], c3, at[cc.7F7F, 10, Const1]; Const2: const ← 003, GOTO[ConstBoth], c3, at[cc.0303, 10, Const2]; const ← 006, GOTO[ConstBoth], c3, at[cc.0606, 10, Const2]; const ← 00C, GOTO[ConstBoth], c3, at[cc.0C0C, 10, Const2]; const ← 018, GOTO[ConstBoth], c3, at[cc.1818, 10, Const2]; const ← 030, GOTO[ConstBoth], c3, at[cc.3030, 10, Const2]; const ← 060, GOTO[ConstBoth], c3, at[cc.6060, 10, Const2]; const ← 0C1, GOTO[ConstBoth], c3, at[cc.C0C0, 10, Const2]; const ← 080, GOTO[ConstBoth], c3, at[cc.8181, 10, Const2]; const ← 0FC, GOTO[ConstBoth], c3, at[cc.FCFC, 10, Const2]; const ← 0F9, GOTO[ConstBoth], c3, at[cc.F9F9, 10, Const2]; const ← 0F3, GOTO[ConstBoth], c3, at[cc.F3F3, 10, Const2]; const ← 0E7, GOTO[ConstBoth], c3, at[cc.E7E7, 10, Const2]; const ← 0CF, GOTO[ConstBoth], c3, at[cc.CFCF, 10, Const2]; const ← 099, GOTO[ConstBoth], c3, at[cc.9F9F, 10, Const2]; const ← 03F, GOTO[ConstBoth], c3, at[cc.3F3F, 10, Const2]; const ← 07E, GOTO[ConstBoth], c3, at[cc.7E7E, 10, Const2]; Const3: const ← 011, GOTO[ConstBoth], c3, at[cc.1111, 10, Const3]; const ← 022, GOTO[ConstBoth], c3, at[cc.2222, 10, Const3]; const ← 044, GOTO[ConstBoth], c3, at[cc.4444, 10, Const3]; const ← 088, GOTO[ConstBoth], c3, at[cc.8888, 10, Const3]; const ← 0EE, GOTO[ConstBoth], c3, at[cc.EEEE, 10, Const3]; const ← 0DD, GOTO[ConstBoth], c3, at[cc.DDDD, 10, Const3]; const ← 0BB, GOTO[ConstBoth], c3, at[cc.BBBB, 10, Const3]; const ← 077, GOTO[ConstBoth], c3, at[cc.7777, 10, Const3]; Const0FF0: const ← const LRot8, c1; const ← const or 0F0, c2; GOTO[ConstDone], c3; ConstF00F: const ← const LRot8, c1; const ← const or 00F, c2; GOTO[ConstDone], c3; ConstLeft: const ← const LRot8, GOTO[ConstDisp], c1; ConstBoth: {Copy the constant to the left half too} const ← const LRot8 or const, GOTO[ConstDisp], c1; ConstDone: Noop, c1; ConstDisp: Xbus ← test, XDisp, c2; DISP4[ConstRet], c3; {------------------------------------------------------------------------------------} {Write address} WriteA: Noop, c1, at[Test.WriteA, 10, DoWord0]; Noop, c2; Noop, c3; WriteALoop: MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← address, address ← address + 1, CarryBr, c2; BRANCH[WriteALoop, $], c3; GOTO[NextBank], c1; {Read and compare with address} ReadA: Q ← rhAddr, c1, at[Test.ReadA, 10, DoWord0]; rhEx ← Q LRot0, c2; Ybus ← 0, ZeroBr, c3; ReadALoop: MAR ← [rhEx, address + 0], RawRef, expected ← address + 0, BRANCH[BugA, $], c1; address ← address + 1, CarryBr, c2; found ← expected xor MD, ZeroBr, BRANCH[ReadALoop, $], c3, LOOPHOLE[stw]; BRANCH[BugA2, $], c1; Noop, c2; Noop, c3; GOTO[NextBank], c1; {------------------------------------------------------------------------------------} {Floating one/zero test. (Should also work with any other constant.)} WriteRot: const ← LRot1 const, c1, at[Test.WriteRot, 10, DoWord0]; expected ← const, c2; Noop, c3; WriteRotLoop: MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, address ← address + 1, CarryBr, c2; expected ← expected LRot1, BRANCH[WriteRotLoop, $], c3; GOTO[NextBank], c1; ReadRot: const ← LRot1 const, c1, at[Test.ReadRot, 10, DoWord0]; expected ← const, c2; Noop, c3; ReadRotLoop: MAR ← [rhAddr, address + 0], RawRef, c1; address ← address + 1, CarryBr, c2; found ← expected xor MD, ZeroBr, BRANCH[$, ReadRotEnd], c3, LOOPHOLE[stw]; BRANCH[BugRt, $], c1; Noop, c2; expected ← expected LRot1, GOTO[ReadRotLoop], c3; ReadRotEnd: BRANCH[BugRt2, $], c1; Noop, c2; Noop, c3; GOTO[NextBank], c1; {------------------------------------------------------------------------------------} {Write, read, write, read, ... all to the same word....} WriteRead: MAR ← [rhAddr, address + 0], RawRef, c1, at[Test.WriteRead, 10, DoWord0]; MDR ← expected, c2; Noop, c3; MAR ← [rhAddr, address + 0], RawRef, c1; Noop, c2; found ← MD, c3; MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; [] ← found xor expected, ZeroBr, c3; MAR ← [rhAddr, address + 0], RawRef, BRANCH[BugWR1, $], c1; Noop, c2; found ← MD, c3; MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; [] ← found xor expected, ZeroBr, c3; MAR ← [rhAddr, address + 0], RawRef, BRANCH[BugWR2, $], c1; Noop, c2; found ← MD, c3; MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; [] ← found xor expected, ZeroBr, c3; MAR ← [rhAddr, address + 0], RawRef, BRANCH[BugWR3, $], c1; Noop, c2; found ← MD, c3; MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; [] ← found xor expected, ZeroBr, c3; MAR ← [rhAddr, address + 0], RawRef, BRANCH[BugWR4, $], c1; Noop, c2; found ← MD, GOTO[ReadCompare], c3; {------------------------------------------------------------------------------------} { Fill the whole bank with a constant. Then scan through, checking each word. complementing each word, and then uncomplementing it.} Scan: Noop, c1, at[Test.Scan, 10, DoWord0]; Noop, c2; Noop, c3; {Fill whole bank with a constant.} ScanZap: MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, address ← address + 1, CarryBr, c2; BRANCH[ScanZap, $], c3; Noop, c1; Noop, c2; Noop, c3; ScanLoop: {Verify that this word hasn't changed.} MAR ← [rhAddr, address + 0], RawRef, c1; Noop, c2; found ← expected xor MD, ZeroBr, c3, LOOPHOLE[stw]; {Flip this word.} MAR ← [rhAddr, address + 0], RawRef, BRANCH[BugS1, $], c1; MDR ← ~expected, c2; Noop, c3; {Verify that it flipped.} MAR ← [rhAddr, address + 0], RawRef, c1; Noop, c2; found ← ~expected xor MD, ZeroBr, c3, LOOPHOLE[stw]; {Put it back the right way.} MAR ← [rhAddr, address + 0], RawRef, BRANCH[BugS2, $], c1; MDR ← expected, address ← address + 1, CarryBr, c2; BRANCH[ScanLoop, $], c3; Noop, c1; Noop, c2; [] ← 0, ZeroBr, c3; ScanCheck: MAR ← [rhAddr, address + 0], RawRef, BRANCH[BugS3, $], c1; address ← address + 1, CarryBr, c2; found ← expected xor MD, ZeroBr, BRANCH[ScanCheck, $], c3, LOOPHOLE[stw]; BRANCH[BugS4, $], c1; Noop, c2; Noop, c3; GOTO[NextBank], c1; {Scan a word of 0s through a bank full of 1s.} Flap: Q ← rhAddr, c1, at[Test.Flap, 10, DoWord0]; rhAdr2 ← Q LRot0, c2; addres2 ← ~address, c3; {Fill whole bank with a constant.} FlapZap: MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, address ← address + 1, CarryBr, c2; BRANCH[FlapZap, $], c3; Noop, c1; Noop, c2; Noop, c3; FlapLoop: {Verify that this word hasn't changed.} MAR ← [rhAddr, address + 0], RawRef, c1; Noop, c2; found ← expected xor MD, ZeroBr, c3, LOOPHOLE[stw]; {Check word at complement of this address.} MAR ← [rhAdr2, addres2 + 0], RawRef, BRANCH[BugF1, $], c1; Noop, c2; found ← expected xor MD, ZeroBr, c3, LOOPHOLE[stw]; {Flip this word.} MAR ← [rhAddr, address + 0], RawRef, BRANCH[BugF2, $], c1; MDR ← ~expected, c2; Noop, c3; {Again, check word at complement of this address.} MAR ← [rhAdr2, addres2 + 0], RawRef, c1; Noop, c2; found ← expected xor MD, ZeroBr, c3, LOOPHOLE[stw]; {Verify that it flipped.} MAR ← [rhAddr, address + 0], RawRef, BRANCH[BugF3, $], c1; Noop, c2; found ← ~expected xor MD, ZeroBr, c3, LOOPHOLE[stw]; {Yet again, check word at complement of this address.} MAR ← [rhAdr2, addres2 + 0], RawRef, BRANCH[BugF4, $], c1; Noop, c2; found ← expected xor MD, ZeroBr, c3, LOOPHOLE[stw]; {Put it back the right way.} MAR ← [rhAddr, address + 0], RawRef, BRANCH[BugF5, $], c1; MDR ← expected, address ← address + 1, CarryBr, c2; addres2 ← addres2 - 1, BRANCH[FlapLoop, $], c3; Noop, c1; Noop, c2; [] ← 0, ZeroBr, c3; {Scan whole bank, just in case...} FlapCheck: MAR ← [rhAddr, address + 0], RawRef, BRANCH[BugF6, $], c1; address ← address + 1, CarryBr, c2; found ← expected xor MD, ZeroBr, BRANCH[FlapCheck, $], c3, LOOPHOLE[stw]; BRANCH[BugF7, $], c1; Noop, c2; Noop, c3; GOTO[NextBank], c1; {------------------------------------------------------------------------------------} {The map tests ignore the normal loop structure. They want to iterate through all of virtural memory.} MapWrite: Q ← highBank, c1, at[Test.MapWrite, 10, DoWord0]; [] ← Q - 1, NegBr, {MAP is in second bank} c2; Q ← lowBank - 1, BRANCH[$, SkipMapWrite1], c3, LOOPHOLE[niblTiming]; [] ← Q - 1, NegBr, c1; expected ← 0, BRANCH[SkipMapWrite2, $], c2; Q ← 0, rhAddr ← 0, c3; MapWriteLoop: Map ← [rhAddr, address + 0], c1; MDR ← expected, expected ← expected + 1, PgCarryBr, c2; address ← address + 0FF + 1, BRANCH[MapWriteLoop, $], c3; Q ← Q + 1, PgCarryBr, c1; BRANCH[$, DoneMapWrite], c2; rhAddr ← Q LRot0, GOTO[MapWriteLoop], c3; DoneMapWrite: GOTO[NextTest], c3; MapRead: expected ← 0, c1, at[Test.MapRead, 10, DoWord0]; Q ← 0, rhAddr ← 0, c2; Noop, c3; MapReadLoop: Map ← [rhAddr, address + 0], c1; Noop, c2; found ← MD, c3; [] ← found xor expected, ZeroBr, c1; expected ← expected + 1, PgCarryBr, BRANCH[BugMap, $], c2; address ← address + 0FF + 1, BRANCH[MapReadLoop, $], c3; Q ← Q + 1, PgCarryBr, c1; BRANCH[$, DoneMapRead], c2; rhAddr ← Q LRot0, GOTO[MapReadLoop], c3; DoneMapRead: GOTO[NextTest], c3; {Code copied from ReadA. Each map word should contain it's address within the bank.} MapVerify: Noop, c1, at[Test.MapVerify, 10, DoWord0]; rhEx ← 1, c2; Ybus ← 0, ZeroBr, c3; MapVLoop: MAR ← [rhEx, address + 0], expected ← address + 0, BRANCH[BugV, $], c1; address ← address + 1, CarryBr, c2; found ← expected xor MD, ZeroBr, BRANCH[MapVLoop, $], c3, LOOPHOLE[stw]; BRANCH[BugV2, $], c1; Noop, c2; GOTO[NextTest], c3; {------------------------------------------------------------------------------------} BugR: GOTO[Error], c3; BugC: found ← found xor expected, CANCELBR[Backup], c2; BugC2: found ← found xor expected, CANCELBR[Backup], c2; BugF: GOTO[Error], c3; BugA: found ← found xor expected, CANCELBR[Backup], c2; BugA2: found ← found xor expected, CANCELBR[Backup], c2; BugRt: found ← found xor expected, CANCELBR[Backup], c2; BugRt2: found ← found xor expected, CANCELBR[Backup], c2; BugWR1: CANCELBR[Errc3], c2; BugWR2: CANCELBR[Errc3], c2; BugWR3: CANCELBR[Errc3], c2; BugWR4: CANCELBR[Errc3], c2; BugS1: found ← found xor expected, CANCELBR[Errc3], c2; BugS2: found ← found xor ~expected, CANCELBR[ErrFlip], c2; BugS3: found ← found xor expected, CANCELBR[Backup], c2; BugS4: found ← found xor expected, CANCELBR[Backup], c2; BugF1: found ← found xor expected, CANCELBR[Errc3], c2; BugF2: found ← found xor expected, CANCELBR[Swap], c2; BugF3: found ← found xor expected, CANCELBR[Swap], c2; BugF4: found ← found xor ~expected, CANCELBR[ErrFlip], c2; BugF5: found ← found xor expected, CANCELBR[Swap], c2; BugF6: found ← found xor expected, CANCELBR[Backup], c2; BugF7: found ← found xor expected, CANCELBR[Backup], c2; BugMap: expected ← expected - 1, CANCELBR[Error], c3; BugV: found ← found xor expected, CANCELBR[Backup], c2; BugV2: found ← found xor expected, CANCELBR[Backup], c2; Swap: address ← ~addres2, GOTO[Error], c3; Backup: address ← address - 1, GOTO[Error], c3; ErrFlip: expected ← ~expected, GOTO[Error], c3; Errc3: Noop, c3; Error: Noop, c1; Noop, c2; Q ← MD, c3, LOOPHOLE[mdok]; found2 ← Q, c1; Noop, c2; Noop, c3; Q ← errorCount, c1; Q ← Q + 1, c2; errorCount ← Q, c3; MAR← [rhAddr, address + 0], RawRef, c1; Noop, c2; Q ← MD, c3; found3 ← Q, c1; Noop, c2; Noop, 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; MesaIntBr, c2; BRANCH[$, DataMismatchWithParityError], c3; DataMismatchButNoParityError: Noop, c1; Noop, c2; GOTO[Go], c3; DataMismatchWithParityError: Noop, c1; L1 ← Info0, c2; CALL[Info], c3; DataMismatchAndParityError: Noop, c1, at[Info0, 10, InfoRet]; Noop, c2; GOTO[Go], c3; {------------------------------------------------------------------------------------} MesaIntBank: Noop, c1; Noop, c2; Noop, c3; MesaInt: Noop, c1; L1 ← Info1, c2; CALL[Info], c3; Q ← errorCount, c1, at[Info1, 10, InfoRet]; Q ← Q + 1, c2; errorCount ← Q, c3; MesaIntIsProbablyAParityError: Noop, c1; Noop, c2; GOTO[Go], c3; {------------------------------------------------------------------------------------} Info: rhAdr2 ← 4, {Misc CIO Chip} c1; addres2 ← 090, c2; addres2 ← addres2 LRot8, {9000} c3; Q ← 05, L0 ← Fetch0, {RdTODatL} c1; CALL[Fetch], c2; toData ← rA, c3, at[Fetch0, 10, FetchRet]; Q ← 04, L0 ← Fetch1, {RdTODatH} c1; CALL[Fetch], c2; rA ← rA LRot8, c3, at[Fetch1, 10, FetchRet]; Q ← toData, c1; rA ← rA or Q, c2; toData ← rA, c3; Q ← 03, L0 ← Fetch2, {RdTOCmd} c1; CALL[Fetch], c2; toCommand ← rA, c3, at[Fetch2, 10, FetchRet]; Q ← 00, L0 ← Fetch3, {RdTOAdrH} c1; CALL[Fetch], c2; toAddrHi ← rA LRot0, c3, at[Fetch3, 10, FetchRet]; Q ← 02, L0 ← Fetch4, {RdTOAdrL} c1; CALL[Fetch], c2; toAddr ← rA, c3, at[Fetch4, 10, FetchRet]; Q ← 01, L0 ← Fetch5, {RdTOAdrM} c1; CALL[Fetch], c2; rA ← rA LRot8, c3, at[Fetch5, 10, FetchRet]; Q ← toAddr, c1; Q ← Q or rA, L1Disp, c2; toAddr ← Q, DISP4[InfoRet], c3; {------------------------------------------------------------------------------------} Setup: Noop, c3; IO ← [rhAdr2, rA + 0], L0Disp, c1; MDR ← Q, DISP4[SetupRet], c2; {------------------------------------------------------------------------------------} Fetch: Noop, c3; IO ← [rhAdr2, addres2 + 0E], {Port B Data} c1; MDR ← Q + 8, c2; Noop, c3; IO ← [rhAdr2, addres2 + 0D], {Port A Data} c1; Noop, c2; rA ← MD, c3; L0Disp, c1; DISP4[FetchRet], c2; {------------------------------------------------------------------------------------} {Scope loops: Let normal stuff run a while to initialize things..} SpinBankLoop: MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; rhAddr ← 1, c3; MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; rhAddr ← 2, c3; MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; rhAddr ← 3, c3; MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; rhAddr ← 4, c3; MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; rhAddr ← 5, c3; MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; rhAddr ← 6, c3; MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; rhAddr ← 7, c3; MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; rhAddr ← 0, c3; address ← address + 1, c1; expected ← expected + 1, c2; Noop, GOTO[SpinBankLoop], c3; FlapDataAndAddress: Q ← rhAddr, c1; Q ← Q and highBank, c2; rhAdr2 ← Q LRot0, c3; Noop, c1; Noop, c2; addres2 ← ~address, c3; FlapDataAndAddressLoop: MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; Noop, c3; MAR ← [rhAdr2, addres2 + 0], RawRef, c1; MDR ← ~expected, c2; Noop, c3; MAR ← [rhAddr, address + 0], RawRef, c1; Noop, c2; found ← MD, c3; MAR ← [rhAdr2, addres2 + 0], RawRef, c1; Noop, c2; found ← MD, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, GOTO[FlapDataAndAddressLoop], c3; SpinData: MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; Noop, c3; MAR ← [rhAddr, address + 0], RawRef, c1; Noop, c2; found ← MD, c3; expected ← expected + 1, c1; Noop, c2; Noop, GOTO[SpinData], c3; SpinAddress: MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; Noop, c3; MAR ← [rhAddr, address + 0], RawRef, c1; Noop, c2; found ← MD, c3; address ← address + 1, c1; Noop, c2; Noop, GOTO[SpinAddress], c3; FlapMap: Q ← rhAddr, c1; rhAdr2 ← Q LRot0, c2; addres2 ← ~address, c3; FlapMapLoop: MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; Noop, c3; Map ← [rhAdr2, addres2 + 0], RawRef, c1; MDR ← ~expected, c2; Noop, c3; MAR ← [rhAddr, address + 0], RawRef, c1; Noop, c2; found ← MD, c3; Map ← [rhAdr2, addres2 + 0], RawRef, c1; Noop, c2; found ← MD, c3; Noop, c1; Noop, c2; Noop, GOTO[FlapMapLoop], c3; ScopeWriteLoop: MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, rA ← rA + 1, CarryBr, c2; BRANCH[ScopeWriteLoop, $], c3; Noop, c1; Noop, c2; GOTO[ScopeWriteLoop], c3; ScopeReadLoop: MAR ← [rhAddr, address + 0], RawRef, c1; rA ← rA + 1, CarryBr, c2; found ← MD, BRANCH[ScopeReadLoop, $], c3; Noop, c1; Noop, c2; GOTO[ScopeReadLoop], c3; WriteReadLoop: MAR ← [rhAddr, address + 0], RawRef, c1; MDR ← expected, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; MAR ← [rhAddr, address + 0], RawRef, c1; Noop, c2; found ← MD, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; expected ← expected RRot1, c2; GOTO[WriteReadLoop], c3; {Note that bank/rhAddr doesn't really matter for IO references....} ScopeWriteLoopIO: IO ← [rhAddr, address + 0], c1; MDR ← expected, c2; Noop, c3; Noop, c1; Noop, c2; GOTO[ScopeWriteLoopIO], c3; ScopeReadLoopIO: IO ← [rhAddr, address + 0], c1; Noop, c2; found ← MD, c3; Noop, c1; Noop, c2; Noop, GOTO[ScopeReadLoopIO], c3; ScopeReadLoopIOClump: IO ← [rhAddr, address + 0], c1; Noop, c2; found ← MD, c3; IO ← [rhAddr, address + 0], c1; Noop, c2; found ← MD, c3; IO ← [rhAddr, address + 0], c1; Noop, c2; found ← MD, c3; IO ← [rhAddr, address + 0], c1; Noop, c2; found ← MD, c3; IO ← [rhAddr, address + 0], c1; Noop, c2; found ← MD, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, GOTO[ScopeReadLoopIOClump], c3; SlowScopeReadLoopIO: IO ← [rhAddr, address + 0], c1; Noop, c2; found ← MD, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, GOTO[SlowScopeReadLoopIO], c3; SpinIOContents: IO ← [rhAddr, address + 0], c1; MDR ← expected, c2; Noop, c3; IO ← [rhAddr, address + 0], c1; Noop, c2; found ← MD, c3; expected ← expected + 1, c1; Noop, c2; Noop, GOTO[SpinIOContents], c3; FlapIOContents: IO ← [rhAddr, address + 0], c1; MDR ← expected, c2; Noop, c3; IO ← [rhAddr, address + 0], c1; MDR ← ~expected, c2; Noop, c3; Noop, c1; Noop, c2; Noop, GOTO[FlapIOContents], c3; {------------------------------------------------------------------------------------} KickPulseGen: IO ← [rhAddr, address + 0], c1; MDR ← expected, c2; rB ← rC, c3; Noop, c1; address ← address + 1, NibCarryBr, c2; BRANCH[KickPulseGen, $], c3; address ← address and ~010, c1; ExtCtrl ← 3, {Gets Bumped on rising edge} c2; ExtCtrl ← 7, c3; KickPulseGenA: Noop, c1; rA ← rA - 1, ZeroBr, c2; KickPulseGenB: BRANCH[KickPulseGenA, $], c3; rB ← rB - 1, ZeroBr, c1; BRANCH[KickPulseGenB, $], c2; Noop, c3; expected ← expected + 1, c1; Noop, c2; Noop, GOTO[KickPulseGen], c3; {------------------------------------------------------------------------------------} ReadHostNumber: rhAddr ← 0, c1; address ← 32, c2; address ← address LRot8, c3; ReadHostNumberLoop: IO ← [rhAddr, address + 0], c1; Noop, c2; rA ← MD, c3; IO ← [rhAddr, address + 1], c1; Noop, c2; rB ← MD, c3; IO ← [rhAddr, address + 2], c1; Noop, c2; rC ← MD, c3; Noop, c1; Noop, c2; Noop, GOTO[ReadHostNumberLoop], c3; {------------------------------------------------------------------------------------} CycleChecker: Noop, c1; XC2npcDisp, c2; BRANCH[WrongCycle, CycleChecker, 0D], c3; WrongCycle: Noop, c*; GetInSync: XC2npcDisp, c*; BRANCH[GetInSync, CycleGlitch, 0D], c*; CycleGlitch: ExtCtrl ← 3, {Gets Bumped on rising edge} c1; ExtCtrl ← 7, c2; GOTO[CycleChecker], c3;