GenRW.mesa
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
Edward Fiala February 7, 1986 1:03:42 pm PST
This diagnostic tests P bus data and addressing and all opcodes which read or write memory. When correctly executed it terminates with a HALT[177777b] at PC = 4021202B on instruction 1002 cycle 2987.
**It seems that the simulator requires addresses specified to it to be byte addresses, so I can't test references to addresses for which either of the top two address bits is non-zero?
DIRECTORY
Basics USING [DoubleShiftLeft],
DragOpsCross USING [XopBase, TrapBase, TrapWidthBytes, bytesPerWord, TrapIndex, Word],
--XopBase, TrapBase, TrapWidthBytes, Inst, wordsPerPage, bytesPerWord, charsPerWord, bitsPerByte, bitsPerCharacter, bitsPerWord, logWordsPerPage, logBitsPerByte, logBitsPerChar, logBytesPerWord, logCharsPerWord, logBitsPerWord, logBytesPerPage, PageCount, PageNumber, maxPagesInVM, SixBitIndex, FiveBitIndex, Word, TwoWords, FourBitIndex, Half, ThreeBitIndex, FourHalves, TwoHalves, Byte, ZerosByte, OnesByte, EightBytes, FourBytes, ByteIndex, BytesPerWord, TwoBytes, Comparison, ByteAddress, WordAddress, FieldDescriptor, TrapWidthWords, KernalLimit, TrapIndex, StackUnderflowTrap, IFUPageFaultTrap, ResetTrap, IFUStackOverflowTrap, EUStackOverflowTrap, RescheduleTrap, ALUCondOver, ALUCondBC, ALUCondIL, ALUCondDO, EUPageFault, EUWriteFault, AUFault, euStack, euJunk, euMAR, euField, euConstant, euAux, euBogus, euLast, ifuXBus, ifuStatus, ifuSLimit, ifuYoungestL, ifuYoungestPC, ifuEldestL, ifuEldestPC, ifuBogus, ifuL, ifuS, ifuPC, ifuLast, IFUStatusRec, IFUStackIndex, IFUStackSize, IFUOverflow, EUStackIndex, EUStackSize, EULocalIndex, EULocals, EUAuxIndex, EUAuxRegs, EUConstIndex, EUConstants, IOLocation, ioRescheduleRequest, ioResetRequest
DragOpsCrossUtils USING [IntToWord, CardToWord],
--BytePCToWordAddress, WordAddressToBytePC, IOOperandToCard, CardToIOOperand, FieldDescriptorToCard, CardToFieldDescriptor, StatusToWord, WordToStatus, BytesToWord, BytesToHalf, WordToBytes, HalfToBytes, HalvesToWord, WordToHalves, HighHalf, LowHalf, LeftHalf, RightHalf, SwapHalves, WordToInt, IntToWord, WordToCard, HalfToCard, ByteToCard, CardToWord, CardToHalf, CardToByte, DragAnd, DragOr, DragXor, DragNot, VanillaAdd, VanillaSub, AddDelta, HalfNot, HalfAnd, HalfOr, HalfXor, HalfShift, DoubleWordShiftLeft, SingleWordShiftLeft, SingleWordShiftRight, TrapIndexToBytePC, XopToBytePC
HandCoding, --Has opcode and register defs.
HandCodingPseudos, --GenLabel, GenLabelHere, SetLabel, Halt, Pause, MakeLabelGlobal, UseLabel8B, UseLabel16, UseLabel32, ProcedureEntry, ProcedureExit, EnableTraps, IndexedJump, SetupField, ExtractField, ShiftLeft, LoadProcessorReg, StoreProcessorReg, DisableTraps, CauseReschedule, CauseReset, GetSPLimit, SetSPLimit, GetL, SetL, GetYoungestPC, GetYoungestL, GetEldestPC, GetEldestL, SetYoungestPC, SetYoungestL, SetEldestPC, SetEldestL
HandCodingSupport; --Area, GetCurrentArea, ReserveData, SetOutputPC, GetProc, PutProc, ProcList, NewArea, GenWithArea, Gen1WithArea, ForceOut, GetOutputPC, WordAlign, OutputByte, OutputOneByte, OutputAlphaBeta, OutputAlphaBetaGammaDelta, OutputWord
GenRW: CEDAR PROGRAM
IMPORTS Basics, DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport
= BEGIN OPEN DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport;
Word: TYPE = DragOpsCross.Word;
In this diagnostic, the auxiliary registers are called aux0, aux1, ..., aux15; the locals are called reg0, reg1, ..., reg15; and the constants are called const0, const1, ..., const15.
const2 contains -1.
const3 is used as an enabling flag for the bounds-check subroutine.
const6 contains 4 for bounds-check trap subroutine.
aux0: AuxRegSpec = [aux[0]];
aux1: AuxRegSpec = [aux[1]];
aux2: AuxRegSpec = [aux[2]];
aux3: AuxRegSpec = [aux[3]];
aux4: AuxRegSpec = [aux[4]];
aux5: AuxRegSpec = [aux[5]];
aux6: AuxRegSpec = [aux[6]];
aux14: AuxRegSpec = [aux[14]];
aux15: AuxRegSpec = [aux[15]];
const5: ConstSpec = [const[5]];
const6: ConstSpec = [const[6]];
const7: ConstSpec = [const[7]];
const8: ConstSpec = [const[8]];
const9: ConstSpec = [const[9]];
const10: ConstSpec = [const[10]];
const11: ConstSpec = [const[11]];
All: PROC = {
area: Area = GetCurrentArea[];
savePC: LONG CARDINAL;
Xops trap at opcode*TrapWidthBytes + xopBase*bytesPerWord = 4,000,000B + 20B * opcode.
FillXop: PROC [inst: CARDINAL, dest: Label] = {
SetOutputPC[inst * DragOpsCross.TrapWidthBytes + DragOpsCross.XopBase * DragOpsCross.bytesPerWord];
drJDB[UseLabel16[dest]];
};
A trap's location is TrapIndex*TrapWidthBytes + TrapBase*bytesPerWord =
4,002,000B + 20B * TrapIndex. TrapIndex definitions are in DragOpsCross.
FillTrap: PROC [tx: DragOpsCross.TrapIndex, dest: Label] = {
SetOutputPC[LOOPHOLE[tx, CARDINAL] * DragOpsCross.TrapWidthBytes + DragOpsCross.TrapBase * DragOpsCross.bytesPerWord];
drJDB[UseLabel16[dest]];
};
The Lizard simulator requires that all storage touched by a program be declared in advance; for data areas touched by EU memory references, this procedure is used to declare the words that will be touched. **Maybe Lizard requires only that each page touched by a program be reserved by a single OutputWord??
ReserveSpace: PROC [pc, nwords: CARD] = {
oldPC: LONG CARDINAL = GetOutputPC[area];
bytePC: LONG CARDINAL ← Basics.DoubleShiftLeft[[lc[pc]], 2].lc;
SetOutputPC[bytePC]; --pc is a byte address
FOR I: CARD IN [0..nwords) DO
OutputWord[area, CardToWord[0], FALSE];
ENDLOOP;
SetOutputPC[oldPC];
};
start: Label = GenLabel[];
dummy: Label = GenLabel[];
enterDataTest: Label = GenLabel[];
enterAddrTest: Label = GenLabel[];
enterRWAllTest: Label = GenLabel[];
enterCSTTest: Label = GenLabel[];
Test P bus data by writing data values with each bit in 0 and 1 states.
GenData: PROC [] ~ {
**Need code to setup the map foor the references here somewhere.
wval: LONG CARDINAL ← 1;
baseAddr: LONG CARDINAL ← 20000B;
SetLabel[enterDataTest];
ReserveSpace[baseAddr, 32];
drLIQB[CardToWord[baseAddr]]; --base register for writes and reads
FOR I: CARDINAL IN [0..32) DO
drLIQB[CardToWord[wval]];
wval ← Basics.DoubleShiftLeft[[lc[wval]], 1].lc;
drSRIn[reg0, I];
ENDLOOP;
wval ← 1;
FOR I: CARDINAL IN [0..32) DO
rdOK: Label = GenLabel[];
drLRIn[reg0, I];
drLIQB[CardToWord[wval]];
wval ← Basics.DoubleShiftLeft[[lc[wval]], 1].lc;
drRJEBJ[popSrc, belowSrcPop, UseLabel8B[rdOK]]; Pause[]; SetLabel[rdOK];
ENDLOOP;
};
Test P bus addressing by writing at addresses with each address bit in 0 and 1 states.
GenAddr: PROC [] ~ {
wval: LONG CARDINAL ← 1;
rval: LONG CARDINAL ← 1;
baseAddr: LONG CARDINAL ← 20100B;
SetLabel[enterAddrTest];
drLIQB[CardToWord[baseAddr]]; --base register for writes and reads
FOR I: CARDINAL IN [0..30) DO
ReserveSpace[baseAddr + wval, 1];
drLIQB[CardToWord[wval]];
wval ← Basics.DoubleShiftLeft[[lc[wval]], 1].lc;
drRVADD[reg1, reg0, popSrc]; --Put memory address into reg1
drLIQB[CardToWord[LONG[I]]];
drSRIn[reg1, 0];
ENDLOOP;
wval ← 1;
FOR I: CARDINAL IN [0..30) DO
rdOK: Label = GenLabel[];
drLIQB[CardToWord[wval]];
wval ← Basics.DoubleShiftLeft[[lc[wval]], 1].lc;
drRRX[topDst, reg0, topSrc];
drLIQB[CardToWord[LONG[I]]];
drRJEBJ[popSrc, belowSrcPop, UseLabel8B[rdOK]]; Pause[]; SetLabel[rdOK];
ENDLOOP;
};
GenRWAll: PROC [] ~ {
139 instructions tests all the memory writes and reads by first writing at addresses just above baseAddr using all the different memory write opcodes and then reading back the values using all the memory read opcodes and testing the data.
RWTest: PROC [baseAddr, dval: LONG CARDINAL] ~ {
LRI0ok: Label = GenLabel[];
LRI13ok: Label = GenLabel[];
RRIok: Label = GenLabel[];
ReadBackBad: Label = GenLabel[];
ReadBackBad1: Label = GenLabel[];
ReadBackBad2: Label = GenLabel[];
dvalx: LONG CARDINAL ← dval;
ReserveSpace[baseAddr, baseAddr + 42];
FOR I: CARDINAL IN [0..16) DO
drLIQB[CardToWord[baseAddr + LONG[I]]];
ENDLOOP;
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1; drSRIn[reg0, 0];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1; drSRIn[reg1, 1];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1; drSRIn[reg2, 2];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1; drSRIn[reg3, 3];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1; drSRIn[reg4, 4];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1; drSRIn[reg5, 5];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1; drSRIn[reg6, 6];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1; drSRIn[reg7, 7];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1; drSRIn[reg8, 8];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1; drSRIn[reg9, 9];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1; drSRIn[reg10, 10];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1; drSRIn[reg11, 11];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1; drSRIn[reg12, 12];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1; drSRIn[reg13, 13];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1; drSRIn[reg14, 14];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1; drSRIn[reg15, 15];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drLIQB[CardToWord[baseAddr + 16]];
drWB[16]; --baseAddr + 32
drLIQB[CardToWord[baseAddr + 17]];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drWSB[17]; --baseAddr + 34
drLIQB[CardToWord[baseAddr + 18]];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drPSB[18]; --baseAddr + 36
drDIS[];
dvalx ← dval;
drLRIn[reg0, 0]; drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJEBJ[popSrc, belowSrcPop, UseLabel8B[LRI0ok]]; SetLabel[ReadBackBad]; Pause[]; SetLabel[LRI0ok];
drLRIn[reg1, 1]; drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad]];
drLRIn[reg2, 2]; drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad]];
drLRIn[reg3, 3]; drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad]];
drLRIn[reg4, 4]; drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad]];
drLRIn[reg5, 5]; drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad]];
drLRIn[reg6, 6]; drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad]];
drLRIn[reg7, 7]; drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad]];
drLRIn[reg8, 8]; drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad]];
drLRIn[reg9, 9]; drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad]];
drLRIn[reg10, 10]; drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad]];
drLRIn[reg11, 11]; drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad]];
drLRIn[reg12, 12]; drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad]];
drLRIn[reg13, 13]; drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJEBJ[popSrc, belowSrcPop, UseLabel8B[LRI13ok]]; SetLabel[ReadBackBad1]; Pause[]; SetLabel[LRI13ok];
drLRIn[reg14, 14]; drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad1]];
drLRIn[reg15, 15]; drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad1]];
drLIQB[CardToWord[baseAddr + 16]];
drRB[16]; --baseAddr + 32
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad1]];
drLIQB[CardToWord[baseAddr + 17]]; drLIB[17];
drQRX[pushAtop, belowSrc];
drLIQB[CardToWord[dvalx]];
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad1]];
drRRX[belowDst, popSrc, belowSrc];
drLIQB[CardToWord[dvalx]]; dvalx ← dvalx + 1;
drLIQB[CardToWord[baseAddr + 18]];
drRSB[18]; --baseAddr + 36
drLIQB[CardToWord[dvalx]];
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad1]];
drLIB[18];
drRX[]; --baseAddr + 36 again
drLIQB[CardToWord[dvalx]];
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad1]];
drLIQB[CardToWord[baseAddr + 18]];
drROR[aux0, popSrc, topSrc];
drLGF[18]; --baseAddr + 36 again
drLIQB[CardToWord[dvalx]];
drRJNEB[popSrc, belowSrcPop, UseLabel8B[ReadBackBad1]];
Here we want reg0 + 38 = baseAddr + 38 to be the address and reg1 to hold the data being written.
drLIQB[CardToWord[baseAddr]];
drSRn[reg0];
drWRI[reg1, reg0, 38];
Here we want aux2 + 20 = baseAddr + 40 to be the address and reg3 to hold the data being written.
drLIQB[CardToWord[baseAddr + 20]];
drROR[aux2, popSrc, topSrc];
drWAI[reg3, aux2, 20];
Here we want reg0 + 38 to be the address and reg15 to receive the data being read.
drRRI[reg15, reg0, 38];
drLRn[reg15];
drRJEBJ[popSrc, reg1, UseLabel8B[RRIok]]; SetLabel[ReadBackBad2]; Pause[]; SetLabel[RRIok];
Here aux2 + 20 = baseAddr + 40 is the address and reg4 receives the data being read.
drRAI[reg4, aux2, 20];
drLRn[reg4];
drRJNEB[popSrc, reg3, UseLabel8B[ReadBackBad2]];
};
SetLabel[enterRWAllTest];
RWTest[30200B, 12345670123B];
RWTest[30300B, 11111111111B];
RWTest[30400B, 22222222222B];
RWTest[30500B, 33333333333B];
};
[S+1] ← Mem([S-2] + AlphaZ); if [S+1] = [S] then Mem([S-2] + AlphaZ) ← [S-1]; S ← S+1.
GenCST: PROC [] ~ {
CSTTest: PROC [addr, instore, old, new: CARD, alpha: CARDINAL] ~ {
STbad: Label = GenLabel[];
STok0: Label = GenLabel[];
drASL[255];
drLIQB[CardToWord[addr - alpha]]; --base register
drLIQB[CardToWord[instore]];
drSRIn[reg0, alpha]; --Mem(addr) ← instore
drLIQB[CardToWord[new]]; --[S-1] = new value conditionally stored
drLIQB[CardToWord[old]]; --[S] = old value compared against storage
drCST[alpha];
drLIQB[CardToWord[instore]];
drRJEBJ[popSrc, belowSrcPop, UseLabel8B[STok0]]; SetLabel[STbad]; Pause[]; SetLabel[STok0];
drLIQB[CardToWord[old]];
drRJNEB[popSrc, belowSrcPop, UseLabel8B[STbad]]; --Fails if stack screwed up
drLRIn[reg0, alpha];
IF instore = old THEN { --Store should succeed
drLIQB[CardToWord[new]];
drRJNEB[popSrc, belowSrcPop, UseLabel8B[STbad]]; --Fails if new not stored
}
ELSE { --Store should fail
drLIQB[CardToWord[instore]];
drRJNEB[popSrc, belowSrcPop, UseLabel8B[STbad]]; --Fails if new stored
};
};
SetLabel[enterCSTTest];
ReserveSpace[30600B, 1];
CSTTest[30300B, 11111111111B, 11111111111B, 12341234123B, 300B]; --Succeed
CSTTest[30201B, 11111111111B, 22222222222B, 12312312312B, 377B]; --Fail
};
WordAlign[area];
SetLabel[dummy];
Pause[]; Pause[]; Pause[]; Pause[]; Pause[]; Halt[123B];
Opcodes 0 and 377B are intercepted by the simulator, but make them trap to dummy here anyway.
savePC ← GetOutputPC[area];
FillTrap[ResetTrap, start];
FillXop[0, dummy];
FillXop[377B, dummy];
SetOutputPC[savePC];
Simulator execution begins here on a Reset.
SetLabel[start];
const0 is in a ROM, so it requires no initialization; const2 is initialized to -1 here; the other constants require no initialization for this diagnostic.
drASL[255];
When there is nothing on the stack, S should be at L-1
drLIQB[IntToWord[-1]];
drROR[const2, topSrc, popSrc]; --Put -1 in const2.
GenData[];
GenAddr[];
GenRWAll[];
GenCST[];
Halt[177777B]; --Terminate here at the end of the program
};
END.