{File name LoadStore.mc
Description: Mesa Load and Store op-codes
Author: Sandman
Created: February 16, 1980
Last edited: Sandman, January 27, 1981 5:56 PM
Garner, April 1, 1980 12:20 PM}

{The Load mesa op-codes consist of the following:
OP
valbytesstktime
LL0
10’b1+11
LL1
11’b1+11
LL2
12’b1+11
LL3
13’b1+11
LL4
14’b1+11
LL5
15’b1+11
LL6
16’b1+11
LL7
17’b1+11
LLB
20’b2+11
LLDB
21’b2+22
LG0
37’b1+11
LG1
40’b1+11
LG2
41’b1+11
LG3
42’b1+11
LG4
43’b1+11
LG5
44’b1+11
LG6
45’b1+11
LG7
46’b1+11
LGB
47’b2+11
LGDB
50’b2+22
LI0
56’b1+11
LI1
57’b1+11
LI2
60’b1+11
LI3
61’b1+11
LI4
62’b1+11
LI5
63’b1+11
LI6
64’b1+11
LIN1
65’b1+11
LINI
66’b1+11
LIB
67’b2+11
LIW
70’b3+12
LINB
71’b2+11
LADRB
72’b2+12
GADRB
73’b2+12
LCO
74’b3+12
LP
161’b1+11

The Store mesa op-codes consist of the following:
OP
valbytesstktime
SL0
22’b1-11
SL1
23’b1-11
SL2
24’b1-11
SL3
25’b1-11
SL4
26’b1-11
SL5
27’b1-11
SL6
30’b1-11
SL7
31’b1-11
SLB
32’b2-11
SLDB
162’b2-22
SG0
51’b1-11
SG1
52’b1-11
SG2
53’b1-11
SG3
54’b1-11
SGB
55’b2-11
SGDB
163’b2-22
PL0
34’b101
PL1
35’b101
PL2
36’b101
PL3
37’b101}
{Times for memory operations are + 2 if page cross + 2 if fix map flags}

{L2
CarryMapRets}
Set[L2.Lcarry, 1];
Set[L2.LDcarry, 5];
Set[L2.Scarry, 0];
Set[L2.SLDcarry, 9];
Set[L2.SGDcarry, 0D]; {1 mod 4}

{*****************************************************************************
LLn{n:[0..7]} Load Local n 1 click
*****************************************************************************}
@LL0:MAR ← Q ← [rhL, L+4], L1 ← L1r.PopOnly, push, GOTO[LLns],c1, opcode[10’b];
@LL1:
MAR ← Q ← [rhL, L+5], L1 ← L1r.PopOnly, push, GOTO[LLns],c1, opcode[11’b];
@LL2:
MAR ← Q ← [rhL, L+6], L1 ← L1r.PopOnly, push, GOTO[LLns],c1, opcode[12’b];
@LL3:
MAR ← Q ← [rhL, L+7], L1 ← L1r.PopOnly, push, GOTO[LLns],c1, opcode[13’b];
@LL4:
MAR ← Q ← [rhL, L+8], L1 ← L1r.PopOnly, push, GOTO[LLns],c1, opcode[14’b];
@LL5:
MAR ← Q ← [rhL, L+9], L1 ← L1r.PopOnly, push, GOTO[LLns],c1, opcode[15’b];
@LL6:
MAR ← Q ← [rhL, L+0A], L1 ← L1r.PopOnly, push, GOTO[LLns],c1, opcode[16’b];
@LL7:
MAR ← Q ← [rhL, L+0B], L1 ← L1r.PopOnly, push, GOTO[LLns],c1, opcode[17’b];

LLns:
STK ← TOS, PC ← PC + PC16, IBDisp, L2←L2.Lcarry, BRANCH[LLTail,LLcarry,1],c2;
LLTail:
TOS ← MD, push, fZpop, DISPNI[OpTable],c3;

LLcarry:
TT ← UvL, GOTO[CarryMap],c3;

{*****************************************************************************
LLB Load Local Byte 1 click
*****************************************************************************}
@LLB:MAR ← Q ← [rhL, L+ib], L1 ← L1r.PopDec, push, GOTO[LLBs],c1, opcode[20’b];

