BBC Micro Elite

# Drawing circles: CIRCLE2

```       Name: CIRCLE2                                           [View in context]
Type: Subroutine
Category: Drawing circles
Summary: Draw a circle (for the planet or chart)
Deep dive: Drawing circles

Draw a circle with the centre at (K3, K4) and radius K. Used to draw the
planet and the chart circles.

Arguments:

STP                  The step size for the circle

K3(1 0)              Pixel x-coordinate of the centre of the circle

K4(1 0)              Pixel y-coordinate of the centre of the circle

Returns:

C flag               The C flag is clear

.CIRCLE2

LDX #&FF               \ Set FLAG = &FF to reset the ball line heap in the call
STX FLAG               \ to the BLINE routine below

INX                    \ Set CNT = 0, our counter that goes up to 64, counting
STX CNT                \ segments in our circle

.PLL3

LDA CNT                \ Set A = CNT

JSR FMLTU2             \ Call FMLTU2 to calculate:
\
\   A = K * sin(A)
\     = K * sin(CNT)

LDX #0                 \ Set T = 0, so we have the following:
STX T                  \
\   (T A) = K * sin(CNT)
\
\ which is the x-coordinate of the circle for this count

LDX CNT                \ If CNT < 33 then jump to PL37, as this is the right
CPX #33                \ half of the circle and the sign of the x-coordinate is
BCC PL37               \ correct

EOR #%11111111         \ This is the left half of the circle, so we want to
ADC #0                 \ flip the sign of the x-coordinate in (T A) using two's
TAX                    \ complement, so we start with the low byte and store it
\ in X (the ADC adds 1 as we know the C flag is set)

LDA #&FF               \ And then we flip the high byte in T
STA T

TXA                    \ Finally, we restore the low byte from X, so we have
\ now negated the x-coordinate in (T A)

CLC                    \ Clear the C flag so we can do some more addition below

.PL37

ADC K3                 \ We now calculate the following:
STA K6                 \
\   K6(1 0) = (T A) + K3(1 0)
\
\ to add the coordinates of the centre to our circle
\ point, starting with the low bytes

LDA K3+1               \ And then doing the high bytes, so we now have:
STA K6+1               \   K6(1 0) = K * sin(CNT) + K3(1 0)
\
\ which is the result we want for the x-coordinate

LDA CNT                \ Set A = CNT + 16
CLC

JSR FMLTU2             \ Call FMLTU2 to calculate:
\
\   A = K * sin(A)
\     = K * sin(CNT + 16)
\     = K * cos(CNT)

TAX                    \ Set X = A
\       = K * cos(CNT)

LDA #0                 \ Set T = 0, so we have the following:
STA T                  \
\   (T X) = K * cos(CNT)
\
\ which is the y-coordinate of the circle for this count

LDA CNT                \ Set A = (CNT + 15) mod 64
AND #63

CMP #33                \ If A < 33 (i.e. CNT is 0-16 or 48-64) then jump to
BCC PL38               \ PL38, as this is the bottom half of the circle and the
\ sign of the y-coordinate is correct

TXA                    \ This is the top half of the circle, so we want to
EOR #%11111111         \ flip the sign of the y-coordinate in (T X) using two's
TAX                    \ ADC adds 1 as we know the C flag is set)

LDA #&FF               \ And then we flip the high byte in T, so we have
ADC #0                 \ now negated the y-coordinate in (T X)
STA T

CLC                    \ Clear the C flag so we can do some more addition below

.PL38

JSR BLINE              \ Call BLINE to draw this segment, which also increases
\ CNT by STP, the step size

CMP #65                \ If CNT >=65 then skip the next instruction
BCS P%+5

JMP PLL3               \ Jump back for the next segment

CLC                    \ Clear the C flag to indicate success

RTS                    \ Return from the subroutine
```