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, zBCAST, zBITBLT, zBLT, zBLTL, zDWDC, zFREE, zGADRB, zIWDC, zLADRB, zLLB, zME, zMISC, zMRE, zMXD, zMXW, zNOTIFY, zPOP, zPUSH, zREQUEUE, zRR, zSLB, 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}; 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, high: CARDINAL] RETURNS [LONG POINTER] = MACHINE CODE {}; 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 [PROGRAM]; GlobalFrameAndEntryPoint: SAFE PROC [link: --ControlLink--UNSPECIFIED] RETURNS [gf: GlobalFrameHandle, ep: CARDINAL]; Codebase, 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. ΞPrincOpsUtils.mesa last edited by Levin on August 8, 1983 11:44 am Last Edited by: Birrell, July 8, 1983 1:16 pm Note to the casual reader: Most of the definitions in this interface are intended for use by wizards. Only the first section "Utilities for Basic Data Structures" is likely to be useful to general clients. In general, clients should avoid procedures that aren't declared to be SAFE. Utilities for Basic Data Structures Conversion among various memory size measures The following procedures are coded in an obscure way to avoid invoking software-implemented arithmetic. This will all go away when the commented code sequences are introduced (in Trinity). RETURN[Basics.DBITSHIFT[words, -logWordsPerPage]] RETURN[Basics.DBITSHIFT[pages, logWordsPerPage]] RETURN[Basics.DBITSHIFT[bytes, -logBytesPerPage]] RETURN[Basics.DBITSHIFT[pages, logBytesPerPage]] Conversion among various memory address measures The following procedures are coded in an obscure way to avoid invoking software-implemented arithmetic. This will all go away when the commented code sequences are introduced (in Trinity). RETURN[Basics.DBITSHIFT[page, logWordsPerPage]] RETURN[Basics.DBITSHIFT[address, -logWordsPerPage]] Block copying utilities Trinity instructions will make this more efficient in the overlapping case. This will be a machine code procedure in Trinity. Long Pointer Manipulation Miscellaneous Utilities for BitBlt and TextBlt (wizards only) Utilities for Xfer data structures (wizards only) Control links Local Frames Global Frames Code segments Allocation Vector Utilities for Process data structures (wizards only) Process Data Area access Monitors and Condition Variables Note: this depends on having one instruction after enabling. Interrupts This procedure allocates one of the sixteen naked notify condition variables, initializes it with the default timeout, and returns a long pointer and wakeup mask with an appropriate bit set. This procedure deallocates a naked notify condition variable previously allocated with AllocateNakedCondition. Utilities for Virtual Memory Map (wizards only) Gets the state and real page of a virtual page; If the page is mapped, also sets the flags to newState. Gets the state and real page of a virtual page; If the page is mapped, also sets the flags to newFlags. Gets the state and real page of a virtual page. Sets the real page and state of a virtual page. Sets the real page and flags of a virtual page. Miscellaneous (wizards only) Κσ– "Cedar" style˜Jšœ™Jšœ/™/J™-šΟk ˜ Jšœœœœ˜,šœ œ˜JšœΪ˜Ϊ——J˜Jšœ œœ ˜+J˜Jš˜J˜Jšœ ˜J˜Jšœ˜œ™J™Jšœ#™#˜Jšœ-™-™Jšœ½™½J˜šΟn œœœ œœœœ˜SJšœ œ™1Jšœ:˜:JšœT˜TJšœ ˜Jšœ˜—J˜šž œœœœ œœœ˜SJšœ œ™0Jšœ+˜+JšœT˜TJšœ ˜Jšœ˜—J˜šž œœœ œœœœ˜SJšœ œ™1Jšœ)˜)šœ ˜ šœœ˜)Jš œœœœ œ˜:—Jšœœ˜)J˜—Jšœ˜Jšœ˜—J˜šž œœœœ œœœ˜SJšœ œ™0Jšœœ˜"Jšœ ˜Jšœ˜—J™—Jšœ0™0™Jšœ½™½J™šžœœœ˜4Jšœ œœœ˜*Jšœ œ™/Jšœ*˜*JšœT˜TJšœœ ˜Jšœ˜—J˜šžœœœ œœœœœ˜eJšœ œ™3Jšœœ ˜-JšœT˜TJšœ ˜Jšœ˜—J˜—Jšœ™™š žœœ œ œ œœ˜RJšœK™Kšžœœœœœœœœ˜AJš œ˜—šœ œ'˜Jšœœ˜(J˜—Jš œœœœœœ ˜1J˜š žœœœœœœ˜3Jšœœœ˜$—J˜šœœœœ˜,Jšœœœ˜'—J˜——Jšœ0™0™š žœœœœœœ˜Pš œœœ œœ˜(Jšœœœ.˜>—Jšœœ˜(Jšœ˜J˜J˜—Jšœœœœ ˜3J˜šžœœœœ˜8Jšœœœœ˜-š œœœ œœ˜(Jšœœœ4˜D—Jšœœ˜+Jšœ˜Jšœ˜J˜—šžœœ˜Jš œœ œ œ œ˜EJšœœœ ˜šœ˜ Jšœ œ œœ˜>Jšœ œ˜+—Jšœœ˜—J™—Jšœ2™2˜Jšœ ™ ™šž œœœ˜+Jšœœ˜"—J˜šž œœ˜#Jšœœ˜"—J˜šžœœœ œœœœœ˜KJšœœ˜0J˜—J˜—Jšœ ™ ™Jšžœœœœ˜EJ˜Jšžœœœ˜=J˜šž œœœ˜*Jšœœ ˜—J˜š žœœœœœœ˜^šœœ˜Jšœœœ˜&Jšœ˜—Jš˜J˜—J˜šž œœœ*˜>Jšœœœœ˜E—J˜—Jšœ ™ ˜šž œœœ˜1Jšœœ ˜—J˜Jš ž œœœΟc œœœ˜LJ˜šžœ œŸ œ˜FJšœœ˜.—J˜—J™ ™šœ žœœ˜3Jš œœœŸœœ˜3Jšœ˜Jšœœ˜Jšœ ˜Jšœ˜—J˜—Jšœ™™š žœœœŸœ˜?Jšœœ ˜—J˜Jš žœœœœœ ˜,J˜——JšŸ5™5˜Jšœ™™š žœœœœœœ˜UJšœœ œœ˜<—J˜š žœœœœœœ˜TJšœœœ˜1—J˜—Jšœ ™ ˜šžœœœœ œœ œ˜AJšœœ˜—J˜šž œœœœœ œœ œ˜JJšœœ˜—J˜š žœœœœ œ˜%Jšœœ˜—J˜š žœœœœœ œ˜.Jšœœ˜—J˜šžœœœœ œœœ œŸ œ˜QJšœœ˜—J˜šžœœ˜Jšœœœ œœœœ œŸ œ˜OJšœœ˜—J˜šžœœœœ œœœ œ˜Jšœ/™/Jšœ7™7šžœœ˜Jšœ Ÿœ˜