*-----------------------------------------------------------
Title[DMesaRWL...March 8, 1981 7:16 PM...Taft];
*-----------------------------------------------------------

%

CONTENTS, by order of occurence

Read/Write Long
RBLRead Byte Long
WBLWrite Byte Long
RDBLRead Double Byte Long
WDBLWrite Double Byte Long

Read/Write Indexed
LongIndexedAddresssubroutine supporting these opcodes
RXLPLRead Index Local Pair Long
WXLPLWrite Indexed Local Pair Long
RXGPLRead Indexed Global Pair Long
WXGPLWrite Indexed Global Pair Long

Read/Write Indirect
LongIndirectAddresssubroutine supporting these opcodes
RILPMRead indexed Local Pair Long
RIGPLRead Indexed Global Pair Long
WILPLWrite Indexed Local Pair Long
WIGPLWrite Indexed Global Pair Long

Read/Write Strings
RSTRLRead String Long
WSTRLWrite STring Long

Read/Write Field
RFLRead Field Long
RFSLRead Field Stack Long
WFLWrite Field Long
WFSLWrite Field Stack Long

Miscellaneous
LPLengthen Pointer
BLTLBlock Transfer Long

%

TopLevel;

* Read/Write using long pointer

*-----------------------------------------------------------
IFUR[RBL, 2, LPtr];
* Read Byte Long:
* p: LONG POINTER ← PopLong[]+LONG[alpha]; Push[Fetch[p]↑];
*-----------------------------------------------------------

BRHi← Stack&-1, Branch[RBLM1];
:IfMEP;
Stack← MD, Branch[.-1];
BRHi← T, Branch[RBLM1];
:EndIf;

RBLM1:
BRLo← Stack&-1, Branch[RILPLM2];
***
Fetch← ID, T← StackNoUfl&+1, IFUNext1;


*-----------------------------------------------------------
IFUR[WBL, 2, LPtr];
* Write Byte Long:
* p: LONG POINTER ← PopLong[]+LONG[alpha]; Store[p]↑ ← Pop[];
*-----------------------------------------------------------

BRHi← Stack&-1, Branch[WBLM1];
:IfMEP;
Stack← MD, Branch[.-1];
BRHi← T, Branch[WBLM1];
:EndIf;

WBLM1:
BRLo← Stack&-1, Branch[WILPLM2];
***
Store← ID, DBuf← Stack&-1, IFUNext0CF;


*-----------------------------------------------------------
IFUR[RDBL, 2, LPtr];
* Read Double Byte Long
* p: LONG POINTER ← PopLong[]+LONG[alpha];
* u ← Fetch[p]↑; v ← Fetch[p+1]↑; Push[u]; Push[v];
*-----------------------------------------------------------

BRHi← Stack&-1, Branch[RDBLM1];
:IfMEP;
Stack← MD, Branch[.-1];
BRHi← T, Branch[RDBLM1];
:EndIf;

RDBLM1:
BRLo← Stack;
T← (Fetch← ID)+1;
Fetch← T, T← MD, Branch[RDBM2];
***
Stack&+1← T, T← MD, Branch[PushT];


*-----------------------------------------------------------
IFUR[WDBL, 2, LPTR]
* Write Double Byte Long
* p: LONG POINTER ← PopLong[]+LONG[alpha];
* Store[p+1]↑ ← Pop[]; Store[p]↑ ← Pop[];
*-----------------------------------------------------------

BRHi← Stack&-1, Branch[WDBLM1];
:IfMEP;
Stack← MD, Branch[.-1];
BRHi← T, Branch[WDBLM1];
:EndIf;

WDBLM1:
BRLo← Stack&-2, Branch[SDBM2];
***
T← (Store← ID)+1, DBuf← Stack&+1;
***
Store← T, DBuf← Stack&-2, IFUNext0CF;

* Read/Write indexed using long pointer

*-----------------------------------------------------------
LongIndexedAddress:
* Entry conditions:
*
T = address of long pointer (relative to current MemBase)
*
ID = alpha2, Stack = index
* Exit conditions:
*
MemBase = LPTR, containing the long pointer
*
T = index+alpha2, stack popped
*-----------------------------------------------------------
Subroutine;
T← (Fetch← T)+1;
RTemp0← MD, Fetch← T;
MemBase← LPtr, T← (ID)+(Stack&-1);
LongAddressR:
* Tail of LongIndirectAddress
RTemp0← MD, BRLo← RTemp0, Branch[.+2, Carry’];
RTemp0← (RTemp0)+1;
BRHi← RTemp0, Return;
TopLevel;

