// MINIT3.BCPL Final display and region initialization
//Init3() does final display and region initialization, then parses
//Com.CM in preparation for doing a Read-Cmds. It returns true if
//Read-Cmds should be done.
get "mdecl.d"
get "streams.d"
get "altofilesys.d"
external [
// OS
CallSwat; SetBlock; MoveBlock; Zero; lvUserFinishProc
OpenFile; Gets; Endofs; Closes; fpComCm
// MIDAS
GetStorage; GetEvenStorage; ZoneErr; Initialized; lvFinishProc
MidasFinish; Restoring; TimeInit3; ElapsedTime
// MASM
VertIntCode; Max; Min; @BlockTable
// MDISP
SaveAdd1; SaveData1; SaveAdd2; SaveData2; SaveAdd3; SaveData3
SavervDASTART; SavedDASTART; DispSpaceNowAvail
StandardLineHeight; NwdsPerScanLine
LineCtrlBlockPtrsVector; FirstDCB; DCBPoolSize; DCBPool
@BadMouseP; FreeBitBufferChain; AlmostFreeBitBufferChain
DCBPoolIn; DCBPoolOut; DCBPoolAvail; VertIntFlag; LinesInUse
GetFreeDCB; PutLineInService; InitBBblock; BBblock
// MRGN
ScreenTV; ScreenLineDirty; ControlV; RegionTable; NRegions
BlankS; MouseButtons; MouseButtonunion; PaintDirtyRegions
// MTXTBUF
InputTextBuffer
// MSYM
MakeNewBlock
// STATE package
StorageLeft
// MINIT2
VecInit; NNonOvBitBuffers; FirstNonOvLine
// Machine dependent
ScreenHeight //Number of text lines on screen
ScreenWidth //Number of chars/line
//Defined here
Init3
]
let Init3(fname) = valof
[
// MRGN
let SSize = (ScreenWidth rshift 1)+1
for I = 1 to ScreenHeight do
[ test LinesInUse!I
ifso
[ ScreenTV!I = GetStorage(SSize)
MoveBlock(ScreenTV!I,BlankS,SSize)
]
ifnot ScreenTV!I = BlankS
]
ScreenLineDirty = VecInit(ScreenHeight,true)
MouseButtons,MouseButtonunion = 0,0
for Rn = 0 to NRegions do
[ let R = RegionTable!Rn
if R eq 0 then CallSwat()
let alx,acx = R>>Rgn.aLineX,R>>Rgn.aCharX
let Llast = alx+R>>Rgn.Height
let Clast = acx+R>>Rgn.Width
for I = alx+1 to Llast do
[ let C1 = acx+1
if (C1 & 1) ne 0 do //Odd byte at beginning
[ (ControlV!I)>>CV↑C1 = Rn; C1 = C1+1 ]
if (Clast & 1) eq 0 do //Even byte at end
[ (ControlV!I)>>CV↑Clast = Rn ]
SetBlock(ControlV!I+(C1 rshift 1),Rn+(Rn lshift 8),
(Clast-C1+1) rshift 1)
]
]
// MDISP
FreeBitBufferChain,AlmostFreeBitBufferChain = 0,0
VertIntFlag,DispSpaceNowAvail = 0,0
BadMouseP = true
CreateDCBs(ScreenHeight+17) //Extras avoid wait for vert. int.
CreateLCBs()
SaveData1 = rv SaveAdd1
IntVec!(VertIntChan) = VertIntCode
SaveData2 = rv SaveAdd2
DASTART!1 = (DASTART!1) logor( 1 lshift (VertIntChan) )
SaveData3 = rv SaveAdd3
rv IntActive = (rv IntActive) logor (1 lshift VertIntChan)
SavervDASTART = rv DASTART //Saved for exit from Midas
//Midas comes up with the display off until the end of the Com.CM
//command file execution. The bit buffers remain in OverlayZone
//until after the first command in the command file is executed.
SavedDASTART = FirstDCB; rv DASTART = 0
Initialized = true
InitBBblock(BBblock,NNonOvBitBuffers)
//Have to dirty all the non-overlay regions so that they will get painted
//when the program is resumed after calls to AltIO.
for Rn = 0 to NRegions do (RegionTable!Rn)>>Rgn.DispDirty = 1
PaintDirtyRegions()
for L = FirstNonOvLine to ScreenHeight do PutLineInService(L)
//Finally, allocate extra symbol blocks with any unused storage. This
//is saved till last to make as many as possible. Everything procedes ok
//with regard to Midas.SymTab because the extra blocks have been written
//onto the disk before calling AltIO and because the first two blocks
//are preserved in Midas.State.
while StorageLeft()-2 > NPagesPerStandardBlock*PageSize do
[ BlockTable!0 = BlockTable!0 + 1
BlockTable!(BlockTable!0) = MakeNewBlock(NPagesPerStandardBlock)
]
lvFinishProc = @lvUserFinishProc
@lvUserFinishProc = MidasFinish
let X,C = 0,nil
test fname ne 0
ifso
[ Restoring!1 = 0
X = fname>>lh; if X > 72 then CallSwat(); for I = 0 to X do
[ InputTextBuffer!I = fname>>CV↑I ]
]
ifnot
//Skip over "Midas.run/n " in Com.CM
[ let F = OpenFile("Com.CM",ksTypeReadOnly,charItem,0,fpComCm)
if F eq 0 then CallSwat()
while not Endofs(F) do [ if Gets(F) eq $ then break ]
while not Endofs(F) do [ C = Gets(F); if C ne $ then break ]
while not Endofs(F) do
[ if X < 72 do [ X = X+1; InputTextBuffer!X = C ] ; C = Gets(F) ]
Closes(F)
InputTextBuffer!0 = X
]
ElapsedTime(lv TimeInit3)
resultis X > 0
]
and CreateLCBs() be
[ let B = GetStorage(ScreenHeight * (size LCB/16))
// create blank space at top of screen
FirstDCB = GetFreeDCB(NwdsPerScanLine,false,0,SkipScanLines rshift 1)
// now set up NLines
let PrevLCB = 0
let LastDCB = FirstDCB
for L = 1 to ScreenHeight do
[ let DCB = GetFreeDCB(NwdsPerScanLine, false, 0,
StandardLineHeight rshift 1)
LastDCB!0 = DCB; LastDCB = DCB
let LCB = B
B = B + (size LCB/16)
LCB>>LCB.DispCtrlBlock = DCB
LCB>>LCB.BitBuffer = 0
LCB>>LCB.PrevLCB = PrevLCB
LCB>>LCB.Hover2 = StandardLineHeight rshift 1
LineCtrlBlockPtrsVector!L = LCB
PrevLCB = LCB
]
LastDCB!0 = 0
]
and CreateDCBs(N) be
[ DCBPoolAvail,DCBPoolIn,DCBPoolOut = 0,0,1
DCBPool = GetStorage(N+1)
let DCBSpace = GetEvenStorage(4*N)
for I = 1 to N do
[ DCBPool!I = DCBSpace; DCBSpace = DCBSpace + 4 ]
DCBPool!0 = 0
DCBPoolSize = N+1
]