*----------------------------------------------------------- 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)]];