BootSwapCross.mesa
last edited by Levin on March 11, 1983 1:26 pm
DIRECTORY
Boot USING [LP, MDSIndex, pRequest, ReadMDS],
BootSwap,
Frame USING [Free, MyLocalFrame, MyGlobalFrame],
Inline USING [COPY, LongCOPY],
Mopcodes USING [zWR],
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.