*-----------------------------------------------------------
Title[LoadRam.mc...June 19, 1982 12:31 PM...Taft];
* Loads microcode from main memory and starts it
*-----------------------------------------------------------
% *--------------------------------------------------------------------
LoadRam loads microcode from an array of "Items" in main memory:
Item: TYPE = MACHINE DEPENDENT RECORD [
extraIM: [0..17B], zero: [0..1] ← 0, unused: [0..377B], type: ItemType,
addr: WORD,
word0: WORD,
word1: WORD];
ItemType: TYPE = MACHINE DEPENDENT {IM (0), IFUM (1), End (2), RM (3)};
The array consists of any number of non-End Items followed by an End Item.
Interpretation of Items:
IM: word0: RSTK[1:3] ,, ALUF[0:3] ,, BSEL[0:2] ,, LC[0:2] ,, ASEL[0:2]
word1: FF[0:7] ,, JCN[0:7]
extraIM: LHparityBad ,, RSTK[0] ,, RHparityBad ,, BLOCK
Note: the Item is ignored if addr selects LoadRamPage [7600..7677].
IFUM: word0: PackedAlpha ,, IFaddr'[0:9]
word1: Sign ,, IPar[0:2] ,, Length'[0:1] ,, RBaseB' ,, MemB[0:2] ,,
TPause' ,, TJump' ,, N[0:3]
RM: word0: RM value
Note: it is illegal for addr to select registers used by LoadRam
(LRFlag, LRItem, LRTemp0, LRTemp1, or LRTemp2).
This is NOT checked -- LoadRam will malfunction if this rule is violated.
End: word0: checksum
word1: start address
LoadRam entry conditions:
Currently selected BR contains long pointer to first Item
LRFlag[15] = 0 to load Ram with tasking off and jump to start
address given in End item (complete microcode replacement).
= 1 to leave tasking on and return at end of loading
rather than using start address (microcode overlay).
RBase = RBase[LRFlag]
Exit conditions:
LRItem points to word after last Item loaded (the End Item)
LRFlag, LRTemp0, LRTemp1, LRTemp2, T, Q clobbered
IFU reset
TaskingOff if it goes to start address, TaskingOn if it returns
Note: the PreFetch←s in this code are not essential. They speed things up,
and they cost no space because they are combined with other operations.
% *--------------------------------------------------------------------
Set[XTask, IP[EMU]];
TopLevel;
OnPage[LoadRamPage]; * All other assemblies avoid this page
Set[LoadRamLoc, LShift[LoadRamPage, 6]];
KnowRBase[LRFlag];
* RBase-relative definitions for RM registers
RVRel[RX0, 0]; RVRel[RX1, 1]; RVRel[RX2, 2]; RVRel[RX3, 3];
RVRel[RX4, 4]; RVRel[RX5, 5]; RVRel[RX6, 6]; RVRel[RX7, 7];
RVRel[RX10, 10]; RVRel[RX11, 11]; RVRel[RX12, 12]; RVRel[RX13, 13];
RVRel[RX14, 14]; RVRel[RX15, 15]; RVRel[RX16, 16]; RVRel[RX17, 17];
*-----------------------------------------------------------
LoadRam: At[LoadRamLoc], * Global entry point
*-----------------------------------------------------------
LRTemp2← Link;
LRItem← A0, IFUReset, Branch[.+2]; * Init memory addr (LPTR-relative)
* Top of loop in TaskingOn case.
* The IM and IFUM loads require TaskingOff, so here we turn TaskingOn
* briefly to allow I/O tasks to run.
LRLoopTOn:
TaskingOn;
* Top of loop in TaskingOff case.
LRLoopTOff:
T← (Fetch← LRItem)+1;
T← (Fetch← T)+1, LRTemp0← MD, Q← MD, * LRTemp0← Item type (and extraIM)
Call[TOffRet]; * TaskingOff
T← (Fetch← T)+1, LRTemp1← MD, * LRTemp1← addr
BDispatch← Q; * Dispatch on Item type
LRItem← (Fetch← T)+1, Q← MD; * Q← word0, MD← word1
* This table contains the first instruction of each case.
* These instructions are duplicated as comments in the body of each case's code.
LRTypeTable: DispTable[4];
T← LDF[LRTemp1, 10, 6], Branch[LRTypeIM];
T← (LRTemp1) OR (100000C), Branch[LRTypeIFUM];
LRFlag, Link← MD, BRGO@[0] RETCL@[2] JCN[45]; * LRTypeEnd (see code there!)
T← RSH[LRTemp1, 4], Branch[LRTypeRM];
*--------------------------------------------------------------------
* Item type = IM
*--------------------------------------------------------------------
LRTypeIM:
* ↑↑↑ T← LDF[LRTemp1, 10, 6]; * Extract page part of addr
PD← T-(Add[LoadRamPage]C);
LRTemp0← RSH[LRTemp0, 13], T← MD, * LRTemp0← extraIM lsh 1, T← word1
Branch[LRNoPrefNext, ALU=0]; * Branch if would overwrite LoadRam
BDispatch← LRTemp0; * Dispatch on RHparity,,BLOCK,,0
Link← LRTemp1; * Link← addr
IMRHTable: DispTable[10];
IMRHB'POK← T; * RHparity=0, BLOCK=0
T← RSH[LRTemp0, 2], Branch[LoadIMLH]; * T← extraIM rsh 1
IMRHBPOK← T; * RHparity=0, BLOCK=1
T← RSH[LRTemp0, 2], Branch[LoadIMLH];
IMRHB'PBad← T; * RHparity=1, BLOCK=0
T← RSH[LRTemp0, 2], Branch[LoadIMLH];
IMRHBPBad← T; * RHparity=1, BLOCK=1
T← RSH[LRTemp0, 2], Branch[LoadIMLH];
LoadIMLH:
T← LRItem, BDispatch← T; * Dispatch on LHparity,,RSTK[0],,?
Link← LRTemp1; * Link← addr
IMLHTable: DispTable[10, 17, 1];
T← A← T, Carry20, IMLHR0'POK← Q; * LHparity=0, RSTK[0]=0
PreFetch← T, LRFlag, DblBranch[LRLoopTOn, LRLoopTOff, R odd];
T← A← T, Carry20, IMLHR0POK← Q; * LHparity=0, RSTK[0]=0
PreFetch← T, LRFlag, DblBranch[LRLoopTOn, LRLoopTOff, R odd];
T← A← T, Carry20, IMLHR0'PBad← Q; * LHparity=0, RSTK[0]=0
PreFetch← T, LRFlag, DblBranch[LRLoopTOn, LRLoopTOff, R odd];
T← A← T, Carry20, IMLHR0PBad← Q; * LHparity=0, RSTK[0]=0
LRPrefNext: * Tail of IFUM and RM cases also
PreFetch← T, B← MD; * Fall thru for sake of LRTypeIFUM case
* Here if IM word would overwrite LoadRam. Just skip over it.
LRNoPrefNext:
IFUReset, LRFlag, DblBranch[LRLoopTOn, LRLoopTOff, R odd];
*--------------------------------------------------------------------
* Item type = IFUM
*--------------------------------------------------------------------
LRTypeIFUM:
* ↑↑↑ T← (LRTemp1) OR (100000C); * Flag to load InsSet
InsSetOrEvent← T; * Load InsSet from addr[6:7]
T← LSH[LRTemp1, 10], LRTemp1← MD; * BrkIns loads from B[0:7]
BrkIns← T, Call[TOffRet]; * Load BrkIns from addr[8:15], delay 1 cycle
IFUMLH← Q; * Load LH from word0 & let it settle
T← A← LRItem, Carry20, B← Q;
IFUMRH← LRTemp1, Branch[LRPrefNext]; * Load RH from word1 & let it settle
*--------------------------------------------------------------------
* Item type = RM
*--------------------------------------------------------------------
LRTypeRM:
* ↑↑↑ T← RSH[LRTemp1, 4]; * T[12:15] ← addr[8:11]; puts
* cycled unmasked result thru ALU
BDispatch← LRTemp1, * Dispatch on addr[13:15]
DblBranch[LowRM, HighRM, ALU>=0]; * Branch on addr[12]
* Registers 0 through 7 in bank
LowRM: T← (LRItem)+(RBase← T)+1; * Select bank; T← advanced Item addr
DispTable[10];
RX0← Q, RBase← RBase[LRFlag], Branch[LRPrefNext];
RX1← Q, RBase← RBase[LRFlag], Branch[LRPrefNext];
RX2← Q, RBase← RBase[LRFlag], Branch[LRPrefNext];
RX3← Q, RBase← RBase[LRFlag], Branch[LRPrefNext];
RX4← Q, RBase← RBase[LRFlag], Branch[LRPrefNext];
RX5← Q, RBase← RBase[LRFlag], Branch[LRPrefNext];
RX6← Q, RBase← RBase[LRFlag], Branch[LRPrefNext];
RX7← Q, RBase← RBase[LRFlag], Branch[LRPrefNext];
* Registers 10 through 17 in bank
HighRM: T← (LRItem)+(RBase← T)+1; * Select bank; T← advanced Item addr
DispTable[10];
RX10← Q, RBase← RBase[LRFlag], Branch[LRPrefNext];
RX11← Q, RBase← RBase[LRFlag], Branch[LRPrefNext];
RX12← Q, RBase← RBase[LRFlag], Branch[LRPrefNext];
RX13← Q, RBase← RBase[LRFlag], Branch[LRPrefNext];
RX14← Q, RBase← RBase[LRFlag], Branch[LRPrefNext];
RX15← Q, RBase← RBase[LRFlag], Branch[LRPrefNext];
RX16← Q, RBase← RBase[LRFlag], Branch[LRPrefNext];
RX17← Q, RBase← RBase[LRFlag], Branch[LRPrefNext];
*--------------------------------------------------------------------
* Item type = End
*--------------------------------------------------------------------
LRTypeEnd:
* ↑↑↑ LRFlag, Link← MD, * Link← word1
* ↑↑↑ Branch[.+2, R odd]; * Which way to exit?
* ↑↑↑ BRGO@[0] RETCL@[2] JCN[45]; * MicroD can't place this, but I can!
Subroutine;
TOffRet:
TaskingOff, Return, * Jump to addr given in word1
At[LoadRamLoc, 20];
TopLevel;
Link← LRTemp2, * Return to caller
At[LoadRamLoc, 21];
Subroutine;
TaskingOn, Return;
TopLevel;
* Fill out rest of page, to make it unavailable to other programs
* loaded with LoadRam.
Repeat[Sub[100, IP[ILC]], ILC[(Branch[.], Breakpoint)]];