{
File name StringField.mc
Description: Mesa String op-codes

Author: don charnley
Trow	22-Oct-87 22:07:45 Change XwdDisp to XdwDisp.
Trow	13-Oct-87 15:31:31 Reverse targets 1 and 2 of XwdDisp.
Fiala 20-May-86 10:00:40 Bugfix for 4MB storage.
Fiala 16-May-86 11:17:34 Changes for 4MB storage.
R. Garner, April 8, 1980  7:09 PM
Charnley, April 8, 1980  5:44 PM
Johnsson, March 13, 1981  5:43 PM
Created: February 26, 1980
}



{The string mesa op-codes consist of the following:
OP	val	bytes	stk	time
RSTR	120'b	2	2+1	4
RSTRL	153'b	2	3+1	5
WSTR	121'b	2	3	5
WSTRL	154'b	2	4	6
}
{The field mesa op-codes consist of the following:
OP	val	field	bytes	stack	time
RF	112'b	s	3	1+1	 4
RF0	xxx	s	2	1+1	 4
RFL	155'b	s	3	2+1	 5
RFS	135'b	d	1	2+1	 5
RFSL	157'b	d	1	3+1	 6
RFC	134'b	s	3	1+1	 5
RILF	xxx	s	2	+1	 5
RILPF	xxx	s	3	+1	 6
RBIT	xxx	s	2	1+1	 4
RILBIT	xxx	s	2	+1	 5
WF	113'b	s	3	2	 9
WFL	156'b	s	3	3	10
WFS	136'b	d	1	3	10
WFSL	160'b	d	1	4	11
WSF	132'b	s	3	2	10
PSF	xxx	s	3	2+1	10
	s	means uses Field Seletor
	d	means uses Field Descriptor
}
{	codes used for L0
	indicate where to return from fixing the map flags
	return is relative to RMapFixCaller
}
{	codes used for L1
	indicate how to reset state if page fault encountered
	return is relative to RFixForTrap
}
{	codes used for L3
	indicate where to return from long string common code
	return is relative to strL
}
Set[ L3.rstrl, 0 ],
Set[ L3.wstrl, 2 ];


{
	RSTR
}
{@RSTR, alpha}
{Timing:	4 clicks, + 2 if fix map flags}

{		entry:		exit:
							
  TOS =		|  inx	|	|  byte	|
						
  STK =		|  ~	|	|  ~	|
	      -->	|  ptr	|	|  ~	|
		|  v	|      -->	|  v	|	}

