//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) ]