// MINIT2.BCPL	Final display and region initialization
//	Last edited: 2 May 1980

//Init2() does final initialization, then parses Com.CM in preparation for
//RdCmds.  It returns non-0 if RCmds should be done.
//Init2 is reexecuted during RunProg, so it must initialize all stuff not
//restored by RestoreState.

get "overlays.d"
get "mdecl.d"
get "mcommon.d"
get "streams.d"

external [
// OS
	Puts; Resets; Gets; Endofs; Closes
	SetBlock; CreateDiskStream; fpComCm

// MIDAS
	MidasSwat; ElapsedTime; Initialized; FinalStorage
	TimeSwapInit2; TimeScreenInit; TimeRCActions; TimeInitHardware
	TimeCmdMenu1; TimePaintRegions; TimeInit2Menu; TimeCmdMenu2
	TimeLoadOvl; TimeComCM

// MOVERLAY
	FirstOD; LastOD; OvTable; ReadOverlay

// MASM
	GetStorage; Wss; @MBlock; ErrorProtect

// MDISP
	PutLineInService; InitBBblock; SetDisplay
	FreeBitBufferChain; AlmostFreeBitBufferChain
	BBblock; VertIntFlag; LineCtrlBlockPtrsVector

// MRGN
	PaintDirtyRegions; ScreenTV; ControlV

// MMENU
	CreateAction; LastPermanentAction; CFileStream

// MTXTBUF
	TxtBNewChar; InputStream; InputTextBuffer

// MCMD
	FormCmdMenu; ExecuteCFile; DoOverlay
	ProgramAct; NPrograms; ReadCAct; NReadCFiles
	CFOutStream; TextCmdOutStream; ShowActionForm; CmdAltMenuP

// MGO
	@CantContinue

// MINIT0
	NNonOvBitBuffers; FirstNonOvLine; FirstLCB; MStatus
	Storage; EndStorage

// xxACTIONS
	ActionPtr

// Machine dependent
	InitHardware; DetachHardware
	@ScreenHeight		//Number of text lines on screen
	@ScreenWidth		//Number of chars/line

//Defined here
	Init2
]

let Init2() = valof
[

	ElapsedTime(lv TimeSwapInit2)
// MRGN
	let SSize = (ScreenWidth rshift 1)+1
	for I = 1 to ScreenHeight do
	[ if ControlV!I ne 0 do
	  [ ScreenTV!I = GetStorage(SSize)
	    SetBlock(ScreenTV!I,20040B,SSize)
	    (ScreenTV!I)>>lh = ScreenWidth
	  ]
	]

// MDISP
	FreeBitBufferChain,AlmostFreeBitBufferChain = 0,0
	VertIntFlag = 0
	for L = 1 to ScreenHeight do
	[ let LCB = LineCtrlBlockPtrsVector!L
	  LCB>>LCB.Line.Buffer = 0
	]
//Initialize bit buffers not part of OverlayZone
	InitBBblock(BBblock,NNonOvBitBuffers)
	ElapsedTime(lv TimeScreenInit)

//Initialize actions for RunProg submenu
	for I = 0 to NPrograms-1 do
		CreateAction(ProgramAct!I,lv ExecuteCFile,ProgramAct!I)
//and RdCmds submenu (prevent CmdCommentStream and CmdCS1 reset so that
//DumpDisplay will work correctly)
	for I = 0 to NReadCFiles-1 do
	[ let Action = CreateAction(ReadCAct!I,lv ExecuteCFile,ReadCAct!I)
	  Action>>Action.ifNoRes = 1
	]
	LastPermanentAction = ActionPtr
	ElapsedTime(lv TimeRCActions)

	let V = vec 100
//MStatus.RunProg is 0 for normal initialization, 1 for RunProg, and
//2 for Dtach.
	let X = MStatus>>MStatus.RunProg
	MStatus>>MStatus.RunProg = 0
//If RunProg, then InputStream still contains whatever was there
//prior to RestoreState; if not RunProg then look at Com.cm
	test X ge 1
	ifso if X eq 2 do		//Dtach?
	  [ TxtBNewChar(#177)		//Clear input text line
	    DetachHardware()		//Detach from old machine
	    CantContinue = 0		//Indicate continuation ok.
	    X = 0			//Indicate no comfile
	  ]
	ifnot
	[ Resets(InputStream)
	  let F = CreateDiskStream(fpComCm,ksTypeReadOnly,charItem)
	  if F eq 0 then MidasSwat(NoComCm)
//Skip possible "; "
	  until Endofs(F) do [ if (Gets(F) & 337B) eq $M then break ]
//Skip over "Midas.run/n " in Com.CM
	  until Endofs(F) do [ if Gets(F) eq $  then break ]
	  let C = nil
	  until Endofs(F) do [ C = Gets(F); if C ne $  then break ]
	  until Endofs(F) do
	  [ X = 1; Puts(InputStream,C); C = Gets(F)
	  ]
	  Closes(F)
	]
//Preserve InputTextBuffer across initialization menu
	MBlock(V,InputTextBuffer,(InputTextBuffer!0)+1)
	ElapsedTime(lv TimeComCM)

	CmdAltMenuP = InitHardware()
	ElapsedTime(lv TimeInitHardware)

//FormCmdMenu before PaintDirtyRegions() avoids display rebuilding.
	FormCmdMenu()
	ElapsedTime(lv TimeCmdMenu1)

	PaintDirtyRegions()
	for L = FirstNonOvLine to ScreenHeight do PutLineInService(L)
	ElapsedTime(lv TimePaintRegions)

//Analogous to StartCmdOverlay in MCMD.
	if CmdAltMenuP ne 0 do
	[ SetDisplay(false)	//Display on to show menu
	  ErrorProtect(lv DoOverlay)
	  SetDisplay(true)	//Display off again
	  CmdAltMenuP = 0
	  ElapsedTime(lv TimeInit2Menu)
	  FormCmdMenu()
	  ElapsedTime(lv TimeCmdMenu2)
	]
//"Initialized" signals that MGetxx and MPutxx procedures may be
//called; used in MMPRGN, also available to machine-dependent code.
	Initialized = true

	FinalStorage = EndStorage-Storage

//Make as many overlays resident as possible, except that "Load" overlay
//is excluded since it may flush others to make symbol Blocks, the
//"Init2" overlay is excluded, and the "Test" overlay is excluded so
//that the MPDEveryTime stuff will not interfere with testing.
	for od = FirstOD+ODsize+ODsize+ODsize to LastOD by ODsize do
	[ let Np = (od+ODsize)>>OD.firstPn-od>>OD.firstPn
	  let NW = Np lshift 8
	  if NW < EndStorage-Storage do
	  [ let P = OvTable!0
	    OvTable!P = Storage; OvTable!(P+1) = od
	    OvTable!0 = P+2
	    ReadOverlay(od>>OD.firstPn,Storage,Np,od)
	    Storage = Storage+NW
	  ]
	]
	ElapsedTime(lv TimeLoadOvl)

	CFileStream = MStatus>>MStatus.CFileStream
	CFOutStream = MStatus>>MStatus.CFOutStream
	TextCmdOutStream = MStatus>>MStatus.TextCmdOutStream
	ShowActionForm = MStatus>>MStatus.ShowActionForm

	Resets(InputStream); MBlock(InputTextBuffer,V,(V!0)+1)
	resultis X ne 0
]