:TITLE[LoadRAM]; % Edit by Fiala 5 February 1982: Bummed 10b mi and improved speed 15 percent; use yBuf-yBuf1 instead of xBuf-xBuf3 and xfTemp to overwrite less of Initialize's device table during CSLKeyboard overlay load; make ExchStkP and SetStkP available as subroutines; fix bugs that caused FFault to be left even when starting the code and odd when restarting the emulator, irrespective of whether LoadRAM is called by Mesa or Alto. Edit by Johnsson, January 28, 1980 12:14 PM NOTES: 1) The exit conditional which allows either a specified starting address, a jump to the Alto emulator, or a jump to the Mesa emulator is unnecessary and non-useful. Instead, simply eliminate the last 7 locations of RamLoaded and IMReserve 2 locations there which the overlay can overwrite with a LoadPage and a GoTo. Current uses all specify the starting address anyway (?), and it is painful to have to put these octal numbers in .MLF files; it would be far easier to assemble code that jumps to the starting addresses into the overlays directly. % %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[Bad.value.for.LRJStart]], Set[LRJStart,300]]; IDF[LRJContinue,IFE[LRJContinue,301,,ER[Bad.value.for.LRJContinue]]]; IDF[LRJGo,IFE[LRJGo,302,,ER[Bad.value.for.LRJGo]],Set[LRJGo,302]]; IDF[ExchStkPLoc,IFE[ExchStkPLoc,330,,ER[Bad.value.for.ExchStkPLoc]], Set[ExchStkPLoc,330]]; IDF[SetStkPLoc,IFE[SetStkPLoc,331,,ER[Bad.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. If the starting address includes a task number .ne. 0, that task will be given control by a Call, so that when that task blocks, LoadRAM will continue and resume the emulator correctly. If the starting address is an emulator program, however, it can return to LoadRAM to resume the emulator only if RTemp and RTemp1 are still valid because StkP will be again restored from RTemp and RTemp1 is checked to decide whether to resume the Alto or Mesa emulators. Entry conditions (at LRJBegin): FFault even to crash on MC1 or stack errors which are illegal during execution of LoadRAM. LP/LPhi base register pointing at array in MakeLoaderFile form xfTemp1 even (must be 20*n) for inline refresh without tasking odd for normal tasking RTemp1 even iff starting address is to be believed RTemp1 .ls. 0 to leave FFault even and resume Alto; .ge. 0 to leave FFault odd and resume Mesa. Reentry conditions to load next overlay (also at LRJBegin): LP,,LPhi untouched xfTemp1, RTemp1, FFault as above Smashes yBuf, yBuf1, and yBuf2 (= RTemp). For compatibility with old LoadRAM, alternate entries at LRJEnter are also provided. At LRJEnter LP/LPhi points at array-1 rather than array; at LRJEnter+1 (the reentry location), LP + xfTemp points at the next mi. Until the overlay skipping code in Pilot, AMesa, etc. is fixed to count in LP/LPhi rather than in xfTemp, this compatibility vestige will be needed. Timing ~ 45 cycles/mi + [38 cycles if overlay started else 41 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_]; %These mi are for compatibility with old LoadRAM, which has a reentry address at LRJStart+1 with the first word at LP+1 and the next word at xfTemp+LP--this new LoadRAM does not use xfTemp and has the start and continue addresses both at LRJBegin; as soon as a microcode system has been reassembled with both the continue and starting addresses equal to LRJGo and has had all dependencies on xfTemp removed, it need not IMReserve these locations. % LRJEnter: T _ xfTemp _ 1C, Skip, At[LRJStart]; T _ xfTemp, At[LRJContinue]; LP _ (LP) + T, At[LRJStart,36]; xfTemp _ 0C, Skip[Carry'], At[LRJStart,37]; LPhi _ (LPhi) + (400C) + 1, At[LRJStart,35]; Nop, At[LRJStart,34]; *This is the new starting address LRJBegin: PFetch1[LP,yBuf,0], At[LRJGo]; PFetch1[LP,yBuf1,1], At[LRJGo,1]; PFetch1[LP,yBuf2,2], At[LRJGo,2]; LP _ (LP) + (3C), Call[LRJ1], At[LRJGo,3]; *LRJ1 returns here if tasking permitted, else jumps here. LRJ2: LU _ yBuf1, UseCTask, Call[LRJadr], At[LRJGo,4]; *Setup for WriteCS0&2 with T _ data bits 32:35; ALUA _ data bits 0:15; *and APCTask&APC _ address. WriteCS0&2, At[LRJGo,5]; LU _ yBuf2, UseCTask, Call[LRJadr], At[LRJGo,6]; *Setup for WriteCS1 with ALUA _ data bits 16:31; APCTask&APC _ address. WriteCS1, GoTo[LRJBegin], At[LRJGo,7]; LRJ1: T _ (yBuf) + (20C), Skip[Carry'], At[LRJGo,10]; LPhi _ (LPhi) + (400C) + 1, GoTo[.-1], At[LRJGo,13]; yBuf _ RSh[yBuf,4], GoTo[RamLoaded,Carry], At[LRJGo,12]; xfTemp1 _ (xfTemp1) + (20C), Skip[R Odd], At[LRJGo,14]; Refresh[xfTemp1], GoTo[LRJ2], At[LRJGo,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 calls here from LRJ2 and LRJ2+2. *Other emulator routes to this mi are unaffected. LRJadr: LU _ LRJAPCTask&APC _ yBuf, Return, At[LRJGo,21]; RamLoaded: RTemp _ IP[FFault]C, Call[ExchStkP], At[LRJGo,15]; RTemp1, Skip[R<0], At[LRJGo,16]; *Setting FFault odd causes MC1 and Stack errors to be handled by notifying *the emulator rather than by crashing--required for Mesa, bad idea for Alto. Stack _ (Stack) or (1C), At[LRJGo,22]; LU _ RTemp1, Skip[R Odd], At[LRJGo,23]; *Odd if no jump *Note that any task can be started. LU _ APCTask&APC _ yBuf1, Call[SetStkP], At[LRJGo,24]; *Some started overlays may return here (NOTE that IP[RTemp] .eq. IP[yBuf2]). RTemp1, GoTo[.+3,R>=0], At[LRJGo,25]; T _ PCB, LoadPageExternal[nePage], At[LRJGo,27]; StkP _ RTemp, GoToExternal[JmpFinLoc], At[LRJGo,17]; LoadPageExternal[opPage3], At[LRJGo,26]; StkP _ RTemp, GoToExternal[P7TailLoc], At[LRJGo,11]; *Useful subroutines ExchStkP: T _ (SStkP&NStkP) xor (377C), At[ExchStkPLoc]; SetStkP: StkP _ RTemp, RTemp _ T, NoRegILockOK, Return, At[SetStkPLoc]; :END[LoadRam]; (2048)\f5