Title[M-Group.mc...May 6, 1980 4:56 PM...Taft];

KnowRBase[AEmRegs];
TopLevel;

* Caution: Do not execute ←Stack, StkP← in the same instruction --
* it doesn’t work!!

* LDA, page 0 [4 cycles]
LDAz:
T← ID;
T← ID, StkP← T, Branch[LDAx];

* LDA, PC-relative [7 cycles]
LDApc:
ETemp← ID, Call[EffAdrPCRel];
StkP← ETemp, Branch[LDAx];

* LDA, AC2- and AC3-relative [5 cycles]
LDA2:
T← ID, StkP← spAC2, Branch[LDA23];
LDA3:
T← ID, StkP← spAC3, Branch[LDA23];
LDA23:
ETemp← ID+(Stack);
T← ETemp, StkP← T, Branch[LDAx];

* LDA indirect, page 0 [5 cycles]
LDAiz:
ETemp← ID;
Fetch← ID, Branch[LDAix];

* LDA indirect, PC-relative [8 cycles]
LDAipc:
ETemp← ID, Call[EffAdrPCRel];
Fetch← T, Branch[LDAix];

* LDA indirect, AC2- and AC3-relative [6 cycles]
LDAi2:
T← ID, StkP← spAC2, Branch[LDAi23];
LDAi3:
T← ID, StkP← spAC3, Branch[LDAi23];
LDAi23:
ETemp← ID+(Stack);
ETemp← T, Fetch← ETemp;
LDAix:
T← MD, StkP← ETemp;
LDAx:
Fetch← T;
StackGetsMD:
Stack← MD, IFUJump[0];

EmIFUReg[040, LDAz, 0, nspAC0];
EmIFUReg[050, LDAz, 0, nspAC1];
EmIFUReg[060, LDAz, 0, nspAC2];
EmIFUReg[070, LDAz, 0, nspAC3];
EmIFUReg[041, LDApc, 1, nspAC0];
EmIFUReg[051, LDApc, 1, nspAC1];
EmIFUReg[061, LDApc, 1, nspAC2];
EmIFUReg[071, LDApc, 1, nspAC3];
EmIFUReg[042, LDA2, 1, nspAC0];
EmIFUReg[052, LDA2, 1, nspAC1];
EmIFUReg[062, LDA2, 1, nspAC2];
EmIFUReg[072, LDA2, 1, nspAC3];
EmIFUReg[043, LDA3, 1, nspAC0];
EmIFUReg[053, LDA3, 1, nspAC1];
EmIFUReg[063, LDA3, 1, nspAC2];
EmIFUReg[073, LDA3, 1, nspAC3];
EmIFUReg[044, LDAiz, 0, nspAC0];
EmIFUReg[054, LDAiz, 0, nspAC1];
EmIFUReg[064, LDAiz, 0, nspAC2];
EmIFUReg[074, LDAiz, 0, nspAC3];
EmIFUReg[045, LDAipc, 1, nspAC0];
EmIFUReg[055, LDAipc, 1, nspAC1];
EmIFUReg[065, LDAipc, 1, nspAC2];
EmIFUReg[075, LDAipc, 1, nspAC3];
EmIFUReg[046, LDAi2, 1, nspAC0];
EmIFUReg[056, LDAi2, 1, nspAC1];
EmIFUReg[066, LDAi2, 1, nspAC2];
EmIFUReg[076, LDAi2, 1, nspAC3];
EmIFUReg[047, LDAi3, 1, nspAC0];
EmIFUReg[057, LDAi3, 1, nspAC1];
EmIFUReg[067, LDAi3, 1, nspAC2];
EmIFUReg[077, LDAi3, 1, nspAC3];

* STA, page 0 [3 cycles]
STAz:
T← ID;
T← ID, StkP← T, Branch[STAx];

* STA, PC-relative [6 cycles]
* The IFU must be restarted after "STA .+n" for small n, since it might
* have pre-fetched the old value. Since PC-relative STA is relatively
* uncommon, we just restart the IFU unconditionally.
STApc:
ETemp← ID, Call[EffAdrPCRel];
StkP← ETemp;
Store← T, DBuf← Stack;
T← (1S)-Q, Branch[StartIFU];* T← PCX+2

* STA, AC2- and AC3-relative [4 cycles]
STA2:
T← ID, StkP← spAC2, Branch[STA23];
STA3:
T← ID, StkP← spAC3, Branch[STA23];
STA23:
ETemp← ID+(Stack);
T← ETemp, StkP← T, Branch[STAx];

* STA indirect, page 0 [4 cycles]
STAiz:
ETemp← ID;
Fetch← ID, Branch[STAix];

* STA indirect, PC-relative [7 cycles]
STAipc:
ETemp← ID, Call[EffAdrPCRel];
Fetch← T, Branch[STAix];

