DIRECTORY BcdOps USING [BcdBase], Environment USING [wordsPerPage], PrincOps USING [GFTIndex, GlobalFrame, GlobalFrameHandle], MB USING [BHandle, Error, Handle, Zero], MBLoaderOps USING [Binding, BindLink, EnumerationDirection], MBStorage USING [FreePages, Pages, PagesForWords], MBVM USING [AllocData, DataSeg, HyperSpace, LongCopyWrite, LongPointerFromSeg, Write], PilotLoadStateFormat USING [ BcdInfo, ConfigIndex, LoadState, LoadStateObject, ModuleInfo, NullConfig, NullModule, PilotVersionID], PrincOpsRuntime USING [GFT]; MBLoadState: PROGRAM IMPORTS MB, MBStorage, MBVM EXPORTS MBLoaderOps = BEGIN OPEN MB; data: MB.Handle _ NIL; loadstate: PilotLoadStateFormat.LoadState _ NIL; nextGFI: CARDINAL _ 1; -- gfi 0 is never used InitLoadState: PUBLIC PROC [h: MB.Handle] = {data _ h}; FinishLoadState: PUBLIC PROC = { IF loadstate # NIL THEN {MBStorage.FreePages[loadstate]; loadstate _ NIL}; data _ NIL; }; InputLoadState: PUBLIC PROC RETURNS [nbcds: PilotLoadStateFormat.ConfigIndex] = { IF loadstate = NIL THEN { lsPages: CARDINAL = MBStorage.PagesForWords[ SIZE[PilotLoadStateFormat.LoadStateObject] -- full-size module table, 0-size bcd table-- + LAST[PilotLoadStateFormat.ConfigIndex] * SIZE[PilotLoadStateFormat.BcdInfo] ]; IF ~data.germ THEN { data.lsseg _ MBVM.AllocData[base: MBVM.HyperSpace, pages: lsPages, dir: up]; data.lsseg.info.readOnly _ FALSE; data.lsseg.bootLoaded _ TRUE; }; loadstate _ MBStorage.Pages[lsPages]; MB.Zero[loadstate, lsPages*Environment.wordsPerPage]; loadstate.versionident _ PilotLoadStateFormat.PilotVersionID; FOR i: CARDINAL IN [0..data.gftLength) DO loadstate.gft[i] _ PilotLoadStateFormat.NullModule; ENDLOOP; loadstate.nBcds _ 0; LOOPHOLE[@loadstate.bcds, LONG POINTER TO CARDINAL]^ _ LAST[PilotLoadStateFormat.ConfigIndex]; nextGFI _ 1; }; RETURN[loadstate.nBcds] }; UpdateLoadState: PUBLIC PROC [ config: PilotLoadStateFormat.ConfigIndex, handle: MB.BHandle] = { bcd: BcdOps.BcdBase = handle.bcd; IF config = PilotLoadStateFormat.NullConfig THEN ERROR; loadstate.bcds[config].origin _ IF data.germ THEN NIL ELSE MBVM.LongPointerFromSeg[handle.bcdSeg]; loadstate.bcds[config].typeExported _ bcd.typeExported; loadstate.bcds[config].exports _ (bcd.nExports # 0); IF config >= loadstate.nBcds THEN loadstate.nBcds _ loadstate.nBcds + 1; }; WriteLoadState: PUBLIC PROC = { IF data.germ THEN RETURN; MBVM.LongCopyWrite[ from: loadstate, to: MBVM.LongPointerFromSeg[data.lsseg], nwords: data.lsseg.pages * Environment.wordsPerPage]; }; EnterModule: PUBLIC PROC [rgfi: PrincOps.GFTIndex, module: PilotLoadStateFormat.ModuleInfo] = {loadstate.gft[rgfi] _ module}; GetModule: PUBLIC PROC [rgfi: PrincOps.GFTIndex] RETURNS [module: PilotLoadStateFormat.ModuleInfo] = { RETURN[loadstate.gft[rgfi]]}; AcquireBcd: PUBLIC PROC [config: PilotLoadStateFormat.ConfigIndex] RETURNS [handle: MB.BHandle] = { RETURN[data.inputBCDs.bcds[config]]}; ReleaseBcd: PUBLIC PROC [handle: MB.BHandle] = {}; InitBinding: PUBLIC PROC [ bcd: BcdOps.BcdBase] RETURNS [binding: MBLoaderOps.Binding] = { BindingSequence: TYPE = RECORD[SEQUENCE COMPUTED CARDINAL OF MBLoaderOps.BindLink]; p: LONG POINTER _ data.zone.NEW[BindingSequence[bcd.nDummies]]; binding _ DESCRIPTOR[ -- BASE[binding] is biased by bcd.firstdummy (p - CARDINAL[bcd.firstdummy * SIZE[MBLoaderOps.BindLink]]), bcd.nDummies]; FOR i: CARDINAL IN [bcd.firstdummy..bcd.firstdummy + bcd.nDummies) DO binding[i] _ MBLoaderOps.BindLink[whichgfi: 0, body: notbound[]]; ENDLOOP; }; ReleaseBinding: PUBLIC PROC [ bcd: BcdOps.BcdBase, binding: MBLoaderOps.Binding] RETURNS [null: MBLoaderOps.Binding] = { IF BASE[binding] # NIL THEN { p: LONG POINTER _ BASE[binding] + bcd.firstdummy*SIZE[MBLoaderOps.BindLink]; data.zone.FREE[@p]; }; RETURN[DESCRIPTOR[NIL, 0]] }; BcdUnresolved: PUBLIC PROC [ bcd: PilotLoadStateFormat.ConfigIndex] RETURNS [BOOL] = { FOR i: PrincOps.GFTIndex IN [0..data.gftLength) DO IF bcd = loadstate.gft[i].config AND ~loadstate.gft[i].resolved THEN RETURN[TRUE]; ENDLOOP; RETURN[FALSE] }; BcdExports: PUBLIC PROC [bcd: PilotLoadStateFormat.ConfigIndex] RETURNS [BOOL] = { RETURN[loadstate.bcds[bcd].exports]}; BcdExportsTypes: PUBLIC PROC [bcd: PilotLoadStateFormat.ConfigIndex] RETURNS [BOOL] = { RETURN[loadstate.bcds[bcd].typeExported]}; GetNextGFI: PUBLIC PROC [reserve: CARDINAL] RETURNS [next: PrincOps.GFTIndex] = { IF (next _ nextGFI) >= data.gftLength THEN MB.Error["GFT overflow"L]; nextGFI _ nextGFI + reserve; }; SetGFTEntry: PUBLIC PROC [ frame: PrincOps.GlobalFrameHandle, gfi: PrincOps.GFTIndex, ngfi: CARDINAL] = { IF gfi+ngfi >= data.gftLength THEN MB.Error["GFT Full"L]; FOR i: CARDINAL IN [gfi..gfi+ngfi) DO bias: CARDINAL = (i-gfi); MBVM.Write[ @PrincOpsRuntime.GFT[i].framePtr, (frame + bias)]; -- bottom two bits of GFT entries bias evi's ENDLOOP; }; EnumerateModules: PUBLIC PROC [ proc: PROC [rgfi: PrincOps.GFTIndex, module: PilotLoadStateFormat.ModuleInfo] RETURNS [BOOL]] RETURNS [i: PrincOps.GFTIndex] = { FOR i IN [0..nextGFI) DO IF loadstate.gft[i].config ~= PilotLoadStateFormat.NullConfig AND proc[i, loadstate.gft[i]] THEN EXIT; ENDLOOP; }; EnumerateBcds: PUBLIC PROC [ dir: MBLoaderOps.EnumerationDirection, proc: PROC [PilotLoadStateFormat.ConfigIndex] RETURNS [BOOL]] RETURNS [config: PilotLoadStateFormat.ConfigIndex] = { SELECT dir FROM recentfirst => FOR config DECREASING IN [0..loadstate.nBcds) DO IF proc[config] THEN RETURN; ENDLOOP; recentlast => FOR config IN [0..loadstate.nBcds) DO IF proc[config] THEN RETURN; ENDLOOP; ENDCASE; RETURN[PilotLoadStateFormat.NullConfig] }; END. 2MBLoadState.mesa Last modified by Sandman on March 13, 1981 4:01 PM Last modified by Lewis on 21-Sep-81 17:08:04 Last modified by Levin on April 5, 1983 3:12 pm allocate temporary copy of loadstate (written into MBVM loadstate by WriteLoadState) avoid compiler warning message GFT management Êa˜Jšœ™Jšœ7™7Jšœ,™,Jšœ/™/J˜šÏk ˜ Jšœœ ˜Jšœ œ˜!Jšœ œ,˜:Jšœœ ˜(Jšœ œ+˜—Jš˜—šœ˜J˜——šŸœœœ˜JšœœDœœ˜]Jšœ˜"šœœ˜šœ<œ˜`Jšœ˜—Jš˜—šœ˜J˜——šŸ œœœ˜J˜&Jšœœ$œœ˜=Jšœ/˜6šœ˜˜šœ œœ˜0Jšœœœ˜Jšœ˜——˜ šœœ˜%Jšœœœ˜Jšœ˜——Jšœ˜—Jšœ!˜'Jšœ˜J˜—šœ˜J˜——…—ºM