*-----------------------------------------------------------
IFUR[RXLPL, 2, L, N[4], PackedAlpha];
* Read Indexed Local Pair Long
IFUR[RXGPL, 2, G, N[3], PackedAlpha];
* Read Indexed Global Pair Long
* index ← Pop[]; p: LONG POINTER ← FetchMDSDbl[L+alpha.left]↑;
-- or G+...
* Push[Fetch[p+LONG[index+alpha.right]]↑];
*-----------------------------------------------------------

T← ID, Branch[RXLPLM1];
:IfMEP;
T← ID, Stack← MD, Branch[RXLPLM1];
T← ID, StkP+1, Branch[RXLPLM1];* T← localBase or globalBase
:EndIf;

RXLPLM1:
T← (ID)+T, Call[LongIndexedAddress];* T← xxBase+alpha1
Fetch← T, T← StackNoUfl&+1, IFUNext1;


*-----------------------------------------------------------
IFUR[WXLPL, 2, L, N[4], PackedAlpha];
* Write Indexed Local Pair Long
IFUR[WXGPL, 2, G, N[3], PackedAlpha];
* Write Indexed Global Pair Long
* index ← Pop[]; p: LONG POINTER ← FetchMDSDbl[L+alpha.left]↑;
-- or G+...
* Store[p+LONG[index+alpha.right]]↑ ← Pop[];
*-----------------------------------------------------------

T← ID, Branch[WXLPLM1];
:IfMEP;
T← ID, Stack← MD, Branch[WXLPLM1];
T← ID, StkP+1, Branch[WXLPLM1];* T← localBase or globalBase
:EndIf;

WXLPLM1:
T← (ID)+T, Call[LongIndexedAddress];
Store← T, DBuf← Stack&-1, IFUNext0CF;

* Read/Write Indirect using long pointer

*-----------------------------------------------------------
LongIndirectAddress:
* Entry conditions:
*
T = address of long pointer (relative to current MemBase)
* Exit conditions:
*
MemBase = LPTR, containing the long pointer
*-----------------------------------------------------------
Subroutine;
T← (Fetch← T)+1;
RTemp0← MD, PD← Fetch← T;* Note this clears Carry
MemBase← LPtr, Branch[LongAddressR];
TopLevel;

*-----------------------------------------------------------
IFUR[RILPL, 2, L, N[4], PackedAlpha];
* Read Indirect Local Pair Long
IFUR[RIGPL, 2, G, N[3], PackedAlpha];
* Read Indirect Global Pair Long
* p: LONG POINTER ← FetchMDSDbl[L+alpha.left]↑;
-- or G+...
* Push[Fetch[p+LONG[alpha.right]]↑];
*-----------------------------------------------------------

T← ID, Branch[RILPLM1];
:IfMEP;
T← ID, Stack← MD, Branch[RILPLM1];
T← ID, StkP+1, Branch[RILPLM1];* T← localBase or globalBase
:EndIf;

RILPLM1:
T← (ID)+T, Call[LongIndirectAddress];* T← xxBase+alpha1
RILPLM2:
* Tail of RBL
Fetch← ID, T← StackNoUfl&+1, IFUNext1;


*-----------------------------------------------------------
IFUR[WILPL, 2, L, N[4], PackedAlpha];
* Write Indirect Local Pair Long
IFUR[WIGPL, 2, G, N[3], PackedAlpha];
* Write Indirect Global Pair Long
* p: LONG POINTER ← FetchMDSDbl[L+alpha.left]↑;
-- or G+...
* Store[p+LONG[alpha.right]]↑ ← Pop[];
*-----------------------------------------------------------

T← ID, Branch[WILPLM1];
:IfMEP;
T← ID, Stack← MD, Branch[WILPLM1];
T← ID, StkP+1, Branch[WILPLM1];* T← localBase or globalBase
:EndIf;

WILPLM1:
T← (ID)+T, Call[LongIndirectAddress];* T← xxBase+alpha1
WILPLM2:
* Tail of WBL
Store← ID, DBuf← Stack&-1, IFUNext0CF;

* Read/Write String using long pointer

*-----------------------------------------------------------
IFUR[RSTRL, 2, LPtr];
* Read String Long
* index ← Pop[]+alpha; p: LONG POINTER ← PopLong[] + index/2;
* data: BytePair ← Fetch[p]↑;
* Push[IF (index MOD 2)=0 THEN data.left ELSE data.right];
*-----------------------------------------------------------

* See comments under RSTR for explanation of the Multiply.

T← (ID)+(Stack&-1), Multiply, Branch[RSTRLM1];
:IfMEP;
T← (ID)+MD, StkP-1, Multiply, Branch[RSTRLM1];
T← (ID)+T, Multiply, Branch[RSTRLM1];* T← (index+alpha)/2
:EndIf;

