{T1Thrash.mc, HGM, 13-Feb-85 22:15:16}
Reserve[0F5F, 0FFF]; {section used by the CP Kernel }
SetTask[0]; StartAddress[Go];
RegDef[flag, R, 0];
RegDef[address, R, 1];
RegDef[rhAddr, RH, 1];
RegDef[statusMask, R, 02];
RegDef[length, R, 03];
RegDef[data, R, 04];
RegDef[key, R, 05];
RegDef[wordIncr, R, 06];
RegDef[packetIncr, R, 07];
RegDef[temp, R, 0D];
RegDef[good, U, 40];
RegDef[missedPackets, U, 41];
RegDef[wrongLength, U, 42];
RegDef[wrongData, U, 43];
RegDef[minLength, U, 44];
RegDef[maxLength, U, 45];
RegDef[passCount, U, 46]; {number of good passes}
Trap: temp ← RRot1 ErrnIBnStkp, ClrIntErr, CANCELBR[$, 0F], c1, at[0];
Xbus ← temp 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: good ← 0, c1;
missedPackets ← 0, c2;
wrongLength ← 0, c3;
wrongData ← 0, c1;
Noop, c2;
Noop, c3;
passCount ← 0, ClrIntErr, c1;
ExtCtrl ← 5, {Init Incr, Zero, UnBlank} c2;
GOTO[Start], c3;
{------------------------------------------------------------------------------------}
Start:
address ← 20, c1;
address ← address LRot8 {2080} c2;
rhAddr ← 0, c3;
Noop, c1;
temp ← 080, c2;
temp ← temp LRot8, {8000} c3;
IO ← [rhAddr, address + 2], {control} c1;
MDR ← temp, {Reset} c2;
Noop, c3;
CheckSwitches:
IO ← [rhAddr, address + 3], {Switches} c1;
Noop, c2;
Q ← MD, c3;
[] ← Q xor 000, ZeroBr, c1;
BRANCH[$, SwitchesAll0s], c2;
temp ← 0FF, c3;
[] ← Q xor temp, ZeroBr, c1;
BRANCH[$, SwitchesAll1s], c2;
Noop, c3;
BoardSetup:
temp ← 098, c1;
temp ← temp LRot8, {9800} c2;
Noop, c3;
IO ← [rhAddr, address + 2], {control} c1;
MDR ← temp, {reset, accept, no int} c2;
temp ← 0, c3;
FilterSetup:
IO ← [rhAddr, address + 3], {Address Filter RAM} c1;
MDR ← temp, c2;
Noop, c3;
Noop, c1;
temp ← temp + 1, PgCarryBr, c2;
BRANCH[FilterSetup, $], c3;
IO ← [rhAddr, address + 2], {control} c1;
MDR ← 0, {go} c2;
Noop, c3;
Noop, c1;
temp ← 030, c2;
temp ← temp LRot8, {3000} c3;
DrainAnotherWord:
IO ← [rhAddr, address + 0], {data} c1;
Noop, c2;
Xbus ← MD, c3;
Noop, c1;
temp ← temp-1, ZeroBr, c2;
BRANCH[DrainAnotherWord, $], c3;
NewLength:
length ← minLength, c1;
Noop, c2;
Noop, c3;
MainLoop:
IO ← [rhAddr, address + 3], {Switches} c1;
Noop, c2;
Q ← MD, {Clear Tran Int} c3;
IO ← [rhAddr, address + 2], {status} c1;
Noop, c2;
Q ← MD, c3;
Noop, c1;
[] ← Q, NegBr, c2;
BRANCH[$, TranAlreadyInterrupting], c3;
SendPacket:
IO ← [rhAddr, address + 0], {data} c1;
MDR ← temp ← length, c2;
data ← key, c3;
SendAnotherWord:
IO ← [rhAddr, address + 0], {data} c1;
MDR ← data, c2;
Noop, c3;
data ← data + wordIncr, c1;
temp ← temp-1, ZeroBr, c2;
BRANCH[SendAnotherWord, $], c3;
Noop, c1;
temp ← 0, c2;
temp ← temp-1, {FFFF} c3;
SendDally:
IO ← [rhAddr, address + 2], {status} c1;
Noop, c2;
Q ← MD, c3;
Noop, c1;
[] ← Q, NegBr, c2;
BRANCH[$, TranInterrupted], c3;
Noop, c1;
temp ← temp-1, ZeroBr, c2;
BRANCH[SendDally, NoTranInterrupt], c3;
TranInterrupted:
Noop, c1;
temp ← 02, c2;
temp ← temp LRot8, {0200} c3;
TranDally:
Noop, {Wait for packet to get around} c1;
temp ← temp-1, ZeroBr, c2;
BRANCH[TranDally, $], c3;
CheckPacket:
IO ← [rhAddr, address + 0], {data} c1;
flag ← 0, c2;
Q ← MD, {Should be 8xxx} c3;
Noop, c1;
[] ← Q, NegBr, c2;
BRANCH[BuffferNotEmpty, $], c3;
IO ← [rhAddr, address + 0], {data} c1;
Noop, c2;
Q ← MD, {Should be length+1} c3;
Q ← Q and ~statusMask, c1;
[] ← Q, NegBr, c2;
BRANCH[$, MissedThePacket], c3;
Q ← Q - 1, c1;
[] ← Q xor length, ZeroBr, c2;
BRANCH[WrongLength, $], c3;
Noop, c1;
data ← key, c2;
temp ← length, c3;
CheckData:
IO ← [rhAddr, address + 0], {data} c1;
Noop, c2;
Q ← MD, {Should be data} c3;
Noop, c1;
[] ← Q xor data, ZeroBr, c2;
BRANCH[WrongData, $], c3;
WrongDataRestart:
data ← data + wordIncr, c1;
temp ← temp-1, ZeroBr, c2;
BRANCH[CheckData, $], c3;
CheckCrc:
IO ← [rhAddr, address + 0], {data} c1;
Noop, c2;
Xbus ← MD, {Discard CRC} c3;
{Delay to keep SUN boards happy}
Noop, c1;
Noop, c2;
Noop, c3;
CheckEmptyAgain:
IO ← [rhAddr, address + 0], {data} c1;
Noop, c2;
Q ← MD, c3;
Noop, c1;
[] ← Q, NegBr, c2;
BRANCH[BuffferNotEmptyAgain, $], c3;
Noop, c1;
[] ← flag, ZeroBr, c2;
BRANCH[WrongDataThisPacket, $], c3;
Q ← good, c1;
Q ← Q + 1, c2;
good ← Q, c3;
Noop, c1;
Q ← Q and 0F0, c2;
ExtCtrl ← Q or 7, {DP ← good/16} c3;
Q ← maxLength, c1;
[] ← length - Q, ZeroBr, c2;
length ← length + 1, BRANCH[MainLoop, $], c3;
Q ← key, c1;
Q ← Q + packetIncr, c2;
key ← Q, c3;
Q ← passCount, c1;
Q ← Q + 1, c2;
passCount ← Q, c3;
Noop, c1;
ExtCtrl ← 3, {Gets Bumped on rising edge} c2;
ExtCtrl ← 7, GOTO[NewLength], c3;
WrongDataThisPacket:
ExtCtrl ← 5, {Init Incr, Zero, UnBlank} c1;
Noop, c2;
GOTO[MainLoop], c3;
{------------------------------------------------------------------------------------}
SwitchesAll0s:
GOTO[Restartc1], c3;
SwitchesAll1s:
GOTO[Restartc1], c3;
TranAlreadyInterrupting:
GOTO[Restartc2], c1;
NoTranInterrupt:
GOTO[Restartc2], c1;
NoRecvInterrupt:
GOTO[Restartc2], c1;
BuffferNotEmpty:
GOTO[Restartc2], c1;
MissedThePacket:
Q ← missedPackets, c1;
Q ← Q + 1, c2;
missedPackets ← Q, GOTO[Restartc1], c3;
WrongLength:
Q ← wrongLength, c1;
Q ← Q + 1, c2;
wrongLength ← Q, GOTO[Restartc1], c3;
WrongData:
Q ← wrongData, c1;
Q ← Q + 1, c2;
wrongData ← Q, c3;
Noop, c1;
Noop, c2;
flag ← 1, GOTO[WrongDataRestart], c3;
BuffferNotEmptyAgain:
GOTO[Restartc2], c1;
Restartc2:
Noop, c2;
Restartc3:
Noop, c3;
Restartc1:
Q ← 0FF, c1;
Noop, c2;
RestartLoop:
Noop, c3;
Q ← Q - 1, ZeroBr, c1;
BRANCH[RestartLoop, $], c2;
ExtCtrl ← 5, GOTO[Start], {Init Incr, Zero, UnBlank} c3;
{------------------------------------------------------------------------------------}
BufferEmptyTest:
ExtCtrl ← 5, {Init Incr, Zero, UnBlank} c1;
temp ← 0, c2;
Noop, c3;
BufferEmptyLoop:
IO ← [rhAddr, address + 0], {data} c1;
Noop, c2;
Q ← MD, {Should be 8xxx} c3;
temp ← temp + 1, c1;
[] ← Q, NegBr, c2;
BRANCH[$, BufferEmptyLoop], c3;
BufferEmptyBug:
temp ← 0, c1;
ExtCtrl ← 3, {Gets Bumped on rising edge} c2;
ExtCtrl ← 7, GOTO[BufferEmptyLoop], c3;
{------------------------------------------------------------------------------------}