<> <> <> <> <> <<>> <> <<>> DIRECTORY DiskFace USING [FileID, Type, DontCare, wordsPerPage], PrincOps USING [aASSOC, aGETF, alpha, aSETF, ControlLink, flagsVacant, FrameHandle, InterimPageState, PageCount, PageFlags, PageNumber, PageState, PageValue, RealPageNumber, zMISC], ProcessorFace USING [useLongMapOps]; BootFile: DEFINITIONS IMPORTS ProcessorFace = BEGIN OPEN PrincOps; currentVersion: CARDINAL = 102; <> <<(102 corresponds to changes that allow > 1 Mword physical memory)>> Location: TYPE = MACHINE DEPENDENT RECORD[ deviceType(0): DiskFace.Type, deviceOrdinal(1): CARDINAL, vp(2): SELECT OVERLAID * FROM disk => [diskFileID(2): DiskFileID], ethernet => [bootFileNumber(2): CARDINAL, net(3), host(4): CARDINAL _ 0], any => [a(2), b(3), c(4), d(5), e(6), f(7), g(10B), h(11B): WORD], ENDCASE ]; DiskFileID: TYPE = MACHINE DEPENDENT RECORD[ <> fID: DiskFace.FileID, -- for disk label -- firstPage: INT, -- for disk label -- firstLink: DiskFace.DontCare -- initial boot chain link -- ]; nullLink: DiskFace.DontCare = LOOPHOLE[LONG[0]]; <> <<>> <> <> <<>> <> <> <> <> <<>> <> <<>> <> <> Header: TYPE = MACHINE DEPENDENT RECORD [ -- first page of boot file version(0): CARDINAL _ currentVersion, creationDate(1): LONG CARDINAL, -- System.GreenwichMeanTime pStartListHeader(3): POINTER, -- when continuation kind=initial (relative to that mds) inLoadMode(4): InLoadMode, continuation(5): Continuation, countData(7): CARDINAL, -- number of nonvacant pages (not counting germ) entries(HeaderStart): HeaderArray ]; HeaderStart: NAT = 10B; HeaderArray: TYPE = ARRAY [0..maxEntriesPerHeader) OF Entry; maxEntriesPerHeader: CARDINAL = (DiskFace.wordsPerPage-HeaderStart)/SIZE[Entry]; Trailer: TYPE = MACHINE DEPENDENT RECORD [ -- entry table after exhausting "Header" version(0): CARDINAL _ currentVersion, entries(1): TrailerArray ]; TrailerStart: NAT = 1; TrailerArray: TYPE = ARRAY [0..maxEntriesPerTrailer) OF Entry; maxEntriesPerTrailer: CARDINAL = (DiskFace.wordsPerPage-TrailerStart)/SIZE[Entry]; Entry: TYPE = MACHINE DEPENDENT RECORD [ page (0): CARDINAL, --PageNumber-- value (1): PageValue ]; InLoadMode: TYPE = {load, restore}; Continuation: TYPE = MACHINE DEPENDENT RECORD [ vp(0): SELECT kind(0:0..7): ContinuationKind FROM initial => [ mdsi(0:8..15): MDSIndex, destination(1): ControlLink ], resumptive => [ mdsi(0:8..15): MDSIndex, -- for WriteMDS hack -- resumee(1): FrameHandle ], ENDCASE ]; ContinuationKind: TYPE = {initial, resumptive}; MDSIndex: TYPE = RECORD [index: [0..256)]; -- high order bits of MDS base pointer MemorySizeToFileSize: PROC [countReal: PageCount] RETURNS [INT] = INLINE { <> RETURN[ countReal -- total data pages +1 -- header page +(MAX[countReal, maxEntriesPerHeader]-maxEntriesPerHeader+maxEntriesPerTrailer-1) /maxEntriesPerTrailer -- trailer pages ] }; <<>> <> <<>> <> aSETMAP: alpha = 150B; aGETMAPFLAGS: alpha = 151B; aSETMAPFLAGS: alpha = 152B; ExchangePageState: PROC [virtual: PageNumber, newState: PageState] RETURNS [pv: PageValue] = INLINE { <> <> OldExchangePageState: PROC [virtual: CARDINAL, state: InterimPageState] RETURNS [oldState: InterimPageState] = MACHINE CODE {zMISC, aSETF}; NewExchangePageState: PROC [vp: LONG CARDINAL, flgs: PageState] RETURNS [tState: PageState, rp: LONG CARDINAL] = MACHINE CODE {zMISC, aSETMAPFLAGS}; IF ProcessorFace.useLongMapOps THEN [tState: pv.state, rp: pv.real] _ NewExchangePageState[virtual, newState] ELSE [flags: pv.state.flags, realPage: pv.real] _ OldExchangePageState[virtual, InterimPageState[FALSE, newState.flags, 0]].oldState; }; ExchangePageFlags: PROC [virtual: PageNumber, newFlags: PageFlags] RETURNS [PageValue] = INLINE { <> <> RETURN ExchangePageState[virtual, PageStateFromFlags[newFlags]]; }; GetPageValue: PROC [virtual: PageNumber] RETURNS [pv: PageValue] = INLINE { <> OldGetPageValue: PROC [virtual: CARDINAL] RETURNS [state: InterimPageState] = MACHINE CODE {zMISC, aGETF}; NewGetPageValue: PROC [vp: LONG CARDINAL] RETURNS [tState: PageState, rp: LONG CARDINAL] = MACHINE CODE {zMISC, aGETMAPFLAGS}; IF ProcessorFace.useLongMapOps THEN [tState: pv.state, rp: pv.real] _ NewGetPageValue[virtual] ELSE [flags: pv.state.flags, realPage: pv.real] _ OldGetPageValue[virtual].state; }; SetPageValue: PROC [virtual: PageNumber, pv: PageValue] = INLINE { <> OldSetPageValue: PROC [virtual: CARDINAL, state: InterimPageState] = MACHINE CODE {zMISC, aASSOC}; NewSetPageValue: PROC [vp, rp: LONG CARDINAL, flgs: PageState] = MACHINE CODE {zMISC, aSETMAP}; IF ProcessorFace.useLongMapOps THEN NewSetPageValue[virtual, pv.real, pv.state] ELSE OldSetPageValue[virtual, InterimPageState[FALSE, pv.state.flags, pv.real]]; }; SetPageFlags: PROC [virtual: PageNumber, real: RealPageNumber, flags: PageFlags] = INLINE { <> SetPageValue[virtual, [state: PageStateFromFlags[flags], real: real]]; }; IsMapped: SAFE PROC [virtual: PageNumber] RETURNS [BOOL] = TRUSTED INLINE {RETURN[GetPageValue[virtual].state.flags ~= flagsVacant]}; IsVacant: SAFE PROC [virtual: PageNumber] RETURNS [BOOL] = TRUSTED INLINE {RETURN[GetPageValue[virtual].state.flags = flagsVacant]}; PageStateFromFlags: SAFE PROC [flags: PageFlags] RETURNS [PageState] = TRUSTED INLINE {RETURN[LOOPHOLE[flags]]}; <<>> END.