WriteSparseMemoryImpl.mesa
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
Russ Atkinson (RRA) October 11, 1985 3:04:35 pm 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,
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
Base: TYPE = SparseMemory.Base;
FourBytes: TYPE = DragOpsCross.FourBytes;
Inst: TYPE = DragOpsCross.Inst;
NameArray: TYPE = HandCodingUtil.NameArray;
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
TestAbort: TYPE = WriteSparseMemory.TestAbort;
Word: TYPE = DragOpsCross.Word;
ZerosWord: Word = DragOpsCross.ZerosWord;
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: BOOL ← TRUE;
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: DragOpsCross.FourBytes = DragOpsCrossUtils.WordToBytes[word];
IO.PutF[st, " %w/", [cardinal[cardW+cardW+cardW+cardW]]];
FOR i:
NAT
IN [0..3]
DO
byte: DragOpsCross.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: DragOpsCross.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:
BOOL ←
FALSE] = {
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.