Routines 
Prev: 13372  Up: Map  Next: 13418 
The address of this routine is found in the table of addresses. It is called via a calculator literal (134, 136 or 140) by the routines at exp, ln, sin and atn.
This important subroutine generates the series of Chebyshev polynomials which are used to approximate to SIN, ATN, LN and EXP and hence to derive the other arithmetic functions which depend on these (COS, TAN, ASN, ACS, ** and SQR).
The polynomials are generated, for n=1, 2, etc. by the recurrence relation T_{n+1}(z)=2zT_{n}(z)T_{n1}(z), where T_{n}(z) is the nth Chebyshev polynomial in z.
The series in fact generates T_{0}, 2T_{1}, 2T_{2}, ..., 2T_{n1}, where n is 6 for SIN, 8 for EXP, and 12 for LN and ATN.
The coefficients of the powers of z in these polynomials may be found in the Handbook of Mathematical Functions by M. Abramowitz and I. A. Stegun (Dover 1965), page 795.
In simple terms this subroutine is called with the 'last value' on the calculator stack, say Z, being a number that bears a simple relationship to the argument, say X, when the task is to evaluate, for instance, SIN X. The calling subroutine also supplies the list of constants that are to be required (six constants for SIN). The series generator then manipulates its data and returns to the calling routine a 'last value' that bears a simple relationship to the requested function, for instance, SIN X.


This subroutine can be considered to have four major parts.
i. The setting of the loop counter. The calling subroutine passes its parameters in the A register for use as a counter. The calculator is entered at GEN_ENT_1 so that the counter can be set.


series  13385  LD B,A  Move the parameter to B.  
13386  CALL GEN_ENT_1  In effect a RST 40 instruction but sets the counter.  
ii. The handling of the 'last value', Z. The loop of the generator requires 2*Z to be placed in mem0, zero to be placed in mem2 and the 'last value' to be zero.


13389  DEFB 49  duplicate: Z, Z  
13390  DEFB 15  addition: 2*Z  
13391  DEFB 192  st_mem_0: 2*Z (mem0 holds 2*Z)  
13392  DEFB 2  delete:   
13393  DEFB 160  stk_zero: 0  
13394  DEFB 194  st_mem_2: 0 (mem2 holds 0)  
iii. The main loop.
The series is generated by looping, using BREG as a counter; the constants in the calling subroutine are stacked in turn by calling stk_data; the calculator is reentered at GEN_ENT_2 so as not to disturb the value of BREG; and the series is built up in the form:
B(R)=2*Z*B(R1)B(R2)+A(R), for R=1, 2, ..., N, where A(1), A(2)...A(N) are the constants supplied by the calling subroutine (SIN, ATN, LN and EXP) and B(0)=0=B(1).
The (R+1)th loop starts with B(R) on the stack and with 2*Z, B(R2) and B(R1) in mem0, mem1 and mem2 respectively.


G_LOOP  13395  DEFB 49  duplicate: B(R), B(R)  
13396  DEFB 224  get_mem_0: B(R), B(R), 2*Z  
13397  DEFB 4  multiply: B(R), 2*B(R)*Z  
13398  DEFB 226  get_mem_2: B(R),2*B(R)*Z, B(R1)  
13399  DEFB 193  st_mem_1: mem1 holds B(R1)  
13400  DEFB 3  subtract: B(R), 2*B(R)*ZB(R1)  
13401  DEFB 56  end_calc  
The next constant is placed on the calculator stack.


13402  CALL stk_data  B(R), 2*B(R)*ZB(R1), A(R+1)  
The calculator is reentered without disturbing BREG.


13405  CALL GEN_ENT_2  
13408  DEFB 15  addition: B(R), 2*B(R)*ZB(R1)+A(R+1)  
13409  DEFB 1  exchange: 2*B(R)*ZB(R1)+A(R+1), B(R)  
13410  DEFB 194  st_mem_2: mem2 holds B(R)  
13411  DEFB 2  delete: 2*B(R)*ZB(R1)+A(R+1)=B(R+1)  
13412  DEFB 53  dec_jr_nz to G_LOOP: B(R+1)  
13413  DEFB 238  
iv. The subtraction of B(N2). The loop above leaves B(N) on the stack and the required result is given by B(N)B(N2).


13414  DEFB 225  get_mem_1: B(N), B(N2)  
13415  DEFB 3  subtract: B(N)B(N2)  
13416  DEFB 56  end_calc  
13417  RET  Finished. 
Prev: 13372  Up: Map  Next: 13418 