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