// MINIT1.BCPL Second initialization // Last edited: 16 November 1979 get "mdecl.d" get "mcommon.d" get "streams.d" external [ // OS CallSwat; Noop; Zero; SetBlock; Dvec // MINIT0 Init0B; @MBlock; RelocTable; Storage; StateBlock; StatePtr FirstStatic; LastStatic // MIDAS MidasSwat; ElapsedTime; TimeMSYM; TimeInit1; StateBlockSize // MASM Resets; Wss; PutTVs; ResetTVs; PutTxts; ResetTxts; @BlockTable GetStorage // MSYM @HeadBlock // MSYMOV UpdateRcd; BlockUpdateRcd; MakeNewBlock; InitSymBlock @LastBlockAddr; @NextM; @LastM2; @LastM1 // MOVERLAY SwappedOut // MRGN AddToEveryTimeList; EveryTimeP; EveryTimeA; ControlV RegionTable; NRegions // MMPRGN MPDEveryTime; FirstMPD; LastMPD // MMENU MenuBlock; @CurrentMDFS; FormMenu; EscMDFS // MCMD CmdMDFS; SavedLoadText // Machine dependent @ScreenHeight; @ScreenWidth; InitMPInterface @MEMWID; @MEMCON; @MEMNAM; @NMEMS @REGWID; @REGCON; @REGNAM; @NREGS // Defined here Init1; NewRegion; NewMPDispBlock; MakeTVS; MakeDisplayLine GetZStorage; GetHStorage; SaveStatics ] manifest [ MaxItemsInCmdMenu = 82 ] let Init1(TempStorage) be [ //Copy relocation information for initialization code into vec because //it gets overwritten by GetStorage. let RelocInfo = RelocTable!0+RelocTable!0+1 Dvec(Init1,lv RelocInfo) MBlock(RelocInfo,RelocTable,RelocTable!0+RelocTable!0+1) Init0B(TempStorage) //Returns only on Midas/I //MRGN EveryTimeP = GetStorage(MaxEveryTime) EveryTimeA = GetStorage(MaxEveryTime) SetBlock(EveryTimeP,Noop,MaxEveryTime) //MSYM BlockTable = GetZStorage((MaxInCoreBlocks*(size BT/16))+1) let CB = MakeNewBlock(NPagesPerHeadBlock,SymKind,0) HeadBlock = InitSymBlock(CB,NPagesPerHeadBlock*PageSize) BlockTable!0 = -1 //So that HeadBlock isn't in BlockTable CB = MakeNewBlock(NPagesPerStandardBlock,SymKind,0) let CurrentBlock = InitSymBlock(CB,NPagesPerStandardBlock*PageSize) LastBlockAddr = CB>>BT.BlockAddr //Enter null & max strings in symtab to avoid end checks unless BlockUpdateRcd(HeadBlock,-(size BH/16 - 1), "", lv LastBlockAddr, 1) & BlockUpdateRcd(CurrentBlock,-(size BH/16 - 1), "", table [ 0 ] , 1) & BlockUpdateRcd(CurrentBlock,-(size BH/16), table [ 1577B; 77577B ] ,table [ 0 ] , 1) do MidasSwat(MSymInitBug) ElapsedTime(lv TimeMSYM) //MMENU MenuBlock = GetZStorage(MaxMenus) // Following must be last items before call on DriverLoop // Put register and memory definitions into symbol table let Body = vec (size Symb/16) Body>>Symb.M.Type = MemSymb for MemX = 0 to NMEMS-1 do [ if (MEMCON+MemX)>>MRType.Defined eq 0 then loop Body>>Symb.M.X = MemX if MEMWID!MemX > (ValSize*16) then MidasSwat(VSEmsg,MEMNAM!MemX) UpdateRcd(MEMNAM!MemX,Body,size Symb.M/16) ] Body>>Symb.R.Type = RegSymb for RegX = 0 to NREGS-1 do [ if (REGCON+RegX)>>MRType.Defined eq 0 then loop Body>>Symb.R.X = RegX if REGWID!RegX > (ValSize*16) then MidasSwat(VSEmsg,REGNAM!RegX) UpdateRcd(REGNAM!RegX,Body,size Symb.R/16) ] //Machine dependent InitMPInterface() //MMPRGN AddToEveryTimeList(MPDEveryTime,nil) //MCMD let rcx,H,W = 0,3,ScreenWidth-1 SavedLoadText = GetZStorage(W+1) CmdMDFS = MakeMenuRegion(size MDFS/16,$X,-1,ScreenHeight-5, 0,H,W,MaxItemsInCmdMenu) EscMDFS = CmdMDFS //Save page zero statics SaveStatics(lv BlockTable,lv CurrentMDFS,lv LastBlockAddr, lv HeadBlock,lv NextM,lv LastM2,lv LastM1) Storage = Init1 //Bind initialization procedures to SwappedOut H = RelocInfo+1 let Lowest = Init1 for I = 1 to RelocInfo!0 do [ if (@H < FirstStatic) % (@H > LastStatic) then CallSwat() if @@H < Lowest then CallSwat() @@H = SwappedOut; H = H+2 ] ElapsedTime(lv TimeInit1) ] and GetHStorage(Size) = valof [ let Vector = GetStorage(Size+1) Vector!0 = Size resultis Vector ] and GetZStorage(Size) = valof [ let Vector = GetStorage(Size) Zero(Vector,Size) resultis Vector ] //For text lines, Rgn, ST, and TV are in sequence; return pointer to TV. and MakeDisplayLine(lvStream,Line,H,W,rcx) = valof [ let S = NewRegion((size Rgn/16)+(size ST/16)+W+1,0, Line,rcx,H,W,TextRgn)+(size Rgn/16) rv lvStream = MakeEmptyTVstream(S,W,PutTxts,ResetTxts) resultis S+(size ST/16) ] and MakeEmptyTVstream(S,Width,PutS,ResetS) = valof [ SetUpStream(S,S+(size ST/16),Width,CallSwat,CallSwat,PutS, ResetS,CallSwat,CallSwat,CallSwat,CallSwat,0,0) Resets(S) resultis S ] //For TV streams, ST structure is followed by TV. and MakeTVS(lvStream,lvVector) be [ rv lvStream = MakeEmptyTVstream( GetStorage((size ST/16)+ScreenWidth+1), ScreenWidth,PutTVs,ResetTVs) rv lvVector = (rv lvStream)+(size ST/16) ] and SetUpStream(S,xPar1,xPar2,xClose,xGets,xPuts,xResets,xPutb, xError,xEndof,xStateof,xType,xPar3) be [ S>>ST.par1 = xPar1; S>>ST.par2 = xPar2 S>>ST.close = xClose; S>>ST.gets = xGets S>>ST.puts = xPuts; S>>ST.reset = xResets S>>ST.putback = xPutb; S>>ST.error = xError S>>ST.endof = xEndof; S>>ST.stateof = xStateof S>>ST.type = xType; S>>ST.par3 = xPar3 ] //Fill in alternate words of StateBlock with pointers to page-zero statics //to be saved. The values are filled in by SaveState. and SaveStatics(lv1,lv2,lv3,lv4,lv5,lv6,lv7,lv8,lv9,lv10, lv11,lv12,lv13,lv14,lv15,lv16,lv17,lv18,lv19,lv20; numargs NA) be //Know that BCPL puts the args in sequential order on the stack [ if NA > 20 then MidasSwat(TMAforSaveStatics) while NA > 0 do [ NA = NA-1; StateBlock!StatePtr = (lv lv1)!NA StatePtr = StatePtr+2 ] if StatePtr > StateBlockSize then MidasSwat(StateBlockTiny) ] //The MDFS stuff uses the words preceding the RGN structure for TextLines, //SizeVec, and ProcVec. //**Note: It is desirable for the regions on a particular line to be //allocated in order, so that the searches by DriverLoop() are short and NewRegion(BlockSize,Offset,rlx,rcx,Height,Width,Type) = valof [ if NRegions ge MaxNRegions then MidasSwat(TooManyRgns) if (rlx+Height > ScreenHeight) % (rcx+Width > ScreenWidth) % (rlx < 0) % (rcx < 0) then MidasSwat(BadNewRegionArgs) let R = GetZStorage(BlockSize+Offset)+Offset R>>Rgn.aLineX = rlx R>>Rgn.aCharX = rcx R>>Rgn.Height = Height R>>Rgn.Width = Width R>>Rgn.Type = Type R>>Rgn.DispDirty = 1 NRegions = NRegions+1 if NRegions ne 0 do [ for I = rlx+1 to rlx+Height do [ if ControlV!I eq 0 then ControlV!I = NRegions ] ] RegionTable!NRegions = R resultis R ] //Menus may be a single letter (A to Z) or a single letter followed //by a small integer (A0 to E19). LineN must be -1 if omitted. //Command menu is "X" and MakeMenuRegion(Size,Letter,LineN,rlx,rcx,H,W,MaxNItems) = valof [ let Offset = H+MaxNItems Offset = Offset+(Offset rshift 1) let S = NewRegion(Size,Offset,rlx,rcx,H,W,MenRgn) S>>MDFS.Letter = Letter S>>MDFS.LineN = LineN S>>MDFS.ProcNMax = MaxNItems S>>MDFS.inLine = 1 // S>>MDFS.SelectedItem = 0; S>>MDFS.mIn = 0 let LetterV = Letter-$A if LineN ge 0 then LetterV = (LetterV*MaxLineN)+LineN+($Z-$A+1) if LetterV ge MaxMenus then MidasSwat(BadMenuName) if MenuBlock!LetterV ne 0 then MidasSwat(DuplicateMenuName) MenuBlock!LetterV = S resultis S ] //Args are Line = line number (0 to n) // C = left character (0 to ScreenWidth-1) // Cnm = command file character identifying region // W = width in characters (C+W < ScreenWidth, W < 128) //**Used to set NoName here for Maxc2 STK stuff,but now are using //**NoName in multi-line items, so no longer works. and NewMPDispBlock(Line,C,Cnm,W) be [ unless (C+W) < ScreenWidth do MidasSwat(BadMPDInit) let MPD = MakeMenuRegion(size MPD/16,Cnm,Line,Line,C,1,W,5) MPD>>MPD.RebuildText = true //DriverLoop will paint MPD>>MPD.TextSpace = W //This should be checked, not sure LastMPD = NRegions if FirstMPD eq 0 then FirstMPD = NRegions ]