*----------------------------------------------------------- Title[Assign.mc...November 23, 1982 5:26 PM...Taft]; * Assignment instructions (PrincOps, chapter 7) *----------------------------------------------------------- % CONTENTS, by order of occurence Immediate instructions LIN1 Load Immediate Negative One LINI Load Immediate Negative Infinity LID0 Load Immediate Double Zero LIn Load Immediate n LIB Load Immediate Byte LINB Load Immediate Negative Byte LIHB Load Immediate High Byte LIW Load Immediate Word Frame instructions LAn Local Address n LAB Local Address Byte LAW Local Address Word LLn Load Local n LLB Load Local Byte LGn Load Global n LGB Load Global Byte LLDn Load Local Double n LLDB Load Local Double Byte LGDn Load Global Double n LGDB Load Global Double Byte SLn Store Local n SLB Store Local Byte SGB Store Global Byte SLDn Store Local Double n SLDB Store Local Double Byte SGDB Store Global Double Byte PLn Put Local n PLB Put Local Byte PLD0 Put Local Double Zero PLDB Put Local Double Byte AL0IB Add Local Zero to Immediate Byte GA0 Global Address n GAB Global Address Byte GAW Global Address Word Pointer instructions Rn Read n RB Read Byte RL0 Read Long Zero RLB Read Long Byte RD0 Read Double Zero RDB Read Double Byte RDL0 Read Double Long Zero RDLB Read Double Long Byte RC Read Code W0 Write Zero WB Write Byte WLB Write Long Byte WDB Write Double Byte WDLB Write Double Long Byte PSB Put Swapped Byte PSD0 Put Swapped Double Zero PSDB Put Swapped Double Byte PSLB Put Swapped Long Byte PSDLB Put Swapped Double Long Byte Contents (cont'd) RIL0n Read Local Indirect Zero n RLIP Read Local Indirect Pair RGIP Read Global Indirect Pair RLILP Read Local Indirect Long Pair RGILP Read Global Indirect Long Pair RLDI00 Read Local Double Indirect Zero Zero RLDIP Read Local Double Indirect Pair RLDILP Read Local Double Indirect Long Pair WLIP Write Local Indirect Pair WLILP Write Local Indirect Long Pair WLDILP Write Local Double Indirect Long Pair String instructions RS Read String RSL Read String Long WS Write String WSL Write String Long Field instructions RF Read Field R0F Read Zero Field RLF Read Long Field RL0F Read Long Zero Field RLFS Read Long Field Stack RCFS Read Code Field Stack RLIPF Read Local Indirect Pair Field RLILPF Read Local Indirect Long Pair Field WF Write Field W0F Write Zero Field WLF Write Long Field WL0F Write Long Zero Field WLFS Write Long Field Stack WS0F Write Swapped Zero Field PSF Put Swapped Field PS0F Put Swapped Zero Field PSLF Put Swapped Long Field Frequently-used exit sequences ExitPushT Push T onto the stack and exit ExitPushMD Push MD onto the stack and exit ExitPushIDPlusT Push ID+T onto the stack and exit ExitReadStackT Fetch word from address T, push it onto the stack, and exit ExitStackMDReadStackT Put MD on stack and then push word fetched from T on stack ExitWriteStackT Store word from stack to address T, pop the stack, and exit ExitWriteDoubleStackT Write 2 words from stack to address T and exit ExitCheckFault Check for fault and exit Subroutines BRHiGetsStackPop Executes BRHi_ Stack&-1 BRLoGetsStack Executes BRLo_ Stack FetchGetsT Executes PD_ Fetch_ T % TopLevel; *-------------------------------------------------------------------- IFUR[LIN1, 1]; * Load Immediate Negative One * Push[177777B]; *-------------------------------------------------------------------- Stack+1_ T-T-1, NextOpcode; *-------------------------------------------------------------------- IFUR[LINI, 1]; * Load Immediate Negative Infinity * Push[100000B]; *-------------------------------------------------------------------- T_ 100000C, Branch[ExitPushT]; *-------------------------------------------------------------------- IFUR[LID0, 1]; * Load Immediate Double Zero * PushLong[LONG[0]]; *-------------------------------------------------------------------- Stack+1_ T_ A0, Branch[ExitPushT]; *-------------------------------------------------------------------- IFUR[LI0, 1, N[0]]; * Load Immediate n IFUR[LI1, 1, N[1]]; IFUR[LI2, 1, N[2]]; IFUR[LI3, 1, N[3]]; IFUR[LI4, 1, N[4]]; IFUR[LI5, 1, N[5]]; IFUR[LI6, 1, N[6]]; IFUR[LI7, 1, N[7]]; IFUR[LI8, 1, N[10]]; IFUR[LI9, 1, N[11]]; IFUR[LI10, 1, N[12]]; * Push[n]; IFUR[LIB, 2]; * Load Immediate Byte * Push[GetCodeByte[]]; *-------------------------------------------------------------------- Stack+1_ ID, NextOpcode; *-------------------------------------------------------------------- IFUR[LINB, 2]; * Load Immediate Negative Byte * Push[BytePair[377B, GetCodeByte[]]; *-------------------------------------------------------------------- T_ (ID) OR (177400C), Branch[ExitPushT]; *-------------------------------------------------------------------- IFUR[LIHB, 2]; * Load Immediate High Byte * Push[BytePair[GetCodeByte[], 0]; *-------------------------------------------------------------------- T_ ShiftRMask[RTemp0], RisID, Branch[ExitPushT]; * LSH[ID, 10] *-------------------------------------------------------------------- IFUR[LIW, 3]; * Load Immediate Word * Push[GetCodeWord[]]; *-------------------------------------------------------------------- T_ ShiftRMask[RTemp0], RisID, * LSH[ID, 10] Branch[ExitPushIDPlusT]; *-------------------------------------------------------------------- IFUR[LA0, 1, N[0]]; * Local Address n IFUR[LA1, 1, N[1]]; IFUR[LA2, 1, N[2]]; IFUR[LA3, 1, N[3]]; IFUR[LA6, 1, N[6]]; IFUR[LA8, 1, N[10]]; * Push[LF + n]; IFUR[LAB, 2]; * Local Address Byte * Push[LF + GetCodeByte[]]; *-------------------------------------------------------------------- T_ (ID)+(LFShadow), Branch[ExitPushT]; *-------------------------------------------------------------------- IFUR[LAW, 3]; * Local Address Word * Push[LF + GetCodeWord[]]; *-------------------------------------------------------------------- T_ ShiftRMask[RTemp0], RisID; * LSH[ID, 10] T_ (LFShadow)+T, Branch[ExitPushIDPlusT]; *-------------------------------------------------------------------- IFUR[LL0, 1, MemBase[LF], N[0]]; * Load Local n IFUR[LL1, 1, MemBase[LF], N[1]]; IFUR[LL2, 1, MemBase[LF], N[2]]; IFUR[LL3, 1, MemBase[LF], N[3]]; IFUR[LL4, 1, MemBase[LF], N[4]]; IFUR[LL5, 1, MemBase[LF], N[5]]; IFUR[LL6, 1, MemBase[LF], N[6]]; IFUR[LL7, 1, MemBase[LF], N[7]]; IFUR[LL8, 1, MemBase[LF], N[10]]; IFUR[LL9, 1, MemBase[LF], N[11]]; IFUR[LL10, 1, MemBase[LF], N[12]]; IFUR[LL11, 1, MemBase[LF], N[13]]; * Push[FetchMds[LF+n]^]; IFUR[LLB, 2, MemBase[LF]]; * Load Local Byte * Push[FetchMds[LF+GetCodeByte[]]^]; IFUR[LG0, 1, MemBase[GF], N[0]]; * Load Global n IFUR[LG1, 1, MemBase[GF], N[1]]; IFUR[LG2, 1, MemBase[GF], N[2]]; * Push[FetchMds[GF+n]^]; IFUR[LGB, 2, MemBase[GF]]; * Load Global Byte * Push[FetchMds[GF+GetCodeByte[]]^]; *-------------------------------------------------------------------- Fetch_ ID, Branch[ExitPushMD]; *-------------------------------------------------------------------- IFUR[LLD0, 1, MemBase[LF], N[0]]; * Load Local Double n IFUR[LLD1, 1, MemBase[LF], N[1]]; IFUR[LLD2, 1, MemBase[LF], N[2]]; IFUR[LLD3, 1, MemBase[LF], N[3]]; IFUR[LLD4, 1, MemBase[LF], N[4]]; IFUR[LLD5, 1, MemBase[LF], N[5]]; IFUR[LLD6, 1, MemBase[LF], N[6]]; IFUR[LLD7, 1, MemBase[LF], N[7]]; IFUR[LLD8, 1, MemBase[LF], N[10]]; IFUR[LLD10, 1, MemBase[LF], N[12]]; * Push[FetchMds[LF+n]^]; Push[FetchMds[LF+n+1]^]; IFUR[LLDB, 2, MemBase[LF]]; * Load Local Double Byte * alpha: BYTE _ GetCodeByte[]; * Push[FetchMds[LF+alpha]^]; Push[FetchMds[LF+alpha+1]^]; IFUR[LGD0, 1, MemBase[GF], N[0]]; * Load Global Double n IFUR[LGD2, 1, MemBase[GF], N[2]]; * Push[FetchMds[GF+n]^]; Push[FetchMds[GF+n+1]^]; IFUR[LGDB, 2, MemBase[GF]]; * Load Global Double Byte * alpha: BYTE _ GetCodeByte[]; * Push[FetchMds[GF+alpha]^]; Push[FetchMds[GF+alpha+1]^]; *-------------------------------------------------------------------- T_ (Fetch_ ID)+1, StkP+1, Branch[ExitStackMDReadStackT]; *-------------------------------------------------------------------- IFUR[SL0, 1, MemBase[LF], N[0]]; * Store Local n IFUR[SL1, 1, MemBase[LF], N[1]]; IFUR[SL2, 1, MemBase[LF], N[2]]; IFUR[SL3, 1, MemBase[LF], N[3]]; * StoreMds[LF+n]^ _ Pop[]; * These are different from the other SLn and SLB in that they don't need * to check for faults because references to the first 4 locals cannot fault. *-------------------------------------------------------------------- Store_ ID, DBuf_ Stack&-1, NextOpcode; *-------------------------------------------------------------------- IFUR[SL4, 1, MemBase[LF], N[4]]; * Store Local n IFUR[SL5, 1, MemBase[LF], N[5]]; IFUR[SL6, 1, MemBase[LF], N[6]]; IFUR[SL7, 1, MemBase[LF], N[7]]; IFUR[SL8, 1, MemBase[LF], N[10]]; IFUR[SL9, 1, MemBase[LF], N[11]]; IFUR[SL10, 1, MemBase[LF], N[12]]; * StoreMds[LF+n]^ _ Pop[]; IFUR[SLB, 2, MemBase[LF]]; * Store Local Byte * StoreMds[LF+GetCodeByte[]]^ _ Pop[]; IFUR[SGB, 2, MemBase[GF]]; * Store Global Byte * StoreMds[GF+GetCodeByte[]]^ _ Pop[]; *-------------------------------------------------------------------- Store_ ID, DBuf_ Stack&-1, NextOpcodeCF; *-------------------------------------------------------------------- IFUR[SLD0, 1, MemBase[LF], N[1]]; * Store Local Double n IFUR[SLD1, 1, MemBase[LF], N[2]]; IFUR[SLD2, 1, MemBase[LF], N[3]]; IFUR[SLD3, 1, MemBase[LF], N[4]]; * StoreMds[LF+n+1]^ _ Pop[]; StoreMds[LF+n]^ _ Pop[]; * These are different from the other SLDn and SLDB in that they don't need * to check for faults because references to the first 4 locals cannot fault. * SLD3 actually references word 4 which can fault, but then references word 3 which * cannot itself fault but will force any fault on word 4 before the opcode exits. *-------------------------------------------------------------------- T_ (Store_ ID)-1, DBuf_ Stack&-1; Store_ T, DBuf_ Stack&-1, NextOpcode; *-------------------------------------------------------------------- IFUR[SLD4, 1, MemBase[LF], N[5]]; * Store Local Double n IFUR[SLD5, 1, MemBase[LF], N[6]]; IFUR[SLD6, 1, MemBase[LF], N[7]]; IFUR[SLD8, 1, MemBase[LF], N[11]]; * StoreMds[LF+n+1]^ _ Pop[]; StoreMds[LF+n]^ _ Pop[]; *-------------------------------------------------------------------- T_ (Store_ ID)-1, DBuf_ Stack&-1, Branch[ExitWriteStackT]; *-------------------------------------------------------------------- IFUR[SLDB, 2, MemBase[LF]]; * Store Local Double Byte * alpha: BYTE _ GetCodeByte[]; * StoreMds[LF+alpha+1]^ _ Pop[]; StoreMds[LF+alpha]^ _ Pop[]; IFUR[SGDB, 2, MemBase[GF]]; * Store Global Double Byte * alpha: BYTE _ GetCodeByte[]; * StoreMds[GF+alpha+1]^ _ Pop[]; StoreMds[GF+alpha]^ _ Pop[]; *-------------------------------------------------------------------- T_ (ID)+1, Branch[ExitWriteDoubleStackT]; *-------------------------------------------------------------------- IFUR[PL0, 1, MemBase[LF], N[0]]; * Put Local n IFUR[PL1, 1, MemBase[LF], N[1]]; IFUR[PL2, 1, MemBase[LF], N[2]]; IFUR[PL3, 1, MemBase[LF], N[3]]; * StoreMds[LF+n]^ _ Pop[]; SP _ SP+1; *-------------------------------------------------------------------- Store_ ID, DBuf_ Stack, NextOpcode; * Refs to first 4 locals cannot fault *-------------------------------------------------------------------- IFUR[PLB, 2, MemBase[LF]]; * Put Local Byte * StoreMds[LF+GetCodeByte[]]^ _ Pop[]; SP _ SP+1; *-------------------------------------------------------------------- Store_ ID, DBuf_ Stack, NextOpcodeCF; *-------------------------------------------------------------------- IFUR[PLD0, 1, MemBase[LF], N[1]]; * Put Local Double Zero * StoreMds[LF+1]^ _ Pop[]; StoreMds[LF]^ _ Pop[]; *-------------------------------------------------------------------- T_ (Store_ ID)-1, DBuf_ Stack&-1; Store_ T, DBuf_ Stack&+1, NextOpcode; * Refs to first 4 locals cannot fault *-------------------------------------------------------------------- IFUR[PLDB, 2, MemBase[LF]]; * Put Local Double Byte * alpha: BYTE _ GetCodeByte[]; * StoreMds[GF+alpha+1]^ _ Pop[]; StoreMds[GF+alpha]^ _ Pop[]; *-------------------------------------------------------------------- T_ (ID)+1; T_ (Store_ T)-1, DBuf_ Stack&-1; Store_ T, DBuf_ Stack&+1, NextOpcodeCF; *----------------------------------------------------------- IFUR[AL0IB, 2, MemBase[LF], N[0]]; * Add Local Zero to Immediate Byte * Push[FetchMds[LF]^ + GetCodeByte[]]; *----------------------------------------------------------- Fetch_ ID, StkP+1; Stack_ (ID)+MD, NextOpcode; *-------------------------------------------------------------------- IFUR[GA0, 1, N[0]]; * Global Address n * Push[GF + n]; IFUR[GAB, 2]; * Global Address Byte * Push[GF + GetCodeByte[]]; *-------------------------------------------------------------------- T_ (ID)+(GFShadow), Branch[ExitPushT]; *-------------------------------------------------------------------- IFUR[GAW, 3]; * Global Address Word * Push[GF + GetCodeWord[]]; *-------------------------------------------------------------------- T_ ShiftRMask[RTemp0], RisID; * LSH[ID, 10] T_ (GFShadow)+T, Branch[ExitPushIDPlusT]; *----------------------------------------------------------- IFUR[R0, 1, MemBase[MDS], N[0]]; * Read n IFUR[R1, 1, MemBase[MDS], N[1]]; * ptr: POINTER _ Pop[]; Push[FetchMds[ptr+n]^]; IFUR[RB, 2, MemBase[MDS]]; * Read Byte * ptr: POINTER _ Pop[]; Push[FetchMds[ptr+GetCodeByte[]]^]; *----------------------------------------------------------- IFetch_ Stack&-1, Branch[ExitPushMD]; *----------------------------------------------------------- IFUR[RL0, 1, MemBase[LPtr], N[0]]; * Read Long Zero * ptr: LONG POINTER _ PopLong[]; Push[Fetch[ptr]^]; IFUR[RLB, 2, MemBase[LPtr]]; * Read Long Byte * ptr: LONG POINTER _ PopLong[]; Push[Fetch[ptr+GetCodeByte[]]^]; *----------------------------------------------------------- BRHi_ Stack&-1, Call[BRLoGetsStack]; Fetch_ ID, StkP-1, Branch[ExitPushMD]; *----------------------------------------------------------- IFUR[RD0, 1, MemBase[MDS], N[0]]; * Read Double Zero * ptr: POINTER _ Pop[]; * u: UNSPECIFIED _ FetchMds[ptr]^; v: UNSPECIFIED _ FetchMds[ptr+1]^; * Push[u]; Push[v]; IFUR[RDB, 2, MemBase[MDS]]; * Read Double Byte: * ptr: POINTER _ Pop[]; * u: UNSPECIFIED _ FetchMds[ptr+alpha]^; v: UNSPECIFIED _ FetchMds[ptr+alpha+1]^; * Push[u]; Push[v]; *----------------------------------------------------------- T_ (IFetch_ Stack)+T+1, TisID, Branch[RDLBTail]; *----------------------------------------------------------- IFUR[RDL0, 1, MemBase[LPtr], N[0]]; * Read Double Long Zero * ptr: LONG POINTER _ PopLong[]; * u: UNSPECIFIED _ Fetch[ptr]^; v: UNSPECIFIED _ Fetch[ptr+1]^; * Push[u]; Push[v]; IFUR[RDLB, 2, MemBase[LPtr]]; * Read Double Long Byte * alpha: BYTE _ GetCodeByte[]; ptr: LONG POINTER _ PopLong[]; * u: UNSPECIFIED _ Fetch[ptr+LONG[alpha]]^; v: UNSPECIFIED _ Fetch[ptr+LONG[alpha]+1]^; * Push[u]; Push[v]; *----------------------------------------------------------- BRHi_ Stack&-1, Call[BRLoGetsStack]; T_ (Fetch_ ID)+1; * Note: must not clobber stack with first word until we know the fetch of * the second word won't fault. RDLBTail: Fetch_ T, T_ MD; Stack_ T, T_ MD, Branch[ExitPushT]; *----------------------------------------------------------- NewOp; ESCEntry[RC], * Read Code * Push[ReadCode[Pop[]+GetCodeByte[]]]; *----------------------------------------------------------- T_ (ID)+(Stack&-1), MemBase_ CB, Branch[ExitReadStackT]; *----------------------------------------------------------- IFUR[W0, 1, MemBase[MDS], N[0]]; * Write Zero * ptr: POINTER _ Pop[]; StoreMds[ptr]^ _ Pop[]; IFUR[WB, 2, MemBase[MDS]]; * Write Byte * ptr: POINTER _ Pop[]; StoreMds[ptr+GetCodeByte[]]^ _ Pop[]; *----------------------------------------------------------- T_ (ID)+(Stack&-1), Branch[ExitWriteStackT]; *----------------------------------------------------------- IFUR[WLB, 2, MemBase[LPtr]]; * Write Long Byte * ptr: LONG POINTER _ PopLong[]; Store[ptr+LONG[GetCodeByte[]]]^ _ Pop[]; *----------------------------------------------------------- BRHi_ Stack&-1; BRLo_ Stack&-1, Branch[@SL4]; *----------------------------------------------------------- IFUR[WDB, 2, MemBase[MDS]]; * Write Double Byte * alpha: BYTE _ GetCodeByte[]; ptr: POINTER _ Pop[]; * StoreMds[ptr+alpha+1]^ _ Pop[]; StoreMds[ptr+alpha]^ _ Pop[]; *----------------------------------------------------------- T_ (ID)+(Stack&-1)+1, Branch[ExitWriteDoubleStackT]; *----------------------------------------------------------- IFUR[WDLB, 2, MemBase[LPtr]]; * Write Double Long Byte * alpha: BYTE _ GetCodeByte[]; ptr: LONG POINTER _ PopLong[]; * Store[ptr+LONG[alpha]+1]^ _ Pop[]; Store[ptr+LONG[alpha]]^ _ Pop[]; *----------------------------------------------------------- BRHi_ Stack&-1; BRLo_ Stack&-2; T_ (Store_ ID)+1, DBuf_ Stack&+1; Store_ T, DBuf_ Stack&-2, NextOpcodeCF; *----------------------------------------------------------- IFUR[PSB, 2, MemBase[MDS]]; * Put Swapped Byte * u: UNSPECIFIED _ Pop[]; ptr: POINTER _ Pop[]; * StoreMds[ptr+GetCodeByte[]]^ _ u; SP _ SP+1; *----------------------------------------------------------- StkP-1; T_ (ID)+(Stack&+1), Branch[ExitWriteStackT]; *----------------------------------------------------------- IFUR[PSD0, 1, MemBase[MDS], N[0]]; * Put Swapped Double Zero * u: UNSPECIFIED _ Pop[]; v: UNSPECIFIED _ Pop[]; ptr: POINTER _ Pop[]; * StoreMds[ptr+1]^ _ v; StoreMds[ptr]^ _ u; SP _ SP+1; IFUR[PSDB, 2, MemBase[MDS]]; * Put Swapped Double Byte * alpha: BYTE _ GetCodeByte[]; * u: UNSPECIFIED _ Pop[]; v: UNSPECIFIED _ Pop[]; ptr: POINTER _ Pop[]; * StoreMds[ptr+alpha+1]^ _ v; StoreMds[ptr+alpha]^ _ u; SP _ SP+1; *----------------------------------------------------------- StkP-2; T_ (ID)+(Stack&+2)+1, Branch[ExitWriteDoubleStackT]; *----------------------------------------------------------- IFUR[PSLB, 2, MemBase[LPtr]]; * Put Swapped Long Byte * u: UNSPECIFIED _ Pop[]; ptr: LONG POINTER _ PopLong[]; * Store[ptr+LONG[GetCodeByte[]]]^ _ u; SP _ SP+2; *----------------------------------------------------------- T_ ID, StkP-1, Call[BRHiGetsStackPop]; BRLo_ Stack&+2, Branch[ExitWriteStackT]; *----------------------------------------------------------- IFUR[PSDLB, 2, MemBase[LPtr]]; * Put Swapped Double Long Byte * alpha: BYTE _ GetCodeByte[]; * u: UNSPECIFIED _ Pop[]; v: UNSPECIFIED _ Pop[]; ptr: LONG POINTER _ PopLong[]; * Store[ptr+LONG[alpha]+1]^ _ v; Store[ptr+LONG[alpha]]^ _ u; SP _ SP+2; *----------------------------------------------------------- T_ (ID)+1, StkP-2, Call[BRHiGetsStackPop]; BRLo_ Stack&+3, Branch[ExitWriteDoubleStackT]; *----------------------------------------------------------- IFUR[RLI00, 1, MemBase[LF], N[0]]; * Read Local Indirect Zero n IFUR[RLI01, 1, MemBase[LF], N[1]]; IFUR[RLI02, 1, MemBase[LF], N[2]]; IFUR[RLI03, 1, MemBase[LF], N[3]]; * ptr: POINTER _ FetchMds[LF]^; Push[FetchMds[ptr+n]^]; *----------------------------------------------------------- Fetch_ 0S, Branch[RxIPTail]; *----------------------------------------------------------- IFUR[RLIP, 2, MemBase[LF], PackedAlpha]; * Read Local Indirect Pair * pair: NibblePair _ GetCodeByte[]; * ptr: POINTER _ FetchMds[LF+pair.left]^; Push[FetchMds[ptr+pair.right]^]; IFUR[RGIP, 2, MemBase[GF], PackedAlpha]; * Read Global Indirect Pair * pair: NibblePair _ GetCodeByte[]; * ptr: POINTER _ FetchMds[GF+pair.left]^; Push[FetchMds[ptr+pair.right]^]; *----------------------------------------------------------- Fetch_ ID; * Fetch from xF+pair.left RxIPTail: RTemp0_ MD, MemBase_ MDS; IFetch_ RTemp0, Branch[ExitPushMD]; * Fetch from MDS+MD+pair.right *----------------------------------------------------------- IFUR[RLILP, 2, MemBase[LF], PackedAlpha]; * Read Local Indirect Long Pair * pair: NibblePair _ GetCodeByte[]; * ptr: LONG POINTER _ FetchDblMds[LF+pair.left]^; * Push[Fetch[ptr+LONG[pair.right]]^]; IFUR[RGILP, 2, MemBase[GF], PackedAlpha]; * Read Global Indirect Long Pair * pair: NibblePair _ GetCodeByte[]; * ptr: LONG POINTER _ FetchDblMds[GF+pair.left]^; * Push[Fetch[ptr+LONG[pair.right]]^]; *----------------------------------------------------------- T_ (Fetch_ ID)+1, Call[LongIndirectAddress]; Fetch_ ID, Branch[ExitPushMD]; *----------------------------------------------------------- IFUR[RLDI00, 1, MemBase[LF], N[0]]; * Read Local Double Indirect Zero Zero * ptr: POINTER _ FetchMds[LF]^; * u: UNSPECIFIED _ FetchMds[ptr]^; v: UNSPECIFIED _ FetchMds[ptr+1]^; * Push[u]; Push[v]; *----------------------------------------------------------- Fetch_ 0S, StkP+1, Branch[RLDIPTail]; *----------------------------------------------------------- IFUR[RLDIP, 2, MemBase[LF], PackedAlpha]; * Read Local Double Indirect Pair * pair: NibblePair _ GetCodeByte[]; * ptr: POINTER _ FetchMds[LF+pair.left]^; * u: UNSPECIFIED _ FetchMds[ptr+pair.right]^; v: UNSPECIFIED _ FetchMds[ptr+pair.right+1]^; * Push[u]; Push[v]; *----------------------------------------------------------- Fetch_ ID, StkP+1; * Fetch from LF+pair.left RLDIPTail: RTemp0_ MD, MemBase_ MDS; T_ (IFetch_ RTemp0)+T+1, TisID, * Fetch from MDS+MD+pair.right Branch[ExitStackMDReadStackT]; *----------------------------------------------------------- IFUR[RLDILP, 2, MemBase[LF], PackedAlpha]; * Read Local Double Indirect Long Pair * pair: NibblePair _ GetCodeByte[]; * ptr: LONG POINTER _ FetchDblMds[LF+pair.left]^; * u: UNSPECIFIED _ FetchMds[ptr+pair.right]^; v: UNSPECIFIED _ FetchMds[ptr+pair.right+1]^; * Push[u]; Push[v]; *----------------------------------------------------------- T_ (Fetch_ ID)+1, Call[LongIndirectAddress]; * Fetch from LF+pair.left T_ (Fetch_ ID)+1, StkP+1, * Fetch from LPtr+pair.right Branch[ExitStackMDReadStackT]; *----------------------------------------------------------- IFUR[WLIP, 2, MemBase[LF], PackedAlpha]; * Write Local Indirect Pair * pair: NibblePair _ GetCodeByte[]; * ptr: POINTER _ FetchMds[L+pair.left]^; StoreMds[ptr+pair.right]^ _ Pop[]; *----------------------------------------------------------- Fetch_ ID; T_ (ID)+MD, MemBase_ MDS, Branch[ExitWriteStackT]; *----------------------------------------------------------- IFUR[WLILP, 2, MemBase[LF], PackedAlpha]; * Write Local Indirect Long Pair * pair: NibblePair _ GetCodeByte[]; * ptr: LONG POINTER _ FetchDblMds[L+pair.left]^; StoreMds[ptr+pair.right]^ _ Pop[]; *----------------------------------------------------------- T_ (Fetch_ ID)+1, Call[LongIndirectAddress]; Store_ ID, DBuf_ Stack&-1, NextOpcodeCF; *----------------------------------------------------------- IFUR[WLDILP, 2, MemBase[LF], PackedAlpha]; * Write Local Double Indirect Long Pair * pair: NibblePair _ GetCodeByte[]; * ptr: LONG POINTER _ FetchDblMds[L+pair.left]^; * Store[ptr+LONG[pair.right]+1]^ _ Pop[]; Store[ptr+LONG[pair.right]]^ _ Pop[]; *----------------------------------------------------------- T_ (Fetch_ ID)+1, Call[LongIndirectAddress]; T_ (ID)+1, Branch[ExitWriteDoubleStackT]; *----------------------------------------------------------- LongIndirectAddress: * Base register setup for long indirect instructions * Entry conditions: * T = address of high word of long pointer (relative to current MemBase) * MD = low word of long pointer * Exit conditions: * MemBase = LPtr, containing the long pointer *----------------------------------------------------------- Subroutine; T_ MD, Fetch_ T; MemBase_ LPtr; T_ MD, BRLo_ T; BRHi_ T, Return; TopLevel; *----------------------------------------------------------- IFUR[RS, 2, MemBase[MDS]]; * Read String * index: CARDINAL _ Pop[]; ptr: POINTER _ Pop[]; * offset: CARDINAL _ GetCodeByte[]+index; word: BytePair _ FetchMds[ptr+offset/2]^; * Push[IF (offset MOD 2)=0 THEN word.left ELSE word.right]; *----------------------------------------------------------- * Note: the Multiply in the following instructions has the effect of, e.g.: * T_ ((ID)+(Stack&-1)) RSH 1 * and additionally the result bit shifted out is captured in Q[0]. * The operation must not generate a carry, and the Q[14] dispatch generated * as a side-effect of Multiply must be neutralized (this is done in StringSetup). T_ (ID)+(Stack&-1), Multiply, * T_ (index+alpha)/2 Call[StringSetup]; * Returns with ALU = Q T_ MD, StkP+1, DblBranch[RLSEven, RLSOdd, ALU>=0]; *----------------------------------------------------------- IFUR[RLS, 2, MemBase[LPtr]]; * Read Long String * index: CARDINAL _ Pop[]; ptr: LONG POINTER _ PopLong[]; * offset: CARDINAL _ GetCodeByte[]+index; word: BytePair _ Fetch[ptr+LONG[offset/2]]^; * Push[IF (offset MOD 2)=0 THEN word.left ELSE word.right]; *----------------------------------------------------------- T_ (ID)+(Stack&-1), Multiply, * T_ (index+alpha)/2 Call[LongStringSetup]; * Returns with ALU = Q T_ MD, StkP+1, DblBranch[RLSEven, RLSOdd, ALU>=0]; RLSEven: Stack_ RSH[T, 10], NextOpcode; RLSOdd: Stack_ T AND (377C), NextOpcode; *----------------------------------------------------------- IFUR[WS, 2, MemBase[MDS]]; * Write String * index: CARDINAL _ Pop[]; ptr: POINTER _ Pop[]; data: BYTE _ LowByte[Pop[]]; * offset: CARDINAL _ GetCodeByte[]+index; word: BytePair _ FetchMds[ptr+offset/2]^; * StoreMds[ptr+offset/2]^ _ * IF (offset MOD 2)=0 THEN BytePair[data, word.right] ELSE BytePair[word.left, data]; *----------------------------------------------------------- T_ (ID)+(Stack&-1), Multiply, * T_ (index+alpha)/2 Call[StringSetup]; * Returns with ALU = Q RTemp0_ T, DblBranch[WLSEven, WLSOdd, ALU>=0]; *----------------------------------------------------------- IFUR[WLS, 2, MemBase[LPtr]]; * Write Long String * index: CARDINAL _ Pop[]; ptr: LONG POINTER _ PopLong[]; data: BYTE _ LowByte[Pop[]]; * offset: CARDINAL _ GetCodeByte[]+index; word: BytePair _ Fetch[ptr+LONG[offset/2]]^; * Store[ptr+LONG[offset/2]]^ _ * IF (offset MOD 2)=0 THEN BytePair[data, word.right] ELSE BytePair[word.left, data]; *----------------------------------------------------------- T_ (ID)+(Stack&-1), Multiply, * T_ (index+alpha)/2 Call[LongStringSetup]; * Returns with ALU = Q RTemp0_ T, DblBranch[WLSEven, WLSOdd, ALU>=0]; WLSEven: T_ DPF[Stack&-1, 10, 10, MD], Branch[WLFTail4]; WLSOdd: T_ DPF[Stack&-1, 10, 0, MD], Branch[WLFTail4]; *----------------------------------------------------------- StringSetup: * Enter: T = (alpha+index)/2; Q[0] = (alpha+index) MOD 2 * Stack[StkP] = ptr * MemBase = MDS * Multiply dispatch pending * Exit: T = ptr + (alpha+index)/2 * MD = FetchMds[T]^ * ALU = Q * Stack popped 1 *----------------------------------------------------------- Subroutine; T_ T+(Stack&-1), Branch[StringSetupTail]; * T_ ptr + (index+alpha)/2 *----------------------------------------------------------- LongStringSetup: * Enter: T = (alpha+index)/2; Q[0] = (alpha+index) MOD 2 * Stack[StkP] = high half of ptr * Stack[StkP-1] = low half of ptr * MemBase = LPtr * Multiply dispatch pending * Exit: T unchanged * LPtr = ptr * MD = Fetch[ptr+T]^ * ALU = Q * Stack popped 2 *----------------------------------------------------------- Subroutine; BRHi_ Stack&-1; BRLo_ Stack&-1, DispTable[1, 2, 2]; * Neutralize Multiply dispatch StringSetupTail: PD_ Q, Fetch_ T, Return, DispTable[1, 2, 2]; * Neutralize Multiply dispatch (StringSetup) TopLevel; *----------------------------------------------------------- IFUR[RF, 3, MemBase[MDS]]; * Read Field * offset: BYTE _ GetCodeByte[]; spec: FieldSpec _ GetCodeByte[]; * ptr: POINTER _ Pop[]; * Push[ReadField[FetchMds[ptr+offset]^, spec]]; IFUR[R0F, 2, MemBase[MDS], N[0]]; * Read Zero Field * spec: FieldSpec _ GetCodeByte[]; * ptr: POINTER _ Pop[]; * Push[ReadField[FetchMds[ptr]^, spec]]; *----------------------------------------------------------- T_ (ID)+(Stack); RFTail: Fetch_ T, Q_ StdShC, Branch[RLFTail2]; *----------------------------------------------------------- IFUR[RLF, 3, MemBase[LPtr]]; * Read Long Field * offset: BYTE _ GetCodeByte[]; spec: FieldSpec _ GetCodeByte[]; * ptr: LONG POINTER _ PopLong[]; * Push[ReadField[Fetch[ptr+LONG[offset]]^, spec]]; IFUR[RL0F, 2, MemBase[LPtr], N[0]]; * Read Long Zero Field * spec: FieldSpec _ GetCodeByte[]; * ptr: LONG POINTER _ PopLong[]; * Push[ReadField[Fetch[ptr]^, spec]]; *----------------------------------------------------------- BRHi_ Stack&-1, Call[BRLoGetsStack]; RLFTail1: Fetch_ ID, Q_ StdShC; RLFTail2: Stack_ MD, RF_ ID; RLFTail3: Stack_ ShiftLMask[Stack], ShC_ Q, NextOpcode; *----------------------------------------------------------- IFUR[RLFS, 1, MemBase[LPtr]]; * Read Long Field Stack * desc: FieldDesc _ Pop[]; * ptr: LONG POINTER _ PopLong[]; * Push[ReadField[Fetch[ptr+LONG[desc.offset]]^, desc.field]]; *----------------------------------------------------------- T_ RSH[Stack&-1, 10], Call[BRHiGetsStackPop]; * T_ offset BRLo_ Stack&+2; Fetch_ T, T_ Stack&-2, Branch[RCFSTail]; *----------------------------------------------------------- NewOp; ESCEntry[RCFS], * Read Code Field Stack * desc: FieldDesc _ Pop[]; offset: CARDINAL _ Pop[]; * Push[ReadField[ReadCode[offset+desc.offset], desc.field]]; *----------------------------------------------------------- T_ ShiftLMask[Stack&-1]; * T_ offset = RSH[T, 10] (ESCEntry: T=Stack[StkP]) T_ (Stack&+1)+T, MemBase_ CB; Fetch_ T, T_ Stack&-1; RCFSTail: Q_ StdShC; Stack_ T_ B_ MD, RF_ T, * No ShC R/T select, so data must be in R and T Branch[RLFTail3]; *----------------------------------------------------------- IFUR[RLIPF, 3, MemBase[LF], PackedAlpha]; * Read Local Indirect Pair Field * pair: NibblePair _ GetCodeByte[]; spec: FieldSpec _ GetCodeByte[]; * ptr: POINTER _ FetchMds[LF+pair.left]^; * Push[ReadField[FetchMds[ptr+pair.right]^, spec]]; *----------------------------------------------------------- Fetch_ ID, StkP+1; * Fetch from LF+pair.left T_ (ID)+MD, MemBase_ MDS, Branch[RFTail]; * T_ ptr+pair.right *----------------------------------------------------------- IFUR[RLILPF, 3, MemBase[LF], PackedAlpha]; * Read Local Indirect Long Pair Field * pair: NibblePair _ GetCodeByte[]; spec: FieldSpec _ GetCodeByte[]; * ptr: LONG POINTER _ FetchDblMds[LF+pair.left]^; * Push[ReadField[Fetch[ptr+LONG[pair.right]]^, spec]]; *----------------------------------------------------------- T_ (Fetch_ ID)+1, StkP+1; * Fetch from LF+pair.left Fetch_ T, Stack&+1_ MD; * Push ptr onto stack Stack_ MD, MemBase_ LPtr, Branch[@RLF]; * Pretend ptr came from stack originally *----------------------------------------------------------- IFUR[WF, 3, MemBase[MDS]]; * Write Field * offset: BYTE _ GetCodeByte[]; spec: FieldSpec _ GetCodeByte[]; * ptr: POINTER _ Pop[]; data: UNSPECIFIED _ Pop[]; * StoreMds[ptr+offset]^ _ WriteField[FetchMds[ptr+offset]^, spec, data]; IFUR[W0F, 2, MemBase[MDS], N[0]]; * Write Zero Field * spec: FieldSpec _ GetCodeByte[]; * ptr: POINTER _ Pop[]; data: UNSPECIFIED _ Pop[]; * StoreMds[ptr]^ _ WriteField[FetchMds[ptr]^, spec, data]; *----------------------------------------------------------- T_ (ID)+(Stack&-1); WFTail: Fetch_ T, Q_ StdShC, Branch[WLFTail2]; *----------------------------------------------------------- IFUR[WLF, 3, MemBase[LPtr]]; * Write Long Field * offset: BYTE _ GetCodeByte[]; spec: FieldSpec _ GetCodeByte[]; * ptr: LONG POINTER _ PopLong[]; data: UNSPECIFIED _ Pop[]; * Store[ptr+offset]^ _ WriteField[Fetch[ptr+LONG[offset]]^, spec, data]; IFUR[WL0F, 2, MemBase[LPtr], N[0]]; * Write Long Zero Field * spec: FieldSpec _ GetCodeByte[]; * ptr: LONG POINTER _ PopLong[]; data: UNSPECIFIED _ Pop[]; * Store[ptr]^ _ WriteField[FetchMds[ptr]^, spec, data]; *----------------------------------------------------------- BRHi_ Stack&-1; BRLo_ Stack&-1; WLFTail1: T_ Fetch_ ID, Q_ StdShC; WLFTail2: RTemp0_ T, WF_ ID; WLFTail3: T_ ShMDBothMasks[Stack&-1], ShC_ Q; WLFTail4: Store_ RTemp0, DBuf_ T, NextOpcodeCF; *----------------------------------------------------------- IFUR[WLFS, 1, MemBase[LPtr]]; * Write Long Field Stack * desc: FieldDesc _ Pop[]; * ptr: LONG POINTER _ PopLong[]; data: UNSPECIFIED _ Pop[]; * Store[ptr+desc.offset]^ _ WriteField[Fetch[ptr+LONG[desc.offset]]^, desc.spec, data]; *----------------------------------------------------------- T_ WF_ Stack&-1, Call[BRHiGetsStackPop]; * T_ offset,,desc, WF_ desc BRLo_ Stack&-1; T_ RTemp0_ RSH[T, 10]; * T_ offset Fetch_ T, T_ Stack; * No ShC R/T select, so data must be in R and T Q_ StdShC, Branch[WLFTail3]; *----------------------------------------------------------- IFUR[WS0F, 2, MemBase[MDS]]; * Write Swapped Zero Field * spec: FieldSpec _ GetCodeByte[]; * data: UNSPECIFIED _ Pop[]; ptr: POINTER _ Pop[]; * StoreMds[ptr]^ _ WriteField[FetchMds[ptr]^, spec, data]; *----------------------------------------------------------- WF_ ID, StkP-1; RTemp0_ Fetch_ Stack&+1; Q_ StdShC; T_ ShMDBothMasks[Stack&-2], ShC_ Q, Branch[WLFTail4]; *----------------------------------------------------------- IFUR[PSF, 3, MemBase[MDS]]; * Put Swapped Field * offset: BYTE _ GetCodeByte[]; spec: FieldSpec _ GetCodeByte[]; * data: UNSPECIFIED _ Pop[]; ptr: POINTER _ Pop[]; * StoreMds[ptr+offset]^ _ WriteField[FetchMds[ptr+offset]^, spec, data]; SP _ SP+1; IFUR[PS0F, 2, MemBase[MDS], N[0]]; * Put Swapped Zero Field * spec: FieldSpec _ GetCodeByte[]; * data: UNSPECIFIED _ Pop[]; ptr: POINTER _ Pop[]; * StoreMds[ptr]^ _ WriteField[FetchMds[ptr]^, spec, data]; SP _ SP+1; *----------------------------------------------------------- StkP-1; T_ (ID)+(Stack&+1), Branch[WFTail]; *----------------------------------------------------------- IFUR[PSLF, 3, MemBase[LPtr]]; * Put Swapped Long Field * offset: BYTE _ GetCodeByte[]; spec: FieldSpec _ GetCodeByte[]; * data: UNSPECIFIED _ Pop[]; ptr: LONG POINTER _ PopLong[]; * Store[ptr+offset]^ _ WriteField[Fetch[ptr+LONG[offset]]^, spec, data]; SP _ SP+2; *----------------------------------------------------------- StkP-1, Call[BRHiGetsStackPop]; BRLo_ Stack&+2, Branch[WLFTail1]; * Frequently-used exit sequences *----------------------------------------------------------- ExitPushT: * Push T onto the stack and exit *----------------------------------------------------------- Stack+1_ T, NextOpcode, Global; *----------------------------------------------------------- ExitPushMD: * Push MD onto the stack and exit *----------------------------------------------------------- Stack+1_ MD, NextOpcode, Global; *----------------------------------------------------------- ExitPushIDPlusT: * Push ID+T onto the stack and exit *----------------------------------------------------------- Stack+1_ (ID)+T, NextOpcode; *----------------------------------------------------------- ExitReadStackT: * Fetch word from address T, push it onto the stack, and exit *----------------------------------------------------------- Fetch_ T, Branch[ExitPushMD], Global; *----------------------------------------------------------- ExitStackMDReadStackT: * Put MD on stack and then push word fetched from T on stack *----------------------------------------------------------- Stack_ MD, Fetch_ T, Branch[ExitPushMD]; *----------------------------------------------------------- ExitWriteStackT: * Store word from stack to address T, pop the stack, and exit *----------------------------------------------------------- Store_ T, DBuf_ Stack&-1, NextOpcodeCF, Global; *----------------------------------------------------------- ExitWriteDoubleStackT: * Store double word from stack to address (T-1), pop the stack, and exit. * Precisely: Stack[StkP] is stored at T, Stack[StkP-1] is stored at T-1, * and StkP is decremented by 2. *----------------------------------------------------------- T_ (Store_ T)-1, DBuf_ Stack&-1, Branch[ExitWriteStackT]; *----------------------------------------------------------- ExitCheckFault: * Check for fault and exit * Branched to by all NextOpcodeCF after Store_ which might fault. *----------------------------------------------------------- T_ MD, NextOpcode, Global; * Subroutines *----------------------------------------------------------- BRHiGetsStackPop: * Executes BRHi_ Stack&-1 *----------------------------------------------------------- Subroutine; BRHi_ Stack&-1, Return, Global; *----------------------------------------------------------- BRLoGetsStack: * Executes BRLo_ Stack *----------------------------------------------------------- Subroutine; BRLo_ Stack, Return, Global; *----------------------------------------------------------- FetchGetsT: * Executes PD_ Fetch_ T *----------------------------------------------------------- Subroutine; PD_ Fetch_ T, Return, Global;