-- XMDebug.Mesa -- Edited by: Levin on March 5, 1979 5:52 PM DIRECTORY AltoDefs: FROM "altodefs" USING [PageSize], BootDefs: FROM "bootdefs" USING [BusyPage, FreePage, PageMap, SystemTableHandle], ControlDefs: FROM "controldefs" USING [FrameCodeBase, GlobalFrameHandle, InstWord], DebugData: FROM "debugdata" USING [ESV], DebugUsefulDefs: FROM "debugusefuldefs" USING [CopyRead, CopyWrite, SREAD], DebugUtilityDefs: FROM "debugutilitydefs" USING [AllocOnDrum, RemoveFromDrum, MapUserSegment], DebugXMDefs: FROM "debugxmdefs", InlineDefs: FROM "inlinedefs" USING [HighHalf, LongNumber], MemoryOps: FROM "memoryops" USING [BankIndex], Mopcodes: FROM "mopcodes" USING [zRBL, zWBL], SegmentDefs: FROM "segmentdefs" USING [DeleteFileSegment, FileSegmentAddress, FileSegmentHandle, FileSegmentObject, SegmentHandle, SegmentObject, SwapIn, Unlock], XMESA: FROM "xmesaops" USING [Bank1X, Bank2X, Bank3X, InUseSeal, XFileSegmentHandle, XFileSegmentObject, XMremote, XSegInfo]; XMDebug: PROGRAM IMPORTS DDptr: DebugData, DebugUsefulDefs, DebugUtilityDefs, InlineDefs, SegmentDefs EXPORTS DebugXMDefs SHARES XMESA, SegmentDefs = BEGIN GFH: TYPE = ControlDefs.GlobalFrameHandle; SH: TYPE = SegmentDefs.SegmentHandle; SO: TYPE = SegmentDefs.SegmentObject; FSH: TYPE = SegmentDefs.FileSegmentHandle; FSO: TYPE = SegmentDefs.FileSegmentObject; XFSH: TYPE = XMESA.XFileSegmentHandle; XFSO: TYPE = XMESA.XFileSegmentObject; XSegInfo: TYPE = XMESA.XSegInfo; -- Utilities DoLongRead: PROCEDURE[LONG POINTER] RETURNS [WORD] = MACHINE CODE BEGIN Mopcodes.zRBL, 0; END; DoLongWrite: PROCEDURE[WORD, LONG POINTER] = MACHINE CODE BEGIN Mopcodes.zWBL, 0; END; XMRead: PUBLIC PROCEDURE [from: LONG POINTER] RETURNS [data: UNSPECIFIED] = BEGIN data ← DoLongRead[from]; RETURN END; XMWrite: PUBLIC PROCEDURE [to: LONG POINTER, data: UNSPECIFIED] = BEGIN seg: SH; SegObj: SO; DoLongWrite[data, to]; -- check for codesegment and write on Drum seg ← SegmentFromLongPointer[to]; IF seg = BootDefs.BusyPage OR seg = BootDefs.FreePage THEN RETURN; DebugUsefulDefs.CopyRead[to: @SegObj, from: seg, nwords: SIZE[SO]]; WITH s: seg SELECT FROM file => IF s.class = code THEN BEGIN pi: POINTER TO ControlDefs.InstWord; chocolate: XFSH = @cSegObj; vanilla: FSH = @vSegObj; cSegObj: XFSO; vSegObj: FSO; xs: XSegInfo; dseg: FSH; ChocolateToVanilla[chocolate, vanilla, @s]; dseg ← DebugUtilityDefs.MapUserSegment[@s]; SegmentDefs.SwapIn[dseg]; dseg.write ← TRUE; WITH c: chocolate SELECT FROM remote => BEGIN IF c.proc # XMESA.XMremote THEN ERROR; DebugUsefulDefs.CopyRead[to: @xs, from: c.info, nwords: SIZE[XSegInfo]]; IF xs.seal # XMESA.InUseSeal THEN ERROR; END; ENDCASE => ERROR; pi ← SegmentDefs.FileSegmentAddress[dseg]+ (LOOPHOLE[to, InlineDefs.LongNumber].lowbits - xs.XMpage*AltoDefs.PageSize); pi↑ ← data; SegmentDefs.Unlock[dseg]; SegmentDefs.DeleteFileSegment[dseg]; VanillaToChocolate[vanilla, chocolate, @s]; END; ENDCASE; RETURN END; XMAllocOnDrum: PUBLIC PROCEDURE[g: GFH] RETURNS[p: POINTER] = BEGIN chocolate: XFSH = @cSegObj; vanilla: FSH = @vSegObj; cSegObj: XFSO; vSegObj: FSO; seg: FSH; seg ← SegmentFromFrame[g]; ChocolateToVanilla[chocolate, vanilla, seg]; p ← DebugUtilityDefs.AllocOnDrum[seg !UNWIND => VanillaToChocolate[vanilla, chocolate, seg]]; VanillaToChocolate[vanilla, chocolate, seg]; RETURN END; XMFreeOnDrum: PUBLIC PROCEDURE[g: GFH] = BEGIN chocolate: XFSH = @cSegObj; vanilla: FSH = @vSegObj; cSegObj: XFSO; vSegObj: FSO; seg: FSH; seg ← SegmentFromFrame[g]; ChocolateToVanilla[chocolate, vanilla, seg]; DebugUtilityDefs.RemoveFromDrum[seg !UNWIND => VanillaToChocolate[vanilla, chocolate, seg]]; VanillaToChocolate[vanilla, chocolate, seg]; END; ChocolateToVanilla: PROCEDURE [chocolate: XFSH, vanilla: FSH, seg: FSH] = BEGIN xs: XSegInfo; DebugUsefulDefs.CopyRead[to: chocolate, from: seg, nwords: SIZE[XFSO]]; vanilla↑ ← LOOPHOLE[chocolate↑]; WITH c: chocolate SELECT FROM remote => BEGIN IF c.proc # XMESA.XMremote THEN ERROR; DebugUsefulDefs.CopyRead[to: @xs, from: c.info, nwords: SIZE[XSegInfo]]; IF xs.seal # XMESA.InUseSeal THEN ERROR; END; ENDCASE => ERROR; vanilla.location ← disk[xs.hint]; DebugUsefulDefs.CopyWrite[to: seg, from: vanilla, nwords: SIZE[FSO]]; END; VanillaToChocolate: PROCEDURE [vanilla: FSH, chocolate: XFSH, seg: FSH] = BEGIN xs: XSegInfo; DebugUsefulDefs.CopyRead[to: vanilla, from: seg, nwords: SIZE[FSO]]; chocolate.file ← vanilla.file; chocolate.base ← vanilla.base; chocolate.pages ← vanilla.pages; chocolate.lock ← vanilla.lock; WITH v: vanilla SELECT FROM disk => WITH c: chocolate SELECT FROM remote => BEGIN DebugUsefulDefs.CopyRead[to: @xs, from: c.info, nwords: SIZE[XSegInfo]]; IF xs.seal # XMESA.InUseSeal THEN ERROR; xs.hint ← v.hint; DebugUsefulDefs.CopyWrite[to: c.info, from: @xs, nwords: SIZE[XSegInfo]]; END; ENDCASE => ERROR; ENDCASE => ERROR; DebugUsefulDefs.CopyWrite[to: seg, from: chocolate, nwords: SIZE[XFSO]]; END; SegmentFromFrame: PROCEDURE [g: GFH] RETURNS [FSH] = BEGIN seg: SH; segment: SO; c: ControlDefs.FrameCodeBase; DebugUsefulDefs.CopyRead[from: @g.code, to: @c, nwords: SIZE[ControlDefs.FrameCodeBase]]; IF c.highByte # 0 THEN RETURN[c.handle]; seg ← SegmentFromLongPointer[c.longbase]; IF seg = BootDefs.FreePage OR seg = BootDefs.BusyPage THEN ERROR; DebugUsefulDefs.CopyRead[from: seg, to: @segment, nwords: SIZE[SO]]; WITH segment SELECT FROM file => RETURN[LOOPHOLE[seg]]; ENDCASE => ERROR END; SegmentFromLongPointer: PROCEDURE [p: LONG POINTER] RETURNS [seg: SH] = BEGIN bank: MemoryOps.BankIndex; page: [0..256); table: BootDefs.SystemTableHandle = DDptr.ESV.tables; bank ← InlineDefs.HighHalf[p]; IF bank ~IN MemoryOps.BankIndex THEN ERROR; page ← LOOPHOLE[p, InlineDefs.LongNumber].lowbits/AltoDefs.PageSize; IF table ~= NIL THEN BEGIN OPEN DebugUsefulDefs; page0map: POINTER TO ARRAY [0..XMESA.Bank3X] OF SegmentDefs.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; END...