* STA indirect, AC2- and AC3-relative [5 cycles]
STAi2:
T← ID, StkP← spAC2, Branch[STAi23];
STAi3:
T← ID, StkP← spAC3, Branch[STAi23];
STAi23:
ETemp← ID+(Stack);
ETemp← T, Fetch← ETemp;
STAix:
T← MD, StkP← ETemp;
STAx:
Store← T, DBuf← Stack, IFUJump[0];

EmIFUReg[100, STAz, 0, nspAC0];
EmIFUReg[110, STAz, 0, nspAC1];
EmIFUReg[120, STAz, 0, nspAC2];
EmIFUReg[130, STAz, 0, nspAC3];
IFUPause[101, 2, MDS, rbAEmRegs, STApc, nspAC0, 1, 0];
IFUPause[111, 2, MDS, rbAEmRegs, STApc, nspAC1, 1, 0];
IFUPause[121, 2, MDS, rbAEmRegs, STApc, nspAC2, 1, 0];
IFUPause[131, 2, MDS, rbAEmRegs, STApc, nspAC3, 1, 0];
EmIFUReg[102, STA2, 1, nspAC0];
EmIFUReg[112, STA2, 1, nspAC1];
EmIFUReg[122, STA2, 1, nspAC2];
EmIFUReg[132, STA2, 1, nspAC3];
EmIFUReg[103, STA3, 1, nspAC0];
EmIFUReg[113, STA3, 1, nspAC1];
EmIFUReg[123, STA3, 1, nspAC2];
EmIFUReg[133, STA3, 1, nspAC3];
EmIFUReg[104, STAiz, 0, nspAC0];
EmIFUReg[114, STAiz, 0, nspAC1];
EmIFUReg[124, STAiz, 0, nspAC2];
EmIFUReg[134, STAiz, 0, nspAC3];
EmIFUReg[105, STAipc, 1, nspAC0];
EmIFUReg[115, STAipc, 1, nspAC1];
EmIFUReg[125, STAipc, 1, nspAC2];
EmIFUReg[135, STAipc, 1, nspAC3];
EmIFUReg[106, STAi2, 1, nspAC0];
EmIFUReg[116, STAi2, 1, nspAC1];
EmIFUReg[126, STAi2, 1, nspAC2];
EmIFUReg[136, STAi2, 1, nspAC3];
EmIFUReg[107, STAi3, 1, nspAC0];
EmIFUReg[117, STAi3, 1, nspAC1];
EmIFUReg[127, STAi3, 1, nspAC2];
EmIFUReg[137, STAi3, 1, nspAC3];

* ISZ, DSZ share the same code, and are distinguished by
* the value of N (2 = ISZ, 0 = DSZ).
* Timings are for result#0 and result=0.

* ISZ, page 0 [6, 11 cycles]
ISZz:
ETemp← ID-1;
T← Fetch← ID, Branch[ISZx];

* ISZ, PC-relative [9, 14 cycles]
ISZpc:
ETemp← ID-1, Call[EffAdrPCRel];
Fetch← T, Branch[ISZx];

* ISZ, AC2- and AC3-relative [7, 12 cycles]
ISZ2:
T← ID-1, StkP← spAC2, Branch[ISZ23];
ISZ3:
T← ID-1, StkP← spAC3, Branch[ISZ23];
ISZ23:
ETemp← ID+(Stack);
T← Fetch← ETemp, Q← T;
ETemp← Q, Branch[ISZx];

* ISZ indirect, page 0 [8, 13 cycles]
ISZiz:
ETemp← ID-1;
Fetch← ID, Branch[ISZix];

* ISZ indirect, PC-relative [11, 16 cycles]
ISZipc:
ETemp← ID-1, Call[EffAdrPCRel];
ISZixf:
Fetch← T, Branch[ISZix];

* ISZ indirect, AC2- and AC3-relative [9, 14 cycles]
ISZi2:
T← ID-1, StkP← spAC2, Branch[ISZi23];
ISZi3:
T← ID-1, StkP← spAC3, Branch[ISZi23];
ISZi23:
ETemp← ID+(Stack);
Fetch← ETemp, ETemp← T, Branch[ISZix];

ISZix:
T← Fetch← MD;
ISZx:
ETemp← (ETemp)+MD;
Store← T, DBuf← ETemp, DblBranch[DoSkip, NoSkip, ALU=0];

* ISZ opcodes
EmIFUReg[020, ISZz, 0, 2];
EmIFUReg[021, ISZpc, 1, 2];
EmIFUReg[022, ISZ2, 1, 2];
EmIFUReg[023, ISZ3, 1, 2];
EmIfuReg[024, ISZiz, 0, 2];
EmIFUReg[025, ISZipc, 1, 2];
EmIFUReg[026, ISZi2, 1, 2];
EmIFUReg[027, ISZi3, 1, 2];

