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