// MDlist2.bcpl -- more listing routines for MicroD // last edited February 2, 1981 3:02 PM get "mddecl.d" get "streams.d" external // defined here [ OpenListFile // (sp, zone) -> stream ListIMAbs // (S) ListOccupied // (S) ListIMap // (S, sources) ListChart // (S, sources) ] external // used [ // OS CreateDiskStream Puts; Wss MoveBlock; Zero // Template PutTemplate // MDload sourceNameWidth // MDmain @IP @DMachine @NInstructions; @IMlocked // MDerr Err GetSource PutBlanks PutFileName // MDinit OutputSource VersionString StartDTString // MDprescan @PageSize; @nPages; @WordMask; @PageMask // MDlist0 CountUsed ListASym // MDasm CountBits; Get1Bit; Set1Bit ] manifest // layout for 2-up landscape listing [ chartLinesPerPage = 75 ] let OpenListFile(sp, zone) = valof [ let s = CreateDiskStream(sp>>Source.pFP, ksTypeWriteOnly, charItem, 0, 0, zone) if s eq 0 then Err(Fatal, "Can't open output file $S", sp>>Source.pName) Err(PassMessage, "Writing $S...", sp>>Source.pName) PutTemplate(s, "** $S** at $S*N*N", VersionString, StartDTString) resultis s ] and ListIMAbs(S) be [ // Identify virtual location corresponding to each absolute one for a = 0 to IMsize-1 do IP(a)>>IM.absPtr = -1 for i = 0 to NInstructions-1 do [ let ip = IP(i) if ip>>IM.placed then IP(ip>>IM.W0)>>IM.absPtr = i ] let lstWidth = (sourceNameWidth ls 4? 4, sourceNameWidth)+2 PutTemplate(S, "IM:*N Real$PFile Symbol*N", PutBlanks, lstWidth-4) let lastpage = -1 for a = 0 to IMsize-1 do if IP(a)>>IM.absPtr ne -1 then [ let page = a & PageMask if page ne lastpage then [ Puts(S, $*N); lastpage = page ] PutTemplate(S, "$5O", a) let i = IP(a)>>IM.absPtr let source = GetSource(i) test source eq 0 ifso PutBlanks(S, lstWidth) // only one source ifnot [ let name = source>>Source.pName PutBlanks(S, lstWidth-name>>BS.length) Wss(S, name) ] let first = (source eq 0? 0, source>>Source.niFirst) let si = i while (si gr first) & (IP(si)>>IM.SymPtr eq 0) do si = si-1 Wss(S, " ") let sym, diff = IP(si)>>IM.SymPtr, i-si test sym eq 0 ifso PutTemplate(S, "$D", diff) ifnot [ ListASym(S, sym) if diff ne 0 then PutTemplate(S, "+$D", diff) ] Puts(S, $*N) ] ] and ListOccupied(S) be [ let ubits, used, reserved = vec IMsize/16, vec maxnPages, vec maxnPages CountUsed(ubits, used, reserved) PutTemplate(S, "INSERT[OccupiedDefs];*N*N*TTITLE[$POccupied];*N", PutFileName, OutputSource>>Source.pName) let reserve(s, p, f, l) be PutTemplate(s, "*TIMRESERVE[$O, $O, $O];*N", p, (f+1)&WordMask, l-f-1) for p = 0 to nPages-1 do if used!p ne 0 then [ PutTemplate(S, "*N** Locations reserved on page $O$S*N*N", p, (p gr 7? "B", "")) let z = p*PageSize-1 let end = z+PageSize for j = z+1 to end do if Get1Bit(ubits, j) eq 0 then // end of an occupied run [ if j ne z+1 then reserve(S, p, z, j) z = j ] if z ne end then reserve(S, p, z, end+1) ] Wss(S, "*N*TEND;*N*N") ] and ListIMap(S, sources) be [ static [ @lstWidth ] let lmap1(s, source, n) be [ Wss(s, " ") let len = PutFileName(s, source>>Source.pName) PutBlanks(s, lstWidth-len) PutTemplate(s, "$6O ($DD)*N", n, n) ] let frees = vec lSource frees>>Source.pName = "Free Instructions = " let res = vec lSource res>>Source.pName = "IMRESERVEd" lstWidth = (sourceNameWidth ge 19? sourceNameWidth, 19) // Print size of each module PutTemplate(S, "$P contains the following modules:*N*N", PutFileName, OutputSource>>Source.pName) let sp = sources until sp eq 0 do [ lmap1(S, sp, sp>>Source.niLast-sp>>Source.niFirst) sp = sp>>Source.next ] PutTemplate(S, "*NTotal Instructions =$6O ($DD)*N", NInstructions, NInstructions) // Print map of each page let ubits, used, reserved = vec IMsize/16, vec maxnPages, vec maxnPages CountUsed(ubits, used, reserved) for p = 0 to nPages-1 do [ PutTemplate(S, "*NPage$6O ($DD):*N", p, p) let base = p*PageSize let sp, u = sources, used!p until sp eq 0 do [ let n = 0 for i = sp>>Source.niFirst to sp>>Source.niLast-1 do [ let ip = IP(i) let abs = ip>>IM.W0 if ((abs & PageMask) eq base) & ip>>IM.placed then n = n+1 // Skip instrs not placed (if assignment pass failed) ] if n ne 0 then lmap1(S, sp, n) sp, u = sp>>Source.next, u-n ] if reserved!p ne 0 then lmap1(S, res, reserved!p) if u ne 0 then Err(PassFatal, "******Page $O IMap discrepancy = $O", p, u) lmap1(S, frees, PageSize-used!p-reserved!p) ] ] and ListChart(S, sources) be [ let lines = 3 // lines occupied on the current page (3 lines written by OpenListFile) // Make 10-character-wide strings for source names, and // identify the source for each location for i = 0 to IMsize-1 do IP(i)>>IM.absPtr = 0 let source = sources until source eq 0 do [ let tag = source>>Source.pDate // don't need date string any more MoveBlock(tag, " ", 6) let name = source>>Source.pName let len = name>>BS.length for i = len by -1 to 1 do if name>>BS.char↑i eq $. then len = i-1 if len gr 10 then len = 10 let j = 11 // leave 1 leading blank while len gr 0 do [ tag>>BS.char↑j = name>>BS.char↑len j, len = j-1, len-1 ] for a = source>>Source.niFirst to source>>Source.niLast-1 do [ let ip = IP(a) if ip>>IM.placed then IP(ip>>IM.W0)>>IM.absPtr = source>>Source.pDate ] source = source>>Source.next ] // Actually produce the chart for page = 0 to nPages-1 do [ let newlines = PageSize/8+4 test lines+newlines gr chartLinesPerPage ifso [ Wss(S, "*014*N"); lines = 1 ] // page eject ifnot [ if page ne 0 then Wss(S, "*N*N"); lines = lines+newlines ] PutTemplate(S, "$S Control Store Locations for page $O ($DD)*N*N", (DMachine eq 0? "D0", "Dorado"), page, page) let pbase = page*PageSize let pend = pbase+PageSize-1 for i = pbase by 8 to pend do [ PutTemplate(S, "$4O/", i) let jnext = i for j = i to i+7 do [ let name = IP(j)>>IM.absPtr if name ne 0 then [ while jnext ls j do [ Wss(S, " "); jnext = jnext+1 ] Wss(S, name) jnext = j+1 ] ] Puts(S, $*N) ] ] ]