//D1goovl.bcpl -- Error print routine called from PrintErrors in D1go. // Last edited: 4 May 1980 get "mcommon.d" get "d1.d" manifest [ get "d1pe.d" ] manifest [ get "d1instrs.d" ] manifest [ get "d1dmux.d" ] manifest [ get "d1regmem.d" ] external [ // MASM ResetsCSS; @WssCSS; WssCS1; PutsCS1; GetField // MDATA GoVec // MIOC DataToStream // MMPRGN FixForm // MCMD WnsCS1; CmdCS1 // MGO StartSetup; HaltWait; HaltWaitMenu; @CantContinue; CallAVec PassiveOnly // MPATTERN @PATTERN // MPRINS NWss; NWss1 // MINIT0 MStatus // D1I0 @DMuxTab; @SaveMIR // D1TABLES @MEMWID; @MEMFORMS // D1ASM @XctL16T; ReadDMux; @Xct; IMtoMIR // D1RES BreakTPC // D1MEM MGetRegData; MGetMemData; @SaveT; @SaveLINK // D1GO SetupIMA; OneStep; MStopped; GetHMask // Defined here OpcodeStep; CallM; PrintPEDetails; PrintCantContinue ] //Keyboard "Call" action. CallM is called from StartWithArgs in MGO. //CallAVec!0 and CallAVec!1 are the collected address, CallAVec!2 is the //MemX of the address, AV is a vector containing Count (up to 5) 32-bit //argument vectors. let CallM(MB,AV,Count) = valof [ SaveLINK = CallRetAddr if Count > 0 then [ SaveT = AV!1; XctL16T(SaveT); Xct(NOOP) ] //"Start" will first load LINK with the subroutine address, and step //the STARTX instruction (= RETURN, B←RWCPREG) with SaveLINK in CPReg. //This causes CallRetAddr to wind up in LINK irrespective of whether //the subroutine is on a call location. SetupIMA(true,CallAVec,CallAVec!2,3,"Call ",MB) OneStep(GoVec>>Go.RunP) resultis StartSetup(HaltWait) //Displays "Abort" & "Dtach" ] //"OS" action. OpcodeStep is called from StartWithAddr in MGO. //AVec and MemX args are supplied if starting at a new address, //omitted if continuing from previous halt. Single-step the //microprocessor until a normal halt condition occurs or an //IFUJump has been executed. and OpcodeStep(MB,AVec,MemX; numargs NA) = valof [ SetupIMA(false,AVec,MemX,NA,(NA ge 3 ? "Step opcode at ", "Next opcode at "),MB) StartSetup(OpcodeWait) ReadDMux(); MStatus>>MStatus.MachRunning = true resultis HaltWaitMenu //Displays "Abort" action ] and OpcodeWait(nil) be [ let DVec = vec 4; IMtoMIR(SaveMIR,DVec) let JCN = GetField(32B,10B,DVec) OneStep(Control+SetRun+SetSS); ReadDMux() //Halt after the IFUJump unless Hold occurred. if (JCN & 347B) eq 47B then unless (DMuxTab!dCJNK3 & 10B) ne 0 do MStopped(true) if (DMuxTab!dESTAT & GetHMask()) ne 0 then MStopped(true,true) ] and PrintCantContinue() be [ ResetsCSS(); WssCSS("Can't continue:") PATTERN = CantContinue NWss(" did-test",didTest) NWss(" did-Load") NWss(" did-PEscan") NWss(" after-Call") NWss(" did-SetClk") NWss(" did-Reset") NWss(" did-Tn") NWss(" IFUM-reset") NWss(" MIRdebug-on-at-break") NWss(" task 17 b.p. mem item displayed") NWss(" touched IMBD") NWss(" did-Fetch-and-←Md") ] //DMuxTab!dESTAT & HaltConditions is in PATTERN and PrintPEDetails() be [ WssCS1("PE's from") NWss1(" IM[21:41]",IMrhPE) NWss1(" IM[0:20]") //Analyze IM/MIR failures if MIRDebug feature enabled. In this case //SaveMIR contains what was in MIR; compare against direct IM output. if ((DMuxTab!dESTAT & MIRDebugena) ne 0) & (not PassiveOnly) & ((PATTERN & (IMrhPE+IMlhPE)) ne 0) do [ let VMIR,VIM,AVec = vec 3,vec 3,vec 1 AVec!0 = 0; AVec!1 = BreakTPC MGetRegData(MIRx,VMIR); MGetMemData(IMXx,VIM,AVec,0) WssCS1(" (IMX["); WnsCS1(BreakTPC); WssCS1("]=") DataToStream(CmdCS1,FixForm(MEMFORMS!IMXx,0),MEMWID!IMXx,VIM,8) PutsCS1($)) ] let TaskBk = not DMuxTab!dRADDR let TaskInErr = TaskBk<<nib0 //Task2Bk let T = DMuxTab!dPERR if (PATTERN & MdPE) ne 0 do [ PrinProcErr(((T & 10000B) ne 0 ? "MD","MDI"),T rshift 2) if (T & 10000B) ne 0 then TaskInErr = TaskBk<<nib1 //Task3Bk ] if (PATTERN & IOBPE) ne 0 then PrinProcErr(((T & 20000B) ne 0 ? "Output","Input"),T rshift 3) if (PATTERN & RAMPE) ne 0 do [ test (T & 1403B) eq 0 ifso WssCS1("RM-STK-T?") ifnot [ if (T & 1002B) ne 0 then PrinProcErr(((T & 100B) ne 0 ? "STK","RM"),T rshift 1) if (T & 401B) ne 0 then PrinProcErr("T",T) ] ] //Task unknown for memory errors if (PATTERN & (MdPE+IOBPE+RAMPE)) ne 0 do [ WssCS1(" (by task "); WnsCS1(TaskInErr); PutsCS1($)) ] //STPerr, HitPerr, and ?MapPerr? (optional) on the mufflers remain //at the values which cause MemPE until ←FaultInfo is done. These //errors are also reset and disabled by NoWake in Mcr. if (PATTERN & MemoryPE) ne 0 do [ PATTERN = DMuxTab!dRFSSRN test (PATTERN & 160000B) ne 0 ifso [ NWss1(" ST",#100000) NWss1(" Map") NWss1(" Cache") ] ifnot WssCS1(" Memory") ] ] and PrinProcErr(Str,Val) be [ PutsCS1($ ); WssCS1(Str) WssCS1(selecton Val & 401B into [ case 400B: "[0:7]" case 1B: "[8:15]" case 401B: "" default: "?" ] ) ]