-- CoreMap.Mesa -- Edited by Sandman on May 21, 1980 12:14 PM -- Edited by Bruce on September 26, 1980 7:35 PM -- Edited by Johnsson on July 16, 1980 8:21 AM DIRECTORY Actions USING [], AltoDefs USING [MaxMDSPage, PageCount, PageNumber, PageSize, PagesPerMDS], Ascii USING [CR, SP], BcdDefs USING [MTIndex, NameRecord], BcdOps USING [BcdBase, MTHandle, NameString, ProcessModules], ControlDefs USING [FrameCodeBase, GFT, GlobalFrameHandle, NullGlobalFrame], DebugFormat USING [NumberFormat], DebugOps USING [ShortCopyREAD, ShortREAD, UserAborted], DOutput USING [Blanks, Char, Number, Octal, Text], Init USING [bootLoaded], Inline USING [BITAND, HighHalf, LongCOPY, LowHalf], DLoadState USING [ AcquireBcd, Enumerate, GetMap, Acquire, Map, ReleaseBcd, Release, ReleaseMap], MachineDefs USING [ConfigIndex], SegmentDefs USING [BankIndex, FileSegmentHandle, FrameDS, HeapDS, PageCount, PageNumber, SegmentHandle, SegmentObject, SystemDS, TableDS], State USING [GetGS], Storage USING [Free, FreePages, FreeString, Node, Pages, Prune, String], Strings USING [AppendSubString, SubStringDescriptor], SwapperOps USING [BusyPage, FreePage, PageMap, RegionTable, SystemTable]; CoreMap: PROGRAM IMPORTS BcdOps, DebugOps, DOutput, DLoadState, Init, Inline, State, Storage, Strings EXPORTS Actions SHARES SegmentDefs = BEGIN OPEN AltoDefs, Ascii, DOutput, SegmentDefs, MachineDefs; byte: DebugFormat.NumberFormat = [8,FALSE,TRUE,3]; pageNF: DebugFormat.NumberFormat = [8,FALSE,TRUE,4]; typeNF: DebugFormat.NumberFormat = [8,FALSE,TRUE,0]; word: DebugFormat.NumberFormat = [8,FALSE,TRUE,6]; WriteLongPointer: PROCEDURE [p: LONG POINTER] = BEGIN OPEN Inline; high: CARDINAL = (IF CARDINAL[LowHalf[p]] > 77777B THEN 1 ELSE 0) + 2*HighHalf[p]; IF high # 0 THEN Number[high, [8,FALSE,TRUE,2]] ELSE Blanks[2]; Number[BITAND[LowHalf[p], 77777B],[8,high # 0,TRUE,5]]; RETURN END; LongAddressFromPage: PROCEDURE [page: PageNumber] RETURNS [LONG POINTER] = BEGIN RETURN[LOOPHOLE[LONG[page]*PageSize]] END; PrintNonSeg: PROCEDURE [ state: {free, busy}, bank: CARDINAL, page: PageNumber, count: PageCount] = BEGIN segBase: PageNumber; segBase _ bank*PagesPerMDS + page; Number[segBase, pageNF]; Char[SP]; WriteLongPointer[LongAddressFromPage[segBase]]; Blanks[5]; Number[count,pageNF]; Text[SELECT state FROM free => " free"L, ENDCASE => " busy"L]; END; PrintSeg: PROCEDURE [ bank: CARDINAL, page: PageNumber, seg: SegmentHandle, count: PageCount] = BEGIN copiedSeg: SegmentObject; segBase: PageNumber; IF seg = SwapperOps.FreePage THEN {PrintNonSeg[free, bank, page, count]; Char[CR]; RETURN}; IF seg = SwapperOps.BusyPage THEN {PrintNonSeg[busy, bank, page, count]; Char[CR]; RETURN}; DebugOps.ShortCopyREAD[ to: @copiedSeg, from: seg, nwords: SIZE[SegmentObject]]; segBase _ copiedSeg.VMpage; Number[segBase, pageNF]; Char[SP]; WriteLongPointer[LongAddressFromPage[segBase]]; WITH s: copiedSeg SELECT FROM data => BEGIN Blanks[5]; Number[count,pageNF]; Text[" data "L]; SELECT s.type FROM FrameDS => Text["frames"L]; SystemDS => Text["system"L]; HeapDS => Text["heap"L]; TableDS => Text["table"L]; 5 => Text["bitmap"L]; 6 => Text["stream buffer"L]; 7 => Text["pup buffer"L]; ENDCASE => Number[s.type,typeNF]; END; file => BEGIN part1: CARDINAL = DebugOps.ShortREAD[@s.file.fp.serial]; Char[SP]; Number[s.base,pageNF]; Char[SP]; Number[s.pages,byte]; Text[" file SN"L]; IF part1 # 0 THEN {Octal[part1]; Text[", "L]}; Octal[DebugOps.ShortREAD[@s.file.fp.serial.part2]]; SELECT s.class FROM code => Text[" code"L]; ENDCASE; Char[' ]; IF ~s.write THEN Char[' ] ELSE Char['W]; IF s.lock > 0 THEN BEGIN Text[" lock="L]; Octal[s.lock]; END; SELECT s.class FROM code => PrintFileName[LOOPHOLE[seg]]; ENDCASE; END; ENDCASE; Char[CR]; END; PrintFileName: PROCEDURE[seg: FileSegmentHandle] = BEGIN node: POINTER TO NameItem; found: BOOLEAN _ FALSE; FOR node _ NameList, node.next UNTIL node = NIL DO IF node.code = seg THEN BEGIN Char[SP]; Text[node.module]; found _ TRUE; END; ENDLOOP; RETURN END; NameItem: TYPE = RECORD [ next: POINTER TO NameItem, code: FileSegmentHandle, module: STRING]; NameList: POINTER TO NameItem _ NIL; SegmentFromFrame: PROCEDURE [g: ControlDefs.GlobalFrameHandle] RETURNS [seg: FileSegmentHandle] = BEGIN c: ControlDefs.FrameCodeBase; DebugOps.ShortCopyREAD[ from: @g.code, to: @c, nwords: SIZE[ControlDefs.FrameCodeBase]]; seg _ SegmentFromCodePointer[c]; IF seg = SwapperOps.FreePage OR seg=SwapperOps.BusyPage THEN RETURN[NIL]; RETURN END; SegmentFromCodePointer: PROCEDURE [c: ControlDefs.FrameCodeBase] RETURNS [seg: FileSegmentHandle] = BEGIN s: SegmentHandle; IF c.highByte # 0 THEN RETURN[c.handle]; s _ SegFromPage[bank: c.otherByte, p: c.offset/AltoDefs.PageSize]; RETURN[LOOPHOLE[s]]; END; FindFrameNames: PROCEDURE = BEGIN OPEN DLoadState; DoOneBcd: PROCEDURE [config: ConfigIndex] RETURNS [BOOLEAN] = BEGIN bcd: BcdOps.BcdBase = AcquireBcd[config]; map: Map = GetMap[config]; DoOneModule: PROCEDURE [mth: BcdOps.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOLEAN] = BEGIN OPEN ControlDefs; frame: GlobalFrameHandle = DebugOps.ShortREAD[@GFT[map[mth.gfi]].frame]; seg: FileSegmentHandle; IF frame = NullGlobalFrame THEN RETURN[FALSE]; seg _ SegmentFromFrame[frame]; IF seg # NIL THEN AddName[seg, bcd, mth.name]; RETURN[FALSE]; END; [] _ BcdOps.ProcessModules[bcd, DoOneModule]; ReleaseMap[map]; ReleaseBcd[bcd]; RETURN[FALSE]; END; [] _ Acquire[ ! ANY => GOTO noNames]; [] _ Enumerate[recentfirst, DoOneBcd]; Release[]; EXITS noNames => NULL; END; AddName: PROCEDURE [code: FileSegmentHandle, bcd: BcdOps.BcdBase, name: BcdDefs.NameRecord] = BEGIN ssb: BcdOps.NameString = LOOPHOLE[bcd+bcd.ssOffset]; ss: Strings.SubStringDescriptor _ [base: @ssb.string, offset: name, length: ssb.size[name]]; s: STRING _ Storage.String[ssb.size[name]]; node: POINTER TO NameItem _ Storage.Node[SIZE[NameItem]]; Strings.AppendSubString[s, @ss]; node^ _ [next: NameList, code: code, module: s]; NameList _ node; END; FreeNames: PROCEDURE = BEGIN node: POINTER TO NameItem; FOR node _ NameList, NameList UNTIL node = NIL DO NameList _ node.next; Storage.FreeString[node.module]; Storage.Free[node]; ENDLOOP; [] _ Storage.Prune[]; END; pageTables: ARRAY BankIndex OF SwapperOps.PageMap _ ALL[NIL]; SegFromPage: PROCEDURE [ bank: CARDINAL, p: PageNumber] RETURNS [SegmentHandle] = BEGIN IF pageTables[bank] = NIL THEN RETURN[NIL]; RETURN[pageTables[bank][p]] END; LP: PROCEDURE [low, high: CARDINAL] RETURNS [LONG POINTER] = MACHINE CODE BEGIN END; GetPageMaps: PROCEDURE = BEGIN OPEN SwapperOps; table: POINTER TO SystemTable = State.GetGS[].gsh.ESV.tables; regions: RegionTable; bank: BankIndex; Masks: ARRAY BankIndex OF CARDINAL = [ 100000B, 40000B, 20000B, 10000B, 4000B, 2000B, 1000B, 400B, 200B, 100B, 40B, 20B, 10B, 4B, 2B, 1B]; DebugOps.ShortCopyREAD[ to: @regions, from: DebugOps.ShortREAD[@table.regions], nwords: SIZE[RegionTable]]; pageTables _ ALL[NIL]; pageTables[0] _ Storage.Pages[1]; DebugOps.ShortCopyREAD[ from: DebugOps.ShortREAD[@table.mdsMap], to: pageTables[0], nwords: PagesPerMDS]; IF Init.bootLoaded THEN RETURN; FOR bank IN [1..LAST[BankIndex]] DO IF regions[bank] # NIL THEN BEGIN pageTables[bank] _ Storage.Pages[1]; Inline.LongCOPY[ from: LP[0, bank], to: pageTables[bank], nwords: PagesPerMDS]; END; ENDLOOP; END; FreePageMaps: PROCEDURE = BEGIN bank: BankIndex; FOR bank IN BankIndex DO IF pageTables[bank] # NIL THEN Storage.FreePages[pageTables[bank]]; ENDLOOP; END; PrintCoremap: PUBLIC PROCEDURE = BEGIN bank: BankIndex; curSeg, nextSeg: SegmentHandle; count: PageCount; page, startPage: PageNumber; BEGIN ENABLE UNWIND => BEGIN FreePageMaps[]; FreeNames[]; END; GetPageMaps[]; FindFrameNames[]; Char[CR]; FOR bank IN BankIndex DO IF pageTables[bank] = NIL THEN LOOP; curSeg _ SegFromPage[bank, startPage _ 0]; page _ count _ 1; UNTIL page > MaxMDSPage DO ENABLE DebugOps.UserAborted => EXIT; nextSeg _ SegFromPage[bank, page]; IF nextSeg # curSeg THEN BEGIN PrintSeg[bank, startPage, curSeg, count]; curSeg _ nextSeg; startPage _ page; count _ 1; END ELSE count _ count + 1; page _ page + 1; REPEAT FINISHED => PrintSeg[bank, startPage, curSeg, count]; ENDLOOP; ENDLOOP; END; FreePageMaps[]; FreeNames[]; Char[CR]; RETURN END; END...