WriteSparseMemoryImpl.mesa
Copyright © 1984, 1985, 1986 by Xerox Corporation. All rights reserved.
Russ Atkinson (RRA) September 11, 1986 0:00:35 am PDT
DIRECTORY
BasicTime USING [Now],
DragOpsCross USING [Byte, FourBytes, Inst, Word, ZerosWord],
DragOpsCrossUtils USING [AddDelta, ByteToCard, CardToWord, WordToBytes, WordToCard],
FS USING [StreamOpen],
HandCodingUtil USING [GetInstArray, NameArray],
IO USING [Close, PutF, PutRope, STREAM],
IOUtils USING [CopyPFProcs, PFCodeProc, PFProcs, SetPFCodeProc, SetPFProcs],
Rope USING [ROPE],
SparseMemory USING [Base, Fetch, NextPresent, NoMore, Probe],
UserCredentials USING [Get],
WriteSparseMemory USING [TestAbort];
WriteSparseMemoryImpl: CEDAR PROGRAM
IMPORTS BasicTime, DragOpsCrossUtils, FS, HandCodingUtil, IO, IOUtils, SparseMemory, UserCredentials
EXPORTS WriteSparseMemory
= BEGIN OPEN DragOpsCross;
Base: TYPE = SparseMemory.Base;
NameArray: TYPE = HandCodingUtil.NameArray;
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
TestAbort: TYPE = WriteSparseMemory.TestAbort;
ToStream: PUBLIC PROC [st: STREAM, base: Base, start: Word, words: INT, byteOutput, displayCode: BOOL, testAbort: TestAbort] = {
index: Word ← start;
limit: LONG CARDINAL
= DragOpsCrossUtils.WordToCard[DragOpsCrossUtils.AddDelta[words, index]];
marker: Word = DragOpsCrossUtils.CardToWord[1234567890];
instArray: NameArray ← globalNameArray;
noneSoFar: BOOLTRUE;
IF displayCode AND instArray = NIL THEN
globalNameArray ← instArray ← HandCodingUtil.GetInstArray[];
DO
oldIndex: Word = index;
word: Word;
wordIndexInPage: CARDINAL = LOOPHOLE[LOOPHOLE[index, FourBytes][3], CARDINAL];
IF testAbort # NIL AND testAbort[] THEN EXIT;
index ← SparseMemory.NextPresent[base, oldIndex ! SparseMemory.NoMore => EXIT];
IF DragOpsCrossUtils.WordToCard[index] >= limit THEN EXIT;
word ← SparseMemory.Fetch[base, index, marker];
IF word = ZerosWord THEN {
we can leave out the 0s except for the first one on a page
IF wordIndexInPage # 0 OR NOT noneSoFar THEN {
We don't need to report this word
index ← DragOpsCrossUtils.AddDelta[1, index];
LOOP;
};
};
IF byteOutput
THEN {
cardW: LONG CARDINAL = DragOpsCrossUtils.WordToCard[index];
bytes: FourBytes = DragOpsCrossUtils.WordToBytes[word];
IO.PutF[st, " %w/", [cardinal[cardW+cardW+cardW+cardW]]];
FOR i: NAT IN [0..3] DO
byte: Byte = bytes[i];
IO.PutF[st, " %w", [cardinal[DragOpsCrossUtils.ByteToCard[byte]]]];
ENDLOOP;
index ← DragOpsCrossUtils.AddDelta[1, index];
IF displayCode THEN {
IO.PutRope[st, " --"];
FOR i: NAT IN [0..3] DO
byte: Byte = bytes[i];
iName: ROPE = instArray[LOOPHOLE[byte]];
IO.PutF[st, " %g", [rope[iName]]];
ENDLOOP;
};
}
ELSE {
When doing 4 words at a time we align on a quadword boundary
off: INTEGER ← (wordIndexInPage MOD 4);
index ← DragOpsCrossUtils.AddDelta[-off, index];
IO.PutF[st, " %w:", [cardinal[DragOpsCrossUtils.WordToCard[index]]]];
THROUGH [0..3] DO
word: Word = SparseMemory.Fetch[base, index, marker];
IF word = marker AND NOT SparseMemory.Probe[base, index] THEN EXIT;
IO.PutF[st, " %w", [cardinal[DragOpsCrossUtils.WordToCard[word]]]];
index ← DragOpsCrossUtils.AddDelta[1, index];
ENDLOOP;
};
IO.PutRope[st, "\n"];
ENDLOOP;
};
ToFile: PUBLIC PROC [name: ROPE, base: Base, byteOutput, displayCode: BOOLFALSE] = {
st: STREAM = FS.StreamOpen[name, create];
pfProcs: IOUtils.PFProcs = IOUtils.CopyPFProcs[st];
[] ← IOUtils.SetPFCodeProc[
pfProcs, 'w, CodeWOctalProc];
[] ← IOUtils.SetPFProcs[st, pfProcs];
IO.PutF[st, "-- %g\n-- %g at %g\n\n",
[rope[name]], [rope[UserCredentials.Get[].name]], [time[BasicTime.Now[]]]];
ToStream[st, base, ZerosWord, LAST[INT], byteOutput, displayCode, NIL];
IO.Close[st];
};
CodeWOctalProc: IOUtils.PFCodeProc = {
IO.PutF[stream, "%bB", val];
};
globalNameArray: NameArray ← NIL;
END.