_24DF_D_L_STEP (using the alternate registers): get the PLOT coordinates from 5C7D COORDS - add the y step to the y coordinate - increment the x step; make it either zero, one or two - add it to the x coordinate - if this makes carry jump on to D L RANGE - if it makes zero without carry report "Integer out of range"; both the x coordinate and the step must be zero. The step represents minus one, a step to the left, and the PLOT coordinates represent a position on the left edge of the screen.The line would go off the left of the screen. _24EC_D_L_PLOT: decrement the x-coordinate; to its original minus one, zero or one - call 22E5 PLOT SUB, which puts a dot on the screen at the coordinates in BC and puts the new coordinates in 5C7D COORDS; it reports an error if the y coordinate is out of range - put the adjusted step indicator back in A - jump back to D L LOOP counting down the step counter - (all T steps have been plotted) clear the machine stack and return. _24F7_D_L_RANGE (adding the incremented step to the x coordinate made a C flag): if the zero flag shows Z jump back toD L PLOT; the x coordinate will be decremented to FF, still on screen - report "Integer out of range"; the line has gone off the right-hand side of the screen. Exit: RET. Output parameters: none - 5C7D COORDS holds the new PLOT position - the DRAW operands have been removed from the calculator stack - the registers may have changed to the alternates. Called from: 2439 ARC START 2477 LINE DRAW Rems: 22AA PIXEL ADD range check 2307 STK TO BC supplies diagonal step in DE 2382 DRAW part of DRAW COMMAND ROUTINE Appendix BASIC demo subroutine (p. 229) DRAW SAVE 2497 (247D CD PRMS1) Misprint: the header is omitted in the notes. Exit from: 247D CD PRMS1 dropping address see address dropping D RPORT C 2C05 (2C02 DIM) Jumps from: 2C2E D NO LOOP DR PRMS 23C1 (2382 DRAW) Jumps from: 23A3 DR SIN NZ DR SIN NZ 23A3 (2382 DRAW) Jumps from: 238D DR 3 PRMS D RUN 2C15 (2C02 DIM) Jumps from: 2C05 D RPORT C DRW STEPS subroutine 2420 Exit routine from the DRAW and CIRCLE routines; the "arc-drawing loop". Used only as an exit routine, but it could be called from m/c with input parameters properly prepared. It is entered with - an "arc count" a, telling how many "arcs" are to be drawn, see 247D CD PRMS1. As elsewhere, "arcs" in quotes means straight-line approximations to short pieces of arc - the start coordinates of the arc in PLOT coordinates - the end coordinates, ditto; for a CIRCLE, these will be the same as the start coordinates - the displacement coordinates for the first "arc" to bedrawn - the sin and cos of the turning angle T which each "arc" must make with the one before. The subroutine draws a - 1 "arcs" of equal length, each turning an angle T from the one before, and then a "closing arc". The "arcs" are drawn by calls to 2487 DRAW LINE, which uses the PLOT position X,Y in 5C7D COORDS and requires DRAW parameters U, V on the calculator stack; the main loop of the subroutine calculates U, V for each "arc" in turn. Then the arc is drawn, leaving the new PLOT coordinates in 5C7D COORDS. The DRAW parameters are calculated as FP numbers, which DRAW LINE rounds to integers, and the PLOT coordinates in 5C7D COORDS are always integers. The cumulative effect of these roundings would cause the curve to wander from a true circular arc after relatively few steps if it wasn't corrected, so the subroutine loop retains in the calculator memory a "dead reckoning" version of the PLOT coordinates in unrounded FP form,and uses these rather than the rounded version in 5C7D COORDS tocalculate the next DRAW parameters. For clarity, these unroundedFP PLOT coordinates are called Xf, Yf in the description below, and the rounded integer coordinates are called Xi, Yi. All the "arcs" are the same length, but each is turned though an angle T relative to the last. The DRAW coordinates U',V' for the next "arc" are calculated from U, V, those for the last, using the same "rotation" formulas as were used in 2382 DRAW: U' = U COS T - V SIN T V' = U SIN T + V COS T. Input parameters: B contains the arc-count a - the last two values on the calculator stack are the coordinates X, Y of the start of the arc; it doesn't matter whether they are rounded or unrounded, in fact CIRCLE inputs unrounded FP numbers and DRAW inputs rounded integers - 5C7D COORDS holds the same coordinates, rounded to integers - the third and fourth last values on the stack are the coordinates of the end-point of the arc, which again may be either FP numbers or integers - mem-1 and mem-2 hold the displacements U, V for the first "arc" - mem-3 and mem-4 hold the SIN and COS of the turning angle T. The mem-1 to mem-4 values are all FP numbers, none of them rounded to integers. Action: reduce the arc count by one for a loop counter - if this makes zero jump on to ARC END - jump into the loop at ARC START. _2425_ARC_LOOP (each turn of the loop returns here with the stack holding, from the top, Yf, Xf, Yz, Xz; Xf and Yf are the_unrounded coordinates of the PLOT position fram which the last "arc" was drawn, Xz and Yz are the end-point coordinates for the whole curve; U and V, the displacements used for the last "arc", are in mem-1 and mem-2 COS T and SIN T are in mem-3 and mem-4): - use the calculator to figure a pair of displacements for the next "arc" using the formulas given above: U' = U COS T - V SIN T V' = U SIN T + V COS T - put these U' and V' in mem-1 and mem-2 replacing U andV; all these numbers are handled in FP form only, without rounding. The calculator stack is left as it was on entry to ARCLOOP. _2439_ARC_START (on each entry to this point all eleven input parameters - four on the stack, four in the memory, two in5C7D COORDS and the loop counter in the B register - are as theywere at the start, except moved on as necessary to draw the next"arc"): stack the counter - use the calculator to add U from mem-1 to Xf on the calculator stack; this is the x coordinate of the next PLOT - call 2D2B STACK A to get Xi from 5C7D COORDS - subtract it from the next x coordinate; Xf + U - Xi isthe first DRAW parameter for the next "arc" - use the calculator to add V from mem-2 to Yf from mem-0; this is the y coordinate of the next PLOT - call 2D2B STACK A to get Yi from 5C7D COORDS hi - subtract it from the next y coordinate; Yf + V - Yi isthe second DRAW parameter for the next "arc" - call 24B7 DRAW LINE to draw the "arc"; it gets its PLOT coordinates from 5C7D COORDS, takes the DRAW parameters from the top of the stack, leaving Yf + V, Xf + U as the top values, and updates the PLOT coordinates in 5C7D COORDS to the new rounded values - jump back to ARC LOOP counting down the loop counter _245F_ARC_END (a - 1 turns of the loop have drawn all butthe last "arc"; as usual the unrounded coordinates for the next PLOT are on top of the stack, and the so far unused Yz, Xz coordinates for the end of the DRAWn line below them): delete the top two values, leaving the Yz, Xz on top - call 2D2B STACK A twice to get the last PLOT coordinates in turn from 5C7D COORDS, and subtract each from itscorresponding end-point coordinate; the resulting DRAW parameters for the final "arc" are left as the only values on the stack. _2477_LINE_DRAW: call 24B7 DRAW LINE to draw the final "arc" to the end-point; it clears the stack and updates the PLOTcoordinates. Exit: to 0D4D TEMPS, which cancels the temporary colour settings from the DRAW or CIRCLE command. Output parameters: none - 5C7D COORDS holds the final PLOT position - all the memory locations mem-0 to mem-5 have been corrupted. Exit from: 235A C ARC GE1 (2320 CIRCLE) 23C1 DR PRMS (2382 DRAW) Rems: 2320 CIRCLE arc drawing loop used DR 3 PRMS 238D (2382 DRAW) Jumps from: 2382 DRAW D SIZE 2C2D (2C02 DIM) Jumps from: 2C1F D LETTER duplicate subroutine (MOVE FP) 33C0 Called very frequently from 0028 FP CALC with the literal 31; also called directly from ROM under the name MOVE FP. Copies five bytes starting at HL to the addresses starting at DE. When called from 335B CALCULATE, this duplicatesthe last value on the stack. Can be called from m/c to copy five bytes - an FP numberor anything else - from any location to any other. Input parameters: the source address in HL, the destination in DE. The CALCULATE routine for unary operations points HL to the last value on the calculator stack and DE to the location beyond the last value, but other addresses may be supplied by m/c. Action: call 33A9 TEST 5 SP, which reports "Out of memory" if there is no room to extend the calculator stack, and makes a counter of 5 - LDIR finishes the copying. Exit: RET. Output parameters: HL and DE are incremented by five; when the call is from CALCULATE, DE will make a new stack end. Called as duplicate from: 03F8 BEEP 0427 BE OCTAVE 233B C R GRE 1 235A C ARC GE1 (twice) 238D DR 3 PRMS 23A3 DR SIN NZ 23C1 DR PRMS (3 times) 2425 ARC LOOP 2439 ARC START 247D CD PRMS1 2497 DRAW SAVE (4 times) 25F8 S RND 2D71 E TST END 2DE3 PRINT FP (twice) 2E01 PF LOOP 2E24 PF SMALL 3449 series-06 3453 G LOOP 36A0 n-mod-m 36AF int 36B7 X NEG 36C4 EXP (twice) 3713 ln 371C VALID 373D GRE.8 3783 get-arg (5 times) 37B7 C ENT (3 times) 37DA tan 37F2 atn 37FA CASES (3 times) 3833 asn (3 times) 384A sqr 3851 to-power 385D XISO Called as MOVE FP from: 2981 SFA MATCH 33B4 STACK NUM 340F get-mem 342D st-mem duration of beep see time dynamic handling of strings see 19E5 RECLAIM 1 ----- "E" or "e" see E-format number E-format has nothing to do with the constant e = 2.718281828...d, except that in both cases e stands for "exponent". For the constant, see under 36C4 EXP. EACH STMT subroutine 198B Dual purpose: looks through a BASIC line for -_either a particular command token - eg DATA or DEF FN -at the start of a statement; only the first code of each statement is checked for a match with the given command, so DATAin SAVE ... DATA etc won't be noticed -_or a statement with a given number. The subroutine steps through the statement to find its terminator: new statements start after 3A colon or after CB THEN, provided they aren't in quotes, ie provided an even numberof codes 22h double quote have been encountered since the start of the statement. At each statement terminator the statement counter is decremented till it reaches zero. In stepping through the statements, the subroutine must take account of 22h double quotes and the FP number forms inserted after each number in the BASIC: colons or THENs after an odd number of quotes, ie within a quotation, don't count as terminators, and number forms may include bytes which would be misread as quotes or terminators. For this reason 0020 NEXT CHAR isn't used in EACH S 2, because it assumes the FP number forms aren't in place: in reading eg "AT 13,7", which appears in the BASIC line as AT 13 , 7 AC 31 33 (0E 00 00 0D 00 00) 2C 37 (0E 00 00 07 00 00) 007D SKIP OVER would cause the first number marker to be missed, and then the 0D would be read as a newline. Input parameters:_either D holds a statement counter and E holds zero; the statements are counted upwards from one at thestart of the line, and a line can't have more than 127d state- ments, see 1B29 STMT L 1 under 1B8A LINE RUN -_or D holds zero and E holds a code byte, the token to be searched for - HL holds a BASIC pointer on the address just before the start of the line. Action: put the BASIC pointer in 5C5D CH ADD - make a "quotes" flag zero; any even value of the flag means "not in quotes". _1990_EACH_S_1: decrement the statement counter - if it reaches zero return; this can't happen if a token is being looked for, because the first decrement makes thecounter FF - move on the BASIC pointer - if the new code doesn't match the token byte jump on to EACH S 3