-- RTCommon.Mesa -- last edited May 20, 1982 10:15 am by Paul Rovner DIRECTORY Inline USING[LowHalf, HighHalf, BITSHIFT, LongNumber, BITOR, BITAND], RTBasic USING[Pointer, Address]; RTCommon: DEFINITIONS IMPORTS Inline = BEGIN OPEN Inline, RTBasic; -- TYPEs Field: TYPE = RECORD[bitFirst: [0..15], bitCount: [0..32]]; -- Constants LMasks: ARRAY [0..16] OF WORD = [0, 100000B, 140000B, 160000B, 170000B, 174000B, 176000B, 177000B, 177400B, 177600B, 177700B, 177740B, 177760B, 177770B, 177774B, 177776B, 177777B]; RMasks: ARRAY [0..16] OF WORD = [0, 1, 3, 7, 17B, 37B, 77B, 177B, 377B, 777B, 1777B, 3777B, 7777B, 17777B, 37777B, 77777B, 177777B]; -- Procedures RepPtrAddr: PROC[ptr: Pointer] RETURNS[Address] = INLINE {RETURN[LOOPHOLE[ptr]]}; RepAddrPtr: PROC[addr: Address] RETURNS[Pointer] = INLINE {RETURN[LOOPHOLE[addr]]}; RepAddrRef: PROC[addr: Address] RETURNS[REF ANY] = INLINE {RETURN[LOOPHOLE[addr]]}; FetchField: PROC[ptr: Pointer, field: Field] RETURNS[CARDINAL] = INLINE {OPEN field; RETURN[BITSHIFT[BITSHIFT[ptr↑, bitFirst], bitCount-16]]}; FetchFieldLong: PROC[ptr: Pointer, field: Field] RETURNS[LONG CARDINAL] = INLINE {OPEN field; IF bitFirst+bitCount <= 16 THEN RETURN[FetchField[ptr, field]] ELSE RETURN[ MakeLongCardinal[ptr↑, FetchField[ptr+1, [bitFirst: bitFirst, bitCount: bitCount-16]]]]}; MakeLongCardinal: PROCEDURE[lo, hi: CARDINAL] RETURNS[lc: LONG CARDINAL] = INLINE {LOOPHOLE[lc, num LongNumber] ← [num[highbits: hi, lowbits: lo]]}; StoreField: PROC[ptr: Pointer, field: Field, newValue: CARDINAL] = INLINE {OPEN field; bitOffset: [0..16] = 16-(bitFirst+bitCount); ptr↑ ← BITOR[ BITAND[ptr↑, LMasks[bitFirst]+RMasks[bitOffset]], BITSHIFT[BITAND[newValue, RMasks[bitCount]], bitOffset]]}; StoreFieldLong: PROC[ptr: Pointer, field: Field, newValue: LONG CARDINAL] = INLINE {OPEN field; IF bitFirst+bitCount <= 16 THEN StoreField[ptr, field, LowHalf[newValue]] ELSE {ptr↑ ← LowHalf[newValue]; StoreField[ptr+1, [bitFirst: bitFirst, bitCount: bitCount-16], HighHalf[newValue]]}}; ShortenLongCardinal: PROC[lc: LONG CARDINAL] RETURNS[CARDINAL] = INLINE {IF HighHalf[lc] # 0 THEN ERROR; RETURN[LOOPHOLE[LowHalf[lc], CARDINAL]]}; ShortenLongPointer: PROC[lp: LONG POINTER] RETURNS[POINTER] = INLINE {local: UNSPECIFIED; IF HighHalf[lp] # HighHalf[@local] THEN ERROR; RETURN[LOOPHOLE[LowHalf[lp], POINTER]]}; ShortenLongInteger: PROC[li: LONG INTEGER] RETURNS[INTEGER] = INLINE {IF li < FIRST[INTEGER] OR li > LAST[INTEGER] THEN ERROR; RETURN[LOOPHOLE[LOOPHOLE[li, Inline.LongNumber].lowbits, INTEGER]]}; END.