*-----------------------------------------------------------
Title[PilotLeftovers.mc...June 29, 1982  1:57 PM...Taft];
* Pilot-related stuff that doesn't seem to belong anywhere else.
* A lot of this originally came from the Alto emulator.
*-----------------------------------------------------------

TopLevel;

% *-----------------------------------------------------------
The microcode is started in one of the following ways:
1. Loaded by Midas and started at InitMap.
2. Self-restarted at Boot by display task in response to 1-push boot.
3. Restarted by BaseBoard at InitMap in response to 2-push boot.
4. Boot-loaded by BaseBoard/Initial and started at BootOrStart.
5. Loaded by software (RunPilot, MesaNetExec) and started at BootOrStart.

In cases 1-4, we want to go through the full memory system initialization
and Germ bootstrap sequence.  In case 5, software has already set up
memory with the appropriate stuff (presumably some flavor of Germ), and
we do NOT want to disturb it.  The problem is to distinguish cases 4 and 5,
since they both enter at BootOrStart.  (This is a consequence of having only
one .eb file for both purposes, and thus only one public starting address.)

We handle this by the following kludge: if page 37002 (the first page
of the Germ) is already mapped then case 5 is assumed; otherwise case 4.
% *-----------------------------------------------------------

*-----------------------------------------------------------
* Display task branches here on a 1-push boot (case 2).
*-----------------------------------------------------------
Set[XTask, IP[DHT]];
DontKnowRBase;

Boot:	Call[TasksOff];
	Call[EmuInitPC];
	LdTPC← T, TaskingOn;
	Block;
* should never awaken again, since we did an I/O Reset.
	Breakpoint, Branch[.];

Subroutine;
EmuInitPC:
	T← EMU, CoReturn;		* Return EMU start PC
TopLevel;
	Branch[InitMap];

*-----------------------------------------------------------
* .eb-format microcode image is started here (cases 4 and 5).
*-----------------------------------------------------------
Set[XTask, IP[EMU]];

BootOrStart: At[BootOrStartLoc],
	RBase← RBase[RTemp0];
	Call[TasksOff];
	T← 37000C;
	T← T OR (2C);
	Call[SetBRForPage];		* Read Map[37002B]
	RMap← RTemp0, SCall[TranslateMapEntry];
	 Branch[InitMap];		* +1: vacant, do full map/mem init
	T← T-T-1, Branch[.+2];		* +2: not vacant, fall through

*-----------------------------------------------------------
* InitMap returns here when done.
*-----------------------------------------------------------
StartEmulator:
	T← A0;				* Full initialization
	RBase← RBase[AEmRegs];
	ETemp4← T, TaskingOff;
	R400← 400C, Call[SetupBRs];	* returns with MemBase set up
	T← A0, NoReschedule;
	InsSetOrEvent← T;		* Disable event counters
	MaintPanel← A0, IFUReset;
	Call[RestoreALUFM];		* Restore ALUFM variables