LLBs:
STK ← TOS, PC ← PC + 1, IBDisp, L2←L2.Lcarry, BRANCH[LLTail,LLcarry,1],c2;
{*****************************************************************************
Load Carry Logic (shared between LLx and LGx)
*****************************************************************************}
CarryMap:Noop,c1;
CarryFix:
Q ← Q - TT, L2Disp,c2;
Q ← Q and 0FF, RET[CarryMapRets],c3;

LcarryMap:
Map ← Q ← [rhMDS, TT+Q],c1, at[Or[L2.Lcarry,2], 10, CarryMapRets];
PC ← PC-PC16,c2;
Rx ← rhRx ← MD, XRefBr, GOTO[RedoR],c3;

{*****************************************************************************
LGn{n:[0..7]} Load Global n 1 click
*****************************************************************************}
@LG0:MAR ← Q ← [rhG, G+3], L1 ← L1r.PopOnly, push, GOTO[LGns],c1, opcode[37’b];
@LG1:
MAR ← Q ← [rhG, G+4], L1 ← L1r.PopOnly, push, GOTO[LGns],c1, opcode[40’b];
@LG2:
MAR ← Q ← [rhG, G+5], L1 ← L1r.PopOnly, push, GOTO[LGns],c1, opcode[41’b];
@LG3:
MAR ← Q ← [rhG, G+6], L1 ← L1r.PopOnly, push, GOTO[LGns],c1, opcode[42’b];
@LG4:
MAR ← Q ← [rhG, G+7], L1 ← L1r.PopOnly, push, GOTO[LGns],c1, opcode[43’b];
@LG5:
MAR ← Q ← [rhG, G+8], L1 ← L1r.PopOnly, push, GOTO[LGns],c1, opcode[44’b];
@LG6:
MAR ← Q ← [rhG, G+9], L1 ← L1r.PopOnly, push, GOTO[LGns],c1, opcode[45’b];
@LG7:
MAR ← Q ← [rhG, G+0A], L1 ← L1r.PopOnly, push, GOTO[LGns],c1, opcode[46’b];

LGns:
STK ← TOS, PC ← PC + PC16, IBDisp, L2←L2.Lcarry, BRANCH[LGTail,LGcarry,1],c2;
LGTail:
TOS ← MD, push, fZpop, DISPNI[OpTable],c3;

LGcarry:
TT ← UvG, GOTO[CarryMap],c3;

{*****************************************************************************
LGB Load Global Byte 1 click
*****************************************************************************}
@LGB:MAR ← Q ← [rhG, G+ib], L1 ← L1r.PopDec, push, GOTO[LGBs],c1, opcode[47’b];

LGBs:
STK ← TOS, PC ← PC + 1, IBDisp, L2←L2.Lcarry, BRANCH[LGTail,LGcarry,1],c2;

{*****************************************************************************
LLDB Load Local Double Byte 2 clicks
*****************************************************************************}
@LLDB:MAR ← Q ← [rhL, L + ib], push, L1 ← L1r.PopDec,c1, opcode[21’b];
STK ← TOS, PC ← PC + PC16, L2←L2.LDcarry, BRANCH[$, LLDBcarry,1],c2;
TOS ← MD,c3;

LLDB2:
MAR ← Q ← [rhL, Q + 1], push, L1 ← L1r.Pop2DecDec,c1;
STK ← TOS, PC ← PC + PC16, IBDisp, L2←L2.Lcarry, BRANCH[LLTail,LLcarry,1],c2;

LLDBcarry:
TT ← UvL, GOTO[CarryMap],c3;
{*****************************************************************************
LGDB Load Global Double Byte 2 clicks
*****************************************************************************}
@LGDB:MAR ← Q ← [rhG, G + ib], push, L1 ← L1r.PopDec,c1, opcode[50’b];
STK ← TOS, PC ← PC + PC16, L2←L2.LDcarry, BRANCH[$, LGDBcarry,1],c2;
TOS ← MD,c3;

LGDB2:
MAR ← Q ← [rhG, Q + 1], push, L1 ← L1r.Pop2DecDec,c1;
STK ← TOS, PC ← PC + PC16, IBDisp, L2←L2.Lcarry, BRANCH[LGTail,LGcarry,1],c2;

