<> <> <> DIRECTORY Basics USING [BITAND, BITSHIFT, LongNumber], PrincOps USING [ aASSOC, aGETF, aRCLK, aSETF, aTEXTBLT, aVERSION, aZERO, BBptr, BBTableAlignment, BBTableSpace, ByteBltBlock, ControlLink, flagsVacant, FrameCodeBase, FrameHandle, FrameSizeIndex, FrameVec, GlobalFrameHandle, InterimPageState, LargeReturnSlot, LastAVSlot, MaxFrameSize, MDSreg, NullLink, PageCount, PageFlags, PageNumber, PageState, ProcessStateBlock, PsbHandle, PsbIndex, PSBreg, PTCreg, Queue, RealPageNumber, returnOffset, TextBltArg, TextBltArgAlignment, TextBltArgSpace, TextBltResult, Ticks, UnboundLink, VersionResult, WDCreg, wordsPerPage, XferTrapStatus, XTSreg, zALLOC, zAND, zBCAST, zBITBLT, zBLT, zBLTL, zDWDC, zFREE, zGADRB, zIWDC, zLADRB, zLIN1, zLLB, zME, zMISC, zMRE, zMXD, zMXW, zNOTIFY, zOR, zPOP, zPUSH, zREQUEUE, zRR, zSHIFT, zSLB, zXOR, zWR]; PrincOpsUtils: DEFINITIONS IMPORTS Basics = BEGIN OPEN PrincOps; <> <<>> <> <> <<>> <> PagesForWords: SAFE PROC [words: INT] RETURNS [pages: PageCount] = TRUSTED INLINE { <> longA: Basics.LongNumber = [li[li: words+wordsPerPage-1]]; longB: Basics.LongNumber = [bytes[lh: longA.hl, ll: longA.lh, hh: 0, hl: longA.hh]]; RETURN[longB.li] }; WordsForPages: SAFE PROC [pages: PageCount] RETURNS [words: INT] = TRUSTED INLINE { <> longA: Basics.LongNumber = [li[li: pages]]; longB: Basics.LongNumber = [bytes[lh: longA.ll, ll: 0, hh: longA.hl, hl: longA.lh]]; RETURN[longB.li] }; PagesForBytes: SAFE PROC [bytes: INT] RETURNS [pages: PageCount] = TRUSTED INLINE { <> n: Basics.LongNumber _ [li[li: bytes+1]]; n _ [num[ lowbits: Basics.BITSHIFT[n.lowbits, -1] + (IF Basics.BITAND[n.highbits, 1] = 1 THEN 100000B ELSE 0), highbits: Basics.BITSHIFT[n.highbits, -1] ]]; RETURN[PagesForWords[n.li]] }; BytesForPages: SAFE PROC [pages: PageCount] RETURNS [bytes: INT] = TRUSTED INLINE { <> words: INT = WordsForPages[pages]; RETURN[words+words] }; <<>> <> <<>> <> <<>> AddressForPageNumber: UNSAFE PROC [page: PageNumber] RETURNS [address: LONG POINTER] = INLINE { <> longA: Basics.LongNumber = [li[li: page]]; longB: Basics.LongNumber = [bytes[lh: longA.ll, ll: 0, hh: longA.hl, hl: longA.lh]]; RETURN[LOOPHOLE[longB.lc]] }; PageNumberForAddress: SAFE PROC [address: LONG POINTER] RETURNS [page: PageNumber] = TRUSTED INLINE { <> longA: Basics.LongNumber = LOOPHOLE[address]; longB: Basics.LongNumber = [bytes[lh: longA.hl, ll: longA.lh, hh: 0, hl: longA.hh]]; RETURN[longB.li] }; <> <<>> LongMove: PROC [from: LONG POINTER, nwords: CARDINAL, to: LONG POINTER] = INLINE { <> Ordered: PROC [lp: LONG POINTER] RETURNS [LONG ORDERED POINTER] = MACHINE CODE {}; IF Ordered[to] IN [Ordered[from]..Ordered[from]+nwords) THEN FOR i: CARDINAL DECREASING IN [0..nwords) DO (to+i)^ _ (from+i)^; ENDLOOP ELSE LongCopy[from: from, to: to, nwords: nwords]; }; COPY, Copy: PROC [from: POINTER, nwords: CARDINAL, to: POINTER] = MACHINE CODE {zBLT}; ByteBlt: PROC [to, from: ByteBltBlock] RETURNS [nBytes: CARDINAL]; <> LongCOPY, LongCopy: PROC [from: LONG POINTER, nwords: CARDINAL, to: LONG POINTER] = MACHINE CODE {zBLTL}; <> <<>> BitOp: TYPE = PROC [UNSPECIFIED, UNSPECIFIED] RETURNS [UNSPECIFIED]; BITAND: BitOp = MACHINE CODE {zAND}; BITOR: BitOp = MACHINE CODE {zOR}; BITXOR: BitOp = MACHINE CODE {zXOR}; BITNOT: PROC [UNSPECIFIED] RETURNS [UNSPECIFIED] = MACHINE CODE {zLIN1; zXOR}; BITSHIFT: PROC [value: UNSPECIFIED, count: INTEGER] RETURNS [UNSPECIFIED] = MACHINE CODE {zSHIFT}; <> LowHalf: PROC [u: LONG POINTER] RETURNS [POINTER] = INLINE {RETURN[LOOPHOLE[LOOPHOLE[u, Basics.LongNumber].lowbits]]}; HighHalf: PROC [u: LONG POINTER] RETURNS [CARDINAL] = INLINE {RETURN[LOOPHOLE[u, Basics.LongNumber].highbits]}; MakeLongPointer: PROC [low: POINTER, high: CARDINAL] RETURNS [LONG POINTER] = INLINE {RETURN[ LOOPHOLE[Basics.LongNumber[num[lowbits: LOOPHOLE[low], highbits: high]]]]}; <> <<>> ZERO, LongZero: PROC [where: LONG POINTER, nwords: CARDINAL] = MACHINE CODE {zMISC, aZERO; zPOP; zPOP}; PUSH: PROC RETURNS [WORD] = MACHINE CODE {zPUSH}; GetClockPulses: SAFE PROC RETURNS [LONG CARDINAL] = TRUSTED MACHINE CODE {zMISC, aRCLK}; VERSION: SAFE PROC RETURNS [VersionResult] = TRUSTED MACHINE CODE {zMISC, aVERSION}; <> <<>> AlignedBBTable: PROC [ip: POINTER TO BBTableSpace] RETURNS [b: BBptr] = INLINE { align: TYPE = MACHINE DEPENDENT RECORD [ s: [0..WORD.LAST/BBTableAlignment), z: [0..BBTableAlignment)]; b _ LOOPHOLE[ip + BBTableAlignment - 1]; LOOPHOLE[b, align].z _ 0; }; BITBLT: PROC [ptr: BBptr] = MACHINE CODE {zBITBLT}; AlignedTextBltArg: PROC [ip: POINTER TO TextBltArgSpace] RETURNS [p: POINTER TO TextBltArg] = INLINE { align: TYPE = MACHINE DEPENDENT RECORD [ s: [0..WORD.LAST/TextBltArgAlignment), z: [0..TextBltArgAlignment)]; p _ LOOPHOLE[ip + TextBltArgAlignment - 1]; LOOPHOLE[p, align].z _ 0; }; TextBlt: PROC [ index: CARDINAL, bitPos: CARDINAL, micaPos: CARDINAL, count: INTEGER, ptr: POINTER TO TextBltArg] RETURNS [ newIndex: CARDINAL, newBitPos: CARDINAL, newMicaPos: CARDINAL, newCount: INTEGER, result: TextBltResult] = MACHINE CODE {zMISC, aTEXTBLT}; <<>> <> <> <<>> GetReturnLink: PROC RETURNS [ControlLink] = MACHINE CODE {zLLB, returnOffset}; SetReturnLink: PROC [ControlLink] = MACHINE CODE {zSLB, returnOffset}; IsBound: SAFE PROC [link: UNSPECIFIED] RETURNS [BOOLEAN] = TRUSTED INLINE { RETURN[link ~= UnboundLink AND link ~= NullLink] }; <> <<>> GetReturnFrame: PROC RETURNS [FrameHandle] = LOOPHOLE[GetReturnLink]; SetReturnFrame: PROC [FrameHandle] = LOOPHOLE[SetReturnLink]; MyLocalFrame: PROC RETURNS [FrameHandle] = MACHINE CODE {zLADRB, 0}; MakeFsi: SAFE PROC [words: [0..MaxFrameSize]] RETURNS [fsi: FrameSizeIndex] = TRUSTED INLINE { FOR fsi IN [0..LastAVSlot) DO IF FrameVec[fsi] >= words THEN RETURN; ENDLOOP; ERROR }; FrameSize: SAFE PROC [fsi: FrameSizeIndex[0..LargeReturnSlot)] RETURNS [[0..MaxFrameSize]] = TRUSTED INLINE {RETURN[FrameVec[fsi]]}; <> MyGlobalFrame: PROC RETURNS [GlobalFrameHandle] = MACHINE CODE {zGADRB, 0}; GlobalFrame: SAFE PROC [link: --ControlLink--UNSPECIFIED] RETURNS [GlobalFrameHandle]; GlobalFrameAndEntryPoint: SAFE PROC [link: --ControlLink--UNSPECIFIED] RETURNS [gf: GlobalFrameHandle, ep: CARDINAL]; <> <<>> Codebase: PROC [frame: GlobalFrameHandle] RETURNS [LONG POINTER --TO CSegPrefix--] = INLINE { c: FrameCodeBase _ frame.code; c.out _ FALSE; RETURN[c.longbase] }; <> <<>> Alloc: PROC [FrameSizeIndex] RETURNS [--FrameHandle--POINTER] = MACHINE CODE {zALLOC}; Free: PROC [POINTER] = MACHINE CODE {zFREE}; <> <> <<>> PsbHandleToIndex: SAFE PROC [handle: PsbHandle] RETURNS [PsbIndex] = TRUSTED INLINE { RETURN[LOOPHOLE[handle, CARDINAL]/SIZE[ProcessStateBlock]]}; PsbIndexToHandle: SAFE PROC [index: PsbIndex] RETURNS [PsbHandle] = TRUSTED INLINE { RETURN[LOOPHOLE[index*SIZE[ProcessStateBlock]]]}; <> Enter: PROC [POINTER TO MONITORLOCK] RETURNS [success: BOOLEAN] = MACHINE CODE {zME}; LongEnter: PROC [LONG POINTER TO MONITORLOCK] RETURNS [success: BOOLEAN] = MACHINE CODE {zME}; Exit: PROC [POINTER TO MONITORLOCK] = MACHINE CODE {zMXD}; LongExit: PROC [LONG POINTER TO MONITORLOCK] = MACHINE CODE {zMXD}; Wait: PROC [POINTER TO MONITORLOCK, POINTER TO CONDITION, --timeout:--CARDINAL] = MACHINE CODE {zMXW}; LongWait: PROC [ LONG POINTER TO MONITORLOCK, LONG POINTER TO CONDITION, --timeout:--CARDINAL] = MACHINE CODE {zMXW}; ReEnter: PROC [POINTER TO MONITORLOCK, POINTER TO CONDITION] RETURNS [success: BOOLEAN] = MACHINE CODE {zMRE}; LongReEnter: PROC [LONG POINTER TO MONITORLOCK, LONG POINTER TO CONDITION] RETURNS [success: BOOLEAN] = MACHINE CODE {zMRE}; Notify: PROC [POINTER TO CONDITION] = MACHINE CODE {zNOTIFY}; LongNotify: PROC [LONG POINTER TO CONDITION] = MACHINE CODE {zNOTIFY}; Broadcast: PROC [POINTER TO CONDITION] = MACHINE CODE {zBCAST}; LongBroadcast: PROC [LONG POINTER TO CONDITION] = MACHINE CODE {zBCAST}; Requeue: PROC [ from: LONG POINTER TO Queue, to: LONG POINTER TO Queue, p: PsbHandle] = MACHINE CODE {zREQUEUE}; EnableAndRequeue: PROC [ from: LONG POINTER TO Queue, to: LONG POINTER TO Queue, p: PsbHandle] = <> MACHINE CODE {zDWDC; zREQUEUE}; <> DisableInterrupts: PROC = MACHINE CODE {zIWDC}; EnableInterrupts: PROC = MACHINE CODE {zDWDC}; AllocateNakedCondition: PROC RETURNS [cv: LONG POINTER TO CONDITION, mask: WORD]; <> DeallocateNakedCondition: PROC [cv: LONG POINTER TO CONDITION]; <> <> ExchangePageState: PROC [virtual: PageNumber, newState: PageState] RETURNS [oldState: PageState, real: RealPageNumber] = INLINE { <> <> DoExchangePageState: PROC [ virtual: --OldPageNumber--CARDINAL, state: InterimPageState] RETURNS [oldState: InterimPageState] = MACHINE CODE {zMISC, aSETF}; [logSingleError: , flags: oldState.flags, realPage: real] _ DoExchangePageState[virtual, InterimPageState[FALSE, newState.flags, 0]].oldState; }; ExchangePageFlags: PROC [virtual: PageNumber, newFlags: PageFlags] RETURNS [oldState: PageState, real: RealPageNumber] = <> <> INLINE {RETURN ExchangePageState[virtual, PageStateFromFlags[newFlags]]}; GetPageState: PROC [virtual: PageNumber] RETURNS [state: PageState, real: RealPageNumber] = INLINE { <> DoGetPageState: PROC [virtual: --OldPageNumber--CARDINAL] RETURNS [state: InterimPageState] = MACHINE CODE {zMISC, aGETF}; [logSingleError: , flags: state.flags, realPage: real] _ DoGetPageState[virtual].state; }; SetPageState: PROC [virtual: PageNumber, real: RealPageNumber, state: PageState] = INLINE { <> DoSetPageState: PROC [virtual: --OldPageNumber--CARDINAL, state: InterimPageState] = MACHINE CODE {zMISC, aASSOC}; DoSetPageState[virtual, InterimPageState[FALSE, state.flags, real]]; }; SetPageFlags: PROC [virtual: PageNumber, real: RealPageNumber, flags: PageFlags] = <> INLINE {SetPageState[virtual, real, PageStateFromFlags[flags]]}; IsMapped: SAFE PROC [virtual: PageNumber] RETURNS [BOOL] = TRUSTED INLINE {RETURN[GetPageState[virtual].state.flags ~= flagsVacant]}; IsVacant: SAFE PROC [virtual: PageNumber] RETURNS [BOOL] = TRUSTED INLINE {RETURN[GetPageState[virtual].state.flags = flagsVacant]}; PageStateFromFlags: SAFE PROC [flags: PageFlags] RETURNS [PageState] = TRUSTED INLINE {RETURN[LOOPHOLE[flags]]}; <<>> <> <<>> WriteMDS: PROC [mdsi: CARDINAL] = MACHINE CODE {zWR, MDSreg}; ReadPSB: PROC RETURNS [currentProcess: PsbHandle] = MACHINE CODE {zRR, PSBreg}; WritePSB: PROC [currentProcess: PsbHandle] = MACHINE CODE {zWR, PSBreg}; ReadPTC: SAFE PROC RETURNS [time: Ticks] = TRUSTED MACHINE CODE {zRR, PTCreg}; WritePTC: SAFE PROC [time: Ticks] = TRUSTED MACHINE CODE {zWR, PTCreg}; ReadWDC: SAFE PROC RETURNS [countDisabled: CARDINAL] = TRUSTED MACHINE CODE {zRR, WDCreg}; WriteWDC: PROC [countDisabled: CARDINAL] = MACHINE CODE {zWR, WDCreg}; ReadATP, ReadOTP: PROC RETURNS [ControlLink] = MACHINE CODE {zLLB, 3B}; ReadXTS: SAFE PROC RETURNS [XferTrapStatus] = TRUSTED MACHINE CODE {zRR, XTSreg}; WriteXTS: PROC [XferTrapStatus] = MACHINE CODE {zWR, XTSreg}; ReadXTP: PROC RETURNS [ControlLink] = MACHINE CODE {zLLB, 3}; END.