:TITLE[LoadRAM]; *Edit by Fiala, 25 November 1980 *Edit by Johnsson, January 28, 1980 12:14 PM %This code will load control store with mi 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 RTemp1 is <0 if resume Alto emulator, >=0 if resume Mesa 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 RTemp1 is <0 if resume Alto emulator, >=0 if resume Mesa % OnPage[LRJpage]; LRJenter: xfTemp ← 1C, At[LRJStart,0]; *following location is the place to restart for overlays T ← xfTemp, At[LRJContinue]; *wait for xfTemp write 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]) + 1, 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]; APCTask&APC ← xBuf3, At[LRJStart,20]; WriteCS0&2, At[LRJStart,21]; LU ← xBuf1, At[LRJStart,22]; APCTask&APC ← 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 ← (SStkP&NStkP) xor (377C), At[LRJStart,31]; RTemp ← IP[FFault]C, At[LRJStart, 27]; StkP ← RTemp, RTemp ← T, NoRegILockOK, At[LRJStart,32]; Stack ← (Stack) or (1C), At[LRJStart,33]; RTemp1, Goto[.+3,R>=0], At[LRJStart,37]; T ← PCB, LoadPageExternal[nePage], At[LRJStart,35]; *For LRJStart on page 0, there are no free 42b-word blocks, so we use the *single available 40b-word block below TimerTable and two unused mi in *TimerTable, which is why there is a gap between 37b and 70b in the *assignments (ugh). GotoExternal[JmpFinLoc], At[LRJStart,70]; LoadPageExternal[opPage3], At[LRJStart,34]; StkP ← RTemp, GotoExternal[P7TailLoc], At[LRJStart,71]; 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];