* DSZ opcodes
EmIFUReg[030, ISZz, 0, 0];
EmIFUReg[031, ISZpc, 1, 0];
EmIFUReg[032, ISZ2, 1, 0];
EmIFUReg[033, ISZ3, 1, 0];
EmIfuReg[034, ISZiz, 0, 0];
EmIFUReg[035, ISZipc, 1, 0];
EmIFUReg[036, ISZi2, 1, 0];
EmIFUReg[037, ISZi3, 1, 0];

* The non-indirect instructions start with MemBase = CODE.

* JMP, page 0 [7 cycles]
JMPz:
T← ID, Branch[JMPx];

* JMP, PC-relative [9 cycles]
JMPpc:
T← 2(ID), Q← PCX’, Call[EffAdrPCRel1];
JMPx:
BRLo← T, ETemp← A0, B← MD;* Wait for previous ref to complete
PCF← ETemp;
RCODE← T, Branch[NoSkip];

* JMP, AC2- and AC3-relative [8 cycles]
JMP2:
StkP← spAC2, Branch[JMP23];
JMP3:
StkP← spAC3, Branch[JMP23];
JMP23:
T← ID+(Stack), Branch[JMPx];

* JMP indirect, page 0 [8 cycles]
JMPiz:
Fetch← ID, FlipMemBase, Branch[JMPix];

* JMP indirect, PC-relative [11 cycles]
JMPipc:
T← 2(ID), Q← PCX’, Call[EffAdrPCRel1];
JMPixf:
Fetch← T, FlipMemBase;
JMPix:
T← MD, Branch[JMPx];

* JMP indirect, AC2- and AC3-relative [10 cycles]
JMPi2:
StkP← spAC2, Branch[JMPi23];
JMPi3:
StkP← spAC3, Branch[JMPi23];
JMPi23:
T← ID+(Stack), Branch[JMPixf];

EmIFUPause[000, JMPz, CODE, 0];
EmIFUPause[001, JMPpc, CODE, 1];
EmIFUPause[002, JMP2, CODE, 1];
EmIFUPause[003, JMP3, CODE, 1];
EmIFUPause[004, JMPiz, MDS, 0];
EmIFUPause[005, JMPipc, MDS, 1];
EmIFUPause[006, JMPi2, MDS, 1];
EmIFUPause[007, JMPi3, MDS, 1];

* The non-indirect instructions start with MemBase = CODE.

* JSR, page 0 [9 cycles normally]
* Branches to BCPL runtime microcode on JSR 300 - 377.
JSRz:
ETemp← (ID)-(300C);
T← (ETemp)+(300C), Branch[JSRz300, ALU>=0];
JSRzx:
Q← PCX’, Branch[JSRx];

* JSR, PC-relative [9 cycles]
JSRpc:
T← 2(ID), Q← PCX’, Call[EffAdrPCRel1];
JSRx:
BRLo← T, ETemp← A0, B← MD;* Wait for previous ref to complete
PCF← ETemp;
StkP← spAC3;
Stack← (NOT Q) RSH 1;
RCODE← T, Q← RCODE;
Stack← (Stack)+Q+1, IFUJump[0];

* JSR, AC2- and AC3-relative [8 cycles]
JSR2:
StkP← spAC2, Branch[JSR23];
JSR3:
StkP← spAC3, Branch[JSR23];
JSR23:
T← ID+(Stack), Branch[JSRzx];

* JSR indirect, page 0 [10 cycles normally]
* Branches to BCPL runtime microcode on JSR @340 - 377.
JSRiz:
ETemp← (ID)-(340C);
T← (ETemp)+(340C), Branch[JSRiz340, ALU>=0];
Fetch← T, FlipMemBase, Branch[JSRix];

* JSR indirect, PC-relative [11 cycles]
JSRipc:
T← 2(ID), Q← PCX’, Call[EffAdrPCRel1];
JSRixf:
Fetch← T, FlipMemBase;
JSRix:
T← MD, Q← PCX’, Branch[JSRx];

* JSR indirect, AC2- and AC3-relative [10 cycles]
JSRi2:
StkP← spAC2, Branch[JSRi23];
JSRi3:
StkP← spAC3, Branch[JSRi23];
JSRi23:
T← ID+(Stack), Branch[JSRixf];


* JSR opcodes
* Define the page 0 and page 0 indirect JSRs to be Regular rather than Pause
* so that if the JSR is intercepted by the BCPL runtime, the BCPL runtime
* routines can exit without having to restart the IFU.
IFUReg[010, 2, CODE, rbAemRegs, JSRz, 17, 0, 0];
EmIFUPause[011, JSRpc, CODE, 1];
EmIFUPause[012, JSR2, CODE, 1];
EmIFUPause[013, JSR3, CODE, 1];
IFUReg[014, 2, MDS, rbAemRegs, JSRiz, 17, 0, 0];
EmIFUPause[015, JSRipc, MDS, 1];
EmIFUPause[016, JSRi2, MDS, 1];
EmIFUPause[017, JSRi3, MDS, 1];