Basics.mesa
For Dragon
Copyright © 1985 by Xerox Corporation. All rights reserved.
Levin on September 20, 1983 11:00 am
Russ Atkinson (RRA) February 27, 1985 8:10:50 pm PST
Doug Wyatt, February 26, 1985 2:49:33 pm PST
Carl Hauser, April 30, 1987 12:45:33 pm PDT
Commonly-used types and values
Word: TYPE = DragOps.Word;
bytesPerWord: NAT = 4;
charsPerWord: NAT = bytesPerWord;
bitsPerByte: NAT = 8;
bitsPerChar: NAT = bitsPerByte;
bitsPerWord: NAT = bitsPerByte*bytesPerWord;
bitsPerHalfword: NAT = bitsPerWord/2;
logBitsPerByte: NAT = 3; --LogBase2[bitsPerByte]
logBitsPerChar: NAT = logBitsPerByte;
logBytesPerWord: NAT = 2; --LogBase2[bytesPerWord]
logCharsPerWord: NAT = logBytesPerWord;
logBitsPerWord: NAT = logBitsPerByte + logBytesPerWord;
LongNumber:
TYPE =
MACHINE
DEPENDENT
RECORD [
this needs further attention
SELECT
OVERLAID *
FROM
real => [real: REAL],
ptr => [ptr: POINTER],
card => [card: CARD32],
int => [int: INT32],
pair => [hi, lo:
CARD16],
note: high order word precedes low order word
bytes => [hh, hl, lh, ll: BYTE],
bits => [bits:
PACKED
ARRAY [0..bitsPerWord)
OF
BOOL],
note: bits [0..16) are in the high word, bits [16..32) are in the low word
ENDCASE
];
ShortNumber:
TYPE =
MACHINE
DEPENDENT
RECORD [
SELECT
OVERLAID *
FROM
sc => [sc: CARD16],
si => [si: INT16],
bytes => [hi, lo: BYTE],
bits => [bits:
PACKED
ARRAY [0..bitsPerHalfword)
OF
BOOL],
note: bit n is higher order than bit n+1
ENDCASE
];
BytePair: TYPE = MACHINE DEPENDENT RECORD [high, low: BYTE];
Comparison: TYPE = {less, equal, greater};
RawWords: TYPE = RECORD [SEQUENCE COMPUTED CARD OF WORD];
RawCards: TYPE = RECORD [SEQUENCE COMPUTED CARD OF CARD];
RawBytes: TYPE = RECORD [PACKED SEQUENCE COMPUTED CARD OF BYTE];
RawChars: TYPE = RECORD [PACKED SEQUENCE COMPUTED CARD OF CHAR];
UnsafeBlock:
TYPE =
RECORD [
An UnsafeBlock describes the byte sequence base[startIndex..startIndex+count).
base: POINTER TO RawBytes ← NIL,
startIndex: INT ← 0,
count: INT ← 0
];
PageCount: TYPE = INT; -- was in PrincOps, try it here for Dragon.
Logic utilities
BitOp:
TYPE =
PROC [
Word,
Word]
RETURNS [
Word];
BITAND: BitOp
= TRUSTED MACHINE CODE {
041H -- AND
};
BITOR: BitOp
= TRUSTED MACHINE CODE {
040H -- OR
};
BITXOR: BitOp
= TRUSTED MACHINE CODE {
0C8H, 0EEH, 0DDH -- RXOR Under, Under, PopTop
};
BITNOT:
PROC [
Word]
RETURNS [
Word]
= TRUSTED MACHINE CODE {
0C8H, 0ECH, 0C6H -- RXOR Top, CONSTANT -1, Top
};
BITSHIFT:
PROC [value:
Word, count:
INT]
RETURNS [
WORD]
... shifts the value by the count. If count is positive, the shift is to the left. If count is negative, the count is to the right.
= INLINE {
IF count >= 0
THEN RETURN [LOOPHOLE[ShiftLeft[LOOPHOLE[value], LOOPHOLE[count, NAT]]]]
ELSE RETURN [LOOPHOLE[ShiftRight[LOOPHOLE[value], LOOPHOLE[-count, NAT]]]]
};
Field Extraction
LowHalf:
PROC [n:
CARD]
RETURNS [
CARD16]
= TRUSTED INLINE { RETURN[LOOPHOLE[n, LongNumber].lo] };
HighHalf:
PROC [n:
CARD]
RETURNS [
CARD16]
= TRUSTED INLINE { RETURN[LOOPHOLE[n, LongNumber].hi] };
Byte0:
PROC [n:
CARD]
RETURNS [
BYTE]
= TRUSTED INLINE { RETURN[LOOPHOLE[n, LongNumber].hh] };
Byte1:
PROC [n:
CARD]
RETURNS [
BYTE]
= TRUSTED INLINE { RETURN[LOOPHOLE[n, LongNumber].hl] };
Byte2:
PROC [n:
CARD]
RETURNS [
BYTE]
= TRUSTED INLINE { RETURN[LOOPHOLE[n, LongNumber].lh] };
Byte3:
PROC [n:
CARD]
RETURNS [
BYTE]
= TRUSTED INLINE { RETURN[LOOPHOLE[n, LongNumber].ll] };
LowByte:
PROC [n:
CARD16]
RETURNS [
BYTE]
= TRUSTED INLINE { RETURN[LOOPHOLE[n, BytePair].low] };
HighByte:
PROC [n:
CARD16]
RETURNS [
BYTE]
= TRUSTED INLINE { RETURN[LOOPHOLE[n, BytePair].high] };
Other operations on long numbers
SwapHalves:
PROC [n: LongNumber]
RETURNS [LongNumber]
= TRUSTED INLINE { RETURN[ [pair[hi: n.lo, lo: n.hi]] ] };
... swaps the 16-bit halves of the 32-bit LongNumber
ExtractHalfWordField: PROC [n: LongNumber, right: [0..bitsPerWord)] RETURNS [CARD16]
= TRUSTED INLINE {
... shifts n right by the given # of bits and returns the resulting low-order 16 bits.
NYI[];
};
ExtractWordField: PROC [n1: LongNumber, n2: LongNumber, right: [0..2*bitsPerWord)] RETURNS [CARD]
= TRUSTED INLINE {
... shifts n1 catenated with n2 right by the given # of bits and returns the resulting low-order 32 bits.
NYI[];
};
Shift:
PROC [ln: LongNumber, dist: [-31..31] ]
RETURNS [LongNumber]
= TRUSTED INLINE {
... shifts left if dist is positive, right if it is negative.
IF dist >= 0
THEN RETURN [ShiftLeft[ln, LOOPHOLE[dist, NAT]]]
ELSE RETURN [ShiftRight[ln, LOOPHOLE[-dist, NAT]]]
};
ShiftLeft:
PROC [ln: LongNumber, dist: [-31..31]]
RETURNS [new: LongNumber]
= TRUSTED INLINE {
... shifts one LongNumber left by dist bits and returns the shifted LongNumber. Shifting left by 1 bit is equivalent to doubling the number.
NYI[];
};
DoubleWordShiftLeft:
PROC [w0,w1: LongNumber, dist: [0..64)]
RETURNS [new: LongNumber] =
TRUSTED
INLINE {
... shifts two Dragon words left by dist bits and returns the leftmost word.
NYI[];
};
ShiftRight:
PROC [ln: LongNumber, dist: [-31..31]
]
RETURNS [new: LongNumber]
= TRUSTED INLINE {
... shifts one LongNumber left by dist bits and returns the shifted LongNumber. Shifting right by 1 bit is equivalent to halving the number.
NYI[];
};
Block copying utilities
Move:
PROC [from:
POINTER, nwords:
CARD, to:
POINTER]
= TRUSTED INLINE {
Trinity instructions will make this more efficient in the overlapping case.
Ordered:
PROC [lp:
POINTER]
RETURNS [
ORDERED
POINTER] =
TRUSTED 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 Copy[from: from, to: to, nwords: nwords];
};
Copy:
PROC [from:
POINTER, nwords:
CARD, to:
POINTER]
= INLINE {NYI[]};
ByteBlt: PROC [to, from: ByteBltBlock] RETURNS [nBytes: CARD];
This will be a machine code procedure in Trinity.
Miscellaneous
Fill:
PROC [where:
POINTER, nwords:
CARD, value:
WORD]
= INLINE {NYI[]};
PUSH:
PROC
RETURNS [
WORD]
= TRUSTED MACHINE CODE {
048H -- DUP
};
GetClockPulses: SAFE PROC RETURNS [CARD]
= {NYI[]};
VERSION: SAFE PROC RETURNS [VersionResult]
= {NYI[]};
Carl Hauser, October 13, 1986 11:23:32 am PDT
Working on conversion for Dragon .
changes to:
LongNumber reordered contained words, bytes and bits; renamed the tags and subfields
ShortNumber retyped the subfields; renamed the tags and subfields
UnsafeBlock retyped the base field.