-- BootSwapCross.mesa (last edited by: Forrest on: May 16, 1980  2:19 PM)
DIRECTORY
  Boot: FROM "Boot" USING [LP, MDSIndex, pRequest, ReadMDS],
  BootSwap: FROM "BootSwap",
  Frame: FROM "Frame" USING [Free, MyLocalFrame, MyGlobalFrame],
  Inline: FROM "Inline" USING [COPY, LongCOPY],
  Mopcodes: FROM "Mopcodes" USING [zWR],
  PrincOps: FROM "PrincOps" USING
    [FrameHandle, GlobalFrameHandle, Port, TrapLink];
BootSwapCross: PROGRAM
  IMPORTS Boot, Frame, Inline EXPORTS BootSwap SHARES BootSwap =
BEGIN OPEN BootSwap, PrincOps;
-- Inter-MDS germ linkage
Initialize: PUBLIC PROCEDURE [mdsiOther: Boot.MDSIndex] =
  BEGIN OPEN port: LOOPHOLE[Port, PrincOps.Port], Frame;
  InitializeMDS[]; -- set pMon
  -- Set up frame for Procedure and make it pending on Port
  port.dest ← [frame[MyLocalFrame[]]]; -- temporarily connect Port to self
  Procedure[];
  -- Now set up local and global frames with copy in other MDS
  lCross.accesslink ← gCross;
  lCross.pc ← port.frame.pc;
  lCross.returnlink ← TrapLink;
  Free[port.frame];
  port.frame ← lCross;
  Inline.COPY[from: MyGlobalFrame[], nwords: nGCross, to: gCross]; -- now mustn’t set global variables
  Inline.LongCOPY[from: lCross, nwords: nLCross+nGCross, to: Boot.LP[highbits: mdsiOther, lowbits: lCross]];
  pMon.CrossMDSCall ←
    LOOPHOLE[gCross+(@port-LOOPHOLE[MyGlobalFrame[], POINTER TO PrincOps.Port])]; -- connect CrossMDSCall to Port
  pMon.pcCross ← LOOPHOLE[lCross.pc]
  END;
InitializeMDS: PUBLIC PROCEDURE =
  BEGIN
  pMon ← LOOPHOLE[Boot.LP[highbits: mdsiGerm, lowbits: lCross-SIZE[Mon]], LONG POINTER TO Mon]
  END;
-- The numbers nGCross and nLCross must be divisible by 4 and not too small!
nGCross: CARDINAL = 12;
limit: CARDINAL = LOOPHOLE[Boot.pRequest];
gCross: GlobalFrameHandle ← LOOPHOLE[limit-(limit MOD 4)-nGCross]; -- variable to avoid compiler bug
nLCross: CARDINAL = 8;
lCross: FrameHandle ← LOOPHOLE[gCross-nLCross]; -- variable to avoid compiler bug
pMon: PUBLIC LONG POINTER TO Mon;
Port: PORT RETURNS [mdsiOther: Boot.MDSIndex, Dest: PROCEDURE];
Procedure: PROCEDURE =
  BEGIN -- address of this frame must be same in both MDS’s; global frames must be "similar"
  mdsiOther: Boot.MDSIndex; Dest: PROCEDURE;
  mdsiBack: Boot.MDSIndex;
  DO
    [mdsiOther, Dest] ← Port[];
    [Dest, mdsiBack] ← Save2AndWriteMDS[Dest, Boot.ReadMDS[], mdsiOther];
    Dest[];
    WriteMDS[mdsiBack];
    ENDLOOP
  END;
Save2AndWriteMDS: PROCEDURE [s1, s2: UNSPECIFIED, mdsi: Boot.MDSIndex] RETURNS [t1, t2: UNSPECIFIED] =
  LOOPHOLE[WriteMDS]; -- t1=s1 AND t2=s2
WriteMDS: PROCEDURE [mdsi: Boot.MDSIndex] =
  MACHINE CODE BEGIN Mopcodes.zWR, 3 END;
END.
LOG
Time: December 18, 1978  9:30 AMBy: McJonesAction: Created file
Time: May 3, 1980  10:32 AMBy: ForrestAction: FrameOps=> Frame, ControlDefs => PrincOps
Time: May 16, 1980  2:20 PMBy: ForrestAction: Delete Import of BootSwap