{File name dbLisp.mc -- modified for Punt testing
Description: DandeLion InterLisp Emulator
Author: Purcell
Created: June 8, 1981 on mem content trap
Last edited: Lichtenberg 9-Jun-85 18:25:01 %4 tried to make ufn call work right
Last edited: Lichtenberg 28-Jul-85 18:27:46 %x% CANCELBR[$] --> ReadCANCELBR[$]
Last edited: Purcell, 3-Feb-85 14:17:41 {%3} apply2 moved from Xufn.
Last edited: Purcell, 3-Feb-85 14:17:41 {%2} Daybreak starts at 0 with 1 trap.
Last edited: Charnley, 23-Mar-84 10:34:55 added L1 set in FNX
Last edited: Charnley, 8-Dec-83 14:12:11 added sink1 org
Last edited: Charnley, 17-Oct-83 16:50:25
Last edited: Purcell 31-Jul-83 17:32:28 fix FNXCross not to depend on S which may be distorted by SCar5
Last Edited: Lichtenberg 31-Jul-83 18:13:40 :: Steve: read comment where you made last change - had to add a click
Last edited: Charnley, 20-Jul-83 11:45:32
Last edited: Charnley, April 14, 1983 11:04 AM; MUL tail added
Last edited: Purcell, April 6, 1983 6:34 PM; Fugato
Last edited: Purcell, March 6, 1983 6:18 PM pad base of stack twice not once
Last edited: Purcell, February 5, 1983 11:42 AM;
Last edited: Purcell, December 27, 1982 9:52 PM; segmentcrossing
Last edited: Purcell, July 27, 1982 12:34 PM}
{use DandeLisp.df, Dandelion.df and Mesa.df for defs}
SetTask[0];
{*************************}
{Traps and Errors: do hard reset}
{*************************}
sink2:
c2;
sink3:
c3;
sink1: at[B0sink1],
uRx ← Rx, CANCELBR[$, 0F], c1;
uTT ← TT, c2;
Rx ← 23, c3;
Rx ← Rx LRot8, c1;
Rx{9000=2328h} ← Rx +28, c2;
Q ← Rx +Q{error#}, GOTO[MPWait], c3;
ErrTrap: Rx ← RRot1 ErrnIBnStkp, ClrIntErr, CANCELBR[$, 0F], c1, at[0];
ErrLoop: Xbus ← Rx LRot0, XwdDisp, c2;
DISP2[CSParErr], c3;
CSParErr: Q ← 0+1, GOTO[sink2], c1, at[0,4,CSParErr];{MP9001}
Q ← 5, {GOTO[sink2],} c1, at[1,4,CSParErr];;{MP9005}
Noop,c2;
GOTO[Germ], c3;{%2}
StackErr: Q ← 2, {CANCELBR[sink2, 3],%M}GOTO[sink2], c1, at[2,4,CSParErr];{MP9002}
IBEmptyErr: Q ← 3, {CANCELBR[sink2, 3],%M}GOTO[sink2], c1, at[3,4,CSParErr];{MP9003}
{*************************
IVAR, IVARX, PVAR, PVARX, FVAR, FVARX, STOREN 25% 4 clicks
**************************}
{L0 set to low nible of opcode; set L3 to 0-3 for I,P,F or S var}
IVAR: MAR ← S ← [rhS, S + 1], GOTO[IVar1], L3 ← 0, c1, opcode[100'b];{40}
MAR ← S ← [rhS, S + 1], GOTO[IVar1], L3 ← 0, c1, opcode[101'b];
MAR ← S ← [rhS, S + 1], GOTO[IVar1], L3 ← 0, c1, opcode[102'b];
MAR ← S ← [rhS, S + 1], GOTO[IVar1], L3 ← 0, c1, opcode[103'b];
MAR ← S ← [rhS, S + 1], GOTO[IVar1], L3 ← 0, c1, opcode[104'b];
MAR ← S ← [rhS, S + 1], GOTO[IVar1], L3 ← 0, c1, opcode[105'b];
MAR ← S ← [rhS, S + 1], GOTO[IVar1], L3 ← 0, c1, opcode[106'b];
IVARX: MAR ← S ← [rhS, S + 1], GOTO[IVar1], L3 ← 0, c1, opcode[107'b];
PVAR: MAR ← S ← [rhS, S + 1], GOTO[PVar1], L3 ← 1, c1, opcode[110'b];{48}
MAR ← S ← [rhS, S + 1], GOTO[PVar1], L3 ← 1, c1, opcode[111'b];
MAR ← S ← [rhS, S + 1], GOTO[PVar1], L3 ← 1, c1, opcode[112'b];
MAR ← S ← [rhS, S + 1], GOTO[PVar1], L3 ← 1, c1, opcode[113'b];
MAR ← S ← [rhS, S + 1], GOTO[PVar1], L3 ← 1, c1, opcode[114'b];
MAR ← S ← [rhS, S + 1], GOTO[PVar1], L3 ← 1, c1, opcode[115'b];
MAR ← S ← [rhS, S + 1], GOTO[PVar1], L3 ← 1, c1, opcode[116'b];
PVARX: MAR ← S ← [rhS, S + 1], GOTO[PVar1], L3 ← 1, c1, opcode[117'b];
FVAR: MAR ← S ← [rhS, S + 1], L2 ← 0, c1, opcode[120'b];{50}
uTOSH ← MDR ← TOSH, DISP3[VnoCar0, 4], L3 ← 4, c2;
MAR ← S ← [rhS, S + 1], L2 ← 1, c1, opcode[121'b];
uTOSH ← MDR ← TOSH, DISP3[VnoCar0, 4], L3 ← 4, c2;
MAR ← S ← [rhS, S + 1], L2 ← 2, c1, opcode[122'b];
uTOSH ← MDR ← TOSH, DISP3[VnoCar0, 4], L3 ← 4, c2;
MAR ← S ← [rhS, S + 1], L2 ← 3, c1, opcode[123'b];
uTOSH ← MDR ← TOSH, DISP3[VnoCar0, 4], L3 ← 4, c2;
MAR ← S ← [rhS, S + 1], L2 ← 4, c1, opcode[124'b];
uTOSH ← MDR ← TOSH, DISP3[VnoCar0, 4], L3 ← 4, c2;
MAR ← S ← [rhS, S + 1], L2 ← 5, c1, opcode[125'b];
uTOSH ← MDR ← TOSH, DISP3[VnoCar0, 4], L3 ← 4, c2;
MAR ← S ← [rhS, S + 1], L2 ← 6, c1, opcode[126'b];
uTOSH ← MDR ← TOSH, DISP3[VnoCar0, 4], L3 ← 4, c2;
FVARX: MAR ← S ← [rhS, S + 1], L2 ← 7, c1, opcode[127'b];
uTOSH ← MDR ← TOSH, DISP3[VnoCar0, 4], L3 ← 4, c2;
@COPYN: MAR ← S ← [rhS, S + 1], GOTO[SVar1], L3 ← 5, c1, opcode[75'b];
IVar1: MDR ← TOSH, DISP3[VnoCar0], c2;
PVar1: MDR ← TOSH, DISP3[VnoCar0, 1], c2;
SVar1: MDR ← TOSH, DISP3[VnoCar0, 5], c2;
{place these intructions for dispatch at VCar1 and for pageCross dispatch}
S ← S + 0FF + 1, GOTO[VCar1], c3, at[2,8,VnoCar0];
S ← S + 0FF + 1, GOTO[VCar1], c3, at[3,8,VnoCar0];
S ← S + 0FF + 1, GOTO[VCar1], L3 ← 4, c3, at[6,8,VnoCar0];
S ← S + 0FF + 1, GOTO[VCar1], c3, at[7,8,VnoCar0];
VCar1: MAR ← [rhS, S + 0], L3Disp, {retry the stack ref} c1;
MDR ← TOSH, DISP3[VnoCar0], c2;
Q ← uIVar, L2Disp, GOTO[V2], c3, at[0,8,VnoCar0];
Q ← PV, L2Disp, GOTO[V2], c3, at[1,8,VnoCar0];
Q ← PV, L2Disp, GOTO[V2], c3, at[4,8,VnoCar0];
Q ← S - ib, c3, at[5,8,VnoCar0];
MAR ← S ← [rhS, S + 1], c1;
MDR←TOS, Rx←Q, L2←3, CANCELBR[VarX, 3],WriteOK, c2;
V2: MAR ← S ← [rhS, S + 1], DISP4[Voff, 8], c1;
Voff: MDR←TOS, Rx←Q+ 0, L2←2, CANCELBR[Var, 2],WriteOK, c2, at[8, 10, Voff];
MDR←TOS, Rx←Q+2, L2←2, CANCELBR[Var,2],WriteOK, c2, at[9,10, Voff];
MDR←TOS, Rx←Q+4, L2←2, CANCELBR[Var,2],WriteOK, c2, at[0A,10, Voff];
MDR←TOS, Rx←Q+ 6, L2←2, CANCELBR[Var,2],WriteOK, c2, at[0B,10, Voff];
MDR←TOS, Rx←Q+8, L2←2, CANCELBR[Var,2],WriteOK, c2, at[0C,10, Voff];
MDR←TOS, Rx←Q+0A, L2←2,CANCELBR[Var,2],WriteOK, c2, at[0D,10, Voff];
MDR←TOS, Rx←Q+0C, L2←2, CANCELBR[Var,2],WriteOK, c2, at[0E,10, Voff];
VoffX: MDR←TOS, Rx←Q+ ib, L2←3, CANCELBR[VarX, 3],WriteOK, c2, at[0F,10, Voff];
Var: rhRx ← nRhS, GOTO[Var2], c3;
VarX: rhRx ← nRhS, GOTO[Var2], c3;
Var2: MAR ← [rhRx, Rx + 0], L3Disp, c1;
[] ← S xor uStkLimO, ZeroBranch, DISP3[IVar3, 2], c2;
IVar3: TOSH ← MD, L2Disp, BRANCH[Var4, StkOvr1], c3, at[2, 8, IVar3];
PVar3: TOSH ← MD, L2Disp, BRANCH[Var4, StkOvr1], c3, at[3, 8, IVar3];
SVar3: TOSH ← MD, L2Disp, BRANCH[Var4, StkOvr1], c3, at[7, 8, IVar3];
Var4: MAR ← Q ← [rhRx, Rx + 1], BRANCH[$, varPcX, 0E{2}], c1;
PC ← PC + PC16, L2 ← L2.0, IBDisp, DISP2[varEnd], c2;
varPcX: PC ← PC + 1, L2 ← L2.0, IBDisp, DISP2[varEnd], c2;
DNI.TOSg: {common tail}
varEnd: TOS ← MD, L2 ← L2.0, DISPNI[OpTable], c3, at[0, 4, varEnd];
varEndCar: Q ← 80'd, GOTO[sink1], {"impossible"} c3, at[2, 4, varEnd];{MP9080}
{Stack Limit:}
StkOvr1: MAR ← Q ← [rhRx, Rx + 1], BRANCH[$, varPcXov, 0E{2}], c1;
PC ← PC + PC16, CANCELBR[varEndOv, 2], c2;
varPcXov: PC ← PC + 1, CANCELBR[varEndOv, 2], c2;
varEndOv: TOS ← MD, GOTO[StackOverflow], c3;
{*******************************
PVAR←, PVARX←, IVARX← 4% 2 clicks
*******************************}
SPVAR: MAR ← Q ← [rhPV, PV + 0 + 1], GOTO[SVar], c1, opcode[130'b];{58}
MAR ← Q ← [rhPV, PV + 2 + 1], GOTO[SVar], c1, opcode[131'b];
MAR ← Q ← [rhPV, PV + 4 + 1], GOTO[SVar], c1, opcode[132'b];
MAR ← Q ← [rhPV, PV + 6 + 1], GOTO[SVar], c1, opcode[133'b];
MAR ← Q ← [rhPV, PV + 8 + 1], GOTO[SVar], c1, opcode[134'b];
MAR ← Q ← [rhPV, PV + 0A + 1], GOTO[SVar], c1, opcode[135'b];
MAR ← Q ← [rhPV, PV + 0C + 1], GOTO[SVar], c1, opcode[136'b];
SVar: MDR ← TOS, Rx←Q, rhRx←nRhS, BRANCH[SVNoCar, SVCarry, 1], c2;
SVCarry: Rx ← Q + 0FF +1, c3;
MAR ← [rhRx, Rx + 0], c1;
MDR ← TOS, c2;
SVNoCar: PC ← PC + PC16, GOTO[SVTail], c3;
@STOREN:
MAR ← Q ← [rhS, S - ib], c1, opcode[74'b];
MDR ← TOS, Rx←Q, rhRx←nRhS, BRANCH[STXNoC, STXCar, 1], c2;
STXCar: Rx ← Q - 0FF -1, GOTO[STCar1], c3;
STCar1: MAR ← [rhRx, Rx + 0], c1;
MDR ← TOS, c2;
STXNoC: PC ← PC + 1, GOTO[SVTail], c3;
@SPVARX: MAR ← Q ← [rhPV, PV + ib + 1], c1, opcode[137'b];{5F}
MDR ← TOS, Rx←Q, rhRx←nRhS, BRANCH[SVXNoC, SVXCar, 1], c2;
SVXCar: Rx ← Q + 0FF +1, GOTO[SVCar1], c3;
@SIVARX: rhRx←nRhS, {1% 3 clicks} c1, opcode[142'b];{62}
Rx ← uIVar, c2;
Rx ← Rx + ib + 1, GOTO[SVCar1], c3;
SVCar1: MAR ← [rhRx, Rx + 0], c1;
MDR ← TOS, c2;
SVXNoC: PC ← PC + 1, c3;
SVTail: MAR ← [rhRx, Rx - 1], L2 ← L2.0, c1;
MDR ← TOSH, IBDisp, DISP2[DNI.nop], WriteOK, c2;
DNI.nop: {common tail}
L2 ← L2.0, DISPNI[OpTable], c3;
CantGetHere:
Q ← 88'd, GOTO[sink1], c3, at[2, 4, DNI.nop];
{*******************************
GVAR 3% 5 clicks
*******************************}
GVAR: MAR ← S ← [rhS, S + 1], c1, opcode[140'b];{60}
MDR ← TOSH, TT ← ib, BRANCH[$, GVCross, 1], c2;
GVnoCross: TT ← TT LRot8, c3;
MAR ← S ← [rhS, S + 1], c1;
MDR ← TOS, rhTT ← uValHigh, CANCELBR[$, 2], WriteOK, c2;
TT ← (TT or ib) LShift1, c3;
Map ← Q ← [rhTT,TT], L0 ← L0.RedoGV, c1;
L1 ← L1.PopOnly, c2;
Rx ← rhRx ← MD, ReadXRefBr, c3;
MAR← [rhRx, Q + 0], ReadBRANCH[GVMap,$], c1, at[L0.RedoGV,10,RMapFixCaller];
[] ← S xor uStkLimO, ZeroBranch, c2;
TOSH ← MD, BRANCH[$, GVStkOvr], c3;
MAR ← Q ← [rhRx, Q + 1], L2 ← L2.0, c1;
PC ← PC + 1 + PC16, IBDisp, CANCELBR[DNI.TOSg, 0], c2;
GVMap: CALL[RLMapFix]{will return to RedoGV}, c2;
{Stack Limit:}
GVStkOvr: MAR ← Q ← [rhRx, Q + 1], c1;
PC ← PC + 1 + PC16, CANCELBR[$,2], c2;
TOS ← MD, GOTO[StackOverflow], c3;
{page cross}
GVCross: S ← S + 0FF + 1, c3;
MAR ← [rhS, S + 0], c1;
MDR ← TOSH, GOTO[GVnoCross], c2;
{*******************************
PVARd← 2% 4 clicks
*******************************}
SPVARd: MAR ← Q ← [rhPV, PV + 0 + 1], GOTO[SVarD], c1, opcode[270'b];{B8}
MAR ← Q ← [rhPV, PV + 2 + 1], GOTO[SVarD], c1, opcode[271'b];
MAR ← Q ← [rhPV, PV + 4 + 1], GOTO[SVarD], c1, opcode[272'b];
MAR ← Q ← [rhPV, PV + 6 + 1], GOTO[SVarD], c1, opcode[273'b];
MAR ← Q ← [rhPV, PV + 8 + 1], GOTO[SVarD], c1, opcode[274'b];
MAR ← Q ← [rhPV, PV + 0A + 1], GOTO[SVarD], c1, opcode[275'b];
MAR ← Q ← [rhPV, PV + 0C + 1], GOTO[SVarD], c1, opcode[276'b];
SVarD: MDR ← TOS, Rx ← Q, rhRx ← nRhS, BRANCH[$, SVDCarry, 1], c2;
SVDcont: PC ← PC + PC16, c3;
MAR ← [rhRx, Rx - 1], c1;
MDR ← TOSH, CANCELBR[$, 2], WriteOK, c2;
Noop, c3;
MAR ← [rhS, S + 0], c1;
S ← S - 1, c2;
TOS ← MD, c3;
MAR ← [rhS, S + 0], L2 ← L2.0, c1;
S ← S - 1, IBDisp, c2;
DNI.TOSHg: {common tail}
TOSH ← MD, L2 ← L2.0, DISPNI[OpTable], c3;
SVDCarry: Rx ← Rx + 0FF +1, c3;
MAR ← [rhRx, Rx + 0], c1;
MDR ← TOS, GOTO[SVDcont], c2;
{*************************
GETBASEN 3% 3 clicks
**************************}
GETBASEN:
TT ← TOS + ib, CarryBr, L2 ← L2.0, c1, opcode[310'b];{C8}
Rx{TOSH+1} ← TOSH+1, BRANCH[$, GBNseg], c2;
rhTT ← TOSH LRot0, c3;
MapGBN: Map ← Q ← [rhTT,TT], L0 ← L0.RedoGBN, c1;
PC ← PC + 1, L1 ← L1.DecDec, c2;
Rx ← rhRx ← MD, ReadXRefBr, c3;
MAR← [rhRx,Q+0], ReadBRANCH[GBNMap,$], c1,at[L0.RedoGBN,10,RMapFixCaller];
TOSH ← smallpl, IBDisp, GOTO[DNI.TOSg], c2;
{ TOS ← MD, L2 ← L2.0, DISPNI[OpTable], c3;}
GBNMap: CANCELBR[RLMapFix, 3]{will return to RedoGBN}, c2;
GBNseg: rhTT ← Rx{TOSH+1} LRot0, GOTO[MapGBN], c3;
{*************************
GETBASEPTRN (base, 1st byte=offset)
**************************}
GETBASEPTRN:
TT ← TOS + ib, CarryBr, c1, opcode[311'b];{C9}
Rx{TOSH+1} ← TOSH+1, BRANCH[$, BPseg], c2;
rhTT ← TOSH LRot0, c3;
MapBP: Map ← Q ← [rhTT,TT], L0 ← L0.RedoBP, c1;
PC ← PC + 1, L1 ← L1.DecDec, c2;
Rx ← rhRx ← MD, ReadXRefBr, c3;
MAR← [rhRx, Q + 0], ReadBRANCH[BPMap,$], c1,at[L0.RedoBP,10,RMapFixCaller];
TOSH ← 0FF, c2;
TOSH ← MD and TOSH, c3;
MAR← [rhRx, Q + 1], L2 ← L2.0, c1;
IBDisp, CANCELBR[DNI.TOSg, 0], c2;
BPMap: CALL[RLMapFix]{will return to RedoBP}, c2;
BPseg: rhTT ← Rx{TOSH+1} LRot0, GOTO[MapBP], c3;
{*************************
GETBASEBYTE: {ptr, disp} 3% 4.5 clicks
**************************}
GETBASEBYTE: {ptr, disp}
MAR ← [rhS, S], S ← S -1, c1, opcode[302'b];{C2}
Ybus ← TOSH xor smallpl, NZeroBr, CANCELBR[$,2], c2;
TT ← MD{ptr}, BRANCH[$, ufnBY], c3;
MAR ← [rhS, S], S ← S - 1, L1 ← L1.PushOnly, c1;
Rx ← TOS RShift1, YDisp, BRANCH[$, BYCarry, 1], c2;
BYret: rhTT ← MD{ptrH}, TT ← TT + Rx, CarryBr, BRANCH[BYeven, $, 0E], c3;
BYodd: Map ← [rhTT, TT], BRANCH[$, BYOseg], c1;
Q ← {u}0FF, L0 ← L0.BYRedoO, c2;
Rx ← rhRx ← MD, ReadXRefBr, c3;
MAR ← [rhRx, TT + 0], ReadBRANCH[BYMapUDO,$], c1, at[L0.BYRedoO,10, RMapFixCaller];
PC ← PC + PC16, L2 ← L2.0, IBDisp, c2;
TOS ← MD and Q, L2 ← L2.0, DISPNI[OpTable], c3;
{**}
BYeven: Map ← [rhTT, TT], BRANCH[$, BYEseg], c1;
Noop, c2;
Rx ← rhRx ← MD, ReadXRefBr, c3;
{**}
MAR← [rhRx, TT + 0], L0 ← L0.BYRedoE, ReadBRANCH[BYMapUDE,$], c1, at[L0.BYRedoE,10, RMapFixCaller];
Q ← ~0FF, L2 ← L2.0, c2;
TOS ← MD and Q, c3;
TOS ← TOS LRot8, GOTO[IB.pc1], c1;
ufnBY: Rx ← 302'b, CANCELBR[ufn2incS, 3] c1;
BYMapUDE: CALL[RLMapFix], c2;
BYMapUDO: CALL[RLMapFix], c2;
{page cross:}
BYCarry: S ← S - 0FF, CANCELBR[$, 0F], c3;
MAR ← [rhS, S + 0], c1;
S ← S - 1, GOTO[BYret], Ybus ← TOS, YDisp, c2;
BYOseg: Q ← rhTT + 1, LOOPHOLE[byteTiming], c2;
rhTT ← Q LRot0, GOTO[BYodd], c3;
BYEseg: Q ← rhTT + 1, LOOPHOLE[byteTiming], c2;
rhTT ← Q LRot0, GOTO[BYeven], c3;
{*************************
PUTBASEN: {ptr, val => ptr} 1% 4 clicks
**************************}
PUTBASEN: MAR ← [rhS, S], S ← S - 1, c1, opcode[315'b];{CD}
Ybus ← TOSH xor smallpl, NZeroBr, CANCELBR[$, 2], c2;
Rx ← MD{ptr}, BRANCH[$, ufnPUTB], c3;
MAR ← [rhS, S], S ← S - 1, L0 ← L0.RedoW, c1;
{uuRx ←}TT ← Rx + ib {+1}, CarryBr, BRANCH[$, PBCar, 1], c2;
PBCont: Q{ptrH} ← rhTT ← MD{ptrH}, BRANCH[$, PBSeg], c3;
PBsegok: Map ← {TT ←} [rhTT, TT +0{- 1}], {Xbus ← ib,} c1;
uuRx{ptr} ← Rx, PC ← PC + 1, L1 ← L1.PushDec2, c2;
Rx ← rhRx ← MD, XwdDisp{XDirtyDisp}, c3;
RedoW: MAR ← [rhRx, TT + 0], DISP2[PBMap], c1,at[L0.RedoW,10,WMapFixCaller];
MDR ← TOS, TOSH ← Q{ptrH}, IBDisp, L2 ← L2.0, c2, at[PgDirty, 4, PBMap];
DNI.funny:
TOS ← uuRx{ptr}, L2 ← L2.0, DISPNI[OpTable], c3;
CALL[WLMapFix], {will return to RedoW} c2, at[PgClean, 4, PBMap];
CALL[WLMapFix], {will return to RedoW} c2, at[PgProt, 4, PBMap];
CALL[WLMapFix], {will return to RedoW} c2, at[PgVacant, 4, PBMap];
ufnPUTB: Rx ← 315'b, GOTO[ufn2incS] c1;
{memory reference is good, but S is +0FF instead of -1}
PBCar: Noop, BRANCH[$, PBCarSeg], c3;
MAR ← S{S - 0FF} ← [rhS, 0 + 0], c1;
S ← S - 1, GOTO[PBCont], c2;
PBCarSeg: MAR ← S{S - 0FF} ← [rhS, 0 + 0], c1;
S ← S - 1, Xbus ← 1, XDisp, GOTO[PBCont], c2;
PBSeg: Q ← Q+1, c1;
rhTT ← Q{ptrH+1} LRot0, c2;
Q ← Q - 1, GOTO[PBsegok], c3;
{*************************}
PUTBASEPTRN: {(ptr, val => ptr) 2% 5 clicks}
MAR ← [rhS, S], S ← S -1, c1, opcode[316'b];{CE}
PC ← PC + 1, CANCELBR[$, 2], c2;
Rx ← MD{ptr}, c3;
MAR ← [rhS, S + 0], L0 ← L0.RedoPBP, c1;
{uuRx ← Rx,} TT ← Rx + ib {+ 1},CarryBr, c2;
Q{ptrH} ← rhTT ← MD{ptrH}, BRANCH[$, PBPSeg], c3;
PBPok: Map ← [rhTT, TT+0], c1;
uuRx ← Rx, S ← S +{-} 1, L1 ← L1.DecDec{PushDec2}, c2;
Rx ← rhRx ← MD, XwdDisp{XDirtyDisp}, c3;
{fiddle with S to make Cin one for uuRx ← Rx}
RedoPBP: MAR ← [rhRx, TT + 1], DISP2[PBPMap], c1,at[L0.RedoPBP,10,WMapFixCaller];
MDR ← TOS, CANCELBR[$, 2], WriteOK, c2, at[PgDirty, 4, PBPMap];
S ← S-2, c3;
MAR ← [rhRx, TT + 0], L2 ← L2.0, c1;
MDR ← TOSH, TOSH ← Q{ptrH}, IBDisp, GOTO[DNI.funny], c2;
{ TOS ← uuRx{ptr}, DISPNI[OpTable], c3;}
CANCELBR[WLMapFix, 3], {return to RedoPBP} c2, at[PgClean, 4, PBPMap];
CANCELBR[WLMapFix, 3], {return to RedoPBP} c2, at[PgProt, 4, PBPMap];
CANCELBR[WLMapFix, 3], {return to RedoPBP} c2, at[PgVacant, 4, PBPMap];
PBPSeg: Q ← Q+1, c1;
rhTT ← Q{ptrH+1} LRot0, c2;
Q ← Q - 1, GOTO[PBPok], c3;
{*************************}
PUTBASEBYTE: {ptr, disp, val => val} {3% 9{7}clicks}
MAR ← [rhS, S], S ← S -1, c1, opcode[307'b];{C7}{S = S - 1}
Ybus ← TOSH xor smallpl, NZeroBr, CANCELBR[$, 2], c2;
Rx ← MD{disp}, BRANCH[$, ufnPBY], c3;
MAR ← [rhS, S + 0], c1;
S ← S -1, c2;{S = S - 2}
Q ← MD{dispH}, c3;
MAR ← [rhS, S], S ← S -1, c1;{S = S - 3}
Ybus ← Q xor smallpl, NZeroBr, CANCELBR[$,2], c2;
uRx ← Rx, TT ← MD{ptr}, BRANCH[$, ufnPBY1], c3;
MAR ← [rhS, S], S ← S - 1, L1 ← L1.Push2OK, c1;{S = S - 4}
Rx ← Rx RShift1, YDisp, BRANCH[$, PBYCarry, 1], c2;
PBYret: rhTT ← MD{ptrH}, TT ← TT + Rx, CarryBr, BRANCH[$, oddS, 0E], c3;
evenS: Map ← [rhTT, TT], BRANCH[$, PBYESeg], c1;
Q ← 0FF, L0 ← L0.WBYRedoE, c2;
Rx ← rhRx ← MD, XwdDisp{XDirtyDisp}, c3;
WBYRedoE: MAR ← [rhRx, TT + 0], DISP2[WBYMapUDE], c1, at[L0.WBYRedoE,10,WMapFixCaller];
TOS ← TOS LRot8, c2, at[PgDirty, 4, WBYMapUDE];
joinY: Q ← MD and Q, c3;
Q ← Q or TOS, c1;
TOS ← TOS LRot8 xor TOS, c2;
TOS ← TOS and 0FF, c3;
MAR ← [rhRx, TT + 0], L2 ← L2.0, c1;
MDR ← Q, IBDisp, GOTO[DNI.pc1], c2;
{ PC ← PC + PC16, L2 ← L2.0, DISPNI[OpTable], c3;}
oddS: Map ← {Q ←} [rhTT, TT], BRANCH[$, PBYOSeg], c1;
L0 ← L0.WBYRedoO, c2;
Rx ← rhRx ← MD, XwdDisp{XDirtyDisp}, c3;
WBYRedoO: MAR ← [rhRx, TT + 0], DISP2[WBYMapUDO], c1, at[L0.WBYRedoO,10,WMapFixCaller];
Q ← ~0FF, GOTO[joinY], c2, at[PgDirty, 4, WBYMapUDO];
ufnPBY: Rx ← 307'b, CANCELBR[ufn2incS, 3] c1;
ufnPBY1: Rx ← 307'b, GOTO[ufn2inc3S], c1;
CALL[WLMapFix], c2, at[PgClean, 4, WBYMapUDE];
CALL[WLMapFix], c2, at[PgProt, 4, WBYMapUDE];
CALL[WLMapFix], c2, at[PgVacant, 4, WBYMapUDE];
CALL[WLMapFix], c2, at[PgClean, 4, WBYMapUDO];
CALL[WLMapFix], c2, at[PgProt, 4, WBYMapUDO];
CALL[WLMapFix], c2, at[PgVacant, 4, WBYMapUDO];
{page cross:}
PBYCarry: S ← S - 0FF, CANCELBR[$, 0F], c3;
MAR ← [rhS, S + 0], c1;
S ← S - 1, GOTO[PBYret], Xbus ← uRx, XDisp, c2;
PBYESeg: Q ← rhTT + 1, LOOPHOLE[byteTiming], c2;
rhTT ← Q LRot0, GOTO[evenS], c3;
PBYOSeg: Q ← rhTT + 1, LOOPHOLE[byteTiming], c2;
rhTT ← Q LRot0, GOTO[oddS], c3;
{*************************
ADDBASE (ptr, disp) 1% 3 clicks
**************************}
ADDBASE: MAR ← [rhS, S], S ← S -1, c1, opcode[320'b];{D0}
Ybus ← TOSH xor smallpl, NZeroBr, CANCELBR[$,2], c2;
Rx ← MD, BRANCH[$, ufnAB], c3;
MAR ← [rhS, S + 0], {S ← S -1,} c1;
TOS ← TOS + Rx, CarryBr, c2;
TOSH ← MD, BRANCH[adBnoc, adBcar], c3;
adBnoc: GOTO[addBtail], c1;
adBcar: TOSH ← TOSH + 1, GOTO[addBtail], c1;
addBtail: S ← S - 1, IBDisp, L2 ← L2.0, c2;
DNI.pc1: {common tail}
PC ← PC + PC16, L2 ← L2.0, DISPNI[OpTable] c3;
ufnAB: Rx ← 320'b, GOTO[ufn2incS], c1;
{*************************
HILOC, LOLOC 2% 1 click
**************************}
HILOC: TOS ← TOSH, GOTO[LoLoc1], c1, opcode[322'b];{D2}
LOLOC: Noop, c1, opcode[323'b];{D3}
LoLoc1: TOSH ← smallpl, IBDisp, L2 ← L2.0, GOTO[DNI.pc1], c2;
{*************************
COPY 3% 2 clicks
**************************}
COPY: MAR ← S ← [rhS, S + 1], c1, opcode[144'b];{64}
CopyRet: MDR ← TOSH, S ← S + 1, BRANCH[$, CopyCarry, 1], c2;
Ybus ← S xor uStkLimO, ZeroBranch, c3;
MAR ← [rhS, S + 0], BRANCH[$, CopyStkLim], c1;
MDR ← TOS, IBDisp, L2 ← L2.0, GOTO[DNI.pc1], c2;
{page cross:}
CopyCarry: S ← S + 0FF, c3;
MAR ← [rhS, S + 0], GOTO[CopyRet], c1;
{Stack Limit:}
CopyStkLim: MDR ← TOS, c2;
PC ← PC + PC16, GOTO[StackOverflow], c3;
{*************************
NIL, KT, ZERO, ONE, SIC, SNIC 15 % 2 clicks
SICX, ACONST, ATOMNUMBER 5 % 3 clicks
**************************}
LinkCross: PV ← Q{PV - 9 + 100h} - 0FF - 1, c3;
MAR ← Q{PV- 9} ← [rhPV, PV + 0], GOTO[link2], c1;
MYALINK: MAR ← Q{PV- 9} ← [rhPV, PV - 9], L3 ← L3.pls1, c1, opcode[146'b];
link2: PV ← Q + 9, BRANCH[$, LinkCross, 1], c2;
Q ← MD, XLDisp, L2 ← L2.0, c3;
MAR ← S ← [rhS, S + 2], BRANCH[linkE, linkO, 0E], c1;
linkE: STK ← MDR ← TOS, TOS ← Q - 0A, DISP2[NoCar], c2;
linkO: STK ← MDR ← TOS, TOS ← Q - 0B, DISP2[NoCar], c2;
ACONST: Rx ← ib, L3 ← L3.atm3, c1, opcode[147'b];{67}
Rx ← Rx LRot8, GOTO[xx], c2;
ATOMN: Rx ← ib, L3 ← L3.pls3, GOTO[sic2], c1, opcode[160'b];{70}
SICX: Rx ← ib, L3 ← L3.pls3, c1, opcode[156'b];{6E}
sic2: Rx ← Rx LRot8, GOTO[xx], c2;
xx: Q ← Rx or ib, Cin←pc16, {prepare for inc3} c3;
MAR ← S ← [rhS, S + 2], c1;
STK ← MDR ← TOS, TOS ← Q, L2 ← L2.0, DISP2[NoCar], c2;
NIL: MAR ← S ← [rhS, S + 2], L3 ← L3.atm1, c1, opcode[150'b];{68}
L3Zero: STK ← MDR ← TOS, TOS ← 0, L2 ← L2.0, DISP2[NoCar], c2;
KT: MAR ← S ← [rhS, S + 2], L3 ← L3.atm1, c1, opcode[151'b];{69}
STK ← MDR ← TOS, TOS ← KTval, L2 ← L2.0, DISP2[NoCar], c2;
ZERO: MAR ← S ← [rhS, S + 2], L3 ← L3.pls1, c1, opcode[152'b];{6A}
STK ← MDR ← TOS, TOS ← 0, L2 ← L2.0, DISP2[NoCar], c2;
ONE: MAR ← S ← [rhS, S + 2], L3 ← L3.pls1, c1, opcode[153'b];{6B}
STK ← MDR ← TOS, TOS ← 1, L2 ← L2.0, DISP2[NoCar], c2;
SIC: MAR ← S ← [rhS, S + 2], L3 ← L3.pls2, c1, opcode[154'b];{6C}
uTOS ← MDR ← TOS, TOS ← ib, L2 ← L2.0, DISP2[NoCar], c2;
SNIC: Q ← ib, {shorten ?%!} c1, opcode[155'b];{6D}
Q ← Q - 0FF - 1, c2;
Noop, c3;
MAR ← S ← [rhS, S + 2], L3 ← L3.neg2, c1;
uTOS ← MDR ← TOS, TOS ← Q, L2 ← L2.0, DISP2[NoCar], c2;
Carry: S ← S + 0FF + 1, L3Disp, c3, at[2,4,NoCar];
MAR ← [rhS, S + 0], BRANCH[saveS, saveU, 0B], c1;
saveU: MDR ← uTOS, L2 ← L2.0, GOTO[NoCar], c2;
saveS: MDR ← STK, L2 ← L2.0, GOTO[NoCar], c2;
NoCar: Ybus ← S xor uStkLimO, ZeroBranch, L3Disp, c3, at[0,4,NoCar];
MAR ← [rhS, S - 1], Xbus←0, XC2npcDisp, L3Disp, DISP4[SicTosh, 8], c1;
MDR ← TOSH, TOSH ← 0{atom}, IBDisp, DISP4[Kinc, 6], WriteOK, c2, at[8, 10, SicTosh];
MDR ← TOSH, TOSH ← 0{atom}, DISP4[KincL, 6], WriteOK, c2, at[9, 10, SicTosh];
MDR ← TOSH, TOSH ← smallpl, IBDisp, DISP4[Kinc, 6], WriteOK, c2, at[0A, 10, SicTosh];
MDR ← TOSH, TOSH ← smallpl, DISP4[KincL, 6], WriteOK, c2, at[0B, 10, SicTosh];
MDR ← TOSH, TOSH ← smallpl, IBDisp, CANCELBR[inc2, 0F], WriteOK, c2, at[0C, 10, SicTosh];
MDR ← TOSH, TOSH ← smallpl, CANCELBR[incL2, 0F], WriteOK, c2, at[0D, 10, SicTosh];
MDR ← TOSH, TOSH ← smallneg, IBDisp, CANCELBR[inc2, 0F], WriteOK, c2, at[0E, 10, SicTosh];
MDR ← TOSH, TOSH ← smallneg, CANCELBR[incL2, 0F], WriteOK, c2, at[0F, 10, SicTosh];
inc2: PC ← PC + 1, L2 ← L2.0, DISPNI[OpTable], c3;
incL2: PC ← PC + 1, L2 ← L2.0, GOTO[StackOverflow], c3;
inc1: PC ← PC + PC16, L2 ← L2.0, DISPNI[OpTable], c3, at[6,10, Kinc];
PC ← PC + PC16, L2 ← L2.0, DISPNI[OpTable], c3, at[7,10, Kinc];
incL1: PC ← PC + PC16, GOTO[StackOverflow], c3, at[6,10, KincL];
PC ← PC + PC16, GOTO[StackOverflow], c3, at[7,10, KincL];
inc3: PC ← PC + 1, L2 ← L2.0, DISPNI[OpTable], c3, at[0E,10, Kinc];
PC ← PC + 2, L2 ← L2.0, DISPNI[OpTable], c3, at[0F,10, Kinc];
incL3: PC ← PC + 1, GOTO[StackOverflow], c3, at[0E,10, KincL];
PC ← PC + 2, GOTO[StackOverflow], c3, at[0F,10, KincL];
{*************************
GCONST
**************************}
{uPCCrossL will be off no matter what: suceed, fault, stkOver}
GCONST: MAR ← S ← [rhS, S + 1], c1, opcode[157'b];{6F}
uTOSH ← MDR ← TOSH, TOSH ← ib, BRANCH[$, GCCarry, 1], c2;
GCNoCarry: Rx ← ib, L0 ← L0.RedoGC, c3;
MAR ← PC ← [rhPC, PC + 2], L1 ← L1.TrapGC{fault trap}, c1;
Rx ← Rx LRot8, BRANCH[$, GCPCCarry, 1], c2;
GCPCNoC: IB ← MD, Q ← Rx, c3;
GCok: MAR ← S ← [rhS, S + 1], c1;
MDR ← TOS, TOS ← Q or ib, CANCELBR[$, 2], WriteOK, c2;
Ybus ← S xor uStkLimO, ZeroBranch, L2 ← L2.0, c3;
MAR ← [rhPC, PC + 1], BRANCH[$, GConStkLim], c1;
RefillNE1: AlwaysIBDisp, L0 ← L0.NERefill.Set, DISP2[NoRCross], c2;
{exceptions:}{if page cross succeedes update UvPCpageL and uPCCrossL}
GCCarry: S ← S + 0FF + 1, c3;
MAR ← [rhS, S + 0], c1;
MDR ← uTOSH, GOTO[GCNoCarry], c2;
GCPCCarry: Q ← 0FF + 1, L1 ← L1.TrapGC{fault trap}, c3;
TT ← UvPCpageL, GOTO[UpdatePC2], c1;
{uPCCrossL will be off no matter what: suceed, fault, stkOver}
GCCross: uPCCrossL ← TT{0 low}, PC ← MD, rhPC ← MD, ReadXRefBr, c3, at[L0.RedoGC,10,ECross];
MAR ← Q ← [rhPC, Q + 0], ReadBRANCH[GCMap, $], c1;
UvPCpageL ← TT, PC ← Q, GOTO[GCPCNoC], c2;
{PC page cross plus map update: save Rx}
GCMap: uRx ← Rx, {returns at GCRedo} c2;
Rx ← PC, Xbus ← PC LRot0,XwdDisp, GOTO[RLMapFix1], c3;
{%x% was CANCELBR[$], should probably be ReadCANCELBR}
GCRedo: MAR ← PC ← [rhPC, Q + 0], ReadCANCELBR[$], c1, at[L0.RedoGC, 10, RMapFixCaller];
Q ← uRx, c2;
UvPCpageL ← TT, IB ← MD, GOTO[GCok], c3;
GCTrap: TOSH ← uTOSH, c1, at[L1.TrapGC,10,Fix];
PC ← Q{PC}{++} - 2, c2;
S ← S -1, GOTO[NoFixes], c3;
{Stack Limit:}
GConStkLim: Noop, CANCELBR[$, 2], c2;
Noop, GOTO[StackOverflow], c3;
{*************************
POP 5% 2 click
**************************}
POP: MAR ← [rhS, S], S ← S - 1, c1, opcode[277'b];{BF}
PC ← PC + PC16, CANCELBR[$, 2], c2;
TOS ← MD, c3;
MAR ← [rhS, S + 0], c1;
S ← S - 1, IBDisp, L2 ← L2.0, GOTO[DNI.TOSHg], c2;
{*************************
SWAP
**************************}
{SWAP: MAR ← [rhS, S - 1], c1, opcode[375'b];{FD}
PC ← PC + PC16, MDR ← TOSH, CANCELBR[$, 2], WriteOK, c2;
TOSH ← MD, c3;
MAR ← [rhS, S + 0], c1;
MDR ← TOS, IBDisp, L2 ← L2.0, GOTO[DNI.TOSg], c2;%M}
SWAP: opcode[375'b],
MAR ← [rhS, S - 1], c1;
CANCELBR[$, 2], c2;
Rx ← MD, c3;
MAR ← [rhS, S - 1], c1;
MDR ← TOSH, CANCELBR[$, 2], WriteOK, c2;
TOSH ← Rx, c3;
MAR ← [rhS, S + 0], c1;
PC ← PC + PC16, c2;
Rx ← MD, c3;
MAR ← [rhS, S + 0], c1;
MDR ← TOS, IBDisp, L2 ← L2.0, c2;
TOS ← Rx, L2 ← L2.0, DISPNI[OpTable], c3;
{*************************
NOP
**************************}
NOP: PC ← PC + PC16, GOTO[IB.nop], c1, opcode[376'b];{FE}
{*************************
EQ 3% 3 clicks
**************************}
EQ: MAR ← [rhS, S], S ← S - 1, c1, opcode[360'b];{F0}
PC ← PC + PC16, CANCELBR[$, 2], c2;
Rx ← MD xor TOS, c3;
MAR ← [rhS, S + 0], c1;
S ← S - 1, c2;
TT ← MD xor TOSH, c3;
Ybus ← Rx or TT, ZeroBr, L2 ← L2.0, c1;
TOSH ← 0{atm}, IBDisp, BRANCH[eqNIL, eqKT], c2;
eqNIL: TOS ← 0{NIL}, L2 ← L2.0, DISPNI[OpTable], c3;
eqKT: TOS ← KTval, L2 ← L2.0, DISPNI[OpTable], c3;
{***********************}
APPLY: {(S) Flush top of stack} opcode[016'b],{0E}
MAR ← [rhS, S - 1], L3{ib's}←0, c1;
applyTl: TT ← 0FF + 1{400=AT.INTERPRETER%}, CANCELBR[$ ,2], c2;
Q ← MD{nargsHi}, c3;
MAR ← [rhS, S + 0], c1;
Ybus ← Q xor smallpl, NZeroBr, c2;
{TOSH ← }rhTOSH ← MD{nargs}, BRANCH[$, appUfn], c3;
rhTT ← TOSH{defHi} LRot0, ZeroBr, c1;
TOSH{args2} ← rhTOSH{args} LShift1, BRANCH[$, applyCode], c2;
notCCode: PV ← PV - 6, c3;
MAR ← [rhPV, PV + 0], c1;
MDR ← TOSH{iVar} ← S - TOSH{arg2} - 1, c2;
PV ← PV + 6, c3;
MAR ← [rhS, S - 1], c1;
MDR ← rhTT, CANCELBR[interpret3, 2], WriteOK, c2;
applyCode: TT ← TOS, GOTO[apply2], c3;
{%3}
apply2: MAR ← [rhPV, PV - 6], c1;
MDR ← TOSH{iVar} ← S - TOSH{arg2} - 1, BRANCH[$, SCar9, 1], c2;
SC9Cont: , c3;
uTT ← TT, TT ← TT LShift1, SE ← 1 {%4 wild hack, get rid of the 1 that was shifted in}, NegBr, c1;
TT ← TT - 1, BRANCH[appLoDEF, appHiDEF], c2;
appLoDEF:
rhTT ← DEFspace, GOTO[fnMD], c3;
appHiDEF:
rhTT ← DEFspaceHi, GOTO[fnMD], c3;
{%3 end}
appUfn: Q ← 14'd, GOTO[sink2], c1;{MP9014}
{***********************}
FNX: MAR ← Q ← [rhS, S + 1], L0 ← L0.RefillFNX, c1, opcode[015'b];{0D}
STK ← MDR ← TOSH,{ rhTT ← DEFspace,} BRANCH[Cont5, SCar5, 1], c2;
Cont5: TOSH ← ib LShift1, XC2npcDisp, c3;
MAR ← [rhPC, PC + 2], BRANCH[$, noNeed, 0E], L1 ← L1.FNX, c1;
TOSH ← TOSH - 2, BRANCH[$, FNXCross, 1], c2;
TOSH ← Q - TOSH, IB ← MD, GOTO[fnIV], L3{ib's}←3, c3;
noNeed: TOSH ← TOSH - 2, CANCELBR[$, 0E], L1 ← L1.FNX, c2;
TOSH ← Q - TOSH, GOTO[fnIV], L3{ib's}←3, c3;
{***********************}
FN0: MAR ← Q ← [rhS, S + 1], L3{ib's}←2, c1, opcode[010'b];{08}
STK ← TOSH, MDR ← TOSH, TOSH ← 1 + Q +1, BRANCH[Cont1, SCar1, 1], c2;
FN1: MAR ← Q ← [rhS, S + 1], L3{ib's}←2, c1, opcode[011'b];{09}
FN1Ext: STK ← MDR ← TOSH, TOSH ← Q - 0, BRANCH[Cont1, SCar1, 1], c2;
FN2: MAR ← Q ← [rhS, S + 1], L3{ib's}←2, c1, opcode[012'b];{0A}
FVcall: STK ← MDR ← TOSH, TOSH ← Q - 2, BRANCH[Cont1, SCar1, 1], c2;
FN3: MAR ← Q ← [rhS, S + 1], L3{ib's}←2, c1, opcode[013'b];{0B}
STK ← MDR ← TOSH, TOSH ← Q - 4, BRANCH[Cont1, SCar1, 1], c2;
FN4: MAR ← Q ← [rhS, S + 1], L3{ib's}←2, c1, opcode[014'b];{0C}
STK ← MDR ← TOSH, TOSH{iVar} ← Q -6, BRANCH[Cont1, SCar1, 1], c2;
Cont1: {rhTT ← DEFspace}, c3;
fnIV: {fix for 16 bit atoms}
Xbus ← ibNA, XLDisp, c1;
BRANCH[FNLoDef, FNHiDef, 1], c2;
FNLoDef: rhTT ← DEFspace, GOTO[fnIVnext], c3;
FNHiDef: rhTT ← DEFspaceHi, GOTO[fnIVnext], c3;
{iVar (new) stored as end of old frame}{High half of S to match Q}{Q: Sev; TOSH: iVar(new)}
fnIVnext:
MAR ← [rhPV, PV - 6], c1;
MDR ← TOSH{iVar}, TT ← ib, BRANCH[$, SCar6, 1], c2;
SC6Cont: TT ← TT LRot8, c3;
fnS: {Flush top of stack} {Q: S even}{High half of S to match Q}
MAR ← Q ← [rhS, Q+1],{High half of S to match Q} c1; {Q ← odd}
MDR ← TOS, S ← Q + 2, CANCELBR[$, 2], WriteOK, c2;
TT ← TT or ib LShift1, c3;
{***********************}
fnMD: {MapDef; rhTT,TT{FunDef} S{oddEmpty} L3{ib's} PV.iVar=TOSH{iVar} PC:+0}
uTT{FunDef} ← Map ← [rhTT{FunDefs}, TT], L0 ← L0.FCRedo, c1;
TOS ← UvCL, L1 ← L1.FC, c2;
uIVar ← TOSH, Rx ← rhRx ← MD, ReadXRefBr, c3;
{Get def cell high}
MAR ← [rhRx, TT + 0], ReadBRANCH[FCMap, $], c1, at[L0.FCRedo, 10,RMapFixCaller];
Q ← PC and 0FF, L1 ← L1.FCH, c2;
Q ← Q - TOS{UvCL}, rhTT{UvChighL} ← MD, XHDisp{compiled?}, c3;
fnD0: {Get def cell low}
MAR ← [rhRx, TT+1], BRANCH[interpret, $, 2], c1;
Rx{uStkLimO} ← uStkLimO, CANCELBR[$, 2], L0 ← L0.FCHRedo, c2;
uPC ← PC, TT{UvCL} ← MD, L3Disp{deltaPC}, c3;
fnMH: {Map function header}
Map ← [rhTT, TT], BRANCH[incPC1, incPC2, 0E], c1;
incPC1: uTOS{savUvCL} ← TOS, TOS{pc} ← Q + PC16, GOTO[jMH], c2;
incPC2: uTOS{savUvCL} ← TOS, TOS ← Q + 1, GOTO[jMH], c2;
jMH: uTOSH{iVar} ← TOSH, PC ← rhPC ← MD, ReadXRefBr, c3;
{Fetch function header 0} {S: odd, empty}
FCHred: MAR ← Q ← [rhPC, TT + 0], L1 ← L1.FCH, ReadBRANCH[FCHMap, $], c1{, at[L0.FCHRedo, 10,RMapFixCaller]};
TOSH{args} ← RShift1 (S-TOSH{iVar}-1), SE←0, c2;
UvCL ← TT, TT{stk} ← MD, c3;
fnH1: {Fetch function header 1} {TOSH{args} non-neg}
MAR ← PC ← [rhPC, Q + 1], c1;
Q{stkNeed} ← TT{stk} + S, CANCELBR[$, 2], c2;
TT{na} ← MD, XHDisp, GOTO[fnH2], c3;
fnH2: {Regs: TOSH{args}, TOS{PC-UvCL}, Rx{uStkLim0}, Q{stkNeed}, TT{na}, PC{header}, PV{pv}, S{s} }
MAR ← [rhPC, PC + 1], BRANCH[$, LamStar, 2], c1;
Ybus ← Rx{uStkLim0} - Q{stkNeed}, CarryBr, CANCELBR[$, 2], c2;
Rx{pv#} ← MD, XHDisp, BRANCH[FnStkOvr, fnH3], c3;
fnH3: {Fetch function header 3}
MAR ← [rhPC, PC + 2], L0←2, BRANCH[h30, h31, 2], c1;
h30: TOSH{wdsXtr+1} ← TOSH{args} - TT{na} LShift1, SE←1, NegBr, CANCELBR[h4, 2], c2;
h31: TOSH{wdsXtr+1} ← TOSH{args} - TT{na} LShift1, SE←1,NegBr, CANCELBR[h4, 2], c2;
h4: Q{start} ← MD, BRANCH[enough, grow], c3;
grow: {grow the stack if necessary}
MAR ← [rhS, S-1], c1;
MDR ← TT ← 0, CANCELBR[$, 2], WriteOK, c2;
TOSH ← TOSH + 1, c3;
fnG: MAR ← S ← [rhS, S+0], c1;
MDR←TT{zero}, TOSH{wdsXtr}←TOSH+1, NegBr, c2;
S ← S+2, BRANCH[enough, grow], c3;
{(N) trim stack and push uBFmark (once was nargs)} {TOSH{argsXtr} non-neg}
enough: MAR ← S ← [rhS, S - TOSH{wdsXtr+1}], c1;
FnNCont: MDR ← uBFmark, BRANCH[$, FnNCar, 1], c2;
TOSH{UvPCpageLOld} ← UvPCpageL, c3;
fnB: {push IVar)}
MAR ← S ← [rhS, S+1], c1;
MDR ← uIVar, CANCELBR[$, 2], WriteOK, c2;
S ← S+1, c3;
fnF: {push uFXmark}
MAR ← S ← [rhS, S+0], L3Disp{deltaPC}, c1;
MDR ← uFXmark, BRANCH[pcInc0, pcInc2, 0D], WriteOK, c2;
pcInc0: TOSH{pc} ← TOSH{UvPCpageLOld} + TOS{PC+UvCL}, NegBr, GOTO[savPv], c3;
pcInc2: TOSH{pc} ← TOSH{UvPCpageLOld} + TOS{PC+UvCL}+1, NegBr, GOTO[savPv], c3;
savPv: {Alink ← oldPvar}
MAR ← S ← [rhS, S+1], BRANCH[$, NegPcError], c1;
MDR ← PV{old}, S ← S+1, CANCELBR[$, 2], WriteOK, c2;
TOS{start-1} ← (Q{start} - 1) RShift1, SE←0, c3;
{(P) Clear PC16, Store relative byte PC = 2*[UvPCpageL-UvCL+(PC and 0FF)]+PC16}
{ MD TOS ← UvCL, }
{ D: Q ← PC and 0FF, }
{ Q{PC-UvCL} ← Q - TOS, }
{ MH TOS{PC-UvCL} ← Q + PC16 {+PC16}, }
{ N: TOSH ← UvPCpageL, }
{ F: TOSH{relWdPC} ← TOSH{UvPCpageL} + TOS{PC-UvCL} {+ 1}, }
{ MDR ← TOSH + TOSH + pc16, }
fnP: MAR{PC} ← PV ← [rhPV, PV - 5], c1;
MDR ← TOSH ← TOSH{pc}+TOSH+PC16, BRANCH[$, FnPCar, 1], c2;
FnPCont: PV{new} ← S + 8{empty fields}, XC2npcDisp, c3;
fnC: {push code base low}
MAR ← [rhS, S+0], IB ← 6{constant}, BRANCH[fnPcOdd, fnPcEv, 0E], c1;
fnPcOdd: MDR ← TOSH ← UvCL, GOTO[fnC0], Cin←pc16, c2;
fnPcEv: MDR ← TOSH ← UvCL, GOTO[fnC0], c2;
fnC0: TOSH{UvPCpageL} ← TOSH and ~0FF, c3;
fnC1: {push code base high}
MAR ← Q ← [rhS, S+1], IBPtr ← 1, L0Disp{pv# zero}, c1;
MDR ← TT ← rhTT, WriteOK, BRANCH[plp, plpD, 0E], c2;
plpD: UvChighL ← TT, S ← Q{S} + ib{6} + 1, GOTO[loopDone], c3;
plp: UvChighL ← TT, S ← Q{S} + ib{6} + 1, {room for next, PC, nameTable, Blink and, Clink} c3;
{(V) push #pvar unbound pointers}
loopP: MAR ← S ← [rhS, S+0], c1;
MDR ← TT{ones}← ~TT xor TT, c2;
S ← S + 2, c3;
MAR ← S ← [rhS, S+0], c1;
MDR ← TT{ones},Rx{pv#}←Rx-1, NegBr, c2;
S ← S + 2, BRANCH[loopP, loopDone], c3;
{(F) start fetch from the byte PC, PC16 cleared previously}
loopDone: MAR ← PC ← [rhPC, PC{+1} + TOS{start-1}], c1;
S ← S + 1, BRANCH[$, CCross,1], c2;
UvPCpageL ← TOSH, IB ← MD, c3;
MAR ← [rhPC, PC + 1], IBPtr←0, L2 ← L2.0, c1;
AlwaysIBDisp, TOSH ← 0, L0← L0.NERefill.Set, DISP2[NoRCross], c2;
CCross: UvPCpageL ← TOSH, c3;
TOSH ← 0, c1;
Noop, c2;
Q ← 0FF + 1, L0 ← L0.JRemap, GOTO[UpdatePC], c3;
{2 more clicks}
{exceptions:}
SCar1: Noop, c3;
Noop, c1;
TOSH ← TOSH + 0FF + 1, {derived from Q} c2;
S ← S + 1, {High half of S to match Q} c3;
MAR ← Q ← [rhS, S + 0], c1;
MDR ← STK, GOTO[Cont1], c2;
SCar5: S ← Q + 0FF + 1, c3;
MAR ← Q ← [rhS, S + 0],{High half of S to match Q} c1;
MDR ← TOSH, {S ← S - 1,}{High half of S to match Q} GOTO[Cont5], c2;
NegPcError: Q ← 13'd, CANCELBR[sink3, 3], c2;{MP9013}
FNXCross: uPCCrossL ← (~TT xor TT), c3;
TOSH ← Q - TOSH, c1;
uRx{savQ} ← Q, c2;
Q ← 0FF + 1, {GOTO[UpdatePC],} {L1 = L1.FNX,} c3;
{FNXCross1:}{UpdatePC:}
TT ← UvPCpageL, GOTO[UpdatePC2], c1;
{FCross:} {UpdatePC returns here}
Rx ← rhRx ← MD, ReadXRefBr, c3, at[L0.RefillFNX,10,ECross];
MAR ← [rhRx, PC + 2], ReadBRANCH[FXMapUD, $], c1, at[L0.RefillFNX,10,RMapFixCaller];
Q ← uRx{SavQ}, {rhTT ← DEFspace,} CANCELBR[$,2], c2;
IB ← MD, L3{ib's}←3, GOTO[fnIV], c3;
{ Q ← uRx{SavQ}, c1;
c2;
GOTO[fnIV],c3;
}
FXMapUD: Noop, CANCELBR[RLMapFix, 3], {returns at FXRedo} c2;
FXFix: TOSH ← STK, GOTO[NoMoreFix], c1, at[L1.FNX,10,Fix];
SCar6: STK ← PV, PV ← PV - 6, c3;
MAR ← [rhPV, PV + 0], c1;
MDR ← TOSH, PV ← STK, GOTO[SC6Cont], c2;
SCar9: STK ← PV, PV ← PV - 6, c3;
MAR ← [rhPV, PV + 0], c1;
MDR ← TOSH, PV ← STK, GOTO[SC9Cont], c2;
FnNCar: S ← S -0FF - 1, c3;
MAR ← [rhS, S + 0], GOTO[FnNCont], c1;
FnPCar: PV ← PV -0FF - 1, c3;
MAR ← [rhPV, PV + 0], c1;
MDR ← TOSH, GOTO[FnPCont], c2;
{S odd empty}
interpret: TOS{atm} ← TT RShift1, CANCELBR[$, 2], c2;
TT ← 0FF + 1{400=AT.INTERPRETER%}, c3;
{interpret: TT ← 0FF + 1{400=AT.INTERPRETER%}, CANCELBR[$, 2], c2;
TOS{UvCL} ← MD, c3;}
interpret1: MAR ← [rhS, S - 1], c1;
MDR ← 0{rhTT}, CANCELBR[$, 2], WriteOK, c2;
interpret3: TT ← TT + TT, CarryBr, c3;
MAR ← [rhS, S + 0], BRANCH[$, intDefhi], c1;
MDR ← TOS{atm}, rhTT ← DEFspace, c2;
intDEFdone:
S ← S + 2, GOTO[fnMD], c3;
intDefhi:
MDR ← TOS{atm}, rhTT ← DEFspaceHi, GOTO[intDEFdone], c2;
LamStar: TT{na} ← TOSH{args}, CANCELBR[$, 2], c2;
Noop, GOTO[fnH2], {try again} c3;
FCMap: CANCELBR[RLMapFix, 3], c2;
FCHMap: Rx ← PC, CALL[RLMapFix], c2;
Noop, ReadCANCELBR[$], c1, at[L0.FCHRedo, 10,RMapFixCaller];
Rx{uStkLimO} ← uStkLimO, c2;
Xbus ← 3, XDisp, GOTO[FCHred], c3;
FnStkOvr: TOSH{iVar} ← uTOSH, CANCELBR[$, 3], c1;
TT{UvCL} ← uTOS, c2;
UvCL ← TT, c3;
Rx ← {0 -} SubovFXP, L3Disp{deltaPC}, GOTO[fchFix2], c1;
{*************************}
FCHFix: {preserves Rx:FXP#}
{Noop,} L3Disp{deltaPC}, c1, at[L1.FCH,10,Fix];
fchFix2: Noop, BRANCH[decPC1, decPC2, 0E], c2;
decPC1: PC ← uPC, GOTO[FCFix], Cin←pc16, c3;
decPC2: PC ← uPC, GOTO[FCFix], c3;
FCFix: L3Disp, c1, at[L1.FC,10,Fix];
TOS ← uTT, DISP4[PCdelt, 0C], c2;
PC ← PC + PC16, GOTO[FCFix1], c3, at[0C, 10, PCdelt];
PC ← PC + 1, GOTO[FCFix1], c3, at[0D, 10, PCdelt];
PC ← 1 + PC + PC16, GOTO[FCFix1], c3, at[0E, 10, PCdelt];
PC ← PC + 2, GOTO[FCFix1], c3, at[0F, 10, PCdelt];
FCFix1: MAR ← [rhS, S - 1], c1;
MDR ← smallpl, CANCELBR[$, 2], WriteOK, c2;
TOSH{args} ← RShift1 (S-TOSH{iVar}-1), SE←0, c3;
MAR ← [rhS, S + 0], c1;
MDR ← TOSH{args}, TOSH ← 0, L2 ← 1{InCall}, c2;
TOS ← TOS RShift1, GOTO[PuntFor], c3;
{ E N D }