% File: LoadRam.mc

Edit by Jim Frandeen, March 11, 1980  11:05 AM, fix refresh
Edit by Johnsson, January 28, 1980  12:14 PM
%


TITLE[LoadRam];

%
This code will load control store with instructions taken from an array
of items in the form:
	word 0	(addr lsh 4) or (cs bits 32d-35d)
	word 1	cs bits 0-15d
	word 2	bits 16d-31d
The last item has addr=7777b.  In the last item word 1 is the start address
of the code just loaded and word 2 is a checksum.  The checksum should be
checked by other software since detection of errors after loading the control
store is of marginal interest.  The code below does not check checksums.

Memory refresh may be done inline by LRJ without tasking.

Entry conditions (AT[LRJStart]):
	LP,,LPhi has base pointer to array in MakeLoaderFile form
	xfTemp1 = 0 for inline refresh without tasks
		= 1 for normal tasking
	RTEMP1 is even iff start address is to be believed

To continue loading after a jump (overlay), jump to LRJContinue.

Reentry conditions (AT[LRJContinue]):
	LP,,LPhi untouched
	xfTemp untouched
	xfTemp1 untouched or as above
	RTEMP1 is even iff start address is to be believed
%
 
		OnPage[LRJpage];

LRJenter:
	xfTemp ← 1c, AT[LRJStart, 0];
* following location is the place to restart for overlays
	T ← xfTemp, AT[LRJContinue];	* wait for write of xfTemp to avoid bypass problem
LRJloop:
	pfetch1[LP,xBuf2],call[LRJIncCount], AT[LRJStart, 2];
	pfetch1[LP,xBuf],call[LRJIncCount], AT[LRJStart, 3];
	pfetch1[LP,xBuf1],call[LRJIncCount], AT[LRJStart, 4];
	lu ← (ldf[xfTemp1,14,3]), goto[DoTask, R Odd], AT[LRJStart,5];
	xfTemp1 ← (xfTemp1) + (2c), skip[alu#0], AT[LRJStart,10];
	  REFRESH[xfTemp1, 0], AT[LRJStart,6];
	T ← ldf[xBuf2,0,14], AT[LRJStart, 7];	* address
	xBuf3 ← T, AT[LRJStart, 13];
LRJloopx:
	lu ← (xBuf3) XNOR (170000c), AT[LRJStart, 14]; *look for m-i address = 7777
	T ← xBuf2, goto[RamLoaded,alu=0], AT[LRJStart, 15];
	LU ← xBuf, AT[LRJStart, 17];
	APC&APCTASK ← xBuf3, AT[LRJStart, 20];
	WRITECS0&2, AT[LRJStart, 21];
	LU ← xBuf1, AT[LRJStart, 22];
	APC&APCTASK ← xBuf3, AT[LRJStart, 23];
	WRITECS1, AT[LRJStart, 24];
	T ← xfTemp, goto[LRJloop], AT[LRJStart, 25];

LRJIncCount:
	T ← xfTemp ← (xfTemp) + 1, UseCTask, goto[LRJRet], AT[LRJStart, 26];

RamLoaded:
	RTEMP1, skip[R Odd], AT[LRJStart, 16];	* odd if no jump
	  APCTASK&APC ← (xBuf1), call[LRJRet], AT[LRJStart, 30];	* set TPC for return
	T ← (GetRSpec[103]) xor (377c), AT[LRJStart, 31];
	RTEMP ← FFaultAdd, AT[LRJStart, 27];
	Stkp ← RTEMP, RTEMP ← T, NoRegILockOK, AT[LRJStart, 32];
	Stack ← (Stack) or (1c), AT[LRJStart, 33];
	LoadPageExternal[7], AT[LRJStart, 34];
	Stkp ← RTEMP, GoToExternal[P7TailLoc], AT[LRJStart, 35];

LRJRet:
	RETURN, AT[LRJStart, 36];

DoTask:	T ← ldf[xBuf2,0,14], call[LRJRet], AT[LRJStart, 11];
	xBuf3 ← T, goto[LRJloopx], AT[LRJStart, 12];

	:END[LoadRam];