//MXTALL.BCPL
get "mx.d"
//TestAll() sequentially tests all the registers and memories in the
//microprocessor using the selected data pattern and a full-sized
//mask for data comparison. On failure the results are left in
//DATA-WAS, SHOULD-BE, and BITS-CHECKED. The testing consists of
//250 iterations for each register and four passes through each memory.
//RepeatGo() starts the microprocessor at an address in IMA (setup by
//MCMD.BCPL), waits for it to halt, then loops endlessly.
//RepestSS() repeatedly single-steps at the selected address.
static [ TAllState; T40; T36; T20; T18; TARM; T12; T9; T8; T4; T3
TestAborted; FirstAct ]
let TestAll() = valof
[ GetPattern(NREALREGS+NREALMEMS-2); TAllState = 0
T40 = table [ 177777B; 177777B; 177400B ]
T36 = table [ 177777B; 177777B; 170000B ]
T20 = table [ 177777B; 170000B; 0 ]
T18 = table [ 177777B; 140000B; 0 ]
TARM = table [ 0; 7777B; 170000B ]
T12 = table [ 177760B; 0; 0 ]
T9 = table [ 177600B; 0; 0 ]
T8 = table [ 177400B; 0; 0 ]
T4 = table [ 170000B; 0; 0 ]
T3 = table [ 160000B; 0; 0 ]
resultis TAllMenu
]
and TAllMenu(S,Nix) be
[ if QuitF eq -2 do
[ QuitF = AddToEveryTimeList(TAllRM,0)
Resets(CmdCommentStream)
]
WsMarkA(QUITact)
if QuitF eq -1 do
[ for I = 0 to NPATS-1 do WsMarkA(PATACT!I) ]
]
and RTest(RegX,DataVec) be
[ TestWidth = REGWID!RegX
WssCSS(REGNAM!RegX); Puts(CmdCommentStream,$ )
UpdateDisplay()
MoveBlock(DMASK,DataVec,3) //Set up comparison mask
XctMic(CLRARM); XctMic(INTRETN) //For P1
Zero(ITRCNT+3,2)
for I = 0 to 250 do
[ PutRegData(RegX,GOODD); GetRegData(RegX,ACTD)
if CheckData() then ErrorStop(REGNAM!RegX," failed")
]
TAllState = TAllState+1
]
and MTest(MemX,DataVec) be
[ let SaveRX,SaveRD,SaveGD,AddrVec = nil,nil,vec 3,vec 1
TestWidth = MEMWID!MemX; AddrVec!0 = 0
if (TAllState & 3) eq 0 do
[ WssCSS(MEMNAM!MemX); Puts(CmdCommentStream,$ )
UpdateDisplay()
]
MoveBlock(DMASK,DataVec,3) //Set up comparison mask
Zero(ITRCNT+3,2)
SaveRX = RANDIX; SaveRD = RANDATA
MoveBlock(SaveGD,GOODD,3)
LoadDone = false
for J = 0 to (MEMLEN!MemX)-1 do
[ AddrVec!1 = J; PutMemData(MemX,AddrVec,GOODD); NextGDATA() ]
MoveBlock(GOODD,SaveGD,3); RANDIX = SaveRX; RANDATA = SaveRD
for J = 0 to (MEMLEN!MemX)-1 do
[ AddrVec!1 = J; GetMemData(MemX,AddrVec,ACTD)
if CheckData() do [ ErrorStop(MEMNAM!MemX," failed") ]
]
TAllState = TAllState+1
]
//MAIN, MAR, KMAR, KUNIT not tested
and TAllRM() be
[ switchon TAllState into
[
case 0: RTest(14,T36); return //EREG
case 1: RTest(0,T8); return //X
case 2: RTest(1,T4); return //AC
case 3: RTest(2,T9); return //Y
case 4: RTest(3,T36); return //P
case 5: RTest(4,T36); return //Q
case 6: RTest(6,T12); return //NPC
case 7: RTest(8,T40); return //MDR
case 8: RTest(10,T40); return //KMDR
case 9: RTest(11,TARM); return //ARM
case 10: RTest(12,T12); return //IMA
case 11: RTest(15,T20); Resets(CmdCommentStream); return //BPC
// The memory tests should begin with two low bits of TAllState eq 0
case 12: case 13: case 14: case 15: MTest(8,T36); return //LM
case 16: case 17: case 18: case 19: MTest(7,T36); return //RM
case 20: case 21: case 22: case 23: MTest(9,T12); return //STK
case 24: case 25: case 26: case 27: MTest(3,T36); return //SM
case 28: case 29: case 30: case 31: MTest(5,T18); return //MP
case 32: case 33: case 34: case 35: MTest(4,T36); return //DM
case 36: case 37: case 38: case 39: MTest(0,T36); return //IM[0,35]
case 40: case 41: case 42: case 43: MTest(1,T36); return //IM[36,71]
case 44: RTest(5,T36); return //F
case 45: RTest(13,T3); return //KUNIT
case 46: RTest(16,T36); endcase //P1
]
ErrorStop("Everything AOK","")
]
//Start microprocessor at selected address and repeatedly restart it
//after breakpoints until termination by mouse.
and RepeatGo(Addr; numargs Zot) =
RepeatX(MGO,Addr,Zot,"Repeating after breakpoints at")
//Similar to RepeatGo, but single-step rather than go
and RepeatSS(Addr; numargs Zot) =
RepeatX(SINSTP,Addr,Zot,"Repeatedly stepping at")
and RepeatX(Inst,Addr,Zot,String) = valof
[ SetupNPCIMA(Addr,Zot)
WssCSS(String); Wos(CmdCommentStream,MADDRL)
QUITact = CreateAction("Abort",lv RepStop,0,0,$C-100B)
QuitF = AddToEveryTimeList(GoMADDRL,Inst)
resultis TestMenu
]
//"Abort" is the only menu item--it comes here
and RepStop(S,garb,Buttons,Nix) be
[ @ADREG = RUN
RSLoop: if (@INREG & 200B) ne 0 then [ XctMic(MSTOP); goto RSLoop ]
Resets(CmdCommentStream); WssCSS("Repeat halted")
MaxcStopped(true)
]
//This is called every time through DriverLoop
and GoMADDRL(inst) be
[ @ADREG = RUN
if (@INREG & 200B) ne 0 then return //Twice avoiding glitches
if (@INREG & 200B) ne 0 then return
RestoreMRegs(2); ResetMaxc(inst)
]
and GetPattern(firstact) be
[ FirstAct = firstact; TestAborted = false
QUITact = CreateAction("Abort",lv TestStop,firstact,0,$C-100B)
DefPattern("ZEROES",0); DefPattern("ONES",1)
DefPattern("CYC1",2); DefPattern("CYC0",3)
DefPattern("RANDOM",4); DefPattern("ALTZO",5)
DefPattern("SEQUENTIAL",6); DefPattern("ALT-SHOULD-BE",7)
QuitF = -1
Zero(ITRCNT,5)
WssCSS("Select data pattern:")
]
and DefPattern(str,PatX) be
[ PATACT!PatX = CreateAction(str,lv SetPattern,PatX)
]
and SetPattern(S,garb,Buttons,PatX) be
[ PATTERN = PatX; QuitF = -2
switchon PatX into
[
case 0:
case 5:
case 6: Zero(GOODD,3); endcase
case 1: SetBlock(GOODD,-1,3); endcase
case 2: MoveBlock(GOODD,table[ 0; 0; 10000B ] ,3); endcase
case 3: MoveBlock(GOODD,table[ -1; -1; 160000B ] ,3); endcase
case 4: NextGDATA(); endcase
case 7: LeftAdjust(GDATA,GOODD,36); endcase
]
FormMenu(CmdMDFS,FormCmdmenuText)
]