MDOutputImpl:
CEDAR
PROGRAM
IMPORTS
Basics, IO, Rope,
MDDefs, MDGlobalVars, 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: BOOL ← TRUE;
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.