:TITLE[LoadRAM]; % Edit by Fiala 25 March 1981: Bummed 10b mi and improved speed 20 percent; changed FFault value for Alto mode exit; use yBuf-yBuf1 instead of xBuf-xBuf3 to overwrite less of Initialize's device table during CSLKeyboard overlay load; make ExchStkP and SetStkP available as subroutines. Edit by Johnsson, January 28, 1980 12:14 PM % %Verify consistency of parameters among all implementations; only Initial should contain this file directly--other programs should use LoadRAMOccupied. GlobalDefs will normally define all entry locations. % IDF[LRJStart,IFE[LRJStart,300,,ER[Incompatible.value.for.LRJStart]], Set[LRJStart,300]]; IDF[LRJContinue,IFE[LRJContinue,300,,ER[Incompatible.value.for.LRJContinue]]]; IDF[ExchStkPLoc,IFE[ExchStkPLoc,330,,ER[Incompatible.value.for.ExchStkPLoc]], Set[ExchStkPLoc,330]]; IDF[SetStkPLoc,IFE[SetStkPLoc,331,,ER[Incompatible.value.for.SetStkPLoc]], Set[SetStkPLoc,331]]; %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. Entry conditions (at LRJenter): FFault even to crash on MC1 or stack errors LP,,LPhi has base pointer to array-1 in MakeLoaderFile form. xfTemp1 = 0 for inline refresh without tasking = 1 for normal tasking RTemp1 is even iff start address is to be believed RTemp1 < 0 if resume Alto emulator, >=0 if resume Mesa Reentry conditions to load next overlay (also at LRJenter): LP,,LPhi untouched xfTemp1 and RTemp1 as above Smashes yBuf, yBuf1, and yBuf2 (= RTemp). Timing ~ 40 cycles/mi + [28 cycles if overlay started else 38 or 39 cycles] + 4 cycles/mi for inline refresh. Fastest possible loop would be about 26 cycles/mi with lots more code and RM registers. % *To avoid "APCTask&APC_ illegal with return" error message... Macro[LRJAPCTask&APC_,FF1@[7] FF2@[10] A_]; LRJenter: LU _ LP, GoTo[.+3,R Odd], At[LRJStart]; PFetch1[LP,yBuf,1], At[LRJStart,2]; PFetch2[LP,yBuf1,2], OddOK, GoTo[.+3], At[LRJStart,1]; PFetch2[LP,yBuf,1], At[LRJStart,3]; PFetch1[LP,yBuf2,3], At[LRJStart,4]; LP _ (LP) + (3C), Call[LRJ1], At[LRJStart,5]; *LRJ1 returns here if tasking permitted, else jumps here. LRJ2: LU _ yBuf1, UseCTask, Call[LRJadr], At[LRJStart,6]; WriteCS0&2, LU _ yBuf2, At[LRJStart,7]; APCTask&APC _ yBuf1, At[LRJStart,10]; WriteCS1, GoTo[LRJenter], At[LRJStart,11]; LRJ1: T _ (yBuf) + (20C), Skip[Carry'], At[LRJStart,12]; LPhi _ (LPhi) + (400C) + 1, GoTo[.-1], At[LRJStart,15]; yBuf _ Rsh[yBuf,4], GoTo[RamLoaded,Carry], At[LRJStart,14]; xfTemp1 _ (xfTemp1) + (20C), Skip[R Odd], At[LRJStart,16]; Refresh[xfTemp1], GoTo[LRJ2], At[LRJStart,20]; *It is ok to do APCTask&APC_ with Return here because, if an io task runs *next, it is not permitted to task (i.e., to have a Return) in its 1st mi; *the emulator needs the APCTask&APC_ for the call here from LRJ2--other *emulator routes to this mi are unaffected. LRJadr: LRJAPCTask&APC _ yBuf1, Return, At[LRJStart,21]; RamLoaded: RTemp1, Skip[R Odd], At[LRJStart,17]; *odd if no jump *Note that any task can be started. LU _ APCTask&APC _ yBuf1, Call[LRJadr], At[LRJStart,22]; *Some started overlays may return here (NOTE that IP[RTemp] .eq. IP[yBuf2]). RTemp _ IP[FFault]C, Call[ExchStkP], At[LRJStart,23]; RTemp1, T _ 1C, NoRegILockOK, GoTo[.+3,R>=0], At[LRJStart,24]; T _ PCB, LoadPageExternal[nePage], At[LRJStart,27]; GoToExternal[JmpFinLoc], At[LRJStart,13]; *Setting FFault odd causes MC1 and Stack errors to be handled by notifying *the emulator rather than by crashing. Stack _ (Stack) or T, LoadPageExternal[opPage3], At[LRJStart,26]; StkP _ RTemp, GoToExternal[P7TailLoc], At[LRJStart,25]; *Useful subroutines ExchStkP: T _ (SStkP&NStkP) xor (377C), At[ExchStkPLoc]; SetStkP: StkP _ RTemp, RTemp _ T, NoRegILockOK, Return, At[SetStkPLoc]; :END[LoadRam];