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