//Mgo.bcpl	machine-independent stop, go, breakpoint stuff
//	Last edited: 9 June 1980
//***Many changes for D0***

get "mdecl.d"
get "mcommon.d"

external [
// MASM
	DummyCall; @WssCSS

// MRGN
	AddToEveryTimeList

// MTXTBUF
	TxtBNewChar; InputTextBuffer

// MSYM
	EvalAText

// MMENU
	@WsMarkA; PrintActionTime

// MCMD
	StartCmdOverlay //;StartLargeOverlay
	WnsCSS; SetAbortPure; @CmdAbortAct; ErrorAbort

// MINIT0
	MStatus

// xxACTIONS
	GoVec; DetachAct; ExitAct

// Machine dependent
	SetupIMA; @CheckStopped; Stop; MStopped; DefaultGoMemory //; OneStep

//Defined here
	HaltWait; HaltWaitMenu; CollectAddr; HaltProc
	StartSetup; @QuitF; @CantContinue; CallAVec

// Defined here for ACTIONS
	SingleStepM; CallWithAddr; StartWithAddr //; StartBigOvlWithAddr
	ProceedM; StartM
]

static [
	@QuitF; @CantContinue = 0; CallAVec
]

//In the action table to call SingleStepM.
let CallWithAddr(lvProc,MB,nil) be
	CollectAddr(DummyCall,lvProc,MB)


//In the action table to call StartM and OpcodeStep (D1)
and StartWithAddr(lvProc,MB,nil) be
	CollectAddr(StartCmdOverlay,lvProc,MB)


//**This has to be resident (calls StartLargeOverlay)
//In the action table to call SimGo (D1)
//and StartBigOvlWithAddr(lvProc,MB,nil) be
//	CollectAddr(StartLargeOverlay,lvProc,MB)


//CollectAddr collects an address argument from the command line and calls
//a procedure like DummyCall, StartCmdOverlay, or StartLargeOverlay.
//The first arg to the call is MB.  The next two args, omitted if nothing
//is on the command line, are AVec and MemX.  ErrorAbort if the input text
//is not an address.
and CollectAddr(Proc,lvCalled,MB) be
[	test InputTextBuffer!0 le 0
	ifso Proc(lvCalled,MB)
	ifnot
	[ let X,AVal = 1,vec size AVal/16
	  unless EvalAText(InputTextBuffer,lv X,AVal,false,
		DefaultGoMemory()) do ErrorAbort()
	  unless AVal>>AVal.TypeStorage eq MemTypeStorage do ErrorAbort()
	  Proc(lvCalled,MB,lv AVal>>AVal.Addr,AVal>>AVal.X)
	]
	TxtBNewChar(177B)	//Clear command line so ;G continues
]


and SingleStepM(MB,AVec,MemX; numargs NA) =
	StartSetup(false,AVec,MemX,NA,"Step at ","Next step at ",MB)


and StartM(MB,AVec,MemX; numargs NA) =
	StartSetup(true,AVec,MemX,NA,"Go ","Resume ",MB)


and StartSetup(RunP,AVec,MemX,NA,S1,S2,MB) = valof
[	SetupIMA(RunP,AVec,MemX,NA,(NA ge 3 ? S1,S2),MB)
	SetAbortPure(lv HaltProc,nil)
	QuitF = AddToEveryTimeList(HaltWait,nil)
	MStatus>>MStatus.MachRunning = true
	resultis DetachMenu
]


and ProceedM(nil,MB,nil) be
[	StartCmdOverlay(lv StartM,MB); TxtBNewChar(#177)
]


and HaltWait(nil) be
[	if CheckStopped() then MStopped(true)
	PrintActionTime()
]


//This is used for keyboard halts to all the indefinitely computing
//go loops.
and HaltProc(nil,nil,nil) be
[	if CheckStopped() eq 0 then Stop()
	test CheckStopped() ne 0
	ifso
	[ WssCSS(", Aborted"); MStopped()
	]
	ifnot WssCSS(", Didn't halt")
]


and HaltWaitMenu(nil,nil) be WsMarkA(CmdAbortAct)


and DetachMenu(S,nil) be
[	WsMarkA(CmdAbortAct); WsMarkA(DetachAct); WsMarkA(ExitAct)
]