{File name FixedLoadStore.mc
Description: Mesa Load and Store op-codes
Author: Sandman
Created: February 16, 1980
Last edited: Sturgis: 14-Jun-84 15:35:18
Sandman, January 27, 1981 5:56 PM
Garner, April 1, 1980 12:20 PM}
{The Load mesa op-codes consist of the following:
OPvalbytesstktime
LL010’b1+11
LL111’b1+11
LL212’b1+11
LL313’b1+11
LL414’b1+11
LL515’b1+11
LL616’b1+11
LL717’b1+11
LLB20’b2+11
LLDB21’b2+22
LG037’b1+11
LG140’b1+11
LG241’b1+11
LG342’b1+11
LG443’b1+11
LG544’b1+11
LG645’b1+11
LG746’b1+11
LGB47’b2+11
LGDB50’b2+22
LI056’b1+11
LI157’b1+11
LI260’b1+11
LI361’b1+11
LI462’b1+11
LI563’b1+11
LI664’b1+11
LIN165’b1+11
LINI66’b1+11
LIB67’b2+11
LIW70’b3+12
LINB71’b2+11
LADRB72’b2+12
GADRB73’b2+12
LCO74’b3+12
LP161’b1+11
The Store mesa op-codes consist of the following:
OPvalbytesstktime
SL022’b1-11
SL123’b1-11
SL224’b1-11
SL325’b1-11
SL426’b1-11
SL527’b1-11
SL630’b1-11
SL731’b1-11
SLB32’b2-11
SLDB162’b2-22
SG051’b1-11
SG152’b1-11
SG253’b1-11
SG354’b1-11
SGB55’b2-11
SGDB163’b2-22
PL034’b101
PL135’b101
PL236’b101
PL337’b101}
{Times for memory operations are + 2 if page cross + 2 if fix map flags}
{L2CarryMapRets}
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[$,LGDBCarry2,1],c2;
TOS ← MD, push, fZpop, DISPNI[OpTable], c3;
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;
{*****************************************************************************
Sturgis: 14-Jun-84 15:44:44
The following is additional carry logic for the case of second word in a page that page faults. The reason that this fix is so bad is that there are at least two case tables that are full, and so I have had to duplicate a lot of code here. The two case tables that are full are the RFixForTrap table, and RMapFixCaller.
The bug is that in the incorrect code, L1 was set to L1r.Pop2DecDec, to be used in the case of a fault, but in fact the value should have been Pop2Dec, but there is no such value, and the table is full. The reason it should have been Pop2Dec is that some joint code has temporarily subtracted 1 from the pc. Unfortunately, I can not simply replace this joint code, as the subroutine it uses has a full return list. So I must also duplicate the subroutine.
It is possible that no one else uses L1r.Pop2DecDec, in which I could replace this case with the one I want. However, it seems too painful to check this.
In the following I leave some indication of where the code is borrowed from.
*****************************************************************************}
{LGcarry}
LGDBCarry2:
TT ← UvG,c3;
{CarryMap}
Noop,c1;
Q ← Q - TT,c2;
Q ← Q and 0FF, c3;
{LcarryMap}
Map ← Q ← [rhMDS, TT+Q],c1;
Noop,c2;
Rx ← rhRx ← MD, XRefBr,c3;
{Read.RedoR}
LGDBCarry3:
MAR ← [rhRx, Q+0], BRANCH[LGDBCarry4, $], c1;
IBDisp,c2;
{LLTail}
TOS ← MD, push, fZpop, DISPNI[OpTable], c3;
{Read.RMapUD}
LGDBCarry4:
Noop,c2;
{CommonSubs.RMapFix}
Xbus ← Rx LRot0, XwdDisp, L3 ← L3.rhMDS.Q, c3;
Map ← [rhMDS,Q], DISP2[LGDBFixRFlags], c1;
LGDBFixRFlags:
MDR ← Rx or 10, GOTO[LGDBCarry5], c2, at[0,4];
MDR ← Rx or 10, GOTO[LGDBCarry5], c2, at[1,4, LGDBFixRFlags];
MDR ← Rx or 10, GOTO[LGDBCarry5], c2, at[2,4, LGDBFixRFlags];
T ← qPageFault, L1Disp, GOTO[RTrap], c2, at[3,4, LGDBFixRFlags];
LGDBCarry5:
Xbus ← 1, XDisp, GOTO[LGDBCarry3],c3;
{*****************************************************************************
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;
{14-Jun-84 15:36:28: Sturgis: repair nasty bug in LGDB, that occurs when second word is in a new page, and that page is not mapped in. The fix is gross, see comments in the opcode}