Rems: 1C16 JUMP C R all separators have been considered separators see 1B6F SEPARATOR above SERIES GENERATOR SUBROUTINE see series-06 series 06 etc subroutine 3449 The notes use three different names for the same subroutine, series-06, series-08 and series-0C. Whichever name is used, series-N calculates the sum of N Chebyshev polynomials,each multiplied by the appropriate constant. This is approximately the value of the function required. See under Chebyshev polynomials in this index, and the illustrated examples of LN X and ATN X on page 227 of the notes. Called in the ROM only from 0028 FP CALC with literals 86, 88 and 8C, but it could called with any literal 80h+N from 80h to 9Fh, ie with N up to 1F. N dictates the number of Chebyshev constants to be read. The literal must be followed by N constants, each one in stk-data format. In 336C SCAN ENT the literal is first converted to 7C, which is used to find the series subroutine in the table; then the original literal less 80h provides the counter N for the constants. The subroutine could be called directly from m/c, ie without going through 0028 FP CALC: the counter N must be in theA register, the argument of the function on the calculator stack, and the N Chebyshev constants in stk-data format must immediately follow the call command. The result would be returned on the calculator stack. However there is no ROM example of such a call. As explained, very inadequately in the header note, and I hope less confusingly in the index under Chebyshev polynomials, if you already have two Chebyshev polynomials, "this one" and "the last one", it is easy to calculate a third, "the next one": the next one = 2Z times this one minus the last one. Use P(i) and A(i) to mean "this polynomial" and "this constant"; i - 1 indicates "the last" and i + 1 "the next". The three simplest polynomials are P(1) = 1 P(2) = 2Z P(3) = 4Z**2 - 2 and the rest are found by the formula P(i + 1) = 2Z * P(i) - P(i - 1). However the constants are given in an order which requires the first constant to be multiplied by the most complicated polynomial, and the last constant by the simplest: so each term of the approximation to the function is A(N + 1 - i) * P(i), and the final approximation is A(N) * P(1) + A(N-1) * P(2) + ... A(1) * P(N) The ROM ingeniously builds up the polynomials and multiplies in the constants at the same time, in a series of stages. Each turn of the loop calculates a value B(i) by the formula B(i) = 2Z*B(i-1) - B(i-2) + A(i), starting with zeroes for B(i - 1) and B(i - 2). So the first four calculations come out as B(1) = A(1) B(2) = 2Z*A(1) + A(2) B(3) = 2Z*B(2) - B(1) + A(3) = 2Z[2Z*A(1) + A(2)] - A(1) + A(3) = (4Z**2 - 1)*A(1) + 2Z*A(2) + A(3) = (4Z**2 - 2)*A(1) + 2Z*A(2) + A(3) + B(1) B(4) = 2Z*B(3) - B(2) + A(4) = 2Z[(4Z**2 - 1)*A(1) + 2Z*A(2) + A(3)] - [2Z*A(1) + A(2)] + A(4) = (8Z**3 - 6Z)*A(1) + (4Z**2 - 2)*A(2) + 2Z*A(3) + A(4) + B(2) In every case it will be found that B(i) = A(1)*P(i) + A(2)*P(i-1) + ... + A(i)*P(1) + B(i-2) so after N turns of the loop the required result is B(N) - B(N-2). Input parameters: A holds the number of constants N - the argument Z of the function is on the calculator stack. Action: put N in the B register and call 335E GEN ENT 1 to store it in 5C67 BREG as a loop counter for later; this enters the calculator - double Z and store 2Z - also store a zero. _3453_G_LOOP (entered on the i'th turn of the loop with 2Z in mem-0 B(i-2) "the last but one" in mem-1; not used initially B(i-1) "the last one" in mem-2; zero initially B(i) "this one" on the stack; zero initially the loop counter N in 5C67 BREG): - use the calculator in a quite straightforward way to calculate 2Z*B(i) - B(i-1); put B(i-1) in mem-1 - call 33C6 STK DATA direct to get the constant A(i+1); it will get the FP form for the constant from bytes following the calling literal or routine - call 3362 GEN ENT 2 to reenter the calculator without resetting 5C67 BREG - add the constant, making B(i+1) = 2Z*B(i) - B(i-1) + A(i+1) - put B(i) in mem-2 and delete it from the calculator stack; all parameters are now in place for the next turn of the loop - if the 5C67 BREG counter isn't yet zero loop back to GLOOP - (the loop has been turned N times) subtract B(N-2) in mem-1 from B(N) on the stack; this is the result. Exit: RET from G LOOP. Output parameters: the result is on the stack - HL and DE are pointers to the last value and stack endas usual. Called from: 36C4 exp (N=8) 373D GRE 8 (N=C) 37B7 C ENT (N=6) 37FA CASES (N=C) Rems: 33C6 STK DATA literals supplied from calling subroutine 367A dec-jr-nz only used in series generator 3713 ln used to calculate (ln M)/(M-1) or (ln 2M)/(2M-1), where M is mantissa of argument 37B5 sin used to calculate sin X using reduced argument 37E2 atn used to calculate atn X using reduced argument SET ATTRIBUTE BYTE SUBROUTINE see 0BDB PO ATTR SET DE subroutine 1195 DE is "set" to hold the_first address, not the last as in the heading of the notes, of the working area currently in use, either the editing area or the work space. If entered with NC in the carry flag, it also sets HL to the last address of thework space. Both calls from ROM are made with the carry flag set, but the exit from 1190 SET HL has it cleared. Input parameters: none. Action: load DE with the address from 5C59 E LINE, the start of the editing area - if bit 5 of FLAGX is zero, return; editing mode - reload DE with the address from 5C61 WORKSP, the startof the work space - if the carry is set, return - load HL with the address from 5C53 STKBOT, the end of the work space. Exit: RET, three alternatives. Output parameters: DE set, also HL if appropriate. Called from: 1031 ED EDGE 111D ED COPY (misprinted SET HL) Exit from: 1190 SET HL SET HL subroutine 1190 HL is "set" to hold the_last address and DE the_first ofthe working area currently in use, either the editing area or the work space; the notes get it wrong. Input parameters: none. Action: set HL to the address in 5C61 WORKSP - move HL back one; to the end of the editing area - clear the carry. Exit: into 1195 SET DE, which does the rest. Output parameters: no change except in HL and the carry. Called from: 1097 CLEAR SP SET MIN subroutine 16B0 Reduces the editing area to a single newline, the work space and calculator stack to zero, and ensures that 5C68 MEM points to its normal address, the base of the calculator memory. There is no call to the RECLAIM routines: these are the highest areas in working RAM, and there is nothing to reclaim above them. Input parameters: none. Action: get the address from 5C59 E LINE, the start of the editing area - put a newline in it - put it in 5C5B K CUR, the current mode cursor address - move on one - put an 80-byte to mark the end of the editing area - move on one - load this address in 5C61 WORKSP, the start of the work space. _16BF_SET_WORK (this entry point is used when the editingarea is to be left as it was): get the address in 5C61 WORKSP - put it in 5C63 STKBOT, the end of the work space. _16C5_SET_STK (this entry point is used when both editingarea and work space are to be left; 5C68 MEM is reset to 5C92 MEMBOT, which is the only point of the jump from 1A15 E L 1): get the address from 5C63 STKBOT - put it in 5C65 STKEND, the end of the calculator stack - put the normal address 5C92 MEMBOT in 5C68 MEM, marking the start of the calculator memory area. Exit: RET, from 16C5 SET STK. Output parameters: HL holds STKEND=STKBOT - new values have been given to the top three of the fourteen system pointers; but not to 5C5D CH ADD and 5C5E X PTR. 12A9 MAIN 1 1313 MAIN G SET PERMANENT COLOURS SUBROUTINE see 1C96 CLASS 07 SET STK 16C5 (16B0 SET MIN) Exit from: 0055 ERROR 3 16B0 SET MIN 16BF SET WORK 1A15 E L 1 SET WORK subroutine 16BF See 16B0 SET MIN. Called from: 1B29 STMT L 1 20FA IN PROMPT SFA CP VR 296B (28B2 LOOK VARS) Jumps from: 295A SFA LOOP SFA END 2991 (28B2 LOOK VARS) Exit from: 2981 SFA MATCH (28B2 LOOK VARS) SFA LOOP 295A (2951 STK F ARG) Jumps from: 296B SFA CP VR SFA MATCH 2981 (28B2 LOOK VARS) Jumps from: 296B SFA CP VR SF ARG LP 2843 (25F5 S FN) Jumps from: 2852 SF ARG VL SF ARGMTS 27D9 (25F5 S FN) Jumps from: auto SF ARGMT 1 2802 (25F5 S FN) Jumps from: 27F7 SF RUN SF ARG VL 2852 (25F5 S FN) Jumps from: 2843 SF ARG LP SF BRKT 1 27D0 (25F5 S FN) Jumps from: 27BD S FN SBRN SF BRKT 2 27E4 (25F5 S FN) Jumps from: 27D9 SF ARGMTS SF CP DEF 2814 (25F5 S FN) Jumps from: 2808 SF FND DEF SF FLAG 6 27E9 (25F5 S FN) Jumps from: 27D0 SF BRKT 1 SF FND DEF 2808 (25F5 S FN) Jumps from: 2825 SF NOT FD S FN subroutine 25F5 Entered only from the scanning function table 2696; the executive routine of the FN function, which must have a corresponding DEF FN statement giving the user's definition of the function. It jumps straight on to S FN SBRN, whose description is included here; there is no room for the whole of this lengthy subroutine in the 100h/256d-byte range of the table offsets of the scanning function table. The left side of a DEF FN statement usually contains a set of arguments (X, Y, Z, ... X$, Y$, Z$, ...) corresponding tosome of the variables in the FN statement; in the DEF FN statement each of the arguments on the left side, even the string arguments, is followed by a number marker and a 5-byte space for the numeric value or string parameters. In the FN expression some of the arguments may be actual values, others expressions or variables in the variables area or arguments of the DEF FN, but they must all have a value - new variables will produce an error. However there may be no arguments at all: functions like DEF FN p()=PI*X or DEF FN r$()= "The result is "+STR$ X are accepted. The subroutine is in two independent parts, one for syntax checking and the other for run time. In syntax checking, only the FN statement is checked. Apart from reporting any syntax errors, the routine puts 5-byte FP number forms after anyplain numbers in the FN arguments; not after variables, eg in FNx(7,3/a) after the 7 and the 3 but not after the a. The run time section - scans the program till a DEF FN statement with matchingname and numeric/string type is found - puts a numeric value or string parameters in each of the 5-byte spaces in the left side of the DEF FN statement, using the value given by the FN expression - evaluates the right side of the DEF FN statement, using24FB SCANNING, which picks up preferentially the values from the"dummy" variables on the left side, but looks in the variables area for any variable names which don't appear on the left side.As always with SCANNING, the result of the evaluation is left aslast value on the calculator stack.