{File name ndbLisp.mc -- modified for Punt testing Description: DandeLion InterLisp Emulator Purcell: 15-Aug-85 18:52:11 {improve 64K atoms in \interp} Purcell: June 8, 1981 Created 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; rhRio ← 5, c1; Rio ← 0, c2; , c3; MAR ← [rhRio, Rio + 0], c1; MDR ← PV, c2; , 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,}{% dont lose msb yet} c3; {fix for 16 bit atoms} uTT ← TT, NegBr, c1; TT ← LShift1 TT, SE ← 1, BRANCH[FNLoDef, FNHiDef], c2; FNLoDef: rhTT ← DEFspace, GOTO[fnMD], c3; FNHiDef: rhTT ← DEFspaceHi, GOTO[fnMD], c3; {***********************} fnMD: {MapDef; rhTT,TT{FunDef+1} S{oddEmpty} L3{ib's} PV.iVar=TOSH{iVar} PC:+0} {uTT ←}{% 64K}{FunDef}TT ← Map ← [rhTT{FunDefs}, TT - 1], 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} ← uTT, 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: uTT ← TT, TT ← LShift1 TT, SE ← 1, NegBr, 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 }