{/ Purcell 31-Jul-83 15:24:34
CJump.mc   26-Jul-83 11:20:28
}
	SetTask[0];

{*************************
	JUMP	1%  2 clicks
**************************}
JUMP:	MAR ← PC ← [rhPC, PC+1], GOTO[JnPos],	c1,opcode[200'b];{80}
	MAR ← PC ← [rhPC, PC+1+PC16], GOTO[JnPos],	c1,opcode[201'b];
	MAR ← PC ← [rhPC, PC+2], GOTO[JnPos],	c1,opcode[202'b];
	MAR ← PC ← [rhPC, PC+2+PC16], GOTO[JnPos],	c1,opcode[203'b];
	MAR ← PC ← [rhPC, PC+3], GOTO[JnPos],	c1,opcode[204'b];
	MAR ← PC ← [rhPC, PC+3+PC16], GOTO[JnPos],	c1,opcode[205'b];
	MAR ← PC ← [rhPC, PC+4], GOTO[JnPos],	c1,opcode[206'b];
	MAR ← PC ← [rhPC, PC+4+PC16], GOTO[JnPos],	c1,opcode[207'b];

	MAR ← PC ← [rhPC, PC+5], GOTO[JnPos],	c1,opcode[210'b];{88}
	MAR ← PC ← [rhPC, PC+5+PC16], GOTO[JnPos],	c1,opcode[211'b];
	MAR ← PC ← [rhPC, PC+6], GOTO[JnPos],	c1,opcode[212'b];
	MAR ← PC ← [rhPC, PC+6+PC16], GOTO[JnPos],	c1,opcode[213'b];
	MAR ← PC ← [rhPC, PC+7], GOTO[JnPos],	c1,opcode[214'b];
	MAR ← PC ← [rhPC, PC+7+PC16], GOTO[JnPos],	c1,opcode[215'b];
	MAR ← PC ← [rhPC, PC+8], GOTO[JnPos],	c1,opcode[216'b];
	MAR ← PC ← [rhPC, PC+8+PC16], GOTO[JnPos],	c1,opcode[217'b];

JnPos:	Xbus←0, XC2npcDisp, BRANCH[$, JnCross, 1],	c2;
	IB ← MD, BRANCH[ptr1, ptr0, 0E],	c3;

JnCross:	Q ← 0FF + 1, L0 ← L0.JRemap, CANCELBR[UpdatePC, 0F],	c3;

JUMPX:	S ← S+1, Xbus←ibNA, XLDisp, L2 ← L2.ok,	c1,opcode[260'b];{B0}
	Rx ← ib RShift1, XLDisp, SE ← 0, BRANCH[jxp, jxn, 1],	c2;
jxp:	Noop, BRANCH[jpe, jpo, 2],	c3;
jxn:	Rx ← 7F-Rx, L2Disp, BRANCH[jne, jno, 2],	c3;


{*************************
	FJUMP, TJUMP	4%  4 clicks
**************************}

FJUMP:	MAR ← [rhS, S], S ← S -1, L2 ← 0,	c1, opcode[220'b];{90}
	 Ybus ← TOSH or TOS, NZeroBr, CANCELBR[jmp, 2],	c2;
	MAR ← [rhS, S], S ← S -1, L2 ← 1,	c1, opcode[221'b];
	 Ybus ← TOSH or TOS, NZeroBr, CANCELBR[jmp, 2],	c2;
	MAR ← [rhS, S], S ← S -1, L2 ← 2,	c1, opcode[222'b];
	 Ybus ← TOSH or TOS, NZeroBr, CANCELBR[jmp, 2],	c2;
	MAR ← [rhS, S], S ← S -1, L2 ← 3,	c1, opcode[223'b];
	 Ybus ← TOSH or TOS, NZeroBr, CANCELBR[jmp, 2],	c2;
	MAR ← [rhS, S], S ← S -1, L2 ← 4,	c1, opcode[224'b];
	 Ybus ← TOSH or TOS, NZeroBr, CANCELBR[jmp, 2],	c2;
	MAR ← [rhS, S], S ← S -1, L2 ← 5,	c1, opcode[225'b];
	 Ybus ← TOSH or TOS, NZeroBr, CANCELBR[jmp, 2],	c2;
	MAR ← [rhS, S], S ← S -1, L2 ← 6,	c1, opcode[226'b];
	 Ybus ← TOSH or TOS, NZeroBr, CANCELBR[jmp, 2],	c2;
	MAR ← [rhS, S], S ← S -1, L2 ← 7,	c1, opcode[227'b];
	 Ybus ← TOSH or TOS, NZeroBr, CANCELBR[jmp, 2],	c2;
	MAR ← [rhS, S], S ← S -1, L2 ← 8,	c1, opcode[230'b];{98}
	 Ybus ← TOSH or TOS, NZeroBr, CANCELBR[jmp, 2],	c2;
	MAR ← [rhS, S], S ← S -1, L2 ← 9,	c1, opcode[231'b];
	 Ybus ← TOSH or TOS, NZeroBr, CANCELBR[jmp, 2],	c2;
	MAR ← [rhS, S], S ← S -1, L2 ← 0A,	c1, opcode[232'b];
	 Ybus ← TOSH or TOS, NZeroBr, CANCELBR[jmp, 2],	c2;
	MAR ← [rhS, S], S ← S -1, L2 ← 0B,	c1, opcode[233'b];
	 Ybus ← TOSH or TOS, NZeroBr, CANCELBR[jmp, 2],	c2;
	MAR ← [rhS, S], S ← S -1, L2 ← 0C,	c1, opcode[234'b];
	 Ybus ← TOSH or TOS, NZeroBr, CANCELBR[jmp, 2],	c2;
	MAR ← [rhS, S], S ← S -1, L2 ← 0D,	c1, opcode[235'b];
	 Ybus ← TOSH or TOS, NZeroBr, CANCELBR[jmp, 2],	c2;
	MAR ← [rhS, S], S ← S -1, L2 ← 0E,	c1, opcode[236'b];
	 Ybus ← TOSH or TOS, NZeroBr, CANCELBR[jmp, 2],	c2;
	MAR ← [rhS, S], S ← S -1, L2 ← 0F,	c1, opcode[237'b];
fj:	 Ybus ← TOSH or TOS, NZeroBr, CANCELBR[jmp, 2],	c2;

TJUMP:	MAR ← [rhS, S], S ← S -1, GOTO[tj],	c1, opcode[240'b];{A0}
	MAR ← [rhS, S], S ← S -1, GOTO[tj],	c1, opcode[241'b];
	MAR ← [rhS, S], S ← S -1, GOTO[tj],	c1, opcode[242'b];
	MAR ← [rhS, S], S ← S -1, GOTO[tj],	c1, opcode[243'b];
	MAR ← [rhS, S], S ← S -1, GOTO[tj],	c1, opcode[244'b];
	MAR ← [rhS, S], S ← S -1, GOTO[tj],	c1, opcode[245'b];
	MAR ← [rhS, S], S ← S -1, GOTO[tj],	c1, opcode[246'b];
	MAR ← [rhS, S], S ← S -1, GOTO[tj],	c1, opcode[247'b];
	MAR ← [rhS, S], S ← S -1, GOTO[tj],	c1, opcode[250'b];{A8}
	MAR ← [rhS, S], S ← S -1, GOTO[tj],	c1, opcode[251'b];
	MAR ← [rhS, S], S ← S -1, GOTO[tj],	c1, opcode[252'b];
	MAR ← [rhS, S], S ← S -1, GOTO[tj],	c1, opcode[253'b];
	MAR ← [rhS, S], S ← S -1, GOTO[tj],	c1, opcode[254'b];
	MAR ← [rhS, S], S ← S -1, GOTO[tj],	c1, opcode[255'b];
	MAR ← [rhS, S], S ← S -1, GOTO[tj],	c1, opcode[256'b];
	MAR ← [rhS, S], S ← S -1, GOTO[tj],	c1, opcode[257'b];
tj:	Ybus ← TOSH or TOS, ZeroBr, CANCELBR[jmp, 2],	c2;

jmp:	TOS ← MD, BRANCH[$, NoJump], L2Disp,	c3;

	MAR ← [rhS, S + 0], DISP4[TgetsL,1],	c1;
TgetsL:	Rx ← 1, L2Disp, GOTO[jjoin],	c2, at[1, 10, TgetsL];
	Rx ← 2, L2Disp, GOTO[jjoin],	c2, at[3, 10, TgetsL];
	Rx ← 3, L2Disp, GOTO[jjoin],	c2, at[5, 10, TgetsL];
	Rx ← 4, L2Disp, GOTO[jjoin],	c2, at[7, 10, TgetsL];
	Rx ← 5, L2Disp, GOTO[jjoin],	c2, at[9, 10, TgetsL];
	Rx ← 6, L2Disp, GOTO[jjoin],	c2, at[0B, 10, TgetsL];
	Rx ← 7, L2Disp, GOTO[jjoin],	c2, at[0D, 10, TgetsL];
	Rx ← 8, L2Disp, GOTO[jjoin],	c2, at[0F, 10, TgetsL];

NoJump:	MAR ← [rhS, S], S ← S -1, CANCELBR[$, 0F],	c1;
	PC ← PC+PC16, L2 ← L2.0, IBDisp, DISP2[njNoCar],	c2;
	S ← S - 0FF,	c3, at[2, 10, njNoCar];

	MAR ← [rhS, S+0],	c1;
	S ← S -1, L2 ← L2.0, IBDisp,	c2;
njNoCar:	TOSH ← MD, L2 ← L2.0, DISPNI[OpTable],	c3, at[0, 10, njNoCar];


{*************************
	FJUMPX, TJUMPX
**************************}
{based on the stack pointer conventions:}
{Q: does MAR← interfere with XLDisp when no pagecarry?}

FJUMPX:	MAR ← [rhS, S], S ← S -1, Xbus←ibNA, XLDisp,	c1, opcode[262'b];{B2}
	Ybus ← TOSH or TOS, {rhTOSH ← nRhS,} NZeroBr, BRANCH[pos, neg, 1],	c2;

TJUMPX:	MAR ← [rhS, S], S ← S -1, Xbus←ibNA, XLDisp,	c1, opcode[263'b];{B3}
	Ybus ← TOSH or TOS, {rhTOSH ← nRhS,} ZeroBr, BRANCH[pos, neg, 1],	c2;


{*************************
	NFJUMPX, NTJUMPX	2%  4 clicks
**************************}

NFJUMPX:	 {different on jump: don't pop}
	MAR ← [rhS, S], S ← S -1, Xbus←ibNA, XLDisp,	c1, opcode[264'b];{B4}
	Ybus ← TOSH or TOS, NZeroBr, BRANCH[Npos, Nneg, 1],	c2;

NTJUMPX:	MAR ← [rhS, S], S ← S -1, Xbus←ibNA, XLDisp,	c1, opcode[265'b];{B5}
	Ybus ← TOSH or TOS, ZeroBr, BRANCH[Npos, Nneg, 1],	c2;

Npos:	uTOS ← TOS, TOS ← MD, BRANCH[$, NoJumpP],	c3;
	TOS ← uTOS,	c1;
	Rx ← ib RShift1, XLDisp, SE ← 0,	c2;
	S ← S + 2, BRANCH[jpe, jpo, 2],	c3;

Nneg:	uTOS ← TOS, TOS ← MD, BRANCH[$, NoJumpF],	c3;
	Rx ← 0FF,	c1;
	Noop,	c2;
	Noop,	c3;
	TOS ← uTOS, {L2 ←   L2.TOS,}	c1;
	Rx ← (ib xor Rx) RShift1, XLDisp, SE ← 0,	c2;
	S ← S + 2, {L2Disp,} BRANCH[jne, jno, 2],	c3;




{*************************
	JUMPXX
**************************}

JUMPXX:	Rx ← ib, XLDisp,	c1,opcode[261'b];{B1}
jw:	Rx ← Rx LRot8, BRANCH[jwPos, jwNeg, 1],	c2;

jwPos:	Rx ← RShift1 (Rx or ib), SE←0, XLDisp, GOTO[jwtos],	c3;
jwNeg:	Rx ← RShift1 (Rx or ib), SE←1, XLDisp, GOTO[jwtos],	c3;

jwtos:	PC ← PC and 0FF, BRANCH[jwEven, jwOdd, 2],	c1;

{PC,,pc16←location in page}
jwEven:	PC ← PC + Rx, GOTO[jwCross],	c2;
jwOdd:	PC ← PC + Rx + PC16, GOTO[jwCross],	c2;

jwCross:	Q ← PC and ~0FF, L0 ← L0.JRemap, GOTO[UpdatePC],	c3;

{*************************
	Common Jump Code
**************************}
pos:	{uTOS ← TOS,} TOS ← MD, BRANCH[$, NoJumpX],	c3;

	MAR ← [rhS, S+0],	c1;
	Rx ← ib RShift1, XLDisp, SE ← 0,	c2;
jjoin:	{uTOSH ← TOSH,} TOSH ← MD, BRANCH[jpe, jpo, 0E],	c3; {!!!}

jpe:	MAR ← PC ← [rhPC, PC + Rx], GOTO[jp],	c1;
jpo:	MAR ← PC ← [rhPC, PC + Rx + PC16],	c1;
jp:	S ← S - 1, Xbus←0, {L2Disp,} XC2npcDisp, BRANCH[$, PCross, 1],	c2;
jp3:	IB ← MD, BRANCH[ptr1, ptr0, 0E],	c3;

ptr0:	MAR ← [rhPC, PC + 1], IBPtr←0, L2 ← L2.0, GOTO[RefillNE2],	c1; 
ptr1:	MAR ← [rhPC, PC + 1], IBPtr←1, L2 ← L2.0, GOTO[RefillNE2],	c1;


NoJumpP:	MAR ← [rhS, S], S ← S -1, Xbus ← ib, GOTO[nj],	c1;
NoJumpF:	MAR ← [rhS, S], S ← S -1, Xbus ← ib, GOTO[nj],	c1;
NoJumpN:	MAR ← [rhS, S], S ← S -1, Xbus ← ib, GOTO[nj],	c1;
NoJumpX:	MAR ← [rhS, S], S ← S -1, Xbus ← ib, GOTO[nj],	c1;
nj:	PC ← PC+1, IBDisp, L2 ← L2.0, DISP4[njxNoCar],	c2;
	S ← S - 0FF,	c3, at[2, 10, njxNoCar];

	MAR ← [rhS, S+0],	c1;
	S ← S -1, IBDisp, L2 ← L2.0,	c2;
njxNoCar:	TOSH ← MD, L2 ← L2.0, DISPNI[OpTable],	c3, at[0, 10, njxNoCar];



PCross:	Q ← 0FF + 1, L0 ← L0.JRemap, CANCELBR[UpdatePC, 0F],	c3;
NCross:	Q ← ~0FF, L0 ← L0.JRemap, CANCELBR[UpdatePC, 0F],	c3;


neg:	TOS ← MD, BRANCH[$, NoJumpN],	c3;

	TT ← 0FF,	c1;
	Noop, {elim by TOSH ← 0, rhTOSH ← MD}	c2;
	Noop, {MAR ← [rhTOSH, S], TOSH ← 0FF}	c3;

	STK ← MAR ← [rhS, S], {S ← 0FE+1, L2 ← L2.STK,}	c1;
	Rx ← (ib xor TT{S}) RShift1, SE ← 0, XLDisp, CANCELBR[$, 2],	c2;
	TOSH ← MD, BRANCH[jne, jno, 2], {L2Disp,}	c3;

jne:	MAR ← PC ← [rhPC, PC - Rx -1], DISP4[jn],	c1;
jno:	MAR ← PC ← [rhPC, PC - Rx - PC16], DISP4[jn],	c1;
jn:	S ← S - 1, XC2npcDisp, BRANCH[jn3, NCross, 0D],	c2, at[L2.ok, 10, jn];
{	S ← STK, XC2npcDisp, BRANCH[jn3, NCross, 0D],	c2, at[L2.STK, 10, jn];
	TOS ← uTOS, XC2npcDisp, BRANCH[jn3, NCross, 0D],	c2, at[L2.TOS, 10, jn];}
jn3:	{S ← S - 1,} IB ← MD, BRANCH[ptr1, ptr0, 0E],	c3;



{*************************}
{Buffer Empty Refill.  Control goes from NoRCross to RefillNE since RefillE+1 does not contain an IBDisp.}
RefillE:	MAR ← [rhPC, PC], PC ← PC-1, L0 ← L0.ERefill,	c1, at[400];
	PC ← PC+1 {restore}, DISP2[NoRCross],	c2;


{Buffer Not Empty Refill.}
OpTable:	{"Noop" location of Instruction Dispatch table}
RefillNE:		at[500],
	{Ybus ← S and 1, ZeroBr,	c1;
	Noop, BRANCH[sNoBreak, sBreak],	c2;
sBreak:	Q ← 3F, GOTO[sink1],	c3;
sNoBreak:	Noop,	c3;
	}
	{TEST IF TOSH NOT VALID}
	{Q ← 3F,	c1;
	Ybus ← Q - TOSH, NegBr,	c2;
	BRANCH[Refil, $],	c3;
	
	RegDef[u9111rhPC, U, 11],RegDef[u9111PC, U, 14],RegDef[u9111TOSH, U, 1C],
	RegDef[u9111vPC, U, 1A],RegDef[u9111vPCH, U, 3C],
X9111:
	Q ← rhPC,	c1;
	u9111rhPC ← Q,	c2;
	Q ← PC,	c3;
	u9111PC ← Q,	c1;
	Q ← UvChighL,	c2;
	u9111vPCH ← Q,	c3;
	Q ← UvPCpageL,	c1;
	u9111vPC ← Q,	c2;
	Q ← TOSH,	c3;
	u9111TOSH ← Q, c1;
	c2;
	GOTO[Refil],	c3;
}
Refil:{RefillNE:}
	MAR ← [rhPC, PC + 1], L2 ← L2.0,	c1{, at[500]};
RefillNE2:	AlwaysIBDisp, L0 ← L0.NERefill.Set, DISP2[NoRCross],	c2;

NoRCross:	IB ← MD, uPCCrossL ← 0, L2 ← L2.0, DISPNI[OpTable],	c3, at[0,4,NoRCross];
RCross:	Q ← 0FF + 1, GOTO[UpdatePC],	c3, at[2,4,NoRCross];

{************************
	Refill Remap Routines
*******************************}

{
Entry:
T	old real PC
Q[0-7]	page displacement to be added to virtual PC
Q[8-15]	ignored
PC[0-7]	ignored
PC[8-15]	valid location within new page
pc16	must be valid

Exit:
UvPCpageL	new virtual PC page
TT	new virtual PC page
rhTT	UvChighL
PC	new real PC value
Q	new real PC value
}
{L0.ERefill & uPCCrossL indicate remap and fetch (NE) PC+1}

UpdatePC:	TT ← UvPCpageL, L1 ← L1.Refill{for fault trap},	c1, at[0F,10];
UpdatePC2:	TT ← TT + Q, rhTT ← UvChighL,	c2;
UpdatePC3:	Q{lowPC} ← PC,	c3;

	Map ← MAR ← TT ← [rhTT, 0+0], L0Disp,	c1;
	Noop , DISP4[ECross],	c2;

	PC ← Q{lowPC},{+} GOTO[NoMoreFix],	c1, at[L1.Refill,10,Fix];

{Buffer Empty Refill page cross OR PCCross flag true.  Remap the PC (which points to 1st or 2nd word of page).  If we are doing an empty refill, return to the Empty Refill code at NoRCross.  If we are updating the PC because PCCross is true, return to Refill-interrupt code.}
{Even if we fault, have UvPCpageL updated.}

ECross:	UvPCpageL ← TT, PC ← MD, rhPC ← MD, XRefBr,	c3, at[L0.ERefill,10,ECross];

ERedo:	MAR ← Q ← [rhPC, Q+0], Xbus ← uPCCrossL, XRefBr, BRANCH[EMapUD, $],	c1, at[L0.ERefill,10,RMapFixCaller];
	PC ← Q, BRANCH[NoRCross, PageCrossed],	c2;

EMapUD:	Rx ← PC, CANCELBR[RLMapFix]  {returns at ERedo},	c2;


{Buffer Not Empty Refill page cross.  Fetch the first word of the next page and do NOT Remap PC.  Set PCCross true and the Refill-Interrupt hardware bit.  Dispatch on the IB (as in the RefillNE code).}

NECross:	Rx ← MD, rhRx ← MD, XRefBr,	c3, at[L0.NERefill,10,ECross];

NERedo:	MAR ← [rhRx, 0+0], MesaIntRq, BRANCH[NEMapUD, $],	c1, at[L0.NERefill,10,RMapFixCaller];
	AlwaysIBDisp, L2 ← L2.0,	c2;
	IB ← MD, uPCCrossL ← (~TT xor TT), L2 ← L2.0, DISPNI[OpTable],	c3;

NEMapUD:	uPCCrossL ← (~TT xor TT), CALL[RLMapFix]  {returns at NERedo},	c2;

{Jump Cross Remap.  Remap the PC (which can point to any word of a page).  uPCCrossL should remain unaltered in case the page cross test at Jgo is true.}
{Even if we fault, have UvPCpageL updated.}

JCross:	UvPCpageL ← TT, PC ← MD, rhPC ← MD, XRefBr,	c3, at[L0.JRemap,10,ECross];

JRedo:	MAR ← Q ← [rhPC, Q+0], BRANCH[JMapUD, $],	c1, at[L0.JRemap,10,RMapFixCaller];
	PC ← Q, Xbus←0, {L2Disp,} XC2npcDisp,	c2;
	IB ← MD, BRANCH[ptr1, ptr0, 0E],	c3;

JMapUD:	Rx ← PC, CALL[RLMapFix]  {returns at JRedo},	c2;

{*************************
	Interrupt Processing
**************************}
MInt0:			 at[600],
	TT ← 0{buffer empty}, Xbus ← uPCCrossL, XRefBr, GOTO[MInt],	c1{, at[600]};

MInt1:			 at[700],

{MInt1:}	TT ← TT xor ~TT{not empty}, Xbus ← uPCCrossL, XRefBr, GOTO[MInt],	c1{, at[700]};

MInt:	Ybus ← uWDC, NZeroBr, BRANCH[$, Crossing],	c2;
	TT ← uWP, ClrIntErr, BRANCH[Interuption, IgnoreInt],	c3;

IgnoreInt:	Noop,	c1;
IBDispOnlyL: IBDisp, L2 ← L2.0, GOTO[DISPNIonly],	c2;
DISPNIonly:	L2 ← L2.0, DISPNI[OpTable],	c3;

Interuption: Ybus ← TT, ZeroBr,	c1;
	BRANCH[Wakeups, NoWakeups],	c2;
{Wakeups:	Rx ← NWWInterrupt, GOTO[DoCall],	c3;}
NoWakeups:	GOTO[IgnoreInt],	c3;

Wakeups:		uWP ← 0,	c3;
	Rx ← 1,	c1;
	uWDC ← Rx,{off interrupts}	c2;
	Rx ← {0 -} KbdFXP, L2 ← 0{NotInCall}, GOTO[PuntFor],	c3;


{uPCCrossL is true.  Check if we are still on last word of page.  If not, go update the PC to point to the next page.  T contains 0 if buffer is empty, -1 otherwise.  This is put back into uPCCrossL.  If buffer is not empty control goes from ECross to PageCross which ignores the first word fetched.}

Crossing:	Ybus ← PC + 1, PgCarryBr, CANCELBR[$],	c3;
	{rCountL{%} ← rCountL + 1,}
	    L0 ← L0.ERefill, BRANCH[$, NotAcross],	c1;
	uPCCrossL ← TT, GOTO[RCross],	c2;

{We haven't crossed the boundary yet.  Save state again, keep uPCCrossL true.}

NotAcross:
	Rx ← LShift1 PC, Cin←pc16,	c2;
	{uCrSavePC ← Rx,}Cin←pc16 {restore}, GOTO[SaveStateR],	c3;

SaveStateR:
	Rx ← ~ErrnIBnStkp,	c1;
	AlwaysIBDisp, L2 ← L2.0,	c2;
	{uCrSaveStkp ← Rx,} L2 ← L2.0, DISPNI[OpTable],	c3;

{We've crossed the page boundary & updated the PC to point to the next page.  Zero uPCCrossL. We know the buffer is not empty, but we also know it is not full so we exit through RefillNE.}

PageCrossed:
	uPCCrossL ← 0, GOTO[RefillNE],	c3, at[1,4,NoRCross];

	{ E N D }