@RSTR:	T ← TOS{inx} + ib, L0 ← L0.RstrR	,c1, opcode[120'b];
	Q ← STK{ptr}, pop, L1 ← L1r.PushDecDec	,c2;
	TT ← RShift1 T, pop	,c3;

	Map ← Q ← [rhMDS,TT + Q], push	,c1;
	PC ← PC + 1	,c2;
	Rx ← rhRx ← MD, XRefBr	,c3;

RstrR:	MAR ← [rhRx,Q + 0], BRANCH[rstrMapUD,$]	,c1, at[L0.RstrR,10, RMapFixCaller];
	[] ← T and 1, ZeroBr	,c2;
rstrEnd:	T ← MD, BRANCH[rD.right,rD.left]	,c3;

rD.left:	T ← T and ~0FF	,c1;
	TOS ← T LRot8{byte}, IBDisp, GOTO[strCom]	,c2;

rD.right:	TOS ← T and 0FF, GOTO[IBDispOnly],	,c1;

DISPNIonly:
strCom:	DISPNI[OpTable]	,c3;

rstrMapUD:	CALL[RMapFix] {will return to RstrR}	,c2;


{
	RSTRL
}
{@RSTRL, alpha}
{Timing:	5 clicks, + 1 if ptrH needs fix, + 2 if fix map flags}

{		entry:		exit:
							
  TOS =		|  inx	|	|  byte	|
						
  STK =		|  ~	|	|  ~	|
	      -->	|  ptrH	|	|  ptrH	|
		|  ptrL	|	|  ~	|
		|  v	|      -->	|  v	|	}


@RSTRL:	T ← TOS{inx} + ib, CarryBr, L3 ← L3.rstrl	,c1, opcode[153'b];
	rhTT ← STK{ptrH}, BRANCH[rstrlNoC,rstrlC]	,c2;
rstrlNoC:	Rx ← RShift1 T, SE←0, pop, GOTO[xstrlCom]	,c3;
rstrlC:	Rx ← RShift1 T, SE←1, pop, GOTO[xstrlCom]	,c3;

xstrlCom:	TT ← STK{ptrL}, pop, L2 ← L2.xSTRL	,c1;
	TT ← TT + Rx, CarryBr, L1 ← L1.Push2DecDec	,c2;
	PC ← PC + 1, pop, BRANCH[rstrlRhOk,$]	,c3;

rhTTIncB:	Q ← rhTT	,c1;
rhTTIncBx:	Q ← Q + 1, pRet2	,c2;
	rhTT ← Q LRot0, RET[rhTTIncBRets]	,c3;

rstrlRhOk:	Map ← Q ← [rhTT,TT], L3Disp	,c1, at[L2.xSTRL,10,rhTTIncBRets];
	push, DISP2[strL,1]	,c2;
strL:	Rx ← rhRx ← MD, XRefBr	,c3, at[Or[L3.rstrl,1],4,strL];

RstrlR:	MAR ← [rhRx,Q + 0], L0 ← L0.RstrlR, BRANCH[rstrlMapUD,$]	,c1, at[L0.RstrlR,10, RMapFixCaller];
	[] ← T and 1, ZeroBr, GOTO[rstrEnd]	,c2;

rstrlMapUD:	CALL[RLMapFix] {will return to RstrlR}	,c2;


{
	WSTR
}
{@WSTR, alpha}
{Timing:	5 clicks, + 2 if fix map flags}

{		entry:		exit:
							
  TOS =		|  inx	|	|  v	|
						
  STK =		|  ~	|	|  ~	|
	      -->	|  ptr	|	|  ptr	|
		|  byte	|	|  byte	|
		|  v	|	|  v	|
		|  u	|      -->	|  u	|	}

@WSTR:	T ← TOS{inx} + ib, L0 ← L0.WstrR,		c1, opcode[121'b];
	Q ← STK{ptr}, L1 ← L1w.PushDecDec,		c2;
	TT ← RShift1 T,					c3;

	Map ← Q ← [rhMDS,TT + Q],			c1;
	PC ← PC + 1,					c2;
{db}	Rx ← rhRx ← MD, XdwDisp, pop,			c3;

WstrR:	MAR ← [rhRx,Q + 0], DISP2[wstrMapUD],		c1, at[L0.WstrR,10, WMapFixCaller];
wstrMapUD:
	CALL[WMapFix] {will return to WstrR},		c2, at[0, 4, wstrMapUD];
{db}	CALL[WMapFix] {WP fault},			c2, at[1, 4, wstrMapUD];
	CALL[WMapFix] {Page fault},			c2, at[3, 4, wstrMapUD];
{db}	Ybus ← T, T ← STK{byte}, pop, YDisp,		c2, at[2, 4, wstrMapUD];
wstrTail:
	TT ← MD, DISP4[wD.left,0E] {test odd/even},	c3;

wD.left:
	T ← T{byte} and 0FF,				c1, at[0E,10,wD.left];
	T ← T LRot8,					c2;
	TT ← TT{mem} and 0FF, GOTO[WstrW],		c3;

wD.right:
	T ← T{byte} and 0FF,				c1, at[0F,10,wD.left];
	TT ← TT{mem} and ~0FF,				c2;
wsrtrX:	Noop, GOTO[WstrW],				c3;

WstrW:	MAR ← [rhRx,Q + 0],				c1;
	MDR ← TT or T, IBDisp, GOTO[SLTail],		c2;


{
	WSTRL
}
{@WSTRL, alpha}
{Timing:	6 clicks, + 1 if ptrH needs fix, + 2 if fix map flags}

{		entry:		exit:
							
  TOS =		|  inx	|	|  v	|
						
  STK =		|  ~	|	|  ~	|
	      -->	|  ptrH	|	|  ~	|
		|  ptrL	|	|  ptrL	|
		|  byte	|	|  byte	|
		|  v	|	|  v	|
		|  u	|      -->	|  u	|	}

@WSTRL:	T ← TOS{inx} + ib, CarryBr, L3 ← L3.wstrl,	c1, opcode[154'b];
	rhTT ← STK{ptrH}, BRANCH[wstrlNoC,wstrlC],	c2;
wstrlNoC:
	Rx ← RShift1 T, SE ← 0, pop, GOTO[xstrlCom],	c3;
wstrlC:	Rx ← RShift1 T, SE ← 1, pop, GOTO[xstrlCom],	c3;

{db}	Rx ← rhRx ← MD, XdwDisp,			c3, at[Or[L3.wstrl,1],4,strL];

WstrlR:	MAR ← [rhRx,Q + 0], DISP2[wstrlMapUD],		c1, at[L0.WstrlR,10, WMapFixCaller];
wstrlMapUD:
	L0 ← L0.WstrlR, CALL[WLMapFix] {will return to WstrlR},	c2, at[0, 4, wstrlMapUD];
{db}	L0 ← L0.WstrlR, CALL[WLMapFix] {WP fault},		c2, at[1, 4, wstrlMapUD];
	L0 ← L0.WstrlR, CALL[WLMapFix] {Page fault},		c2, at[3, 4, wstrlMapUD];
{db}	Ybus ← T, T ← STK{byte}, pop, YDisp, GOTO[wstrTail],	c2, at[2, 4, wstrlMapUD];


{
	RF
}
{@RF, alpha, fd}
{Timing:	4 clicks, + 2 if fix map flags}

{		entry:		exit:
							
  TOS =		|  ptr	|	|  field	|
						
  STK =		|  ~	|	|  ~	|
	      -->	|  u	|      -->	|  u	|	}

@RF:	TT ← TOS + ib{alpha}, L1 ← L1r.NoFixes	,c1, opcode[112'b];
	rhTT ← UvMDS	,c2;
	Noop	,c3;

rfMap:	Map ← Q ← [rhTT,TT], L0 ← L0.rflR	,c1, at[L2.RFL,10,rhTTIncBRets];
rfX:	T ← fd.pos, pop	,c2;
	Rx ← rhRx ← MD, XRefBr, push	,c3;

rfR:	MAR ← [rhRx,Q + 0], BRANCH[rfRMapUD,$]	,c1, at[L0.rflR,10, RxMapFixCaller];
	T ← T + ib{fd.size} + 1, rhT ← ib{fd.size}	,c2;
rfA:	T ← MD{data}, Ybus ← T{shift}, YDisp, L2 ← L2.rfRetPC3	,c3;

rfB:	TT ← LRot1 T, Xbus ← 1, XDisp, DISP4[CycleMask]	,c1;

	{CycleMask Subroutine Here}

rfRetPC3:	TOS ← TOS and TT, IBDisp	,c2, at[L2.rfRetPC3,10,MaskRet];
	PC ← 1 + PC + 1, Cin←pc16, DISPNI[OpTable]	,c3;

rfRMapUD:	CALL[RLxMapFix] {will return to rfR}	,c2;


{
	RF0
}
{@RF0, fd}
{Timing:	4 clicks, + 2 if fix map flags}

{		entry:		exit:
							
  TOS =		|  ptr	|	|  field	|
						
  STK =		|  ~	|	|  ~	|
	      -->	|  u	|      -->	|  u	|	}

	{ UNUSED AT PRESENT
@RF0:	Map ← Q ← [rhMDS,TOS], L1 ← L1r.NoFixes	,c1, opcode[3D];
	T ← fd.pos, pop	,c2;
	Rx ← rhRx ← MD, XRefBr, push	,c3;

rfR0:	MAR ← [rhRx,Q + 0], L0 ← L0.rfR0, BRANCH[rfR0MapUD,$]	,c1, at[L0.rfR0,10, RxMapFixCaller];
	T ← T + ib{fd.size} + 1, rhT ← ib{fd.size}	,c2;
rfA1:	T ← MD{data}, Ybus ← T{shift}, YDisp, L2 ← L2.rfRetPC2	,c3;

rfB1:	TT ← LRot1 T, Xbus ← 1, XDisp, DISP4[CycleMask]	,c1;

	{CycleMask Subroutine Here}

rfRetPC2:	TOS ← TOS and TT, IBDisp	,c2, at[L2.rfRetPC2,10,MaskRet];
	PC ← PC + 1, Cin←pc16, DISPNI[OpTable]	,c3;

rfR0MapUD:	CALL[RxMapFix] {will return to rfR0}	,c2;
	}


{
	RFL
}
{@RFL, alpha, fd}
{Timing:	5 clicks, + 2 if fix map flags, + 1 if fix rh}

{		entry:		exit:
							
  TOS =		|  ptrH	|	|  field	|
						
  STK =		|  ~	|	|  ~	|
	      -->	|  ptrL	|	|  ~	|
		|  u	|      -->	|  u	|	}


@RFL:	TT ← STK{ptrL}, pop, L1 ← L1r.PushOnly	,c1, opcode[155'b];
	TT ← TT + ib{alpha}, CarryBr, L2 ← L2.RFL	,c2;
	rhTT ← TOS{ptrH} LRot0, BRANCH[rfMap,$]	,c3;

	Q ← rhTT, CALL[rhTTIncBx]{returns to rfMap}	,c1;

{
	RFS
}
{@RFS}
{Timing:	5 clicks, + 2 if fix map flags}

{		entry:		exit:
							
  TOS =		|  desc	|	|  field	|
						
  STK =		|  ~	|	|  ~	|
	      -->	|  ptr	|	|  ~	|
		|  u	|      -->	|  u	|	}

@RFS:	T ← TOS{desc} LRot8	,c1, opcode[135'b];
	Q ← 0FF and T{desc.offset}	,c2;
	TT ← STK, pop, L0 ← L0.rfsR	,c3;

	Map ← Q ← [rhMDS,TT + Q], L1 ← L1r.PushOnly	,c1;
	T ← TOS LRot12{desc.pos} + TOS{desc.size} + 1	,c2, Suppress Timing Warning {low 4 bits only};
	Rx ← rhRx ← MD, XRefBr	,c3;

rfsR:	MAR ← [rhRx,Q + 0], BRANCH[rfsRMapUD,$]	,c1, at[L0.rfsR,10, RxMapFixCaller];
	rhT ← TOS{desc.size} LRot0	,c2;
rfsA:	T ← MD{data}, Ybus ← T{shift}, YDisp, L2 ← L2.rfRetPC1	,c3;

	TT ← LRot1 T, Xbus ← 1, XDisp, DISP4[CycleMask]	,c1;

	{CycleMask Subroutine Here}

rfRetPC1:	TOS ← TOS and TT, IBDisp, fXpop, push,	,c2, at[L2.rfRetPC1,10,MaskRet];
	PC ← PC + 0, Cin←pc16, DISPNI[OpTable]	,c3;

rfsRMapUD:	CALL[RxMapFix] {will return to rfsR}	,c2;


{
	RFSL
}
{@RFSL}
{Timing:	6 clicks, + 2 if fix map flags, + 1 if rh fix}

{		entry:		exit:
							
  TOS =		|  desc	|	|  field	|
						
  STK =		|  ~	|	|  ~	|
	      -->	|  ptrH	|	|  ~	|
		|  ptrL	|	|  ~	|
		|  u	|      -->	|  u	|	}


@RFSL:	T ← TOS{desc} LRot8, L1 ← L1r.Push2Only	,c1, opcode[157'b];
	T ← 0FF and T{desc.offset}	,c2;
	rhTT ← STK{ptrH}, pop	,c3;

	TT ← STK{ptrL}, pop, L0 ← L0.rfslR	,c1;
	TT ← TT + T, CarryBr, L2 ← L2.RFSL	,c2;
	BRANCH[rfslMap,$]	,c3;

	Q ← rhTT, CALL[rhTTIncBx]	,c1;

rfslMap:	Map ← Q ← [rhTT,TT]	,c1, at[L2.RFSL,10,rhTTIncBRets];
	T ← TOS LRot12{desc.pos} + TOS{desc.size} + 1	,c2, Suppress Timing Warning {low 4 bits only};
	Rx ← rhRx ← MD, XRefBr	,c3;

rfslR:	MAR ← [rhRx,Q + 0], BRANCH[rfslRMapUD,$]	,c1, at[L0.rfslR,10, RxMapFixCaller];
	rhT ← TOS{desc.size} LRot0, GOTO[rfsA]	,c2;

rfslRMapUD:	CALL[RLxMapFix] {will return to rfslR}	,c2;


{
	RFC
}
{@RFC, alpha, fd}
{Timing:	5 clicks, + 2 if fix map flags}

{		entry:		exit:
							
  TOS =		|  offset	|	|  field	|
						
  STK =		|  ~	|	|  ~	|
	      -->	|  u	|      -->	|  u	|	}


@RFC:	TT ← UvC{codeBase low}, L1 ← L1r.NoFixes	,c1, opcode[134'b];
	TT ← TT + ib	,c2;
	rhTT ← UvChigh{codeBase high}	,c3;

	Map ← Q ← [rhTT,TOS + TT], L0 ← L0.rflR, GOTO[rfX]	,c1;


{
	RILF
}
{@RILF, fd}
{Timing:	5 clicks, + 2 if fix map flags}
{A page cross doens't occur for local 0}

{		entry:		exit:
							
  TOS =		|  v	|	|  field	|
						
  STK =		|  ~	|	|  ~	|
		|  ~	|      -->	|  v	|
	      -->	|  u	|	|  u	|	}


	{ UNUSED AT PRESENT
@RILF:	MAR ← Q ← [rhL,L + Lbias], push	,c1, opcode[xxx];
	STK ← TOS{v}, CANCELBR[$,2]	,c2;
	TT ← MD	,c3;

rilfMap:	Map ← Q ← [rhMDS,TT], L1 ← L1r.PopOnly	,c1;
	T ← fd.pos	,c2;
	Rx ← rhRx ← MD, XRefBr, GOTO[rfR0]	,c3;
	}


{
	RILPF
}
{@RILPF, alpha, fd}
{Timing:	6 clicks, + 2 if fix map flags, + 3 if remap L}
{A page cross doens't occur for local 0}

{		entry:		exit:
							
  TOS =		|  v	|	|  field	|
						
  STK =		|  ~	|	|  ~	|
		|  ~	|      -->	|  v	|
	      -->	|  u	|	|  u	|	}


	{ UNUSED AT PRESENT
@RILPF:	TT ← Lbias, push, L2 ← L2.rilpfMap	,c1, opcode[xxx];
	TT ← alpha.left + TT, L1 ← L1r.PopOnly	,c2;
	T ← alpha.right 	,c3;

	MAR ← Q ← [rhL,L + TT]	,c1;
	STK ← TOS{v}, BRANCH[$,LRemaprf1,1]	,c2;
	Q ← MD, GOTO[rilpfX]	,c3;

rilpfMap:	Q ← TT	,c1, at[L2.rilpfMap,10,LGRemapCaller];
	Noop	,c2;
	Noop	,c3;

rilpfX:	Map ← Q ← [rhMDS,T + Q], Xbus ← ib{alpha}	,c1;
	T ← fd.pos	,c2;
	Rx ← rhRx ← MD, XRefBr, GOTO[rfR]	,c3;

LRemaprf1:	CALL[LGxRemap] {will return to rilpfMap}	,c3;
	}


{
	RBIT
}
{@RBIT, alpha(alpha.left, fd.pos)}
{Timing:	4 clicks, + 2 if fix map flags}

{		entry:		exit:
							
  TOS =		|  ptr	|	|  field	|
						
  STK =		|  ~	|	|  ~	|
	      -->	|  u	|      -->	|  u	|	}


	{ UNUSED AT PRESENT
@RBIT:	Map ← Q ← [rhMDS,TOS + alpha.left], L1 ← L1r.NoFixes	,c1, opcode[xxx];
	T ← ib{fd.pos} + 1, pop	,c2;
	Rx ← rhRx ← MD, XRefBr, push	,c3;


rbitR:	MAR ← [rhRx,Q + 0], L0 ← L0.rbitR, BRANCH[rbitRMapUD,$]	,c1, at[L0.rbitR,10, RxMapFixCaller];
	rhT ← 0, GOTO[rfA1]	,c2;

rbitRMapUD:	CALL[RMapFix] {will return to rbitR}	,c2;
	}


{
	RILBIT
}
{@RILBIT, alpha(alpha.left, fd.pos)}
{Timing:	5 clicks, + 2 if fix map flags}
{A page cross can't occur or local 0}

{		entry:		exit:
							
  TOS =		|  v	|	|  field	|
						
  STK =		|  ~	|	|  ~	|
		|  ~	|      -->	|  v	|
	      -->	|  u	|	|  u	|	}


	{ UNUSED AT PRESENT
@RILBIT:	MAR ← Q ← [rhL,L + Lbias], push	,c1, opcode[xxx];
	STK ← TOS{v}, L1 ← L1r.PopOnly, CANCELBR[$,2]	,c2;
	TT ← MD	,c3;

rilbitMap:	Map ← Q ← [rhMDS,TT + alpha.left]	,c1;
	T ← ib{fd.pos} + 1, L1 ← L1r.PopOnly	,c2;
	Rx ← rhRx ← MD, XRefBr, GOTO[rbitR]	,c3;
	}


{
	WF
}
{@WF, alpha, fd}
{Timing:	9 clicks, + 2 if fix map flags}

{		entry:		exit:
							
  TOS =		|  ptr	|	|  v	|
						
  STK =		|  ~	|	|  ptr	|
	      -->	|  field	|	|  field	|
		|  v	|	|  v	|
		|  u	|      -->	|  u	|	}

@WF:	TT ← TOS + ib{alpha}, L1 ← L1w.NoFixes,		c1, opcode[113'b];
	rhTT ← UvMDS, push,				c2;
	STK ← TOS, pop,					c3;

wfMap:	Map ← Q ← [rhTT, TT],				c1, at[L2.WFL,10,rhTTIncBRets];
	T ← Q,						c2;
wfMapx:
{db}	Rx ← rhRx ← MD, XdwDisp,			c3;

wfR:	MAR ← [rhRx,Q + 0], DISP2[wfRMapUD],		c1, at[L0.wfR,10, WxMapFixCaller];
wfRMapUD:
	GOTO[wfRMapUD1] {will return to wfR},		c2, at[0, 4, wfRMapUD];
{db}	GOTO[wfRMapUD1] {WP fault},			c2, at[1, 4, wfRMapUD];
	GOTO[wfRMapUD1] {Page fault},			c2, at[3, 4, wfRMapUD];
{db}	TOS ← ib{fd}, uTemp ← T,			c2, at[2, 4, wfRMapUD];
wfA:	Q ← MD{data},					c3;

	T ← STK,					c1;
	Xbus ← ~TOS LRot12, XDisp,			c2;
	Xbus ← MaskRetA, XDisp, DISP4[MaskTbl],		c3;

	{MaskTbl Subroutine here,			c1:}
	uFrame ← TT,					c2, at[MaskRetA,10,MaskRet];
	TOS ← TOS LRot12 + TOS,				c3, Suppress Timing Warning {only low 4 bits used};

	rhT ← ~TOS LRot0,				c1;
	Ybus ← ~TOS, YDisp, L2 ← L2.MaskRetB,		c2;
	TT ← LRot1 T, Xbus ← 1, XDisp, DISP4[CycleMask],	c3;

	{CycleMask Subroutine Here}

wfRet:	TT ← RShift1 ~TT, SE←1,				c1, at[L2.MaskRetB,10,MaskRet];
	TT ← uFrame and TT{TT now has mem alligned mask},	c2;
	Q ← Q and ~TT, L1Disp,				c3;

wfSpec:	PC ← PC + 1 + PC16, DISP4[wfSpecA],		c1;
wfSpecA:
	TOS ← TOS and TT,				c2, at[L1w.NoFixes,10,wfSpecA];
wfSpecB:
	T ← uTemp,					c3;

wfW:	MAR ← [rhRx,T + 0],				c1;
	MDR ← Q or TOS, pop, IBDisp, GOTO[SLTail],	c2;

wfRMapUD1:
	L0 ← L0.wfR,					c3;
	Noop,						c1;
	CALL[WLxMapFix],				c2;


{
	WFL
}
{@WFL, alpha, fd}
{Timing:	10 clicks, + 2 if fix map flags, + 1 if fix rh}

{		entry:		exit:
							
  TOS =		|  ptrH	|	|  v	|
						
  STK =		|  ~	|	|  ~	|
	      -->	|  ptrL	|	|  ptrL	|
		|  field	|	|  field	|
		|  v	|	|  v	|
		|  u	|      -->	|  u	|	}


@WFL:	TT ← STK{ptrL}, pop, L2 ← L2.WFL	,c1, opcode[156'b];
	TT ← TT + ib{alpha}, CarryBr, L1←L1w.PushOnly	,c2;
	rhTT ← TOS{ptrH} LRot0, BRANCH[wfMap,$]	,c3;

	Q ← rhTT, CALL[rhTTIncBx]	,c1;

	TOS ← TOS and TT, GOTO[wfSpecB]	,c2, at[L1w.PushOnly,10,wfSpecA];


{
	WFS
}
{@WFS}
{Timing:	10 clicks, + 2 if fix map flags}

{		entry:		exit:
							
  TOS =		|  desc	|	|  v	|
						
  STK =		|  ~	|	|  ~	|
	      -->	|  ptr	|	|  ptr	|
		|  field	|	|  field	|
		|  v	|	|  v	|
		|  u	|      -->	|  u	|	}


@WFS:	T ← TOS{desc} LRot8	,c1, opcode[136'b];
	Q ← 0FF and T{desc.offset}	,c2;
	TT ← STK, pop, L0 ← L0.wfsR	,c3;

	Map ← Q ← [rhMDS,TT + Q]	,c1;
	uTemp ← Q, L1 ← L1w.PushOnly	,c2;
{db}	Rx ← rhRx ← MD, XdwDisp	,c3;

wfsR:	MAR ← [rhRx,Q + 0], DISP2[wfsRMapUD],		c1, at[L0.wfsR,10, WxMapFixCaller];
wfsRMapUD:
	CALL[WxMapFix] {will return to wfsR},		c2, at[0, 4, wfsRMapUD];
{db}	CALL[WxMapFix] {WP fault},			c2, at[1, 4, wfsRMapUD];
	CALL[WxMapFix] {Page fault},			c2, at[3, 4, wfsRMapUD];
{db}	PC ← PC - 1, L1 ← L1w.NoFixes, GOTO[wfA],	c2, at[2, 4, wfsRMapUD];


{
	WFSL
}
{@WFSL}
{Timing:	11 clicks, + 2 if fix map flags, + 1 if fix rh}

{		entry:		exit:
							
  TOS =		|  desc	|	|  v	|
						
  STK =		|  ~	|	|  ~	|
	      -->	|  ptrH	|	|  ptrH	|
		|  ptrL	|	|  ptrL	|
		|  field	|	|  field	|
		|  v	|	|  v	|
		|  u	|      -->	|  u	|	}

@WFSL:	T ← TOS{desc} LRot8, pop	,c1, opcode[160'b];
	Q ← 0FF and T{desc.offset}	,c2;
	TT ← STK{ptrL}, push	,c3;

	L2 ← L2.WFSL	,c1,;
	TT ← TT + Q{desc.offset}, CarryBr, L0←L0.wfslR	,c2;
	rhTT ← STK{ptrH}, pop, BRANCH[wfslMap,$]	,c3;

	Q ← rhTT, CALL[rhTTIncBx]	,c1;

wfslMap:
	Map ← Q ← [rhTT,TT],				c1, at[L2.WFSL,10,rhTTIncBRets];
	uTemp ← Q, L1 ← L1w.Push2Only,			c2;
{db}	Rx ← rhRx ← MD, XdwDisp, pop,			c3;

wfslR:	MAR ← [rhRx,Q + 0], DISP2[wfslRMapUD],		c1, at[L0.wfslR,10, WxMapFixCaller];
wfslRMapUD:
	CALL[WLxMapFix] {will return to wfslR},		c2, at[0, 4, wfslRMapUD];
{db}	CALL[WLxMapFix] {WP fault},			c2, at[1, 4, wfslRMapUD];
	CALL[WLxMapFix] {Page fault},			c2, at[3, 4, wfslRMapUD];
{db}	PC ← PC - 1, L1 ← L1w.NoFixes, GOTO[wfA],	c2, at[2, 4, wfslRMapUD];


{
	WSF
}
{@WSF, alpha, fd}
{Timing:	9 clicks, + 2 if fix map flags}

{		entry:		exit:
							
  TOS =		|  field	|	|  v	|
						
  STK =		|  ~	|	|  field	|
	      -->	|  ptr	|	|  ptr	|
		|  v	|	|  v	|
		|  u	|      -->	|  u	|	}


@WSF:	Q ← STK, push	,c1, opcode[132'b];
	TT ← Q + ib{alpha}, L1 ← L1w.PopOnly	,c2;
	rhTT ← UvMDS  	,c3;

	Map ← Q ← [rhTT, TT]	,c1;
	T ← Q, STK ← TOS, GOTO[wfMapx]	,c2;

	TOS ← TOS and TT, pop, GOTO[wfSpecB]	,c2, at[L1w.PopOnly,10,wfSpecA];


{
	PSF
}
{@WSF, alpha, fd}
{Timing:	10 clicks, + 2 if fix map flags}

{		entry:		exit:
							
  TOS =		|  field	|	|  ptr	|
						
  STK =		|  ~	|	|  field	|
	      -->	|  ptr	|	|  ~	|
		|  v	|      -->	|  v	|	}


	{ UNUSED AT PRESENT
@PSF:	TT ← STK, push,					c1, opcode[xxx];
	STK ← TOS{field}, L1 ← L1w.PopOnly,		c2;
	Noop,						c3;

	Map ← Q ← [rhMDS,TT + ib{alpha}],		c1;
	Noop,						c2;
{db}	Rx ← rhRx ← MD, XdwDisp, GOTO[wfR],		c3;

	PC ← 1 + PC + 1, Cin←pc16, GOTO[wfSpecA],	c1, at[L2.MaskRetC,10,wfSpec];
	}