Routines
 Prev: 08980 Up: Map Next: 09090
08992: THE 'CIRCLE' COMMAND ROUTINE
 The address of this routine is found in the parameter table. This routine draws an approximation to the circle with centre co-ordinates X and Y and radius Z. These numbers are rounded to the nearest integer before use. Thus Z must be less than 87.5, even when (X,Y) is in the centre of the screen. The method used is to draw a series of arcs approximated by straight lines. CIRCLE has four parts: i. Tests the radius. If its modulus is less than 1, just plot X,Y. ii. Calls CD_PRMS1, which is used to set the initial parameters for both CIRCLE and DRAW. iii. Sets up the remaining parameters for CIRCLE, including the initial displacement for the first 'arc' (a straight line in fact). iv. Jumps to DRW_STEPS to use the arc-drawing loop. Parts i. to iii. will now be explained in turn. i. The radius, say Z', is obtained from the calculator stack. Its modulus Z is formed and used from now on. If Z is less than 1, it is deleted from the stack and the point X,Y is plotted by a jump to PLOT. CIRCLE 08992 RST 24 Get the present character. 08993 CP "," Test for comma. 08995 JP NZ,REPORT_C If not so, report the error. 08998 RST 32 Get next character (the radius). 08999 CALL CLASS_06 Radius to calculator stack. 09002 CALL CHECK_END Move to consider next statement if checking syntax. 09005 RST 40 Use calculator. 09006 DEFB 42 abs: X, Y, Z 09007 DEFB 61 re_stack: Z is re-stacked; its exponent is therefore available. 09008 DEFB 56 end_calc 09009 LD A,(HL) Get exponent of radius. 09010 CP 129 Test whether radius less than 1. 09012 JR NC,C_R_GRE_1 If not, jump. 09014 RST 40 If less, delete it from the stack. 09015 DEFB 2 delete: X, Y 09016 DEFB 56 end_calc 09017 JR PLOT Just plot the point X, Y. ii. 2π is stored in mem-5 and CD_PRMS1 is called. This subroutine stores in the B register the number of arcs required for the circle, viz. A=4*INT (π*SQR Z/4)+4, hence 4, 8, 12, etc., up to a maximum of 32. It also stores in mem-0 to mem-4 the quantities 2π/A, SIN(π/A), 0, COS (2π/A) and SIN (2π/A). C_R_GRE_1 09019 RST 40 09020 DEFB 163 stk_pi_2: X, Y, Z, π/2 09021 DEFB 56 end_calc 09022 LD (HL),131 Now increase exponent to 131, changing π/2 into 2π. 09024 RST 40 X, Y, Z, 2π. 09025 DEFB 197 st_mem_5: (2π is copied to mem-5) 09026 DEFB 2 delete: X, Y, Z 09027 DEFB 56 end_calc 09028 CALL CD_PRMS1 Set the initial parameters. iii. A test is made to see whether the initial 'arc' length is less than 1. If it is, a jump is made simply to plot X, Y. Otherwise, the parameters are set: X+Z and X-Z*SIN (π/A) are stacked twice as start and end point, and copied to COORDS as well; zero and 2*Z*SIN (π/A) are stored in mem-1 and mem-2 as initial increments, giving as first 'arc' the vertical straight line joining X+Z, y-Z*SIN (π/A) and X+Z, Y+Z*SIN (π/A). The arc-drawing loop at DRW_STEPS will ensure that all subsequent points remain on the same circle as these two points, with incremental angle 2π/A. But it is clear that these 2 points in fact subtend this angle at the point X+Z*(1-COS (π/A)), Y not at X, Y. Hence the end points of each arc of the circle are displaced right by an amount 2*(1-COS (π/A)), which is less than half a pixel, and rounds to one pixel at most. 09031 PUSH BC Save the arc-count in B. 09032 RST 40 X, Y, Z 09033 DEFB 49 duplicate: X, Y, Z, Z 09034 DEFB 225 get_mem_1: X, Y, Z, Z, SIN (π/A) 09035 DEFB 4 multiply: X, Y, Z, Z*SIN (π/A) 09036 DEFB 56 end_calc 09037 LD A,(HL) Z*SIN (π/A) is half the initial 'arc' length; it is tested to see whether it is less than 0.5. 09038 CP 128 09040 JR NC,C_ARC_GE1 If not, the jump is made. 09042 RST 40 09043 DEFB 2 delete: X, Y, Z 09044 DEFB 2 delete: X, Y 09045 DEFB 56 end_calc 09046 POP BC Clear the machine stack. 09047 JP PLOT Jump to plot X, Y. C_ARC_GE1 09050 RST 40 X, Y, Z, Z*SIN (π/A) 09051 DEFB 194 st_mem_2: (Z*SIN (π/A) to mem-2 for now) 09052 DEFB 1 exchange: X, Y, Z*SIN (π/A), Z 09053 DEFB 192 st_mem_0: X, Y, Z*SIN (π/A), Z (Z is copied to mem-0) 09054 DEFB 2 delete: X, Y, Z*SIN (π/A) 09055 DEFB 3 subtract: X, Y-Z*SIN (π/A) 09056 DEFB 1 exchange: Y-Z*SIN (π/A), X 09057 DEFB 224 get_mem_0: Y-Z*SIN (π/A), X, Z 09058 DEFB 15 addition: Y-Z*SIN (π/A), X+Z 09059 DEFB 192 st_mem_0: (X+Z is copied to mem-0) 09060 DEFB 1 exchange: X+Z, Y-Z*SIN (π/A) 09061 DEFB 49 duplicate: X+Z, Y-Z*SIN (π/A), Y-Z*SIN (π/A) 09062 DEFB 224 get_mem_0: sa, sb, sb, sa 09063 DEFB 1 exchange: sa, sb, sa, sb 09064 DEFB 49 duplicate: sa, sb, sa, sb, sb 09065 DEFB 224 get_mem_0: sa, sb, sa, sb, sb, sa 09066 DEFB 160 stk_zero: sa, sb, sa, sb, sb, sa, 0 09067 DEFB 193 st_mem_1: (mem-1 is set to zero) 09068 DEFB 2 delete: sa, sb, sa, sb, sb, sa 09069 DEFB 56 end_calc (Here sa denotes X+Z and sb denotes Y-Z*SIN (π/A).) 09070 INC (IY+98) Incrementing the exponent byte of mem-2 sets mem-2 to 2*Z*SIN(π/A). 09073 CALL FIND_INT1 The last value X+Z is moved from the stack to A and copied to L. 09076 LD L,A 09077 PUSH HL It is saved in HL. 09078 CALL FIND_INT1 Y-Z*SIN (π/A) goes from the stack to A and is copied to H. HL now holds the initial point. 09081 POP HL 09082 LD H,A 09083 LD (23677),HL It is copied to COORDS. 09086 POP BC The arc-count is restored. 09087 JP DRW_STEPS The jump is made to DRW_STEPS. (The stack now holds X+Z, Y-Z*SIN (π/A), Y-Z*SIN (π/A), X+Z.)
 Prev: 08980 Up: Map Next: 09090