* make sure keys are all 1's -- core image does not contain page 376b
	T← (R400) XOR (177433C);
	ETemp1← T-T-1, Cnt← 6S;		* Initialize 177033B..177041B
	T← (Store← T)+1, DBuf← ETemp1, Branch[., Cnt#0&-1];

*-----------------------------------------------------------
* Task initialization routines all work according to the following pattern:
* XXXInitPC:
*	T← XXX, CoReturn;		* T← task number
*	first instruction of task initialization;
* Thus, calling XXXInitPC loads Link with the PC of the first instruction
* of the init routine and T with the task number.  These are precisely
* the arguments needed to do a LdTPC!
* Note: leave FF free in calls to the XXXInitPC routines.
* ETemp4 = 0 if booting, -1 if restarting emulator.
*-----------------------------------------------------------

InitTasks:
* First, init all non-emulator task PCs to -1.  ETemp1 = -1 here.
	ETemp0← 17C;
	Link← ETemp1;
	ETemp0← (ETemp0)-1, LdTPC← ETemp0;
	Branch[.-2, ALU#0];

* Now init specific task PCs
	Call[JNKInitPC];
	LdTPC← T, Wakeup[JNK];

	Call[EOTInitPC];
	LdTPC← T, Wakeup[EOT];

	Call[EITInitPC];
	LdTPC← T, Wakeup[EIT];

	Call[DSKInitPC];
	LdTPC← T, Wakeup[DSK];

	Call[FLTInitPC];
	LdTPC← T, Wakeup[FLT];

	Call[AUTInitPC];
	LdTPC← T, Wakeup[AUT];

* Display task initialization is slightly complicated, because the tasks
* must be set up according to whether the Alto terminal is hooked to the
* DispY board or the DispM board.
* DisplayInitConfig figures out what the configuration is, and sets a flag.
* Next, DHTInitPC and DWTInitPC return the starting PCs and task numbers
* for special (non-Alto terminal) microcode that may be present, or for
* dummy microcode in DisplayMain otherwise.
* Finally, THTInitPC and TWTInitPC return the starting PCs and task numbers
* for the Alto terminal microcode; the task numbers will be either AHT/AWT
* or DHT/DWT, depending on whether or not the DispM board is installed.
* If no DispM board is installed, this initialization will override the
* earlier DHT/DWT task initialization.
* Note: THTInitPC handles its own wakeup, since there's no way to
* issue Wakeup to a task given as a variable.

	IFUReset;			* Here to break consecutive .+1 constraints
	Call[DisplayInitConfig];
KnowRBase[TWTRegion];

	Call[DHTInitPC];		* For special display microcode
	LdTPC← T, Wakeup[DHT];
	Call[DWTInitPC];
	LdTPC← T;

	Call[THTInitPC];		* For Alto terminal microcode
	LdTPC← T;
	Call[TWTInitPC];
	LdTPC← T, RBase← RBase[AEmRegs];
	ETemp4, TaskingOn, Branch[.+2, R<0]; * Want to boot?
	Branch[GermBoot];		* Yes, go boot the Germ
	Branch[MGo];			* No, just start the Mesa emulator

*-----------------------------------------------------------
SetupBRs:
* Initialize all Base Registers.
* Clobbers T and ETemp.
*-----------------------------------------------------------
Subroutine;

	T← LShift[37, 10]C;		* MemBase addressed from A[3:7]
DoBRs:	ETemp← A0, MemBase← T;		* Init all registers to {0, 0}
	BRHi← ETemp;
	T← T-(400C);
	BRLo← ETemp, Branch[DoBRs, ALU>=0];
	MemBase← IOBR, Return;		* return with correct MemBase

*-----------------------------------------------------------
TasksOff:
* Reset all I/O devices.
* This is now accomplished simply by issuing an IOReset.
* IOReset is controlled by the manifold register addressed by 2240-2257,
* which has the following things in it (DMAdr[0:11]):
*	Bit 8:	EclUp		(normally 1)
*	Bit 9:	EnableRfPd'	(normally 0)
*	Bit 10:	IOReset'	(normally 1)
*	Bit 11:	RunRfsh		(normally 1)
* Returns with TaskingOff, RBase=AEmRegs.
*-----------------------------------------------------------
Subroutine;

	TaskingOff;
	T← A0, RBase← RBase[ETemp4];
	ETemp4← Link;
TopLevel;
	TIOA← T;			* Don't address any IO register
	ETemp1← 2000C;
	T← (ETemp1) OR (251C), Call[SetDMuxAddress]; * IOReset' ← 0
	UseDMD;
	T← (ETemp1) OR (253C), Call[SetDMuxAddress]; * IOReset' ← 1
Subroutine;
	Link← ETemp4;
	UseDMD, Return;

*-----------------------------------------------------------
RestoreALUFM:
* Restores the ALUFM variables to their standard values.
* Clobbers T
*-----------------------------------------------------------
Subroutine;

	T← AFM15;
	ALUFMRW← T, ALUF[15];
	T← AFM17;
	ALUFMRW← T, ALUF[17], Return;

*-----------------------------------------------------------
* some locations for doing code patching
* make sure FF is not used for LONGGO
*-----------------------------------------------------------
LX0:	TaskingOn;
	TaskingOn, PD← T;
	TaskingOn, Branch[.+2, ALU=0];
	TaskingOn;
	TaskingOn, PD← T;
	TaskingOn, Branch[.+2, ALU#0];
	TaskingOn;
LX7:	TaskingOn, Branch[LX0];

TopLevel;