Routines 
Prev: 2314  Up: Map 
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  2320  RST $18  Get the present character.  
2321  CP ","  Test for comma.  
2323  JP NZ,REPORT_C  If not so, report the error.  
2326  RST $20  Get next character (the radius).  
2327  CALL CLASS_06  Radius to calculator stack.  
232A  CALL CHECK_END  Move to consider next statement if checking syntax.  
232D  RST $28  Use calculator.  
232E  DEFB $2A  abs: X, Y, Z  
232F  DEFB $3D  re_stack: Z is restacked; its exponent is therefore available.  
2330  DEFB $38  end_calc  
2331  LD A,(HL)  Get exponent of radius.  
2332  CP $81  Test whether radius less than 1.  
2334  JR NC,C_R_GRE_1  If not, jump.  
2336  RST $28  If less, delete it from the stack.  
2337  DEFB $02  delete: X, Y  
2338  DEFB $38  end_calc  
2339  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  233B  RST $28  
233C  DEFB $A3  stk_pi_2: X, Y, Z, π/2  
233D  DEFB $38  end_calc  
233E  LD (HL),$83  Now increase exponent to +83, changing π/2 into 2π.  
2340  RST $28  X, Y, Z, 2π.  
2341  DEFB $C5  st_mem_5: (2π is copied to mem5)  
2342  DEFB $02  delete: X, Y, Z  
2343  DEFB $38  end_calc  
2344  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.


2347  PUSH BC  Save the arccount in B.  
2348  RST $28  X, Y, Z  
2349  DEFB $31  duplicate: X, Y, Z, Z  
234A  DEFB $E1  get_mem_1: X, Y, Z, Z, SIN (π/A)  
234B  DEFB $04  multiply: X, Y, Z, Z*SIN (π/A)  
234C  DEFB $38  end_calc  
234D  LD A,(HL)  Z*SIN (π/A) is half the initial 'arc' length; it is tested to see whether it is less than 0.5.  
234E  CP $80  
2350  JR NC,C_ARC_GE1  If not, the jump is made.  
2352  RST $28  
2353  DEFB $02  delete: X, Y, Z  
2354  DEFB $02  delete: X, Y  
2355  DEFB $38  end_calc  
2356  POP BC  Clear the machine stack.  
2357  JP PLOT  Jump to plot X, Y.  
C_ARC_GE1  235A  RST $28  X, Y, Z, Z*SIN (π/A)  
235B  DEFB $C2  st_mem_2: (Z*SIN (π/A) to mem2 for now)  
235C  DEFB $01  exchange: X, Y, Z*SIN (π/A), Z  
235D  DEFB $C0  st_mem_0: X, Y, Z*SIN (π/A), Z (Z is copied to mem0)  
235E  DEFB $02  delete: X, Y, Z*SIN (π/A)  
235F  DEFB $03  subtract: X, YZ*SIN (π/A)  
2360  DEFB $01  exchange: YZ*SIN (π/A), X  
2361  DEFB $E0  get_mem_0: YZ*SIN (π/A), X, Z  
2362  DEFB $0F  addition: YZ*SIN (π/A), X+Z  
2363  DEFB $C0  st_mem_0: (X+Z is copied to mem0)  
2364  DEFB $01  exchange: X+Z, YZ*SIN (π/A)  
2365  DEFB $31  duplicate: X+Z, YZ*SIN (π/A), YZ*SIN (π/A)  
2366  DEFB $E0  get_mem_0: sa, sb, sb, sa  
2367  DEFB $01  exchange: sa, sb, sa, sb  
2368  DEFB $31  duplicate: sa, sb, sa, sb, sb  
2369  DEFB $E0  get_mem_0: sa, sb, sa, sb, sb, sa  
236A  DEFB $A0  stk_zero: sa, sb, sa, sb, sb, sa, 0  
236B  DEFB $C1  st_mem_1: (mem1 is set to zero)  
236C  DEFB $02  delete: sa, sb, sa, sb, sb, sa  
236D  DEFB $38  end_calc  
(Here sa denotes X+Z and sb denotes YZ*SIN (π/A).)


236E  INC (IY+$62)  Incrementing the exponent byte of mem2 sets mem2 to 2*Z*SIN(π/A).  
2371  CALL FIND_INT1  The last value X+Z is moved from the stack to A and copied to L.  
2374  LD L,A  
2375  PUSH HL  It is saved in HL.  
2376  CALL FIND_INT1  YZ*SIN (π/A) goes from the stack to A and is copied to H. HL now holds the initial point.  
2379  POP HL  
237A  LD H,A  
237B  LD ($5C7D),HL  It is copied to COORDS.  
237E  POP BC  The arccount is restored.  
237F  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: 2314  Up: Map 