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