//MINIT0.BCPL First init // This file is loaded with the program. After execution, its // storage is added to free storage. When "Midas/I" is typed, a // new Midas.State file is created after about 5 seconds of // initialization. When "Midas/R" is typed, Midas // resumes from its previous AltIO call. Otherwise, Midas restores its // state from the existing Midas.State file. get "streams.d" get "altofilesys.d" get "mdecl.d" // Need def of MaxBlockPages external [ // OS CallSwat; SetBlock; MoveBlock; Zero; diskKd; sysZone fpSysDir; Allocate; Free; WriteDiskDescriptor; OpenFile Closes; Gets; Puts; Wss; ReadBlock; WriteBlock; Endofs; Resets PositionPage; FileLength; keys // KEYBOARD CreateKeyboardStream // MIDAS ElapsedTime; FirstStatic; LastStatic TimeJunta; TimeLookup; TimeOutLdFP; TimeOvScan TimeQFiles; TimeFont // MDISP FontP; Evec; PseudoFontVec; LineCtrlBlockPtrsVector // MRGN ControlV; ScreenTV; BlankS // MINIT2 VecInit; GetHStorage; GetZStorage; MakeTVS // State package GetStorage; StorageInit; BeginSave; SaveStatics; Storage; EndStorage // MTV TVSpareTVs; TVSpareTVec // MSYM TVtoString; @StringVec // MCMD NPrograms; ProgramAct; NQuickFiles; FileBlock // Overlay package OverlayScan // MDI LookupEntries // Machine dependent InitHardware1; ScreenHeight; ScreenWidth //Defined here MidasFP; MidasRFP; BlockStoreFP; FixUpFP; ErrsFP; mdsInitFP StateStream; ZoneErr; Init0 ] static [ MidasFP; MidasRFP; BlockStoreFP; FixUpFP; ErrsFP; mdsInitFP StateStream StackSize = #4400; SysZoneSize = #5000 ZoneErr = 0 //0 disables checking ] manifest [ NFNames = 8 // Number of names being looked up NumOverlays = 8 // Max number of overlays (was 7 on // 10 February 77) OvTSize = 5*NumOverlays+25 MaxQuickFiles = 60 // Maximum no. files in table ] let Init0(CFA,Switch) = valof [ StorageInit(FirstStatic,LastStatic,SysZoneSize,StackSize) keys = CreateKeyboardStream() ElapsedTime(lv TimeJunta) InitHardware1() //Build a table of file names to be looked up in the System directory let SysDirStream = OpenFile(0,ksTypeReadOnly,wordItem,0,fpSysDir) let ProgramsFP,FontFP = nil,nil let NV,SV = vec NFNames,vec NFNames let PrVec = GetStorage(lDV*NFNames) //Names should be upper case so that they will compare eq later SetupFPN(lv MidasFP,NV,SV,0,PrVec,"MIDAS.STATE",-1) SetupFPN(lv BlockStoreFP,NV,SV,1,PrVec,"MIDAS.SYMTAB",MaxBlockPages) SetupFPN(lv FixUpFP,NV,SV,2,PrVec,"MIDAS.FIXUPS",-1) SetupFPN(lv ErrsFP,NV,SV,3,PrVec,"MIDAS.ERRORS",-1) SetupFPN(lv MidasRFP,NV,SV,4,PrVec,"MIDAS.RESUME",-1) SetupFPN(lv ProgramsFP,NV,SV,5,PrVec,"MIDAS.PROGRAMS",0) SetupFPN(lv FontFP,NV,SV,6,PrVec,"GACHA10.AL",0) SetupFPN(lv mdsInitFP,NV,SV,7,PrVec,"MIDAS.MIDAS",0) // Use storage at the low end of the block used by GetStorage let Undefined = LookupEntries(SysDirStream,NV,PrVec,NFNames, true,Storage,EndStorage-Storage) if Undefined ne 0 do [ for I = 0 to NFNames-1 do [ if PrVec!(lDV*I) eq 0 then CreateFile(NV!I,SV!I,PrVec+(lDV*I)) ] ] ElapsedTime(lv TimeLookup) //First part of MDISP init Evec = GetStorage(EvecSize+1) PseudoFontVec = GetStorage(PFVecSize+1) LineCtrlBlockPtrsVector = GetStorage(ScreenHeight)-1 //First part of init for MRGN let SSize = (ScreenWidth rshift 1)+1 BlankS = GetStorage(SSize); SetBlock(BlankS,20040B,SSize) BlankS>>lh = ScreenWidth ControlV = GetHStorage(ScreenHeight) ScreenTV = GetHStorage(ScreenHeight) for I = 1 to ScreenHeight do [ ControlV!I = GetZStorage((ScreenWidth+1) rshift 1) ] BeginSave() //Initialize for SaveState/RestoreState if Switch eq 0 do //No switch = RestoreState [ Closes(SysDirStream) StateStream = OpenFile(NV!0,ksTypeReadOnly,wordItem,0,MidasFP) resultis false ] switchon Switch & not 40B into [ case $R: Closes(SysDirStream) StateStream = OpenFile(NV!4,ksTypeReadOnly,wordItem,0,MidasRFP) resultis false default: CallSwat("Bad switch") case $I: endcase ] OverlayScan(lv CFA>>CFA.fp,GetStorage(OvTSize),OvTSize, lv CFA>>CFA.fa) ElapsedTime(lv TimeOvScan) //Init for MTV and MSYM needed by BuildPrograms MakeTVS(lv TVSpareTVs,lv TVSpareTVec) StringVec = GetStorage(129) BuildPrograms(SysDirStream,ProgramsFP); Closes(SysDirStream) ElapsedTime(lv TimeQFiles) let FontStream = OpenFile(0,ksTypeReadOnly,wordItem,0,FontFP) let SizeFont = (FileLength(FontStream)+1) rshift 1 PositionPage(FontStream,1); FontP = GetStorage(SizeFont)+2 ReadBlock(FontStream,FontP-2,SizeFont); Closes(FontStream) ElapsedTime(lv TimeFont) SaveStatics(lv StringVec) StateStream = OpenFile(NV!0,ksTypeWriteOnly,wordItem, verLatestCreate,MidasFP) resultis true ] 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 CreateFile(Name,npgs,FileDV) be [ if npgs eq 0 then CallSwat("File doesn't exist: ",Name) Zero(FileDV,lDV) if npgs eq -1 then return //-1 = Optional file let FileFP = FileDV+(offset DV.fp/16) let BTsize = diskKd>>KD.diskBTsize let BitTable = lv (diskKd>>KD.diskBitTable) let bt = Allocate(sysZone,BTsize+1) MoveBlock(bt,BitTable,BTsize) //Copy the bit table bt!BTsize = -1 let best = 0 let maxp, max, cur = nil, 0, 0 for i = 0 to BTsize do test bt!i eq 0 ifso cur = cur+1 ifnot [ if cur > max then maxp, max = i-cur, cur cur = 0 ] if max*16 ge npgs then best = maxp let X = BitTable!(best-1) if best ne 0 do [ SetBlock(BitTable,-1,best-1) //Allocate pages below best BitTable!(best-1) = X % (-X) //Use bits from previous word diskKd>>KD.bitTableChanged = true //So it won't be read ] let scratch = vec #400 //Now write the file let newst = OpenFile(Name,ksTypeWriteOnly,wordItem,verNew,FileFP) if newst ne 0 then [ for i = 1 to npgs do WriteBlock(newst,scratch,#400) Closes(newst) ] if best ne 0 do [ MoveBlock(BitTable,bt,best-1) //Restore bit table BitTable!(best-1) = X % ((BitTable!(best-1)) & not (X % -X)) diskKd>>KD.bitTableChanged = true WriteDiskDescriptor() ] Free(sysZone,bt) if newst eq 0 then CallSwat("CreateFile failed",Name) ] //BuildPrograms reads "Midas.Programs" and treats the names there //as follows: // a name containing no "." is made into a "Run-Program" 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. and BuildPrograms(SysDirStream,ProgramsFP) be [ let S = OpenFile(0,ksTypeReadOnly,charItem,0,ProgramsFP) if S eq 0 then CallSwat("Bug in LookupEntries") let NV = vec MaxQuickFiles //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 while not Endofs(S) do [ Resets(TVSpareTVs); let DotFlag = false until Endofs(S) do [ let C = Gets(S) switchon C into [ case $,: case $ : case 15B: case 12B: break //Separators case $.: DotFlag = true default: if (C < 40B) % (C > 176B) then CallSwat("Illegal chars in Midas.Programs") Puts(TVSpareTVs,C); loop ] ] if TVSpareTVec!0 eq 0 then loop //Just separators if not DotFlag do [ let NameEnd = TVSpareTVec!0; Wss(TVSpareTVs,".MIDAS") NV!midasPtr = MoveString(TVtoString(TVSpareTVec)) midasPtr = midasPtr+1; TVSpareTVec!0 = NameEnd Wss(TVSpareTVs,".MB") ] mbPtr = mbPtr-1 NV!mbPtr = MoveString(TVtoString(TVSpareTVec)) if mbPtr le midasPtr then CallSwat("Too many file names in Midas.Programs") loop ] //Now pack NV for LookupEntries let NFNames = midasPtr+MaxQuickFiles-mbPtr MoveBlock(NV+midasPtr,NV+mbPtr,MaxQuickFiles-mbPtr) let PrVec = vec MaxQuickFiles*lDV //For DV's let Undefined = LookupEntries(SysDirStream,NV,PrVec,NFNames, true,Storage,EndStorage-Storage) NQuickFiles = NFNames - Undefined let FBsize = NQuickFiles*lDV; FileBlock = GetZStorage(FBsize) ProgramAct = GetZStorage(midasPtr) //Table of names converted //to table of Actions by MCMD let FBPtr,Progptr = 0,0 for I = 0 to NFNames-1 do [ let DV = PrVec + (I*lDV) if DV!0 ne 0 do [ let Str = NV!I; let StrSize = (Str>>lh rshift 1)+1 DV!0 = Str; MoveBlock(FileBlock+FBPtr,DV,lDV); FBPtr = FBPtr+lDV if FBPtr > FBsize then CallSwat("Bug in LookupEntries") if I < midasPtr do [ let PStr = GetStorage(StrSize-3) //Truncate ".Midas" MoveBlock(PStr,Str,StrSize-3) PStr>>lh = Str>>lh - 6 ProgramAct!Progptr = PStr; Progptr = Progptr+1 ] ] ] NPrograms = Progptr ] and MoveString(String) = valof [ let Size = (String>>lh rshift 1)+1 let DestStr = GetStorage(Size) MoveBlock(DestStr,String,Size) resultis DestStr ]