Routines 
Prev: 08980  Up: Map  Next: 09090 
The address of this routine is found in the parameter table.
This routine draws an approximation to the circle with centre coordinates 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:
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 restacked; 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 mem5 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 mem0 to mem4 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 mem5)  
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 XZ*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 mem1 and mem2 as initial increments, giving as first 'arc' the vertical straight line joining X+Z, yZ*SIN (π/A) and X+Z, Y+Z*SIN (π/A). The arcdrawing 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*(1COS (π/A)), Y not at X, Y. Hence the end points of each arc of the circle are displaced right by an amount 2*(1COS (π/A)), which is less than half a pixel, and rounds to one pixel at most.


09031  PUSH BC  Save the arccount 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 mem2 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 mem0)  
09054  DEFB 2  delete: X, Y, Z*SIN (π/A)  
09055  DEFB 3  subtract: X, YZ*SIN (π/A)  
09056  DEFB 1  exchange: YZ*SIN (π/A), X  
09057  DEFB 224  get_mem_0: YZ*SIN (π/A), X, Z  
09058  DEFB 15  addition: YZ*SIN (π/A), X+Z  
09059  DEFB 192  st_mem_0: (X+Z is copied to mem0)  
09060  DEFB 1  exchange: X+Z, YZ*SIN (π/A)  
09061  DEFB 49  duplicate: X+Z, YZ*SIN (π/A), YZ*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: (mem1 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 YZ*SIN (π/A).)


09070  INC (IY+98)  Incrementing the exponent byte of mem2 sets mem2 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  YZ*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 arccount is restored.  
09087  JP DRW_STEPS  The jump is made to DRW_STEPS.  
(The stack now holds X+Z, YZ*SIN (π/A), YZ*SIN (π/A), X+Z.)

Prev: 08980  Up: Map  Next: 09090 