{ LatchTest.mc, HGM, 12-Feb-85 5:10:29 }
Reserve[0F5F, 0FFF]; {section used by the CP Kernel }
SetTask[0]; StartAddress[Go];
{ Test the 6 latches that remember what's on the BUS when an XackTimeout happens.
This test assumes:
Main memory location FFxxxx doesn't exist.
IO location xx0000 doesn't exist.
Both the CP and Misc are n slots with P2 connectors. }
{Used to access CIO chips}
RegDef[address, R, 2];
RegDef[rhAddr, RH, 2];
RegDef[address10, R, 3];
RegDef[address20, R, 4];
{Used to generate troubles}
RegDef[what, R, 8];
RegDef[where, R, 9];
RegDef[rhWhere, RH, 9];
{Data returned from Latches}
RegDef[toCommand, R, 0A];
RegDef[toData, R, 0B];
RegDef[toAddr, R, 0C];
RegDef[toAddrHi, RH, 0C];
RegDef[temp, R, 0E];
Set[Get0, 0];
Set[Get1, 1];
Set[Get2, 2];
Set[Get3, 3];
Set[Get4, 4];
Set[Get5, 5];
Set[Get6, 6];
Set[Get7, 7];
Set[Get8, 8];
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: rhAddr ← 4, {Misc CIO Chip} c1;
address ← 090, c2;
address ← address LRot8, {9000} c3;
address10 ← address + 10, c1;
address20 ← address + 20, c2;
ExtCtrl ← 5, {Init Incr, Zero, UnBlank} c3;
MainLoop:
{Setup for Interrupt on XackTimeout}
IO ← [rhAddr, address + 0], {Master Control} c1;
MDR ← 1, {Reset} c2;
Noop, c3;
IO ← [rhAddr, address + 0], {Master Control} c1;
MDR ← 000, {Clear Reset} c2;
Noop, c3;
IO ← [rhAddr, address + 0], {Master Control} c1;
MDR ← 080, {MIE} c2;
Noop, c3;
IO ← [rhAddr, address20 + 3], {Port A Direction} c1;
MDR ← 0FF, {All Bits Input} c2;
Noop, c3;
IO ← [rhAddr, address + 0E], {Port B Data} c1;
MDR ← 0F, {Disable all outputs} c2;
Noop, c3;
IO ← [rhAddr, address20 + 0B], {Port B Direction} c1;
MDR ← 0F0, {Output on low 4 bits} c2;
Noop, c3;
IO ← [rhAddr, address + 1], {Master Config Control} c1;
MDR ← 084, {Enable Ports A+B} c2;
Noop, c3;
IO ← [rhAddr, address20 + 0C], {Port B Special IO} c1;
MDR ← 40, {ONEs Catcher for TOXack} c2;
Noop, c3;
IO ← [rhAddr, address20 + 0D], {Port B Polarity} c1;
MDR ← 40, c2;
Noop, c3;
IO ← [rhAddr, address20 + 0F], {Port B Mask} c1;
MDR ← 40, c2;
Noop, c3;
IO ← [rhAddr, address + 09], {Port B Command} c1;
MDR ← 0C0, {Set Interrupt Enable} c2;
Noop, c3;
IO ← [rhAddr, address20 + 08], {Port B Mode} c1;
MDR ← 4, {Bit Port, OR Matcher} c2;
ClrIntErr, c3;
StartTesting:
Q ← ExtStat, MesaIntBr, c1;
BRANCH[$, MesaIntAlreadySet], c2;
Noop, c3;
what ← 0, c1;
rhWhere ← 0, c2;
where ← 0, c3;
DataLoop:
IO ← [rhWhere, where + 0], c1;
MDR ← what, c2;
Noop, c3;
{Argh, the silly chip is very slow}
Noop, c1; Noop, c2; Noop, c3;
Noop, c1; Noop, c2; Noop, c3;
Noop, c1; Noop, c2; Noop, c3;
Noop, c1; Noop, c2; Noop, c3;
temp ← ExtStat, MesaIntBr, c1;
BRANCH[MesaIntNotSet, $], c2;
Noop, c3;
IO ← [rhAddr, address + 0E], {Port B Data} c1;
MDR ← 000, {Clear caught 1} c2;
Noop, c3;
IO ← [rhAddr, address + 09], {Port B Command} c1;
MDR ← 0B0, {Reset IP} c2;
Noop, c3;
ClrIntErr, c1;
Noop, c2;
Noop, c3;
temp ← ExtStat, MesaIntBr, c1;
BRANCH[$, MesaIntStillSet], c2;
Noop, c3;
L0 ← Get0, c1;
CALL[GetInfo], c2;
Noop, c3, at[Get0, 10, GetRet];
[] ← toData xor what, NZeroBr, c1;
BRANCH[$, DataNotLatched], c2;
Noop, c3;
DataLoopEnd:
Noop, c1;
what ← what + 1, CarryBr, c2;
BRANCH[DataLoop, $], c3;
rhWhere ← 0FF, c1;
where ← 0, c2;
Noop, c3;
AddrLoop:
MAR ← [rhWhere, where + 0], RawRef, c1;
MDR ← what, c2;
Noop, c3;
L0 ← Get1, c1;
CALL[GetInfo], c2;
Noop, c3, at[Get1, 10, GetRet];
[] ← toAddr xor where, NZeroBr, c1;
BRANCH[$, AddressNotLatched], c2;
Noop, c3;
AddrLoopEnd:
Noop, c1;
where ← where + 1, CarryBr, c2;
BRANCH[AddrLoop, $], c3;
rhWhere ← 0, c1;
where ← 0, c2;
Noop, c3;
AddrHiLoop:
IO ← [rhWhere, where + 0], c1;
MDR ← what, c2;
Noop, c3;
L0 ← Get2, c1;
CALL[GetInfo], c2;
Q ← rhWhere, c3, at[Get2, 10, GetRet];
[] ← Q xor toAddrHi, NZeroBr, c1;
BRANCH[$, AddrHiNotLatched], c2;
Noop, c3;
AddrHiLoopEnd:
Q ← rhWhere, c1;
Q ← Q + 1, c2;
rhWhere ← Q LRot0, c3;
{The Multibus only supports 23 bits of word addressing.
Thus we have to stop sooner than you might expect.}
Q ← Q and 080, c1;
[] ← Q, NZeroBr, c2;
BRANCH[AddrHiLoop, $], c3;
CommandTests:
rhWhere ← 0, c1;
where ← 0, c2;
Noop, c3;
IO ← [rhWhere, where + 0], c1;
MDR ← what, c2;
Noop, c3;
L0 ← Get3, c1;
CALL[GetInfo], c2;
Q ← 058, c3, at[Get3, 10, GetRet];
[] ← Q xor toCommand, NZeroBr, c1;
BRANCH[$, IOWCFailed], c2;
Noop, c3;
IO ← [rhWhere, where + 0], c1;
Noop, c2;
what ← MD, c3;
L0 ← Get4, c1;
CALL[GetInfo], c2;
Q ← 054, c3, at[Get4, 10, GetRet];
[] ← Q xor toCommand, NZeroBr, c1;
BRANCH[$, IORCFailed], c2;
Noop, c3;
rhWhere ← 0FF, c1;
where ← 0, c2;
Noop, c3;
MAR ← [rhWhere, where + 0], RawRef, c1;
MDR ← what, c2;
Noop, c3;
L0 ← Get5, c1;
CALL[GetInfo], c2;
Q ← 051, c3, at[Get5, 10, GetRet];
[] ← Q xor toCommand, NZeroBr, c1;
BRANCH[$, MRWTFailed], c2;
Noop, c3;
MAR ← [rhWhere, where + 0], RawRef, c1;
Noop, c2;
what ← MD, c3;
L0 ← Get6, c1;
CALL[GetInfo], c2;
Q ← 052, c3, at[Get6, 10, GetRet];
[] ← Q xor toCommand, NZeroBr, c1;
BRANCH[$, MRDCFailed], c2;
Noop, c3;
MAR ← [rhWhere, where + 0], RawRef, ADR0, c1;
MDR ← what, c2;
Noop, c3;
L0 ← Get7, c1;
CALL[GetInfo], c2;
Q ← 071, c3, at[Get7, 10, GetRet];
[] ← Q xor toCommand, NZeroBr, c1;
BRANCH[$, ADR0Failed], c2;
Noop, c3;
MAR ← [rhWhere, where + 0], RawRef, BHEN, c1;
Noop, c2;
what ← MD, c3;
L0 ← Get8, c1;
CALL[GetInfo], c2;
Q ← 042, c3, at[Get8, 10, GetRet];
[] ← Q xor toCommand, NZeroBr, c1;
BRANCH[$, BHENFailed], c2;
Noop, c3;
AllDone:
ExtCtrl ← 3, {Gets Bumped on rising edge} c1;
ExtCtrl ← 7, c2;
GOTO[MainLoop], c3;
{------------------------------------------------------------------------------------}
GetInfo:
Noop, c3;
IO ← [rhAddr, address + 0E], {Port B Data} c1;
MDR ← 08, {RdTOAdrH} c2;
Noop, c3;
IO ← [rhAddr, address + 0D], {Port A Data} c1;
Noop, c2;
toAddrHi ← MD, c3;
IO ← [rhAddr, address + 0E], {Port B Data} c1;
MDR ← 09, {RdTOAdrM} c2;
Noop, c3;
IO ← [rhAddr, address + 0D], {Port A Data} c1;
Noop, c2;
toAddr ← MD, c3;
IO ← [rhAddr, address + 0E], {Port B Data} c1;
MDR ← 0A, {RdTOAdrL} c2;
Noop, c3;
IO ← [rhAddr, address + 0D], {Port A Data} c1;
toAddr ← toAddr LRot8, c2;
toAddr ← toAddr or MD, c3;
IO ← [rhAddr, address + 0E], {Port B Data} c1;
MDR ← 0B, {RdTOCmd} c2;
Noop, c3;
IO ← [rhAddr, address + 0D], {Port A Data} c1;
Noop, c2;
toCommand ← MD, c3;
IO ← [rhAddr, address + 0E], {Port B Data} c1;
MDR ← 0C, {RdTODatH} c2;
Noop, c3;
IO ← [rhAddr, address + 0D], {Port A Data} c1;
Noop, c2;
toData ← MD, c3;
IO ← [rhAddr, address + 0E], {Port B Data} c1;
MDR ← 0D, {RdTODatL} c2;
Noop, c3;
IO ← [rhAddr, address + 0D], {Port A Data} c1;
toData ← toData LRot8, c2;
toData ← toData or MD, c3;
L0Disp, c1;
DISP4[GetRet], c2;
{------------------------------------------------------------------------------------}
MesaIntAlreadySet: GOTO[Restart], c3;
MesaIntNotSet: GOTO[Restart], c3;
MesaIntStillSet: GOTO[Restart], c3;
DataNotLatched: GOTO[Restart], c3;
AddressNotLatched: GOTO[Restart], c3;
AddrHiNotLatched: GOTO[Restart], c3;
IOWCFailed: GOTO[Restart], c3;
IORCFailed: GOTO[Restart], c3;
MRDCFailed: GOTO[Restart], c3;
MRWTFailed: GOTO[Restart], c3;
ADR0Failed: GOTO[Restart], c3;
BHENFailed: GOTO[Restart], c3;
Restart:
Q ← 0FF, c1;
Noop, c2;
RestartLoop:
Noop, c3;
Q ← Q - 1, ZeroBr, c1;
BRANCH[RestartLoop, $], c2;
GOTO[Go], c3;