//MXPAR.BCPL parity error reporting and scanning overlay
get "mx.d"
manifest [ qeTimeout=#40; qeDIP=#20; qeAPE=#10; qePBF=4; qeDE=2; qeSE=1 ]
static [ NLMPEs ]
let ReportPE(Z) be
[ if (Z & 20B) ne 0 do WssCSS("Memory data bus PE ")
test (Z & 40B) ne 0
ifso
[ WssCSS("LMPE "); let ARMvec = vec 2; GetRegData(11,ARMvec)
let E = ARMvec!0
if (E & 2000B) ne 0 do WssCSS("IM[0,17] ")
if (E & 1000B) ne 0 do WssCSS("IM[18,35] ")
if (E & 400B) ne 0 do WssCSS("IM[36,53] ")
if (E & 200B) ne 0 do WssCSS("IM[54,71] ")
if (E & 100B) ne 0 do WssCSS("SM[0,17] ")
if (E & 40B) ne 0 do WssCSS("SM[18,35] ")
if (E & 20B) ne 0 do WssCSS("MAP ")
]
ifnot if (Z & 100B) ne 0 do
[ let Mask = qeTimeout+qeDIP+qeAPE+qeDE
let AnyErrors = (Z & 60B) ne 0
if ParityFatal ne 0 then Mask = Mask + qePBF
if SingleFatal ne 0 then Mask = Mask + qeSE
@ADREG = JKERRS
let MemErr = @INREG
ReportMemErrors("J",(MemErr rshift 8) & Mask,lv AnyErrors)
ReportMemErrors("K",MemErr & Mask,lv AnyErrors)
@ADREG = LMERRS; MemErr = @INREG
ReportMemErrors("L",(MemErr rshift 8) & Mask,lv AnyErrors)
ReportMemErrors("M",MemErr & Mask,lv AnyErrors)
test AnyErrors
ifso [ @ADREG = RESR; @OUTREG = 125B ]
ifnot WssCSS("mysteriously")
]
]
and ReportMemErrors(Quad,Errors,lvPred) be
[ if Errors eq 0 then return
rv lvPred = true
for I = 0 to 5 do
[ let Mask = 1 lshift I
if (Errors & Mask) ne 0 then WssCSS(
selecton I into
[
case 0: "SE "
case 1: "DE "
case 2: "PBF "
case 3: "APE "
case 4: "DIP "
case 5: "NXM "
] )
]
WssCSS("in "); WssCSS(Quad)
Puts(CmdCommentStream,$ )
]
//Each bipolar memory, in cycles when it is not used, is implicitly
//read, so the MP and SM words pointed to by Y may potentially cause
//LMPE's, even when we aren't interested in them.
//The parity error hardware consists of one register for the IM PE
//indications and one for the SM/DM/DM1/DM2 and MP indications. Each
//of these registers is clocked only when there are no parity errors
//currently in the register. Hence, the code below has to cope with
//persistent MP or SM errors making it impossible to scan the memory
//of interest in that group and with a persistent IM error making
//it impossible to check the IM address of interest.
and ScanForLMPE() be
[ let AVec,DVec,ARMvec,ScanVec,PE = vec 1,vec 4,vec 2,vec 2,nil
let ClearArm = table [ 0; 0; 0 ]
AVec!0 = 0; NLMPEs = 0
//Preserve ARM across scan
XctR36(RDARM,ARMvec); ARMvec!0 = (ARMvec!0 & 16B) lshift 3
for I = 0 to MEMLEN!2 - 1 do //Scan IM
[ AVec!1 = I; ConvertAV(AVec,2)
XctL36(LDARM,ClearArm) //Clear PE indications
XctMic(RDIMH) //All four IM cards will be read
XctR36(RDARM,ScanVec)
if (ScanVec!0 & 3600B) ne 0 do
[ PE = ScanVec!0
if (PE & 2000B) ne 0 then ReportLMPE("IM[0,17]",I)
if (PE & 1000B) ne 0 then ReportLMPE("IM[18,35]",I)
if (PE & 400B) ne 0 then ReportLMPE("IM[36,53]",I)
if (PE & 200B) ne 0 then ReportLMPE("IM[54,71]",I)
]
]
//If subsequently ever use MP parity, have to change ConvertAV below to
//memory 5 and add RestoreMRegs(5) after RDARM.
for I = 0 to 777B do //Scan SM
[ AVec!1 = I; ConvertAV(AVec,3) //Address SM
XctL36(LDARM,ClearArm) //Clear and load parity
XctR36(RDARM,ScanVec)
test (ScanVec!0 & 160B) ne 0
ifso
[ PE = ScanVec!0
if (PE & 100B) ne 0 then ReportLMPE("SM[0,17]",I)
if (PE & 40B) ne 0 then ReportLMPE("SM[18,35]",I)
if (PE & 20B) ne 0 then ReportLMPE("MP",I)
]
ifnot //SM and MP errors in an address prevent check of
//same address in DM, DM1, or DM2
[ XctMic(RDDM); XctR36(RDARM,ScanVec)
if (ScanVec!0 & 160B) ne 0 do
[ if (ScanVec!0 & 100B) ne 0 then ReportLMPE("DM[0,17]",I)
if (ScanVec!0 & 40B) ne 0 then ReportLMPE("DM[18,35]",I)
XctL36(LDARM,ClearArm)
]
XctMic(RDDM1); XctR36(RDARM,ScanVec)
if (ScanVec!0 & 160B) ne 0 do
[ if (ScanVec!0 & 100B) ne 0 then ReportLMPE("DM1[0,17]",I)
if (ScanVec!0 & 40B) ne 0 then ReportLMPE("DM1[18,35]",I)
XctL36(LDARM,ClearArm)
]
XctMic(RDDM2); XctR36(RDARM,ScanVec)
if (ScanVec!0 & 160B) ne 0 do
[ if (ScanVec!0 & 100B) ne 0 then ReportLMPE("DM2[0,17]",I)
if (ScanVec!0 & 40B) ne 0 then ReportLMPE("DM2[18,35]",I)
]
]
]
// for I = 1000B to 1777B do //Scan MP high part
// [ AVec!1 = I; ConvertAV(AVec,5)
// XctL36(LDARM,ClearArm) //Clear and load parity
// XctR36(RDARM,ScanVec)
// if (ScanVec!0 & 20B) ne 0 do ReportLMPE("MP",I)
// ]
RestoreAfterLoad() //Restore address registers
XctL36(LDARM,ARMvec) //Restore ARM
Resets(CmdCommentStream); Wns(CmdCommentStream,NLMPEs,0,10)
WssCSS(" error"); if NLMPEs ne 1 then Puts(CmdCommentStream,$s)
]
and ReportLMPE(MemName,Addr) be
[ NLMPEs = NLMPEs+1
Resets(CmdCommentStream); WssCSS("PE in ")
WssCSS(MemName); Puts(CmdCommentStream,$ )
Wns(CmdCommentStream,Addr,0,8)
DisplayError(0,"Continue",0,0)
]