//MINIT0.BCPL First init // Last edited: 11 July 1980 // This file is loaded with the program. After execution, its storage // is added to free storage. On "Midas/I", initialize Midas; on // "Midas/R" (Maxc2 Midas only), resume from previous AltIO call. // Otherwise, initialize Midas from the state file. get "sysdefs.d" get "streams.d" get "altofilesys.d" get "disks.d" //for def of fillInDA get "mdecl.d" get "mcommon.d" get "overlays.d" external [ // OS SysErr; MoveBlock; SetBlock; Zero; fpSysDir; OpenFile CreateDiskStream; Closes; Gets; WriteBlock; Endofs lvUserFinishProc; Noop; Junta; GotoLabel; CallersFrame InitializeZone; sysZone; lvSysZone keys; CreateKeyboardStream // OVERLAYSINIT OverlayScan // MDI LookupEntries // GACHA10 FontP // MIDAS InitRes; MidasFinish; MidasSwat lvFinishProc; ElapsedTime; SysZoneSize; StackSize TimeJunta; TimeLoadRam; TimeJunkInit; TimeLookup1; TimeCreateFiles TimeOvScan; TimeLookup2; TimeQFiles; CodeOS; StorageSize AvailBlockSize; BBblockSize // MASM Puts; Resets; Wss; VertIntCode; SelfRel; GetStorage; GetEvenStorage // MDATA MidasCFA // MOVERLAY KillOverlays; OvTable // MTXTBUF InputStream; InputTextBuffer; TxtBNewChar // MSYM TVtoString; @StringVec; Map; NQuickFiles; FileBlock // MDISP MakeDispZoneAvail; ZoneErr SaveData1; SaveData2; SaveData3; SavervDASTART; SavedDASTART LineCtrlBlockPtrsVector; AvailBlock; BBblock FontCharWidth; AvailBlockNLines NwdsPerScanLine; StandardLineHeight; BitBufferLen // MRGN ScreenTV; ScreenLineDirty; RegionTable; ControlV SelectedRegion; CharInputRoutine // MMPRGN MPDs; @MPDVVec // MMENU @ItemV; ItemStream; SkipName; EscInputText; TimeStartAction // MCMD RestoreState; CmdCommentStream; CmdCS1; NPrograms; ProgramAct NReadCFiles; ReadCAct // MGO CallAVec // MDEBUG Vec60 // MINIT1 MakeDisplayLine; MakeTVS; GetHStorage; GetZStorage; NewRegion // xxACTIONS ActionBlock; LastAction; NHWCFActions; HWCFActions // Machine dependent InitHardware1; @ScreenHeight; @ScreenWidth @REGNAM; @REGFORMS; @NREGS; @MEMNAM; @MEMFORMS; AltMInput; @NMEMS MachVersion //Defined here Init0; Init0B; CopyTemplate; @MBlock Storage; EndStorage; StateBlock; StatePtr; StateEnd BlockStoreFP; FixUpFP; ErrsFP; RunProgFP; DtachFP // MidasRFP @ACTS; RelocTable; MStatus; CmdCS0Vec; CmdCS1Vec NNonOvBitBuffers; FirstNonOvLine; FirstLCB; SkipScanLines FirstStatic; LastStatic; NStatics; StateBlockSize ProgramStream; TimeStream ] static [ FirstStatic // Loc of first static from Layout vector LastStatic // Last static from Layout vector NStatics StateBlockSize = #40 //> no. saved page zero statics*2 Storage; EndStorage; StateBlock; StatePtr = 0; StateEnd RelocTable // Pointer to vector of init procedures from Layout // vector (RelocTable!0 has no. reloc pairs) Switch // Command line switch to program BlockStoreFP; FixUpFP; ErrsFP; RunProgFP; DtachFP // MidasRFP @MBlock; MStatus; CmdCS0Vec; CmdCS1Vec ProgramStream; TimeStream; CopyTemplate; @ACTS NNonOvBitBuffers; FirstNonOvLine; FirstLCB; LCBSpace Leading = 1; SkipScanLines = 130 ExtraBitBuffers = -3 //Should be ge 1 - no. blank screen lines ] manifest [ codePtr = #335 NFNames = 5 // Number of names being looked up NumOverlays = 37 // Max number of overlays (was 35 on // 28 October 1979 for Dorado Midas) // MapSize = 2*(MaxBlockPages+1)+13+(size FP/16) //For ISF package OvTSize = (ODsize+1)*NumOverlays+12 MaxQuickFiles = 60 // Maximum no. files in table ] let Init0(Layout,userParams,CFA) be [ FirstStatic = Layout!26 LastStatic = Layout!27 NStatics = LastStatic-FirstStatic+1 RelocTable = Layout!31 Switch = userParams!1 CopyTemplate = Noop //Needed by levStreams MBlock = MoveBlock //Use zrel call to this common subr. //Save Midas.run CFA across Junta for OverlayScan MBlock(MidasCFA,CFA,lCFA) //Convert assembled-in self-relative pointers to absolute for I = ActionBlock to LastAction by size Action/16 do I>>Action.Name = I>>Action.Name+I LastAction = LastAction+(size Action/16) let Action = HWCFActions //Args for HWActions are string pointers to file names for I = 1 to NHWCFActions do [ Action>>Action.Arg = Action>>Action.Arg+(lv Action>>Action.Arg) Action = Action+(size Action/16) ] for I = 0 to NREGS-1 do [ REGNAM!I = SelfRel(REGNAM+I) if REGFORMS!I ne 0 then REGFORMS!I = SelfRel(REGFORMS+I) ] for I = 0 to NMEMS-1 do [ MEMNAM!I = SelfRel(MEMNAM+I) if MEMFORMS!I ne 0 then MEMFORMS!I = SelfRel(MEMFORMS+I) ] //Make length error-checks on the machine-description tables if (MEMNAM-REGNAM) ne NREGS*6 then MidasSwat(RTablesInconsistent) if (AltMInput-MEMNAM) ne NMEMS*7 then MidasSwat(MTablesInconsistent) Junta(levStreams,Init0A) ] and Init0A(nullArg) be [ ElapsedTime(lv TimeJunta) CodeOS = -(lv nullArg) //Approximate size of OS //Storage is initialized here rather than in Init0B because Init0B // uses considerable stack space, all wasted when the new stack is // created. Init0A doesn't have much stack space. Storage = rv codePtr EndStorage = (lv nullArg)-4-StackSize StorageSize = EndStorage-Storage //Orig. size for stats rv codePtr = EndStorage //The ZoneErr static, normally 0, can be set to CallSwat or SysErr //to invoke zone checking. sysZone = InitializeZone(GetStorage(SysZoneSize),SysZoneSize, SysErr,ZoneErr) rv lvSysZone = sysZone keys = CreateKeyboardStream() // Init0B returns true if full initialization should be done. // GotoLabel is required here to prevent MidasSwat() by ReleaseOverlay() GotoLabel(CallersFrame(),InitRes) ] and Init0B(TempStorage) be [ //*Replaced this stuff by making GACHA10.AL into a .br file // let FontStream = CreateDiskStream(FontFP,ksTypeReadOnly) // let SizeFont = (FileLength(FontStream)+1) rshift 1 // PositionPage(FontStream,1); FontP = GetStorage(SizeFont)+2 // ReadBlock(FontStream,FontP-2,SizeFont); Closes(FontStream) // StorageFont = SizeFont //Was 2170 for gacha10.al // ElapsedTime(lv TimeFont) //Max char width = exact if fixed pitch font FontCharWidth = (FontP-1)>>rh NwdsPerScanLine = ((ScreenWidth*FontCharWidth-1) rshift 4)+1 StandardLineHeight = FontP!(-2) & 177776B //Initialize LCB's (line control blocks) and turn off the display //Do this first so that the machine will run fast during rest of init. LineCtrlBlockPtrsVector = GetStorage(ScreenHeight)-1 LCBSpace = GetEvenStorage((ScreenHeight+1)*(size LCB/16)) // create blank space at top of screen FirstLCB = GetFreeDCB(SkipScanLines rshift 1) // now set up NLines let LCB = nil for L = 1 to ScreenHeight do [ LCB = GetFreeDCB(StandardLineHeight rshift 1) LineCtrlBlockPtrsVector!L = LCB ] LCB>>LCB.Sepr.Link = 0 SaveData1 = IntVec!VertIntChan SaveData2 = DASTART!1 SaveData3 = rv IntActive SavervDASTART = rv DASTART //Saved for exit from Midas IntVec!VertIntChan = VertIntCode DASTART!1 = (DASTART!1) % (1 lshift (VertIntChan)) rv IntActive = (rv IntActive) logor (1 lshift VertIntChan) //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 = FirstLCB; rv DASTART = 0 lvFinishProc = @lvUserFinishProc @lvUserFinishProc = MidasFinish BitBufferLen = StandardLineHeight * NwdsPerScanLine //The register menu lines become the OverlayZone. Lines below that //are put in service by Init2. let OvLines = ScreenHeight-11 NNonOvBitBuffers = 11 + ExtraBitBuffers FirstNonOvLine = OvLines+1 AvailBlockNLines = OvLines BBblockSize = (BitBufferLen+2) * (ScreenHeight + ExtraBitBuffers) AvailBlockSize = OvLines*(BitBufferLen+2) BBblock = GetEvenStorage(BBblockSize) AvailBlock = BBblock+BBblockSize-AvailBlockSize MStatus = GetZStorage(size MStatus/16) //For RunProg, Dtach ACTS = GetStorage(100) //For actions using alternate command menus Vec60 = GetStorage(60) //For SaveDGen and RestoreDGen in MDEBUG StringVec = GetStorage(129) //For TVtoString and MLOAD CallAVec = GetStorage(3); SetBlock(CallAVec,-1,3) //For MGO TimeStartAction = GetStorage(2) //For MMENU //First part of init for MRGN ScreenLineDirty = GetHStorage(ScreenHeight) SetBlock(ScreenLineDirty+1,true,ScreenHeight) ScreenTV = GetHStorage(ScreenHeight) Zero(ScreenTV+1,ScreenHeight) //Temporarily use vec's for these two; then copy these to real storage //if Midas/I. This avoids saving the storage on the state file and //allows InputTextBuffer to be written on RunProg. let Rtab,CVtab = vec MaxNRegions,vec 80 Zero(Rtab,MaxNRegions); Zero(CVtab,80) RegionTable,ControlV = Rtab,CVtab SelectedRegion = NewRegion(size Rgn/16,0,0,0,ScreenHeight, ScreenWidth,NopRgn) let W = ScreenWidth-1 //MakeDisplayLine args are lvStream,Line,Height,Width,FirstC, where //Lines are numbered from 1 and chars from 0. A pointer to the TV for //the line is returned. MakeDisplayLine(lv ProgramStream,ScreenHeight-10,1,50,0) MakeDisplayLine(lv TimeStream,ScreenHeight-10,1,W-50,50) CmdCS0Vec = MakeDisplayLine(lv CmdCommentStream,ScreenHeight-8,1,W,0) CmdCS1Vec = MakeDisplayLine(lv CmdCS1,ScreenHeight-7,1,W,0) InputTextBuffer = MakeDisplayLine(lv InputStream,ScreenHeight-1,1,W,0) CharInputRoutine = TxtBNewChar //First part of init for MMENU EscInputText = GetZStorage(ScreenWidth+1) SkipName = GetStorage(11) MakeTVS(lv ItemStream,lv ItemV) MakeTVS(lv MPDs,lv MPDVVec) ElapsedTime(lv TimeJunkInit) InitHardware1() Storage = InitHardware1+1000B //1000B kludge bypasses MachVersion ElapsedTime(lv TimeLoadRam) //Build a table of file names to be looked up in the System directory let SysDirStream = CreateDiskStream(fpSysDir,ksTypeReadOnly) //NFNames must be .le. MaxQuickFiles let NV,SV = vec MaxQuickFiles,vec MaxQuickFiles let FileDV = GetStorage(lDV*NFNames) SetupFPN(lv RunProgFP,NV,SV,0,FileDV,"MIDAS.RUNPROG",1) SetupFPN(lv DtachFP,NV,SV,1,FileDV,"MIDAS.DTACH",1) SetupFPN(lv BlockStoreFP,NV,SV,2,FileDV,"SWATEE",0) //Instead of SWATEE, can use: // SetupFPN(lv BlockStoreFP,NV,SV,2,FileDV,"MIDAS.SYMTAB",MaxBlockPages) SetupFPN(lv FixUpFP,NV,SV,3,FileDV,"MIDAS.FIXUPS",1) SetupFPN(lv ErrsFP,NV,SV,4,FileDV,"MIDAS.COMPARE",1) //No longer do these two // SetupFPN(lv FontFP,NV,SV,5,FileDV,"GACHA10.AL",0) // SetupFPN(lv MidasRFP,NV,SV,6,FileDV,"MIDAS.RESUME",-1) // LookupEntries uses .85 + .03/file seconds with ~240 files in directory // Use storage at the low end of the block used by GetStorage let Undefined = LookupEntries(SysDirStream,NV,FileDV,NFNames, true,BBblock,BBblockSize) ElapsedTime(lv TimeLookup1) Map = GetStorage(MaxBlockPages+1) test Undefined ne 0 ifso Switch = $I //Force Midas/I ifnot [ Map!0 = BlockStoreFP>>FP.leaderVirtualDa SetBlock(Map+1,fillInDA,MaxBlockPages) ] //Show last editing dates Wss(ProgramStream,"Midas 7/11/80"); Wss(ProgramStream,MachVersion) //Initialize for SaveState/RestoreState //Storage allocated after this point will be saved/restored on/from the //state file(s) MakeDispZoneAvail() StateEnd = EndStorage switchon Switch & not 40B into [ case 0: Closes(SysDirStream) //No switch = RestoreState RestoreState(DtachFP,false) //Doesn't return //case $R: Closes(SysDirStream) // RestoreState(MidasRFP,false) default: MidasSwat(BadSwitch) case $I: endcase ] StateBlock = GetStorage(StateBlockSize) //Use BBblock for scratch storage because it is the largest hunk //of storage available at this time--but have to rebuild OverlayZone //because of this. if OverlayScan(lv MidasCFA>>CFA.fp,GetStorage(OvTSize),OvTSize, lv MidasCFA>>CFA.fa,BBblock,BBblockSize) < 0 then MidasSwat(OvlScanFailure) OvTable = GetZStorage(NumOverlays*2+1); OvTable!0 = 1 ElapsedTime(lv TimeOvScan) MakeDispZoneAvail() if Undefined ne 0 do [ for I = 0 to NFNames-1 do [ if FileDV!0 eq 0 do [ let Name,npgs = NV!I,SV!I if npgs eq 0 then MidasSwat(NonXFile,Name) Zero(FileDV,lDV) if npgs ne -1 do [ let scratch = vec #400 //Now write the file let S = OpenFile(Name,ksTypeWriteOnly,wordItem,verNew, FileDV+(offset DV.fp/16)) test S ne 0 ifso [ for i = 1 to npgs do WriteBlock(S,scratch,#400) Closes(S) ] ifnot MidasSwat(CreateFailed,Name) ] ] FileDV = FileDV+lDV ] Map!0 = BlockStoreFP>>FP.leaderVirtualDa SetBlock(Map+1,fillInDA,MaxBlockPages) KillOverlays() ] ElapsedTime(lv TimeCreateFiles) //Build these FP's in TempStorage which is the CFileStack vec passed //through Init1(..) to Init0B(..) from InitRes(..). //MIDAS.MIDAS is executed to setup state files for Dtach and RunProg //actions. SetupFPN(lv FileDV,NV,SV,0,TempStorage,"MIDAS.MIDAS",0) let MProgFP,UProgFP = nil,nil let MProgS,UMProgS = "MIDAS.PROGRAMS","MIDAS.USERPROGRAMS" SetupFPN(lv MProgFP,NV,SV,1,TempStorage,MProgS,0) SetupFPN(lv UProgFP,NV,SV,2,TempStorage,UMProgS,-1) Undefined = LookupEntries(SysDirStream,NV,TempStorage,3, true,BBblock,BBblockSize) let HaveUserPrograms = true if Undefined ne 0 do [ if TempStorage!(lDV+lDV) eq 0 then HaveUserPrograms = false for I = 0 to 1 do [ if TempStorage!(lDV*I) eq 0 then MidasSwat(NonXFile,NV!I) ] ] ElapsedTime(lv TimeLookup2) //Read "Midas.Programs" and "Midas.UserPrograms" treating the names //there as follows: // a name containing no "." is made into a "RunProg" menu item // if name.midas exists, and both name.midas and name.mb // are entered into the QuickOpenFile table; // if the name contains a ".", it is only entered into the QuickOpenFile // table. //In either case no entry is made in the QuickOpenFile table unless the //file exists. //The algorithm below puts pointers to ".Midas" files at the low end //of NV and to ".mb" and other files at the high end let midasPtr,mbPtr = 0,MaxQuickFiles SetupMidasFiles(MProgFP,MProgS,NV,SV,lv midasPtr,lv mbPtr) if HaveUserPrograms do [ SetupMidasFiles(UProgFP,UMProgS,NV,SV,lv midasPtr,lv mbPtr) ] //Now pack NV for LookupEntries let NFNames = midasPtr+MaxQuickFiles-mbPtr MBlock(NV+midasPtr,NV+mbPtr,MaxQuickFiles-mbPtr) let DV = vec MaxQuickFiles*lDV Undefined = LookupEntries(SysDirStream,NV,DV,NFNames, true,BBblock,BBblockSize) Closes(SysDirStream) MakeDispZoneAvail() NQuickFiles = NFNames - Undefined let FBsize = NQuickFiles*lDV; FileBlock = GetZStorage(FBsize) ProgramAct = GetZStorage(midasPtr) //Table of names defined as //actions by MINIT2 let FBPtr = 0 ReadCAct,NReadCFiles,NPrograms = ProgramAct+midasPtr,0,0 for I = 0 to NFNames-1 do [ if DV!0 ne 0 do [ let Str = NV!I; let StrSize = (Str>>lh rshift 1)+1 DV!0 = Str; MBlock(FileBlock+FBPtr,DV,lDV); FBPtr = FBPtr+lDV if FBPtr > FBsize then MidasSwat(LUEBug) if I < midasPtr do [ let PStr = GetStorage(StrSize-3) //Truncate ".Midas" MBlock(PStr,Str,StrSize-3) PStr>>lh = Str>>lh - 6 test SV!I ifso [ ReadCAct = ReadCAct-1; NReadCFiles = NReadCFiles+1 rv ReadCAct = PStr ] ifnot [ ProgramAct!NPrograms = PStr; NPrograms = NPrograms+1 ] ] ] DV = DV+lDV ] ElapsedTime(lv TimeQFiles) RegionTable = GetStorage(MaxNRegions) MBlock(RegionTable,Rtab,MaxNRegions) ControlV = GetStorage(ScreenHeight+1) MBlock(ControlV,CVtab,ScreenHeight+1) Storage = Init0 ] and SetupFPN(lvFP,NV,SV,X,PrVec,Name,Size) be [ NV!X = Name; SV!X = Size rv lvFP = PrVec+(offset DV.fp/16)+lDV*X ] and SetupMidasFiles(FP,Str,NV,SV,lvmidasPtr,lvmbPtr) be [ let S = CreateDiskStream(FP,ksTypeReadOnly,charItem) if S eq 0 then MidasSwat(LUEBug) while not Endofs(S) do [ Resets(ItemStream); let DotFlag,StarFlag = false,false until Endofs(S) do [ let C = Gets(S) switchon C into [ case $**: StarFlag = true case $,: case $ : case $*N: break //Separators case $.: DotFlag = true default: if (C < 40B) % (C > 176B) then MidasSwat(IllegalChars,Str) Puts(ItemStream,C) case 0: loop ] ] if ItemV!0 eq 0 then loop //Just separators test DotFlag ifso [ lvmbPtr!0 = lvmbPtr!0-1 NV!(lvmbPtr!0) = MoveString(TVtoString(ItemV)) ] ifnot [ let NameEnd = ItemV!0; Wss(ItemStream,".MIDAS") NV!(lvmidasPtr!0) = MoveString(TVtoString(ItemV)) SV!(lvmidasPtr!0) = StarFlag lvmidasPtr!0 = (lvmidasPtr!0)+1 unless StarFlag do [ ItemV!0 = NameEnd; Wss(ItemStream,".MB") lvmbPtr!0 = lvmbPtr!0-1 NV!(lvmbPtr!0) = MoveString(TVtoString(ItemV)) ] ] if lvmbPtr!0 le lvmidasPtr!0 then MidasSwat(TooManyNames,Str) loop ] Closes(S) ] and MoveString(String) = valof [ let Size = (String>>lh rshift 1)+1 let DestStr = GetStorage(Size) MBlock(DestStr,String,Size) resultis DestStr ] and GetFreeDCB(Hover2) = valof [ let LCB = LCBSpace LCBSpace = LCBSpace+(size LCB/16) //DCB for regular stuff LCB>>LCB.Line.Link = LCB+(size dcb/16) LCB>>LCB.Line.BufC = HTab lshift 8 LCB>>LCB.Line.Buffer = 0 //= BitBuffer+2 if bit buffer LCB>>LCB.Line.Height = Hover2 //DCB for line separation LCB>>LCB.Sepr.Link = LCBSpace LCB>>LCB.Sepr.BufC = HTab lshift 8 LCB>>LCB.Sepr.Buffer = 0 LCB>>LCB.Sepr.Height = Leading resultis LCB ]