//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: "?"
] )
]