LGDBcarry:
TT ← UvG, GOTO[CarryMap],c3;
{*****************************************************************************
Load Double Carry Logic (shared by LLDx and LGDx)
*****************************************************************************}
{First word on next page => remap page and get both words}
LDcarryMap:Map ← Q ← [rhMDS, TT+Q],c1, at[Or[L2.LDcarry,2], 10, CarryMapRets];
L0 ← L0.LDcarry,c2;
Rx ← rhRx ← MD, XRefBr,c3;

LDcarry:
MAR ← [rhRx, Q+0], BRANCH[LDcarryMapUD, $],c1, at[L0.LDcarry,10,RMapFixCaller];
Noop,c2;
TOS ← MD,c3;

MAR ← [rhRx, Q+1], push, GOTO[LLns],c1;

LDcarryMapUD:
CALL[RMapFix], {will return to LDcarry}c2;

{*****************************************************************************
LIn{n:[0..6]} Load Immeadiate n 1 click
*****************************************************************************}
@LI0:T ← 0, push, GOTO[LInTail],c1, opcode[56’b];
@LI1:
T ← 1, push, GOTO[LInTail],c1, opcode[57’b];
@LI2:
T ← 2, push, GOTO[LInTail],c1, opcode[60’b];
@LI3:
T ← 3, push, GOTO[LInTail],c1, opcode[61’b];
@LI4:
T ← 4, push, GOTO[LInTail],c1, opcode[62’b];
@LI5:
T ← 5, push, GOTO[LInTail],c1, opcode[63’b];
@LI6:
T ← 6, push, GOTO[LInTail],c1, opcode[64’b];

LInTail:
STK ← TOS, PC ← PC + PC16, IBDisp,c2;
PushT:
TOS ← T, push, fZpop, DISPNI[OpTable],c3;
{*****************************************************************************
LIN1 Load Immeadiate Negative One 1 click
*****************************************************************************}
@LIN1:T ← T xor ~T, push, GOTO[LInTail],c1, opcode[65’b];
{*****************************************************************************
LINI Load Immeadiate Negative Infinity 1 click
*****************************************************************************}
@LINI:T ← RShift1 0, SE ← 1, push, GOTO[LInTail],c1, opcode[66’b];

{*****************************************************************************
LIB Load Immeadiate Byte 1 click
*****************************************************************************}
@LIB:T ← ib, push,c1, opcode[67’b];
STK ← TOS, PC ← PC + 1, IBDisp, GOTO[PushT],c2;
{*****************************************************************************
LIW Load Immeadiate Word 2 clicks
*****************************************************************************}
@LIW:T ← ib, push,c1, opcode[70’b];
LIWx:
PC ← PC + 1,c2;
T ← T LRot8,c3;

T ← T or ib, GOTO[LInTail],c1;
{*****************************************************************************
LINB Load Immeadiate Negative Byte 1 click
*****************************************************************************}
@LINB:Q ← ib, push,c1, opcode[71’b];
STK ← TOS, PC ← PC + 1, push, fZpop, IBDisp,c2;
TOS ← Q xor ~0FF, DISPNI[OpTable],c3;
{*****************************************************************************
LADRB Local Address Byte 2 clicks
*****************************************************************************}
@LADRB:TT ← UvL,c1, opcode[72’b];
LADRBx:
T ← ib, push,c2;
PC ← PC + PC16,c3;

T ← TT + T, GOTO[LInTail],c1;
{*****************************************************************************
GADRB Global Address Byte 2 clicks
*****************************************************************************}
@GADRB:TT ← UvG, GOTO[LADRBx],c1, opcode[73’b];
{*****************************************************************************
LCO Load Code Offset 2 clicks
*****************************************************************************}
@LCO:T ← ib, push, GOTO[LIWx],c1, opcode[74’b];
{*****************************************************************************
LP Lengthen Pointer2 click
*****************************************************************************}
@LP:[] ← TOS, ZeroBr, fXpop, push,c1, opcode[161’b];
BRANCH[LPnot, LPnil],c2;
LPnot:
T ← UvMDS, GOTO[LPTail],c3;
LPnil:
T ← 0, GOTO[LPTail],c3;

LPTail:
push, GOTO[LInTail],c1;

