-- 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.