//D1go.bcpl microprocessor stop and go 23 June 1983
get "mcommon.d"
get "d1.d"
manifest [ get "d1pe.d" ]
manifest [ get "d1instrs.d" ]
manifest [ get "d1regmem.d" ]
//manifest [ get "d1dmux.d" ] "TOO MANY NAMES" so..
manifest [ dCJNK3=#16; dRTSB=#36; dFFK=#126; dESTAT=#164 ]
external [
// MINIT0
MStatus
// MIDAS
MidasSwat
// MASM
ErrorProtect; ResetsCSS; PutsCSS; @WssCSS; WssCS1; GetField
// MDATA
GoVec; CallAVec
// MRGN
RemoveFromEveryTimeList
// MSYM
SearchBlocks
// MCMD
QuitCmdOverlay; DisplayError; ErrorAbort; WnsCSS
CmdCommentStream; PassiveOnly
// MGO
@CantContinue; @QuitF
// MPATTERN
@PATTERN
// D1I0
@DMuxTab; HWStatus
// D1I1
@LDRMEM
// D1I2
ConfigUnknown
// D1TABLES
@MEMLEN; @MEMNAM
// D1ASM
@DoStrobe; LoadMIR; @Xct; @XctL16C; @XctL16Q; @SelectTask
Start; ContinueProgram; LoadDMD; LoadDWatch; stNotInVM; stNotIMA
// D1MEM
MGetMemData; SaveTIOA; @SaveLINK; @SaveTPC; @SaveTask; @SaveQ
// D1RES
RestoreD1Temps; ReadAllRegs; BreakTPC; BreakTask
// D1VM
LookUpVA; LookUpAA; @VirtualP
// D1GOOVL
PrintPEDetails; PrintCantContinue
// D1POKE
PassivePending
// D1CONFIG
FindConfiguration; ShowConnection; IMXmask
//Defined here
OneStep; MStopped; SetupIMA; DefaultGoMemory
PrCCV; PrintErrors; GetHMask; HaltFailed
]
//Setup for SS, Go, or Call. GoP is true for Go or Call, false for SS.
//AVec and MemX are either IMx (virtual) or IMXx (absolute).
//NA eq 1 sets up for a continue from last breakpoint (ignoring AVec and
//MemX); NA eq 3 indicates that a new go or step is being issued for the
//current task.
//SetupIMA leaves its results in GoVec as described in the "Go"
//structure def in MCommon.D.
let SetupIMA(GoP,AVec,MemX,NA,Str,MB) be
[ //RunP gets the final value for the Step or Go
GoVec>>Go.RunP = GoP ? Control+SetRun,Control+SetRun+SetSS
test NA ge 3
ifso //New go for current task
[ GoVec>>Go.Task = SaveTask
NA = AVec!1
switchon MemX into
[
case IMx: NA = LookUpAA(NA)
if NA < 0 then ErrorAbort(stNotInVM)
case IMXx: GoVec>>Go.Addr = NA; endcase
default: ErrorAbort(stNotIMA)
]
GoVec>>Go.Proc = Start
//Following code is a subset of "ResetControl" in D1Reset.bcpl.
LoadMIR(LDRMEM+TON)
DoStrobe(Control+SetRun+SetSS)
Xct(NOOP)
if (MB & BottomButton) eq 0 do
[ let RunControl = RunEnable+HWStatus>>HWStatus.RunControl
LoadDMD(RunControl & not IOResetx)
// Xct(IFRES); Xct(NOSKED)
XctL16Q(#1400); Xct(TIOAFQ)
XctL16Q(#32); Xct(OUTPUTFQ) //Reset interim dsp cont
XctL16Q(#1); Xct(TESTFQ) //Reset junk wakeups
XctL16Q(SaveTIOA); Xct(TIOAFQ) //Restore TIOA
Xct(RFINFO) //Reset fault task
XctL16Q(SaveQ)
SelectTask(0)
SaveTPC = IMXmask
XctL16C(LLINK,SaveTPC); LoadMIR(LDRMEM+RETN)
DoStrobe(Control+SetRun+SetSS)
for I = 1 to #17 do
[ XctL16C(LLINK,SaveTPC); Xct(NOOP)
XctL16C(LTPC,I)
]
DoStrobe(Clock+UseCPReg+ClrReady)
DoStrobe(Clock+UseCPReg)
XctL16C(LLINK,SaveLINK); Xct(NOOP)
LoadDMD(RunControl) //Turn off IOReset
]
]
ifnot //Continue
[ if CantContinue ne 0 do
[ ErrorProtect(lv PrintCantContinue)
DisplayError(0,"Try to continue",0,0)
]
GoVec>>Go.Proc = ContinueProgram
]
CantContinue = 0
RestoreD1Temps()
LoadDWatch()
//The 3rd arg "GoVec" below should be (lv GoVec>>Go.Addr)-1 because
//GoVec is misdefined with an "Addr" argument rather than an "AVec" arg.
ShowTaskandPC(Str,GoVec>>Go.Task,GoVec)
(GoVec>>Go.Proc)(GoVec)
]
//Subroutine used by d1ti, d1simres, and mgo
and OneStep(ContArg) be
[ DoStrobe(Control); DoStrobe(Control+ClrStop); DoStrobe(ContArg)
]
//**Eventually maybe do something for microcomputer here and in
//**SetupIMA.
and DefaultGoMemory() = valof
[ resultis VirtualP ? MEMNAM!IMx,MEMNAM!IMXx
]
//Called from MStopped, ShowTaskandPC, PrintTLINK, PrintIFUM, and PrintDMXw
//For MemX eq IMx, AVec!1 is -1 if undefined, else valid.
//For MemX eq IMXx, AVec!1 may have garbage in high bits.
and PrCCV(AVec,MemX) be
[ let virt = AVec!1 //Correct if MemX eq IMx
let absol = virt & IMXmask //Correct if MemX eq IMXx
switchon MemX into
[
default: MidasSwat(NotGoMemX)
case IMXx: virt = LookUpVA(absol); endcase
case IMx: if virt < 0 do
[ WssCSS(stNotInVM); return
]
absol = LookUpAA(virt)
//If virt ge 0 then virt is valid IM address, so LookUpAA must always succeed
if absol < 0 then MidasSwat(LookUpAAFail)
endcase
]
if VirtualP do
[ if virt ge 0 do
[ let AVec1 = vec 1; AVec1!0 = 0; AVec1!1 = virt
SearchBlocks(CmdCommentStream,IMx,AVec1); return
]
WssCSS("abs ") //Only get here for MemX eq IMXx
]
WnsCSS(absol)
]
and HaltFailed() be //Called by MGO.BCPL when Stop() fails to halt machine
[ if ConfigUnknown do
[ WssCSS("--assuming no Control section"); MStopped()
]
]
//Called from SingleStepM, HaltWait, and HaltProc in MGO, from SimGo in
//D1SIMT, and from InitHardware in D1I2. A message like "Go at 3:FOO"
//was printed on CmdCommentStream by SetupIMA; the caller may append other
//text to CmdCommentStream before calling MStopped. MStopped appends a
//string to describe the BP location on CmdCommentStream, prints error
//information on CmdCS1, and cleans up after the SS, Go, or whatever.
//GoFlag is omitted for keyboard halts, true for BP or error halts,
//false for SS actions; MStopped returns when GoFlag is false, but does
//QuitCmdOverlay when it is omitted or true.
and MStopped(GoFlag; numargs NA) be
[ if QuitF ge 0 do RemoveFromEveryTimeList(QuitF)
MStatus>>MStatus.MachRunning = false
if PassivePending then PassiveOnly = true
//FindConfiguration clutters CmdCommentStream and CmdCS1, so do
//ShowConnection to print a simpler message that is followed by the
//MStopped printout.
test ConfigUnknown
ifso
[ FindConfiguration(); ShowConnection(); ReadAllRegs(2)
]
ifnot ReadAllRegs(0)
let HaltBits = DMuxTab!dESTAT
if (HaltBits & MIRDebugena) ne 0 then
CantContinue = CantContinue % MIRdebugon
PrintErrors(HaltBits) //Printout confined to CmdCS1
//Did last instruction do Fetch← and ←Md?
if (DMuxTab!dCJNK3 & #10) eq 0 do //If last inst not held
[ let RTSB = DMuxTab!dRTSB & #66
let getsMd = (RTSB eq #20) % (RTSB eq #2) % (RTSB eq #22)
let didFetch = true //False warnings & miss ←MDI if PassiveOnly
unless PassiveOnly do
[ let DVec,AVec = vec 3,vec 1
AVec!0,AVec!1 = 0,BreakTPC
MGetMemData(IMXx,DVec,AVec)
let oldASEL,oldBSEL = GetField(16B,3,DVec),GetField(10B,3,DVec)
//oldFFmem = (BSEL < 4) & (JCN < 20B) ? FF.01,3
let oldFFmem = (oldBSEL < 4) &
(GetField(32B,4,DVec) ne 0) ? GetField(22B,2B,DVec),3
didFetch = (oldASEL eq 3) % ((oldASEL eq 1) & (oldFFmem eq 3))
]
if getsMd & didFetch then CantContinue = CantContinue+didFetMD
]
//**Should handle SS thru CallRetAddr and Abort happening after
//**CallRetAddr below also.
if (NA > 0) then
test GoFlag
ifso test (BreakTPC eq CallRetAddr) & (CallAVec!0 ne -1)
ifso
[ CantContinue = CantContinue % didCall
WssCSS(", return from ")
PrCCV(CallAVec,CallAVec!2); CallAVec!0 = -1
QuitCmdOverlay()
]
ifnot ShowTaskandPC(", halt after ",BreakTask,(lv BreakTPC)-1)
ifnot WssCSS(", halt")
ShowTaskandPC(" at ",GoVec>>Go.Task,(lv GoVec>>Go.Addr)-1)
if (NA < 1) % GoFlag then QuitCmdOverlay()
]
and ShowTaskandPC(str,task,AVec) be
[ WssCSS(str); WnsCSS(task); PutsCSS($:)
PrCCV(AVec,IMXx)
]
and PrintErrors(ESTAT) be
[ PATTERN = ESTAT & (GetHMask())
if (PATTERN & (IMlhPE+IMrhPE)) eq (IMlhPE+IMrhPE) do
[ WssCS1("BrkP, "); PATTERN = PATTERN & not (IMlhPE+IMrhPE)
]
test PATTERN eq 0
ifso WssCS1("No errors")
ifnot ErrorProtect(lv PrintPEDetails)
]
and GetHMask() = valof
[ let D = DMuxTab!dESTAT
let HMask = (D & IMrhPEena) ne 0 ? IMrhPE,0
if (D & IMlhPEena) ne 0 then HMask = HMask+IMlhPE
if (D & IOBPEena) ne 0 then HMask = HMask+IOBPE
if (D & RAMPEena) ne 0 then HMask = HMask+RAMPE
if (D & MemoryPEena) ne 0 then HMask = HMask+MemoryPE
if (D & MdPEena) ne 0 then HMask = HMask+MdPE
resultis HMask
]