{*****************************************************************************
SLn{n:[0..7]} Store Local n 1 click
*****************************************************************************}
@SL0:MAR ← Q ← [rhL, L+4], L1 ← L1w.DecOnly, push, GOTO[SLns],c1, opcode[22’b];
@SL1:
MAR ← Q ← [rhL, L+5], L1 ← L1w.DecOnly, push, GOTO[SLns],c1, opcode[23’b];
@SL2:
MAR ← Q ← [rhL, L+6], L1 ← L1w.DecOnly, push, GOTO[SLns],c1, opcode[24’b];
@SL3:
MAR ← Q ← [rhL, L+7], L1 ← L1w.DecOnly, push, GOTO[SLns],c1, opcode[25’b];
@SL4:
MAR ← Q ← [rhL, L+8], L1 ← L1w.DecOnly, push, GOTO[SLns],c1, opcode[26’b];
@SL5:
MAR ← Q ← [rhL, L+9], L1 ← L1w.DecOnly, push, GOTO[SLns],c1, opcode[27’b];
@SL6:
MAR ← Q ← [rhL, L+0A], L1 ← L1w.DecOnly, push, GOTO[SLns],c1, opcode[30’b];
@SL7:
MAR ← Q ← [rhL, L+0B], L1 ← L1w.DecOnly, push, GOTO[SLns],c1, opcode[31’b];

SLns:
MDR ← STK ← TOS, PC ← PC + PC16, pop, IBDisp, BRANCH[$,SLcarry,1],c2;
SLTail:
TOS ← STK, pop, DISPNI[OpTable],c3;

SLcarry:
TT ← UvL, L2←L2.Scarry, GOTO[CarryMap],c3;

{*****************************************************************************
SLB Store Local Byte 1 click
*****************************************************************************}

@SLB:
MAR ← Q ← [rhL, L+ib], L1 ← L1w.DecDec, push, GOTO[SLBs],c1, opcode[32’b];

SLBs:
MDR ← STK ← TOS, PC ← PC + 1, pop, IBDisp, BRANCH[SLTail,SLcarry,1],c2;

{*****************************************************************************
PLn{n:[0..3]} Put Local n 1 click
*****************************************************************************}
{no page carry possible on local 0-3}
@PL0:MAR ← Q ← [rhL, L+4], fXpop, push, GOTO[PLns],c1, opcode[33’b];
@PL1:
MAR ← Q ← [rhL, L+5], fXpop, push, GOTO[PLns],c1, opcode[34’b];
@PL2:
MAR ← Q ← [rhL, L+6], fXpop, push, GOTO[PLns],c1, opcode[35’b];
@PL3:
MAR ← Q ← [rhL, L+7], fXpop, push, GOTO[PLns],c1, opcode[36’b];

PLns:
MDR ← TOS, PC ← PC + PC16, IBDisp, CANCELBR[DISPNIonly,0],c2;
{*****************************************************************************
Store Carry Logic (shared between SLx and SGx)
*****************************************************************************}
ScarryMap:Map ← Q ← [rhMDS, TT+Q], {map next page}c1, at[L2.Scarry, 10, CarryMapRets];
L0 ← L0.Scarry,c2;
Rx ← rhRx ← MD, XDirtyDisp,c3;

Scarry:
MAR ← [rhRx, Q+0], BRANCH[ScarryMapUD, $, 1],c1, at[L0.Scarry,10,WMapFixCaller];
SGStore:
MDR ← TOS, IBDisp, CANCELBR[SLTail,0],c2;

ScarryMapUD:
CALL[WMapFix], {will return to Scarry}c2;

{*****************************************************************************
SGn{n:[0..7]} Store Global n 1 click
*****************************************************************************}
@SG0:Q ← G + 3, PgCarryBr, L1←L1w.DecOnly, GOTO[SGns],c1, opcode[51’b];
@SG1:
Q ← G + 4, PgCarryBr, L1←L1w.DecOnly, GOTO[SGns],c1, opcode[52’b];
@SG2:
Q ← G + 5, PgCarryBr, L1←L1w.DecOnly, GOTO[SGns],c1, opcode[53’b];
@SG3:
Q ← G + 6, PgCarryBr, L1←L1w.DecOnly, GOTO[SGns],c1, opcode[54’b];

