## TPAL = TP Assembly Language

Example source file "primes.t"
--- as in TP­book Section 6.5.2 ---

to TP­page / compressed version primes.dry
```         Routine for Computing Primes
==============================
Routine PRIMES computes primes up to n by the sieve of Erathostenes,
complemented as explained on TP-book page 226. The routine is
completely self-contained, "PRIMEND:" labels its final line.

Inputs:  [A]= n < &/2,  p1,p2,p3,p4 stacky;
Returns: 2,3,5,... primes -= n  wordwise on T1,
p1 on top word = pi(n),  p2,p3,p4 as before.

P.PRIMES: JPHA.ALARM,           if  n += &/2
LC=2, CT1+, LM=3, MT1+, store 2,3
LB=5, JNL.PRIM3,        if  n += 5  then main routine
SB.C, JAZ.PRIM1,        if  n=2
JHAZ.PRIM2,             if  n=3 or n=4
P1-, CM,                for n=1 or n=0
PRIM1:  P1-, CM,                for n<3
PRIM2:  CT1, RTS,               store pi(n) and return
-------------------------------------------------------
Main part of PRIMES:  (for n += 5)
--------------------
PRIM3:  BT0+, LM=4, MT0+,       p:= 5,  dp:= 4
AT0+, LC=0,             store n,  s:= 0
PRIM4:  CT0,                    save  s = number of sequences  on T0
LCBM p, ML, LA.M,        p -> C,  v:= p^2 -> A  ([E]=0 by ML)
LM.C, SM H1,            2p -> M
LB n, JGR.PMERGE,       if  p^2 > n  then start merging
storing sequence of multiples  v = m.p  for m congruent 1, 5 mod 6,
ZT1+,                   set bottom zero for sequence
LK dp, KM, JKM.PRIM6,   if dp > 2 (then old dp equal to 4)
JGR.PRIM7,              if  v > n  then exit
PRIM6:  AT1+, AD.M, JNG.PRIM5,  v:= v + 2p,  loop while  v -= n

next prime p:
-------------
PRIM7:  LA=6, SB dp, AT dp,     dp:= 6 - dp
AD.C, LC.A,             p:= p + dp
LB=1, LK=2,             t:= 1, dt:= 2
: LA=6, SB.K, LK.A,       dt:= 6 - dt
AD.B, LB.A, LA=0,       t:= t + dt
LM.C, DIV, JAZ.PRIM7,   p = q.t + r,  if r=0 then next p
LA.M, JGR,        trial divisions while q > t
CT p, PTN 121,          store prime p and alternate T1/T2
LC0, CP, J.PRIM4,       s:= s+1, loop for next sequence
-----------------
Merging the sequences, increasing from bottom zero word on T1,T2,
---------------------  decreasing from top word &-1 on T3,T4;
PMERGE: AC.A, AT3, LM0,         set initial &-1 and get s
JMZ.PRIM8,              if s=0 (for n<25)
then empty final sequence
-PMERG- Pass for merging the sequences from T1,T2 upon T3,T4:
-------
PMRG1:  P1-, P2-, LAE.M,        parity(s) -> E
SML 1, SB.M, LCM.A,     s:= ceil(s/2) -> M,C
JEZ.PMRG2,              if old s was even
PTN 121,                else adjust order of tapes
AC.A, J.PMRG6,          and copy one sequence upon T3
---------------
PMRG2:  AC.A, LB2-,             init merge loop
- - - - - -
PMRG3:  AT3+,                   here [A] first
PMRG4:  LA1-, JA.PMRG5,         loop while nonzero
: BT3+, LB2-, JB,         copy remaining elements from T2
J.PMRG7
----------
PMRG5:  JGR.PMRG3,              if [A] first
JEQ.PMRG4,              if equal then skip [A]
BT3+, LB2-, JB,         here [B] first; loop while nonzero
- - - - - - - -
PMRG6:  AT3+, LA1-, JA,         copy remaining elements from T1
- - - - - - - -
PMRG7:  DP1-A, DP2-A,           discard old sequences, here [A]=0
PT 343, JCM.PMRG2,      loop for s sequences

-QMERG- Pass for merging the sequences from T3,T4 upon T1,T2:
-------
P1+, P2+, P3-, P4-
LABE.M, SBL 1,          parity(s) -> E,  floor(s/2) -> B
SB.B, LCM.A,            s:= ceiling(s/2) -> M,C
JE.QMRGE,               if old s was odd
QMRG2:  LA=0, LB4-,             init merge loop
- - - - - -
QMRG3:  AT1+,                   here [A] first
QMRG4:  LA3-, JHAZ.QMRG5,       loop while below &-1
: BT1+, LB4-, JHBZ,       copy remaining elements from T4
J.QMRG7
-----------
QMRG5:  JLS.QMRG3,              if [A] first
JEQ.QMRG4,              if equal then skip [A]
BT1+, LB4-, JHBZ,       here [B] first; loop while below &-1
- - - - - - - - -
QMRG6:  AT1+, LA3-, JHAZ,       copy remaining elements from T3
- - - - - - - - -
QMRG7:  LA=0, DP3-A, DP4-A,     discard old sequences
PT 121, JCM.QMRG2,      loop for s sequences
P3+, P4+, J.PMRG1,
-------------------
QMRGE:  PT 343,                 adjust order of tapes (since old s odd)
LA=0, JB.QMRG6,         and copy one sequence upon T1, if old s > 1
P4+,                    else adjust p4 and enter finals

Final part of PRIMES:
---------------------
PRIM8:  LA=5, LCMK=2,           p:= 5,  pi:= 2,  h:= 0 -> HM
PRIM9:  AT1+, CP,               store prime and count  pi:= pi + 1
PRIMA:  AD.K, HM+,              p:= p+2, h:= not(h)
JHM.PRIMB,  AD.K,       p:= p+2, if h=0
PRIMB:  LB3-, JEQ.PRIMA,        no prime, if p is an element of the sequence
P3+, LB n, JNG.PRIM9,   while  p -= n