BlockOpsImpl.mesa
Copyright © 1987 by Xerox Corporation. All rights reserved.
Willie-Sue, January 18, 1988 1:54:52 pm PST
DIRECTORY
Basics USING [LongNumber],
BasicTime USING [GetClockPulses, Pulses, PulsesToMicroseconds],
BlockOps,
PrincOpsUtils USING [LongZero],
Random USING [Create, NextInt, RandomStream],
VM USING [PagesForWords, AddressForPageNumber, Interval, Pin, SimpleAllocate];
BlockOpsImpl:
CEDAR
MONITOR
IMPORTS BasicTime, PrincOpsUtils, Random, VM, BlockOps =
BEGIN
blkSpace64K: LONG POINTER TO BlockOps.LookupRecord ← NIL;
blkSpace128K: LONG POINTER TO BlockOps.LookupRecord ← NIL;
opBltSpace64K: LONG POINTER TO BlockOps.OpBltRecord ← NIL;
beginPulses, stopPulses: BasicTime.Pulses;
Init64K:
ENTRY
PROC =
TRUSTED {
IF blkSpace64K =
NIL
THEN {
nPages: INT ← VM.PagesForWords[SIZE[BlockOps.LookupRecord]];
interval: VM.Interval ← VM.SimpleAllocate[nPages];
VM.Pin[interval];
blkSpace64K ← LOOPHOLE[VM.AddressForPageNumber[interval.page]];
nPages ← VM.PagesForWords[SIZE[BlockOps.OpBltRecord]];
interval ← VM.SimpleAllocate[nPages];
VM.Pin[interval];
opBltSpace64K ← LOOPHOLE[VM.AddressForPageNumber[interval.page]];
interval ← VM.SimpleAllocate[256];
VM.Pin[interval];
blkSpace64K.src ← LOOPHOLE[VM.AddressForPageNumber[interval.page]];
opBltSpace64K.srcA ← blkSpace64K.src;
interval ← VM.SimpleAllocate[256];
VM.Pin[interval];
opBltSpace64K.dst ← blkSpace64K.dst ← LOOPHOLE[VM.AddressForPageNumber[interval.page]];
interval ← VM.SimpleAllocate[256];
VM.Pin[interval];
opBltSpace64K.srcB ← blkSpace64K.table ← LOOPHOLE[VM.AddressForPageNumber[interval.page]];
FOR i:
CARD16
IN [0..
LAST[
CARD16]]
DO
(blkSpace64K.src+i)^ ← i;
(blkSpace64K.table+i)^ ← 2*i;
ENDLOOP;
};
TRUSTED {
PrincOpsUtils.LongZero[blkSpace64K.dst+1, LAST[CARD16]];
blkSpace64K.dst^ ← 0;
};
};
Init128K:
ENTRY
PROC[doRand:
BOOL] =
TRUSTED {
IF blkSpace128K =
NIL
THEN {
nPages: INT = VM.PagesForWords[SIZE[BlockOps.LookupRecord]];
interval: VM.Interval ← VM.SimpleAllocate[nPages];
VM.Pin[interval];
blkSpace128K ← LOOPHOLE[VM.AddressForPageNumber[interval.page]];
interval ← VM.SimpleAllocate[512];
VM.Pin[interval];
blkSpace128K.src ← LOOPHOLE[VM.AddressForPageNumber[interval.page]];
interval ← VM.SimpleAllocate[512];
VM.Pin[interval];
blkSpace128K.dst ← LOOPHOLE[VM.AddressForPageNumber[interval.page]];
interval ← VM.SimpleAllocate[256];
VM.Pin[interval];
blkSpace128K.table ← LOOPHOLE[VM.AddressForPageNumber[interval.page]];
{
src: LONG POINTER TO CARD16 ← blkSpace128K.src;
tbl: LONG POINTER TO CARD16 ← blkSpace128K.table;
IF doRand
THEN {
rs: Random.RandomStream = Random.Create[LONG[LAST[CARD16]]+1, 1234567];
FOR k:
CARD16
IN [0..1]
DO
FOR i:
CARD16
IN [0..
LAST[
CARD16]]
DO
ln: Basics.LongNumber = LOOPHOLE[Random.NextInt[rs]];
src^ ← ln.lo;
src ← src + 1;
ENDLOOP;
ENDLOOP;
}
ELSE
FOR k:
CARD16
IN [0..1]
DO
srcV: CARD16 ← LAST[CARD16] ;
FOR i:
CARD16
IN [0..
LAST[
CARD16]]
DO
src^ ← srcV;
src ← src + 1;
srcV ← srcV - 1;
ENDLOOP;
ENDLOOP;
FOR i:
CARD16
IN [0..
LAST[
CARD16]]
DO
tbl^ ← 2*i;
tbl ← tbl + 1;
ENDLOOP;
};
};
PrincOpsUtils.LongZero[blkSpace128K.dst+1, LAST[CARD16]];
blkSpace128K.dst^ ← 0;
PrincOpsUtils.LongZero[blkSpace128K.dst+1+LAST[CARD16], LAST[CARD16] ];
(blkSpace128K.dst+LAST[CARD16]+1)^ ← 0;
};
TbMc1:
PROC[n:
CARD16]
RETURNS[
INT] =
TRUSTED {
Init64K[];
blkSpace64K.srcSkip ← 1;
blkSpace64K.dstSkip ← 1;
blkSpace64K.count ← n;
beginPulses ← BasicTime.GetClockPulses[];
BlockOps.TableLookup[blkSpace64K];
stopPulses ← BasicTime.GetClockPulses[];
RETURN[BasicTime.PulsesToMicroseconds[stopPulses - beginPulses]];
};
TbMc2:
PROC[dstSkip, n:
CARD16]
RETURNS[
INT] =
TRUSTED {
Init128K[FALSE];
blkSpace128K.srcSkip ← 1;
blkSpace128K.dstSkip ← dstSkip;
blkSpace128K.count ← n;
beginPulses ← BasicTime.GetClockPulses[];
BlockOps.TableLookup[blkSpace128K];
stopPulses ← BasicTime.GetClockPulses[];
RETURN[BasicTime.PulsesToMicroseconds[stopPulses - beginPulses]];
};
TbMc3:
PROC[dstSkip, n:
CARD16]
RETURNS[
INT] =
TRUSTED {
Init128K[TRUE];
blkSpace128K.srcSkip ← 1;
blkSpace128K.dstSkip ← dstSkip;
blkSpace128K.count ← n;
beginPulses ← BasicTime.GetClockPulses[];
BlockOps.TableLookup[blkSpace128K];
stopPulses ← BasicTime.GetClockPulses[];
RETURN[BasicTime.PulsesToMicroseconds[stopPulses - beginPulses]];
};
Tb3:
PROC[dstSkip, n:
CARD16]
RETURNS[
INT] =
TRUSTED {
Init128K[TRUE];
blkSpace128K.srcSkip ← 1;
blkSpace128K.dstSkip ← dstSkip;
blkSpace128K.count ← n;
beginPulses ← BasicTime.GetClockPulses[];
SlowTableLookup[blkSpace128K];
BEGIN
src: LONG POINTER TO CARD16 ← LOOPHOLE[blkSpace128K.src];
dst: LONG POINTER TO CARD16 ← LOOPHOLE[blkSpace128K.dst];
table: LONG POINTER TO CARD16 ← LOOPHOLE[blkSpace128K.table];
srcSkip: CARD16 = blkSpace128K.srcSkip;
dstSkip: CARD16 = blkSpace128K.dstSkip;
FOR i:
CARDINAL
IN [0..n)
DO
dst^ ← (table+src^)^;
src ← src + srcSkip;
dst ← dst + dstSkip;
ENDLOOP;
END;
stopPulses ← BasicTime.GetClockPulses[];
RETURN[BasicTime.PulsesToMicroseconds[stopPulses - beginPulses]];
};
OpMc1:
PROC[delta, count:
CARDINAL, op: BlockOps.BltOp]
RETURNS[
INT] =
TRUSTED {
Init64K[];
opBltSpace64K.delta ← delta;
opBltSpace64K.count ← count;
opBltSpace64K.op ← op;
beginPulses ← BasicTime.GetClockPulses[];
BlockOps.OpBlt[opBltSpace64K];
stopPulses ← BasicTime.GetClockPulses[];
RETURN[BasicTime.PulsesToMicroseconds[stopPulses - beginPulses]];
};