Prev: 13372 Up: Map Next: 13418
13385: THE 'SERIES GENERATOR' SUBROUTINE (offset 62)
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 Tn+1(z)=2zTn(z)-Tn-1(z), where Tn(z) is the nth Chebyshev polynomial in z.
The series in fact generates T0, 2T1, 2T2, ..., 2Tn-1, 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.
Input
A Series parameter (6, 8 or 12)
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 mem-0, zero to be placed in mem-2 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 (mem-0 holds 2*Z)
13392 DEFB 2 delete: -
13393 DEFB 160 stk_zero: 0
13394 DEFB 194 st_mem_2: 0 (mem-2 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 re-entered 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(R-1)-B(R-2)+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(R-2) and B(R-1) in mem-0, mem-1 and mem-2 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(R-1)
13399 DEFB 193 st_mem_1: mem-1 holds B(R-1)
13400 DEFB 3 subtract: B(R), 2*B(R)*Z-B(R-1)
13401 DEFB 56 end_calc
The next constant is placed on the calculator stack.
13402 CALL stk_data B(R), 2*B(R)*Z-B(R-1), A(R+1)
The calculator is re-entered without disturbing BREG.
13405 CALL GEN_ENT_2
13408 DEFB 15 addition: B(R), 2*B(R)*Z-B(R-1)+A(R+1)
13409 DEFB 1 exchange: 2*B(R)*Z-B(R-1)+A(R+1), B(R)
13410 DEFB 194 st_mem_2: mem-2 holds B(R)
13411 DEFB 2 delete: 2*B(R)*Z-B(R-1)+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(N-2). The loop above leaves B(N) on the stack and the required result is given by B(N)-B(N-2).
13414 DEFB 225 get_mem_1: B(N), B(N-2)
13415 DEFB 3 subtract: B(N)-B(N-2)
13416 DEFB 56 end_calc
13417 RET Finished.
Prev: 13372 Up: Map Next: 13418