RSTRLM1:
BRHi← Stack&-1;
BRLo← Stack, Branch[RSTRM2], DispTable[1, 2, 2];


*-----------------------------------------------------------
IFUR[WSTRL, 2, LPtr];
* Write String Long
* index ← Pop[]+alpha; p: LONG POINTER ← PopLong[] + index/2;
* byte: BYTE ← Pop[]; data: BytePair ← Fetch[p]↑;
* IF (index MOD 2) = 0 THEN data.left ← byte ELSE data.right ← byte;
* Store[p]↑ ← data;
*-----------------------------------------------------------

T← (ID)+(Stack&-1), Multiply, Branch[WSTRLM1];
:IfMEP;
T← (ID)+MD, StkP-1, Multiply, Branch[WSTRLM1];
T← (ID)+T, Multiply, Branch[WSTRLM1];* T← (index+alpha)/2
:EndIf;

WSTRLM1:
BRHi← Stack&-1;
BRLo← Stack&-1, Branch[WSTRM2], DispTable[1, 2, 2];

* Read/Write Field Long

:If[AltoMode];
********** Alto version **********
*-----------------------------------------------------------
IFUR[RFL, 3, Code, N[2]];
* Read Field Long
* Alto Mesa: this is an aligned 3-byte instruction
*-----------------------------------------------------------

T← (ID)-(PCX’), Branch[RFLM1];* T← PCX+3
:IfMEP;
T← (ID)-(PCX’), Stack← MD, Branch[RFLM1];
T← (ID)-(PCX’), StkP+1, Branch[RFLM1];
:EndIf;

RFLM1:
RTemp0← (T-1) RSH 1, Call[RWFAlphaBeta];
MemBase← LPTR;
RFLM2:
BRHi← Stack&-1;
BRLo← Stack, Branch[RFM3];

*-----------------------------------------------------------
IFUR[RFSL, 1, LPtr, N[1]];
* Read Field Stack Long
* Alto Mesa: this is an aligned 1-byte instruction
*-----------------------------------------------------------

RTemp0← T← Stack&-1, Branch[RFSLM1];
:IfMEP;
RTemp0← T← B← MD, StkP-1, Branch[RFSLM1];
RTemp0← T, Branch[RFSLM1];
:EndIf;

RFSLM1:
RTemp1← (ID)-(PCX’);* PCX+2
T← RSH[T, 10], RTemp1, Branch[.+2, R odd];
PCF← RTemp1;* Restart IFU at PCX+2
RTemp0← (RTemp0) AND (377C), Branch[RFLM2];

:Else;
******** PrincOps version ********
*-----------------------------------------------------------
IFUR[RFL, 3, LPtr];
* Read Field Long
* p: LONG POINTER ← PopLong[]+alpha; Push[ReadField[Fetch[p]↑, beta]];
*-----------------------------------------------------------

BRHi← Stack&-1, Branch[RFLM1];
:IfMEP;
Stack← MD, Branch[.-1];
BRHi← T, Branch[RFLM1];
:EndIf;

RFLM1:
BRLo← Stack;
Fetch← ID, Branch[RFM1];

*-----------------------------------------------------------
IFUR[RFSL, 1, LPtr];
* Read Field Stack Long
* desc: FieldDesc ← Pop[]; p: LONG POINTER ← PopLong[]+desc.offset;
* Push[ReadField[Fetch[p]↑, desc.field]];
*-----------------------------------------------------------

T← RSH[Stack&-1, 10], Branch[RFSLM1]; * T← offset
:IfMEP;
Stack← MD, Branch[.-1];
T← RSH[T, 10], Branch[RFSLM1];
:EndIf;

RFSLM1:
BRHi← Stack&-1;
BRLo← Stack&+2;
Fetch← T, T← Stack&-2, Branch[RFSM2];

:EndIf;
**********************************

:If[AltoMode];
********** Alto version **********
*-----------------------------------------------------------
IFUR[WFL, 3, Code, N[2]];
* Write Field Long
* Alto Mesa: this is an aligned 3-byte instruction
*-----------------------------------------------------------

T← (ID)-(PCX’), Branch[WFLM1];* T← PCX+3
:IfMEP;
T← (ID)-(PCX’), Stack← MD, Branch[WFLM1];
T← (ID)-(PCX’), StkP+1, Branch[WFLM1];
:EndIf;

WFLM1:
RTemp0← (T-1) RSH 1, Call[RWFAlphaBeta];
MemBase← LPTR;
WFLM2:
BRHi← Stack&-1;
BRLo← Stack&-1, Branch[WFM3];

*-----------------------------------------------------------
IFUR[WFSL, 1, LPtr, N[1]];
* Write Field Stack Long
* Alto Mesa: this is an aligned 1-byte instruction
*-----------------------------------------------------------

