MDOutputImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Willie-Sue, July 29, 1987 4:30:05 pm PDT
DIRECTORY
Basics USING [BITAND, BITSHIFT, ShortNumber],
IO,
Rope,
MDADefs,
MDDefs,
MDGlobalVars,
MDOps,
MDUtils;
MDOutputImpl: CEDAR PROGRAM
IMPORTS
Basics, IO, Rope,
MDDefs, MDGlobalVars, MDUtils
EXPORTS
MDOps, MDUtils
= BEGIN OPEN MDDefs, MDGlobalVars;
lastSource: SrcFile ← NIL;
Report: PUBLIC PROC[reportType: MDOps.ReportType,
 format: ROPE, v1, v2, v3, v4, v5: IO.Value ← [null[]]] = {
reportStrm.PutF[format, v1, v2, v3, v4, v5];
IF listingFile.strm # NIL THEN
listingFile.strm.PutF[format, v1, v2, v3, v4, v5];
IF reportType = fatalError THEN ERROR MDDefs.Error[IO.PutFR[format, v1, v2, v3, v4, v5]];
};
PutWord: PUBLIC PROC[strm: STREAM, val: WORD] = {
sn: Basics.ShortNumber ← LOOPHOLE[val];
strm.PutChar[LOOPHOLE[sn.hi, CHAR]];
strm.PutChar[LOOPHOLE[sn.lo, CHAR]];
};
PutInteger: PUBLIC PROC[strm: STREAM, val: INTEGER] = {
sn: Basics.ShortNumber ← LOOPHOLE[val];
strm.PutChar[LOOPHOLE[sn.hi, CHAR]];
strm.PutChar[LOOPHOLE[sn.lo, CHAR]];
};
PutCardinal: PUBLIC PROC[strm: STREAM, val: CARDINAL] = {
sn: Basics.ShortNumber ← LOOPHOLE[val];
strm.PutChar[LOOPHOLE[sn.hi, CHAR]];
strm.PutChar[LOOPHOLE[sn.lo, CHAR]];
};
GetWord: PUBLIC PROC[strm: STREAM] RETURNS[val: WORD] = {
sn: Basics.ShortNumber;
sn.hi ← LOOPHOLE[strm.GetChar[], BYTE];
sn.lo ← LOOPHOLE[strm.GetChar[], BYTE];
RETURN[LOOPHOLE[sn, WORD]];
};
GetInteger: PUBLIC PROC[strm: STREAM] RETURNS[val: WORD] = {
sn: Basics.ShortNumber;
sn.hi ← LOOPHOLE[strm.GetChar[], BYTE];
sn.lo ← LOOPHOLE[strm.GetChar[], BYTE];
RETURN[LOOPHOLE[sn, WORD]];
};
GetCardinal: PUBLIC PROC[strm: STREAM] RETURNS[val: CARDINAL] = {
sn: Basics.ShortNumber;
sn.hi ← LOOPHOLE[strm.GetChar[], BYTE];
sn.lo ← LOOPHOLE[strm.GetChar[], BYTE];
RETURN[LOOPHOLE[sn, CARDINAL]];
};
WriteMemoryDef: PUBLIC PROC[memNum, width: INTEGER, name: ROPE] = {
strm: STREAM = outFile.strm;
PutWord[strm, MBmemory];
PutWord[strm, memNum];
PutWord[strm, width];
WriteSymbolName[strm, name];
};
WriteSymbolName: PUBLIC PROC[strm: STREAM, name: ROPE] = {
len: INT = name.Length[];
FOR i: INT IN [0..len) DO
strm.PutChar[name.Fetch[i]];
ENDLOOP;
IF len MOD 2 = 1 THEN strm.PutChar['\000]
ELSE PutWord[strm, 0];  -- end marker for name
};
ListIM: PUBLIC PROC[listingFile: OutputFile, srcFileList: SrcFile] = {
Report[infoOnly, "Writing listing...\n\n"];
};
ListIMUsed: PUBLIC PROC[listingFile: OutputFile] = {
FOR i: CARDINAL IN [0..nPages) DO
page: MDADefs.DoradoPage = MDUtils.GetPageN[i];
IF page.used # 0 THEN
listingFile.strm.PutF["Page %4b: %4b locations used, %4b free\n",
IO.card[i*DoradoPageSize], IO.card[page.used], IO.card[DoradoPageSize-page.used] ];
ENDLOOP;
listingFile.strm.PutChar['\n];
};
ListNonIM: PUBLIC PROC[listingFile: OutputFile, listingLevel: INTEGER] = {
IF listingLevel < 0 THEN {
ListIFUMShort[listingFile.strm];
RETURN
};
ListRM[listingFile.strm];
ListIFUM[listingFile.strm, listingLevel = listFull];
ListALUFM[listingFile.strm];
};
PutRing: PUBLIC PROC[addr: CARDINAL] = {
min: CARDINAL ← 0;  -- Put out in increasing address order
lastS: SrcFile ← NIL;
DO
i: CARDINAL ← RingMin[addr, addr, min];
myS: SrcFile;
IF i = 10000B THEN EXIT;
myS ← GetSource[i];
IF myS # lastS THEN {
reportStrm.PutF[" [%g]\n", IO.rope[myS.fullName]];
lastS ← myS;
};
reportStrm.PutChar['\t];
PutAddr[i, myS];
PutAData[i];
reportStrm.PutChar['\n];
min ← i + 1;
ENDLOOP;
reportStrm.PutChar['\n];
};
GetSource: PUBLIC PROC[addr: CARDINAL] RETURNS[src: SrcFile] = {
myS: SrcFile ← srcFileList;
IF lastSource # NIL THEN
IF addr >= lastSource.niFirst AND addr < lastSource.niLast THEN RETURN[lastSource];
DO
IF addr >= myS.niFirst AND addr < myS.niLast THEN
RETURN[lastSource ← myS];
IF (myS ← myS.next) = NIL THEN RETURN[lastSource ← myS];
ENDLOOP;
};
PutAddr: PROC[addr: CARDINAL, src: SrcFile] = TRUSTED {
ip: IMRecordPtr;
RShift6: PROC[w0Addr: CARDINAL] RETURNS[CARDINAL] = TRUSTED
{ RETURN[LOOPHOLE[Basics.BITSHIFT[LOOPHOLE[w0Addr], -6], CARDINAL]] };
And77B: PROC[w0Addr: CARDINAL] RETURNS[CARDINAL] = TRUSTED
{ RETURN[LOOPHOLE[Basics.BITAND[LOOPHOLE[ip.word0.W0Addr], 77B], CARDINAL]] };
Print symbolic address
PutLabel[addr, src.niFirst];
Print placement information
ip ← MDUtils.IMPtr[addr];
IF ip.word0.onPageAndPlaced = 1 OR ip.word0.atW0AndatWord = 1 THEN {
reportStrm.PutChar['(];
IF ip.word0.onPageAndPlaced = 1 THEN
reportStrm.PutF["%b", IO.card[RShift6[ip.word0.W0Addr]] ]
ELSE reportStrm.PutRope["xx"];
IF ip.word0.atW0AndatWord = 1 THEN
reportStrm.PutF["%02b", IO.card[And77B[ip.word0.W0Addr]] ]
ELSE reportStrm.PutRope["xx"];
reportStrm.PutChar[')];
};
};
PutAData: PUBLIC PROC[addr: CARDINAL] = TRUSTED {
ip: IMRecordPtr ← MDUtils.IMPtr[addr];
IF ip.word0.atW0AndatWord = 0 AND ip.mask # 177777B THEN
reportStrm.PutF[" %b", IO.card[ip.mask]];
Following stuff is just to help me (lpd) debug
reportStrm.PutF["[%b: b%g%b", IO.card[addr],
IO.char[IF ip.links.jbcLinked = 1 THEN '* ELSE '=],
IO.card[ip.word2.W2AddrAndbLink] ];
IF ip.links.aLink # addr THEN
reportStrm.PutF[", a%g%b", IO.char[IF ip.links.aLinked = 1 THEN '* ELSE '=],
IO.card[ip.links.aLink] ];
reportStrm.PutChar['] ];
};
PutLabel: PROC[addr, firstInFile: CARDINAL] = TRUSTED {
imPtr: IMRecordPtr ← MDUtils.IMPtr[addr];
IF imPtr.symbol # NIL THEN {
reportStrm.PutF["(=%g)", IO.rope[imPtr.symbol.name]];
RETURN;
};
FOR i: CARDINAL DECREASING IN [firstInFile .. addr) DO
imPtr ← MDUtils.IMPtr[i];
IF imPtr.symbol # NIL THEN {
reportStrm.PutF["%g+%g", IO.rope[imPtr.symbol.name], IO.card[addr-i] ];
RETURN
};
ENDLOOP;
this shouldn't happen
reportStrm.PutF["No labels found between %g and %g", IO.card[firstInFile], IO.card[addr]];
};
RingMin: PROC[start, stop, min: CARDINAL] RETURNS[max: CARDINAL] = {
i: CARDINAL ← start;
max ← 10000B;
DO
IF i >= min AND i < max THEN max ← i;
TRUSTED { i ← MDUtils.IMPtr[i].word2.W2AddrAndbLink };
IF i = stop THEN EXIT;
ENDLOOP;
};
ListIFUMShort: PROC[strm: STREAM] = {
first: BOOLTRUE;
xlo: CARDINAL ← 0;
Pairs: PROC[lo, hi: CARDINAL] = {
IF first THEN {
strm.PutRope["IFUM locations used:\n"];
first ← FALSE;
};
IF lo = hi THEN strm.PutF["%6b\n", IO.card[lo]]
ELSE strm.PutF["%6b - %4b\n", IO.card[lo], IO.card[hi] ];
};
FOR i: CARDINAL IN [0..IFUMsize) DO
IF ~ifumBits[i] THEN {
IF xlo # i THEN Pairs[xlo, i-1];
xlo ← i + 1;
};
ENDLOOP;
IF xlo # IFUMsize THEN Pairs[xlo, IFUMsize-1];
};
ListRM: PROC[strm: STREAM] = {};
ListIFUM: PROC[strm: STREAM, full: BOOL] = {};
ListALUFM: PROC[strm: STREAM] = {};
END.