-- BootSwap.mesa (last edited by: Forrest on: July 19, 1980 7:59 PM)
-- The location of switches should be defined in SDDefs!!
DIRECTORY
Boot USING [
Action, inLoad, Location, LP, MDSIndex, outLoad, pInitialLink, pRequest,
ReadMDS, Request, teledebug],

BootFile USING [Continuation, ContinuationKind, InLoadMode],
--DeviceCleanup: FROM "DeviceCleanup" USING [Perform],
Environment USING [PageCount, wordsPerPage],
Frame
USING [MyLocalFrame],
Inline
USING [LongCOPY],
Mopcodes
USING [zMISC],
PrincOps
USING [BytePC, FrameHandle],
SDDefs USING [SD --, sFirstFree--],
TemporaryBooting
USING [defaultSwitches, Switches];

BootSwap: DEFINITIONS IMPORTS Boot--, DeviceCleanup--, Frame, Inline =
BEGIN
sPilotSwitches: CARDINAL = 142B; -- SDDefs.SD[sPilotSwitches] is the home for switches, used to be called SDDefs.sFirstFree.

Initialize: PROC [mdsiOther: Boot.MDSIndex];
-- Per-system initialization (does InitializeMDS also)
InitializeMDS: PROC;
-- Per-MDS initialization

GetPStartListHeader: PROC RETURNS [POINTER] =
-- Valid after start of initial boot file up until first call to OutLoad
INLINE { RETURN[pMon.pStartListHeader] };

OutLoad: PROC [pLocation: POINTER TO Boot.Location, inLoadMode: BootFile.InLoadMode]
RETURNS [ResponseKind[outLoaded..resumed]] =
-- Assume interrupts disabled, all devices turned off
INLINE BEGIN
-- Set up request in cross-MDS monitor shared with germ
-- (until MDS field is added to PSB, simulate process switch with WriteMDS)
RC: TYPE = MACHINE DEPENDENT RECORD [ -- to get around compiler bug
fill: [0..177B], kind:
BootFile.ContinuationKind, mdsi: Boot.MDSIndex , resumee: UNSPECIFIED];
--
pMon.continuation ← [fill: 0, vp: resumptive[mdsi: Boot.ReadMDS[], resumee: Frame.MyLocalFrame[]]];
pMon.continuation ← LOOPHOLE[RC[
fill: 0, kind: resumptive, mdsi: Boot.ReadMDS[], resumee: Frame.MyLocalFrame[]]];
pMon.inLoadMode ← inLoadMode;
SetGermArguments[
Boot.outLoad, pLocation];
-- pMon.state ← request;
--
NOTIFY pMon.condRequest;
--
WHILE pMon.state~=response DO WAIT pMon.condResponse ENDLOOP;
CallGerm[];
RETURN[pMon.responseKind]
END;

ResponseKind:
TYPE = {initiated, outLoaded, resumed};

InLoad: PROC [
pMicrocodeCopy,
pGermCopy:
LONG POINTER, nGerm: CARDINAL,
pLocation:
POINTER TO Boot.Location,
switches:
TemporaryBooting.Switches ← TemporaryBooting.defaultSwitches] =
-- Load boot file, performing microcode and germ swap if necessary
INLINE BEGIN
-- IF pMicrocodeCopy~=NIL THEN DeviceCleanup.Perform[kill]; ++ causes FATAL ERROR IN PASS 4
IF pGermCopy~=NIL THEN
Inline.LongCOPY[from: pGermCopy, nwords: nGerm, to: Boot.LP[highbits: mdsiGerm, lowbits: countSkip*Environment.wordsPerPage]];
SetGermArguments[
Boot.inLoad, pLocation];
LOOPHOLE[Boot.LP[highbits: mdsiGerm, lowbits: @SDDefs.SD[sPilotSwitches]], LONG POINTER TO TemporaryBooting.Switches]↑ ←
switches;
IF pMicrocodeCopy~=NIL THEN LoadRam[pMicrocode: pMicrocodeCopy, andJump: TRUE]; -- never returns
CallGerm[]
END;

-- The germ is free to ingore pLocation
Teledebug: PROC [pLocation: POINTER TO Boot.Location] =
-- Assume interrupts disabled, all devices turned off
INLINE BEGIN
-- Set up request in cross-MDS monitor shared with germ
-- (until MDS field is added to PSB, simulate process switch with WriteMDS)
SetGermArguments[Boot.teledebug, pLocation];
CallGerm[];
END;

SetGermArguments:
PRIVATE PROC [action: Boot.Action, pLocation: POINTER TO Boot.Location] =
INLINE BEGIN
pRequest:
LONG POINTER TO Boot.Request = LOOPHOLE[Boot.LP[highbits: mdsiGerm, lowbits: Boot.pRequest]];
pRequest↑ ← [action, pLocation↑];
END;

CallGerm:
PRIVATE PROC =
INLINE BEGIN
pMon.CrossMDSCall[mdsiOther: mdsiGerm, Dest:
LOOPHOLE[Boot.pInitialLink]];
LOOPHOLE[pMon.CrossMDSCall, POINTER TO PrincOps.FrameHandle].pc ← LOOPHOLE[pMon.pcCross];
END;

LoadRam:
PRIVATE PROC [pMicrocode: LONG POINTER, andJump: BOOLEAN] = MACHINE CODE BEGIN Mopcodes.zMISC, 3 END;

-- Extension to basic request for cross-MDS communication
-- WHEN THIS IS CHANGED, both Pilot and Germ will be incompatible untill both are updated!! (at the very least add things to the front)
Mon: PRIVATE TYPE = --MONITORED-- RECORD [
-- constants for WriteMDS hack:
CrossMDSCall: PROC [mdsiOther: Boot.MDSIndex, Dest: PROC],
pcCross:
PrincOps.BytePC,
-- additional fields for outLoad request:
continuation: resumptive BootFile.Continuation, -- for WriteMDS hack
inLoadMode:
BootFile.InLoadMode,
-- response fields:
responseKind: ResponseKind,
fill: [0..8192) ← 0,
pStartListHeader:
POINTER, -- only if responseKind=booted
selfFill:
RECORD [a, b, c, d: UNSPECIFIED] -- obsolete, remove someday
-- state: {request, response},
-- condRequest:
CONDITION,
-- condResponse:
CONDITION, ++ only if responseKind~=booted
];

pMon: PRIVATE LONG POINTER TO Mon;

-- Attributes of germ
mdsiGerm: Boot.MDSIndex = 76B; -- until Pilot is moved from first 64K
countSkip:
Environment.PageCount = 2; -- initial vacant pages within germ; will become 0
pCountGerm:
PRIVATE POINTER TO Environment.PageCount = LOOPHOLE[1377B]; -- excluding pageBuffer

END.
LOG
Time: April 17, 1980 12:39 AMBy: ForrestAction: Move teledebug to Boot
Time: April 24, 1980 5:07 PMBy: ForrestAction: FrameOps => Frame, ControlDefs => PrincOps
Time: July 19, 1980 7:16 PMBy: ForrestAction: Started programming around SDDefs changing. Took self out of PMon