RTemp0← T← Stack&-1, Branch[WFSLM1];
:IfMEP;
RTemp0← T← B← MD, StkP-1, Branch[WFSLM1];
RTemp0← T, Branch[WFSLM1];
:EndIf;

WFSLM1:
RTemp1← (ID)-(PCX’);* PCX+2
T← RSH[T, 10], RTemp1, Branch[.+2, R odd];
PCF← RTemp1;* Restart IFU at PCX+2
RTemp0← (RTemp0) AND (377C), Branch[WFLM2];

:Else;
******** PrincOps version ********
*-----------------------------------------------------------
IFUR[WFL, 3, LPtr];
* Write Field Long
* p: LONG POINTER ← PopLong[]+alpha; data ← Pop[];
* Store[p]↑ ← WriteField[Fetch[p]↑, data, beta];
*-----------------------------------------------------------

BRHi← Stack&-1, Branch[WFLM1];
:IfMEP;
Stack← MD, Branch[.-1];
BRHi← T, Branch[WFLM1];
:EndIf;

WFLM1:
BRLo← Stack&-1;
T← Fetch← ID, Branch[WFM1];

*-----------------------------------------------------------
IFUR[WFSL, 1, LPtr];
* Write Field Stack Long
* desc: FieldDesc ← Pop[]; p: LONG POINTER ← PopLong[]+desc.offset;
* data ← Pop[]; StoreMDS[p]↑ ← WriteField[FetchMDS[p]↑, data, desc.field];
*-----------------------------------------------------------

T← Stack&-1, Branch[WFSLM2];
:IfMEP;
T← Stack&-1← MD, Branch[WFSLM2];
:EndIf;
WFSLM2:
RTemp0← T← RSH[T, 10], Branch[WFSM1]; * T← offset

WFSM1:
BRHi← Stack&-1;
BRLo← Stack&-1;
Fetch← T, T← Stack&+3;* T← data -- so that ShC R/T select
WF← Stack&-3, Branch[WFM2];* bits don’t matter
:EndIf;
**********************************

*-----------------------------------------------------------
IFUR[LP, 1, MDS];
* Lengthen Pointer
* p: POINTER ← Pop[]; PushLong[LengthenPointer[p]];
*-----------------------------------------------------------

DummyRef← 0S, PD← Stack&+1, T← MD, Branch[LPM1];
:IfMEP;
DummyRef← 0S, Stack&+1← PD← MD, Branch[LPM1];
DummyRef← 0S, PD← T, StkP+2, T← MD, Branch[LPM1];
:EndIf;

LPM1:
Branch[.+2, ALU=0];* Skip if NIL
StackT← VAHi, IFUNext2;* Lengthen with high part of MDS
StackT← A0, IFUNext2;* LONG[NIL]


*-----------------------------------------------------------
IFUR[BLTL, 1, MDS];
* Block Transfer Long
* DO
* dest: LONG POINTER ← PopLong[]; count: CARDINAL ← Pop[];
* source: LONG POINTER ← PopLong[];
* IF count=0 THEN EXIT;
* Store[dest]↑ ← Fetch[source]↑;
* PushLong[source+1]; Push[count-1]; PushLong[dest+1];
* IF InterruptPending[] THEN GOTO Suspend;
* REPEAT Suspend => PC ← savePC;
* ENDLOOP;
*-----------------------------------------------------------

T← Stack&-1, MemBase← BBDstBR, Branch[BLTLM1];
:IfMEP;
T← Stack&-1← B← MD, MemBase← BBDstBR, Branch[BLTLM1];
MemBase← BBDstBR, Branch[BLTLM1];
:EndIf;

BLTLM1:
RTemp0← A0, BRHi← T;
BRLo← Stack&-1;
T← Stack&-2, FlipMemBase;
BRLo← Stack&+1;
BRHi← Stack&+3;
RTemp1← A0, Call[BLTSetupTransfer];

* See comments under BLTSetupTransfer for how this loop works.
Subroutine;
BLTLMLoop:
MemBase← BBSrcBR, CoReturn;
StkP-2, Branch[BLTLMDone, ALU=0]; * T = words remaining
T← (Stack&-2)-(Q← T);* T← words done this time
Stack&+1← (Stack&+1)+T;* Advance dest pointer on stack
Stack&+1← A← Stack&+1, XorSavedCarry;
Stack&+1← Q;* Update count on stack
Stack&+1← (Stack&+1)+T;* Advance source pointer on stack
Stack← A← Stack, XorSavedCarry, Branch[BLTLMLoop];

TopLevel;

BLTLMDone:
StkP-3, IFUNext0;