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 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:
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 |