-- XCoreMap.Mesa
-- Edited by Levin on March 19, 1979 9:04 AM
DIRECTORY
AltoDefs: FROM "altodefs" USING [PageSize],
BcdDefs: FROM "bcddefs" USING [MTHandle, MTIndex, NameRecord, NameString],
BcdOps: FROM "bcdops" USING [BcdBase, ProcessModules],
BootDefs: FROM "bootdefs" USING [BusyPage, FreePage, PageMap, SystemTableHandle],
ControlDefs: FROM "controldefs" USING [FrameCodeBase, GFT, GlobalFrameHandle],
DebugData: FROM "debugdata" USING [debugPilot, ESV],
DebugMiscDefs: FROM "debugmiscdefs" USING [CommandNotAllowed, ControlDEL],
DebugUsefulDefs: FROM "debugusefuldefs" USING [AddCommand, AREAD, MREAD, SREAD],
DebugUtilityDefs: FROM "debugutilitydefs" USING [LoadStateInvalid],
InlineDefs: FROM "inlinedefs" USING [BITAND, HighHalf, LowHalf],
IODefs: FROM "iodefs" USING [CR, NumberFormat, Rubout, SP, WriteChar, WriteLine, WriteNumber,
WriteOctal, WriteString],
MemoryOps: FROM "memoryops" USING [BankIndex],
LoadStateOps: FROM "loadstateops" USING [AcquireBcd, ConfigIndex,
EnumerateBcds, GetMap, InputLoadState, Map,
ReleaseBcd, ReleaseLoadState, ReleaseMap],
SegmentDefs: FROM "segmentdefs" USING [FileSegmentHandle, PageCount, PageNumber, SegmentHandle],
StreamDefs: FROM "streamdefs" USING [ControlDELtyped],
StringDefs: FROM "stringdefs" USING [AppendSubString, SubStringDescriptor],
SystemDefs: FROM "systemdefs" USING [AllocateHeapNode, AllocateHeapString, AllocateSegment,
FreeHeapNode, FreeHeapString, FreeSegment, PruneHeap],
XMESA: FROM "XMesaOps" USING [Bank1X, Bank2X, Bank3X, XMremote, XSegInfo, XSegmentHandle,
XSegmentObject],
XMesaDefs: FROM "XMesaDefs" USING [MaxXPage, PagesPerBank];
XCoreMap: PROGRAM
IMPORTS BcdOps, DDptr: DebugData, DebugMiscDefs, DebugUsefulDefs, DebugUtilityDefs, LoadStateOps,
InlineDefs, IODefs, SystemDefs, StringDefs, StreamDefs
SHARES XMESA, SegmentDefs =
BEGIN
OPEN AltoDefs, SystemDefs, IODefs, SegmentDefs;
byte: NumberFormat = NumberFormat[8,FALSE,TRUE,3];
pageNF: NumberFormat = NumberFormat[8,FALSE,TRUE,4];
word: NumberFormat = NumberFormat[8,FALSE,TRUE,6];
CopyRead: PROCEDURE [from, to: POINTER, nwords: CARDINAL] =
BEGIN
i: CARDINAL;
FOR i IN [0..nwords) DO
(to+i)↑ ← DebugUsefulDefs.SREAD[from+i];
ENDLOOP;
RETURN
END;
PrintPages: PROCEDURE[page:PageNumber, count:PageCount, state:PageState] =
BEGIN
WriteNumber[page,pageNF]; WriteChar[SP];
WriteLongPointer[LongAddressFromPage[page]];
WriteString[" "L];
WriteNumber[count,pageNF];
WriteLine[SELECT state FROM
free => " free"L,
data => " data"L,
file => " file"L,
busy => " busy"L,
ENDCASE => " ?"L];
RETURN
END;
WriteLongPointer: PROCEDURE [p: LONG POINTER] =
BEGIN
highOit: CARDINAL = (IF LOOPHOLE[InlineDefs.LowHalf[p], CARDINAL] > 77777B THEN 1 ELSE 0) +
2*InlineDefs.HighHalf[p];
WriteChar[IF highOit = 0 THEN ' ELSE '0 + highOit];
WriteNumber[InlineDefs.BITAND[InlineDefs.LowHalf[p], 77777B],[8,highOit # 0,TRUE,5]];
RETURN
END;
LongAddressFromPage: PROCEDURE [page: PageNumber] RETURNS [LONG POINTER] =
BEGIN
RETURN[LOOPHOLE[LONG[page]*PageSize]]
END;
BaseFromSeg: PROCEDURE [seg: XMESA.XSegmentHandle] RETURNS [p: PageNumber] =
BEGIN
WITH s: seg SELECT FROM
data => RETURN[IF s.VMpage= 0 THEN s.XMpage ELSE s.VMpage];
file =>
WITH xs: s SELECT FROM
disk => RETURN[xs.VMpage];
remote =>
IF xs.proc = XMESA.XMremote THEN
BEGIN
info: XMESA.XSegInfo;
CopyRead[to: @info, from: xs.info, nwords: SIZE[XMESA.XSegInfo]];
RETURN[info.XMpage]
END
ELSE RETURN[xs.VMpage];
ENDCASE;
ENDCASE
END;
PrintSegment: PROCEDURE [seg: XMESA.XSegmentHandle] RETURNS [state: PageState, size: PageCount] =
BEGIN
copiedSeg: XMESA.XSegmentObject;
segBase: PageNumber;
CopyRead[to: @copiedSeg, from: seg, nwords: SIZE[ XMESA.XSegmentObject]];
segBase ← BaseFromSeg[@copiedSeg];
WITH s: copiedSeg SELECT FROM
data => BEGIN PrintPages[segBase, s.pages, data]; RETURN[data, s.pages] END;
file =>
BEGIN
WriteNumber[segBase,pageNF]; WriteChar[SP];
WriteLongPointer[LongAddressFromPage[segBase]]; WriteChar[SP];
WriteNumber[s.base,byte]; WriteChar[SP];
WriteNumber[s.pages,pageNF]; WriteChar[SP];
WriteString["SN"L];
WriteOctal[DebugUsefulDefs.AREAD[@s.file.fp.serial.part2]];
SELECT s.class FROM
code => WriteString[" code"L];
ENDCASE;
IF s.read OR s.write THEN WriteChar[' ];
IF s.read THEN WriteChar['R];
IF s.write THEN WriteChar['W];
WITH xs: s SELECT FROM
remote => IF xs.proc = XMESA.XMremote THEN WriteChar['X] ELSE WriteString[" remote"L];
ENDCASE;
IF s.lock > 0 THEN
BEGIN
WriteString[" lock="L];
WriteOctal[s.lock];
END;
SELECT s.class FROM
code => PrintFileName[LOOPHOLE[seg]];
ENDCASE;
WriteChar[CR];
RETURN[file, s.pages]
END;
ENDCASE
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
WriteChar[SP];
WriteString[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;
CopyRead[from: @g.code, to: @c, nwords: SIZE[ControlDefs.FrameCodeBase]];
seg ← SegmentFromCodePointer[c];
IF seg = BootDefs.FreePage OR seg = BootDefs.BusyPage THEN ERROR;
RETURN
END;
SegmentFromCodePointer: PROCEDURE [c: ControlDefs.FrameCodeBase] RETURNS [seg: FileSegmentHandle] =
BEGIN
bank: MemoryOps.BankIndex;
page: [0..256);
table: BootDefs.SystemTableHandle = DDptr.ESV.tables;
IF c.highByte # 0 THEN RETURN[c.handle];
bank ← c.highHalf;
IF bank ~ IN MemoryOps.BankIndex THEN ERROR;
page ← LOOPHOLE[c.shortbase, CARDINAL]/AltoDefs.PageSize;
IF table # NIL THEN
BEGIN OPEN DebugUsefulDefs;
page0map: POINTER TO ARRAY [0..XMESA.Bank3X] OF SegmentHandle ← SREAD[@table.pagemap];
pagemap: POINTER TO BootDefs.PageMap;
pagemap ←
SELECT bank FROM
1 => SREAD[@page0map[XMESA.Bank1X]],
2 => SREAD[@page0map[XMESA.Bank2X]],
3 => SREAD[@page0map[XMESA.Bank3X]],
ENDCASE => page0map;
IF pagemap = NIL THEN ERROR;
RETURN[SREAD[@pagemap[page]]]
END
ELSE ERROR
END;
FindFrameNames: PROCEDURE =
BEGIN OPEN DebugUsefulDefs, LoadStateOps;
DoOneBcd: PROCEDURE [config: ConfigIndex] RETURNS [BOOLEAN] =
BEGIN
bcd: BcdOps.BcdBase = AcquireBcd[config];
map: Map = GetMap[config];
DoOneModule: PROCEDURE [mth: BcdDefs.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOLEAN] =
BEGIN OPEN ControlDefs;
frame: GlobalFrameHandle = MREAD[@GFT[map[mth.gfi]].frame];
AddName[SegmentFromFrame[frame], bcd, mth.name];
RETURN[FALSE];
END;
[] ← BcdOps.ProcessModules[bcd, DoOneModule];
ReleaseMap[map];
ReleaseBcd[bcd];
RETURN[FALSE];
END;
[] ← InputLoadState[ ! DebugUtilityDefs.LoadStateInvalid => GOTO noNames];
[] ← EnumerateBcds[recentfirst, DoOneBcd];
ReleaseLoadState[];
EXITS
noNames => NULL;
END;
AddName: PROCEDURE [code: FileSegmentHandle, bcd: BcdOps.BcdBase, name: BcdDefs.NameRecord] =
BEGIN
ssb: BcdDefs.NameString = LOOPHOLE[bcd+bcd.ssOffset];
ss: StringDefs.SubStringDescriptor ←
[base: @ssb.string, offset: name, length: ssb.size[name]];
s: STRING ← SystemDefs.AllocateHeapString[ssb.size[name]];
node: POINTER TO NameItem ← AllocateHeapNode[SIZE[NameItem]];
StringDefs.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;
SystemDefs.FreeHeapString[node.module];
SystemDefs.FreeHeapNode[node];
ENDLOOP;
[] ← SystemDefs.PruneHeap[];
END;
PageState: TYPE = {free,data,file,busy};
PageMap: DESCRIPTOR FOR ARRAY OF XMESA.XSegmentHandle ← DESCRIPTOR[NIL,XMesaDefs.MaxXPage+1];
StateFromPage: PROCEDURE [p: PageNumber] RETURNS [XMESA.XSegmentHandle, PageState] =
BEGIN
RETURN[
PageMap[p],
SELECT LOOPHOLE[PageMap[p], SegmentHandle] FROM
BootDefs.FreePage => free,
BootDefs.BusyPage => busy,
ENDCASE => data] -- well it doesn't really matter
END;
CopyPageMap: PROCEDURE [map: POINTER, start: PageNumber] =
BEGIN
i: PageNumber;
IF map = NIL THEN
FOR i IN [0..XMesaDefs.PagesPerBank) DO PageMap[start+i] ← LOOPHOLE[BootDefs.BusyPage] ENDLOOP
ELSE
CopyRead[from: map, to: @PageMap[start], nwords: XMesaDefs.PagesPerBank];
END;
DisplayCoremap: PUBLIC PROCEDURE =
BEGIN
seg: XMESA.XSegmentHandle;
i: MemoryOps.BankIndex;
segSize: PageCount;
count: PageCount ← 0;
page, hole: PageNumber ← 0;
state, next: PageState ← free;
table: BootDefs.SystemTableHandle = DDptr.ESV.tables;
pagemap: POINTER TO BootDefs.PageMap ← DebugUsefulDefs.SREAD[@table.pagemap];
IF DDptr.debugPilot THEN
BEGIN
IODefs.WriteString["Debugging Pilot--"];
SIGNAL DebugMiscDefs.CommandNotAllowed;
END;
PageMap ← DESCRIPTOR [AllocateSegment[LENGTH[PageMap]], LENGTH[PageMap]];
BEGIN ENABLE UNWIND => BEGIN FreeSegment[BASE[PageMap]]; FreeNames[]; END;
CopyRead[from:@pagemap[0], to: @PageMap[0], nwords: XMesaDefs.PagesPerBank];
FOR i IN [1..LAST[MemoryOps.BankIndex]] DO
CopyPageMap[DebugUsefulDefs.SREAD[@pagemap[XMESA.Bank1X+i-1]], i*XMesaDefs.PagesPerBank];
ENDLOOP;
FindFrameNames[];
WriteChar[CR]; page ← 0;
UNTIL page >= LENGTH[PageMap] DO
ENABLE Rubout => EXIT;
[seg, next] ← StateFromPage[page];
IF next # state AND count#0 THEN
BEGIN
PrintPages[hole,count,state];
hole ← hole + count; count ← 0;
END;
segSize ← 1;
SELECT next FROM
free => state ← free;
busy => state ← busy;
ENDCASE => [state, segSize] ← PrintSegment[seg];
page ← page + segSize;
SELECT state FROM
data, file => hole ← page;
ENDCASE => count ← count+1;
IF StreamDefs.ControlDELtyped[] THEN SIGNAL DebugMiscDefs.ControlDEL;
REPEAT
FINISHED => IF count#0 THEN PrintPages[hole,count,state];
ENDLOOP;
END;
FreeSegment[BASE[PageMap]];
FreeNames[];
WriteChar[CR];
RETURN
END;
DebugUsefulDefs.AddCommand["XCoremap", DisplayCoremap];
END...