-- 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...