*-----------------------------------------------------------
Title[PilotBoot.mc...June 18, 1982  3:31 PM...Taft];
* Pilot Germ boot sequence
*-----------------------------------------------------------

TopLevel;
DontKnowRBase;
Set[XTask, IP[EMU]];


*-----------------------------------------------------------
* Data structures
*-----------------------------------------------------------

* Germ conventions:
MC[baseGerm, 1000];		* = BootSwap.countSkip * wordsPerPage

* pRequest: POINTER TO Request = LOOPHOLE[1360B];
MC[pRequest, 1360];

* Request: TYPE = MACHINE DEPENDENT RECORD [
MC[Req.action, 0];		* action: Action,
MC[Req.deviceType, 1];		* deviceType: Device.type,
MC[Req.deviceOrdinal, 2];	* deviceOrdinal: CARDINAL,
MC[Req.vp, 3];			* vp: SELECT OVERLAID * FROM
				*   disk => [diskFileID: DiskFileID],
				*   ethernet => [bfn, net, host: CARDINAL];

* Device.Type: TYPE = {diablo31, sa800, sa1000, sa4000, cdc9730, ethernet};
MC[DType.sa4000, 3];		* Actually, Dorado Trident disk
MC[DType.ethernet, 5];

* Action: TYPE = {inLoad, outLoad, bootPhysicalVolume, teleDebug, noOp};
MC[Act.bootPhysicalVolume, 2];

* pSwitches: POINTER TO ARRAY [0..2] OF CARDINAL = LOOPHOLE[1242B];
MC[pSwitches, 1242];


*-----------------------------------------------------------
* Entry conditions:
*	Real memory has been mapped contiguously at the bottom of virtual
*	memory, and zeroed.  Base registers have been set up.
*	I/O devices have been initialized and are quiescent.
* Exit conditions:
*	Germ loaded into memory and Mesa emulator started executing it.
*-----------------------------------------------------------

GermBoot:
	RBase← RBase[BTemp0];
	MemBase← IOBR;
	BootDataPtr← baseGerm;		* Where to load it
	BTemp2← Desc.bi.germ, SCall[DiskBootSoft]; * What to load
GermBootFailed:
	 Breakpoint, Branch[.];		* +1: boot failed

* Store into the Germ the magic values that tell it what to do.
	T← And[pRequest!, 177400]C;	* Set up the Request
	T← T OR (And[pRequest!, 377]C);
	T← (Store← T)+1, DBuf← Act.bootPhysicalVolume;
	T← (Store← T)+1, DBuf← DType.sa4000;
	Store← T, DBuf← 0C;

	T← And[pSwitches!, 177400]C;	* Set up the Switches -- all zeroes
	T← T OR (And[pSwitches!, 377]C);
	Cnt← 2S;
	T← (Store← T)+1, DBuf← 0C, Branch[., Cnt#0&-1];

* We ought to be able to remap the Germ into MDS 76 simply by exchanging map
* entries in MDSs 0 and 76 for those pages into which the Germ was read.
* However, that would leave a hole (vacant pages) in MDS 0, and apparently
* the Germ can't cope with that.  So instead we steal some pages from the
* end of mapped virtual memory, remap them into MDS 76, and copy the Germ.
* Note that BootDataPtr points to start of the page after the Germ.
	T← BootDataPtr, RBase← RBase[RTemp0];
	RTemp2← Q← T;			* Save it in 2 places
	RTemp1← A0, MemBase← LPtr;
FindEndMappedVM:
	T← RSH[RTemp1, 10];
	BRHi← T;
	T← LSH[RTemp1, 10];
	BRLo← T;
	RTemp0← A0, SCall[ReadMapPage];
	 Branch[GermRemapLpE];		* +1: found first vacant page
	RTemp1← (RTemp1)+1, Branch[FindEndMappedVM]; * +2: not vacant

GermRemapLp:
	RTemp2← (RTemp2)-(400C),	* RTemp2← VA of page to do
		Branch[GermRemapDone, ALU=0];
	T← RTemp1← (RTemp1)-1;		* T← last mapped virtual page
	Call[SetBRAndFlushPage];
	RTemp0← A0, Call[ReadMapPage];
	RTemp3← T,			* Old contents of that map entry
		DispTable[1, 1, 1];	* Always return here from ReadMapPage
	T← 60000C, Call[WriteMapPage];	* Make it vacant
	T← RSH[RTemp2, 10];		* T← Germ page number to do
	T← T+(LShift[PilotMDSHi!, 10]C); * T← that page # in MDS 76
	Call[SetBRAndFlushPage];	* Actually, don't need to flush
	T← RTemp3, Call[WriteMapPage];	* Put stolen page into the map
GermRemapLpE:
	PD← (RTemp2)-(baseGerm), Branch[GermRemapLp]; * See if done all pages

* At this point, LPtr points to the base of where the Germ will go in MDS 76.
* Q still has the VA of the first page after where the Germ is now in MDS 0.
GermRemapDone:
	RTemp2← Q;
	T← (RTemp2)-(baseGerm);

* Not the world's fastest BLT loop, but who cares?
	RTemp2← (RTemp2)-1, MemBase← IOBR;
	Fetch← RTemp2;
	T← T-1, MemBase← LPtr;
	Store← T, DBuf← MD, Branch[.-3, ALU#0];

	Branch[MGo];			* Go start it up!