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
DIRECTORY
DragOps;
Basics: CEDAR DEFINITIONS
= BEGIN
Temporary placeholder
NYI: PROC [] RETURNS [] ~ INLINE {
};
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.
Arithmetic utilities
CompareCard: PROC [a, b: CARD] RETURNS [c: Comparison]
= INLINE {
c ← SELECT TRUE FROM
a=b => equal,
a>b => greater,
ENDCASE => less;
};
CompareINT: PROC [a, b: INT] RETURNS [c: Comparison]
= INLINE {
c ← SELECT TRUE FROM
a=b => equal,
a>b => greater,
ENDCASE => less;
};
Mult: PROC [CARD, CARD] RETURNS [product: CARD]
= INLINE {NYI[]};
Div: PROC [num, den: CARD] RETURNS [CARD]
= {NYI[]};
Can raise RuntimeError.DivideCheck on overflow or RuntimeError.ZeroDivisor if den = 0.
DivMod: PROC [num, den: CARD] RETURNS [quotient, remainder: CARD]
= {NYI[]};
Can raise RuntimeError.DivideCheck on overflow or RuntimeError.ZeroDivisor if den = 0.
Bounds checking
BoundsCheck: PROC [value, bound: CARD] RETURNS [CARD]
= TRUSTED MACHINE CODE {
043H -- BC
};
... RETURN [IF value >= bound THEN ERROR RuntimeError.BoundsCheck ELSE value]
NonNegative: PROC [value: INT] RETURNS [INT]
= TRUSTED MACHINE CODE {
083H, 027H -- QBC TopATop, CONSTANT 80000000H
};
... IF value < 0 THEN ERROR RuntimeError.BoundsCheck ELSE RETURN [value]
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[]};
Utilities for BitBlt and TextBlt (wizards only)
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]
= {NYI[]};
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: CARD, bitPos: CARD, micaPos: CARD,
count: INT, ptr: POINTER TO TextBltArg]
RETURNS
[
newIndex: CARD, newBitPos: CARD, newMicaPos: CARD,
newCount: INT, result: TextBltResult
]
= { NYI[]};
END.
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.