SGns:
Xbus ← rhG, XDirtyDisp, push, BRANCH[SGnNoCross, SGnCross],c2;
SGnNoCross:
STK ← TOS, pop, PC ← PC + PC16, BRANCH[SGMapFix, SGMapOK, 1],c3;
SGnCross:
STK ← TOS, pop, PC ← PC + PC16, CANCELBR[SGCrossFix,3],c3;

SGMapOK:
MAR ← [rhG, Q+0], GOTO[SGStore]c1;
SGMapFix:TT ← UvG, L2←L2.Scarry,c1;
SGMapFixx:
Q ← Q - TT,c2;
Q ← Q and 0FF,c3;

Map ← [rhMDS, TT],c1;
L2Disp,c2;
rhG ← MD, RET[CarryMapRets],c3;

SGCrossFix:
TT ← UvG, L2←L2.Scarry, GOTO[SGMapFixx],c1;


{*****************************************************************************
SGB Store Global Byte 1 click
*****************************************************************************}
@SGB:Q ← G + ib, PgCarryBr, L1 ← L1w.DecDec,c1, opcode[55’b];

SGBs:
Xbus ← rhG, XDirtyDisp, push, BRANCH[SGbNoCross, SGbCross],c2;

SGbNoCross:
STK ← TOS, pop, PC ← PC + 1, BRANCH[SGMapFix, SGMapOK, 1],c3;
SGbCross:
STK ← TOS, pop, PC ← PC + 1, CANCELBR[SGCrossFix,3],c3;

{*****************************************************************************
SLDB Store Local Double Byte 2 clicks
*****************************************************************************}
@SLDB:MAR ← Q ← [rhL, L + ib], L1 ← L1w.NoFixes,c1, opcode[162’b];
MDR ← STK, push, L2←L2.SLDcarry, BRANCH[$, SLDBcarry,1],c2;
PC ← PC + PC16, STK ← TOS, pop,c3;

SLDB2:
MAR ← Q ← [rhL, Q + 1], pop, L1 ← L1w.PushDecDec,c1;
SLDB2x:
MDR ← TOS, PC ← PC + PC16, IBDisp, BRANCH[SLTail,SLcarry,1],c2;

SLDBcarry:
TT ← UvL, GOTO[CarryMap],c3;

{*****************************************************************************
SGDB Store Global Double Byte 2 clicks
*****************************************************************************}
@SGDB:Q ← G + ib + 1, PgCarryBr, L2←L2.SGDcarry,c1, opcode[163’b];
Xbus ← rhG, Q ← Q - 1, XDirtyDisp, push, BRANCH[$,SGDBcarry],c2;
STK ← TOS, pop, BRANCH[SGDBMapFix, SGDBMapOK, 1],c3;

SGDBMapOK:
MAR ← Q ← [rhG, Q + 0],c1;
MDR ← STK,c2;
PC ← PC + PC16,c3;

MAR ← [rhG, Q + 1], pop, GOTO[SLDB2x],c1;

SGDBMapFix:
TT ← UvG, CALL[SGMapFixx],c1;

T ← TOS, L1 ← L1w.PushDec,c1, at[L2.SGDcarry,10,CarryMapRets];
Q ← TT + Q, GOTO[WDBx],c2;

SGDBcarry:
STK ← TOS, pop, CANCELBR[$,3],c3;
TT ← UvG, CALL[SGMapFixx],c1;

{*****************************************************************************
Store Double Carry Logic (shared by SLDx)
*****************************************************************************}
{First word on next page => remap page and store both words}
SDcarryMap:Map ← Q ← [rhMDS, TT+Q],c1, at[Or[L2.SLDcarry,2], 10, CarryMapRets];
L0 ← L0.SDcarry,c2;
Rx ← rhRx ← MD, XDirtyDisp, pop,c3;

SDcarry:
MAR ← [rhRx, Q+0], BRANCH[SDcarryMapUD, $, 1],c1, at[L0.SDcarry,10,WMapFixCaller];
MDR ← STK, push,c2;
STK ← TOS, PC ← PC + PC16, pop,c3;

MAR ← [rhRx, Q+1], pop,c1;
MDR ← TOS, PC ← PC + PC16, IBDisp, CANCELBR[SLTail,0],c2;

SDcarryMapUD:
CALL[WMapFix], {will return to SDcarry}c2;