<> <> <> 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]] }; <> PutLabel[addr, src.niFirst]; <> 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]]; <> 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; <> 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.