Elite on the BBC Micro and NES

# Version analysis of CHKON

This code appears in the following versions (click to see it in the source code):

Code variations between these versions are shown below.

```       Name: CHKON
Type: Subroutine
Category: Drawing circles
Summary: Check whether any part of a circle appears on the extended screen

Arguments:

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               Clear if any part of the circle appears on-screen, set
if none of the circle appears on-screen

(A X)                Minimum y-coordinate of the circle on-screen (i.e. the
y-coordinate of the top edge of the circle)

P(2 1)               Maximum y-coordinate of the circle on-screen (i.e. the
y-coordinate of the bottom edge of the circle)

.CHKON

LDA K3                 \ Set A = K3 + K
CLC

LDA K3+1               \ Set A = K3+1 + 0 + any carry from above, so this
ADC #0                 \ effectively sets A to the high byte of K3(1 0) + K:
\
\   (A ?) = K3(1 0) + K
\
\ so A is the high byte of the x-coordinate of the right
\ edge of the circle

BMI PL21               \ If A is negative then the right edge of the circle is
\ to the left of the screen, so jump to PL21 to set the
\ C flag and return from the subroutine, as the whole
\ circle is off-screen to the left

LDA K3                 \ Set A = K3 - K
SEC
SBC K

LDA K3+1               \ Set A = K3+1 - 0 - any carry from above, so this
SBC #0                 \ effectively sets A to the high byte of K3(1 0) - K:
\
\   (A ?) = K3(1 0) - K
\
\ so A is the high byte of the x-coordinate of the left
\ edge of the circle

BMI PL31               \ If A is negative then the left edge of the circle is
\ to the left of the screen, and we already know the
\ right edge is either on-screen or off-screen to the
\ right, so skip to PL31 to move on to the y-coordinate
\ checks, as at least part of the circle is on-screen in
\ terms of the x-axis

BNE PL21               \ If A is non-zero, then the left edge of the circle is
\ to the right of the screen, so jump to PL21 to set the
\ C flag and return from the subroutine, as the whole
\ circle is off-screen to the right

.PL31

LDA K4                 \ Set P+1 = K4 + K
CLC
STA P+1

LDA K4+1               \ Set A = K4+1 + 0 + any carry from above, so this
ADC #0                 \ does the following:
\
\   (A P+1) = K4(1 0) + K
\
\ so A is the high byte of the y-coordinate of the
\ bottom edge of the circle

BMI PL21               \ If A is negative then the bottom edge of the circle is
\ above the top of the screen, so jump to PL21 to set
\ the C flag and return from the subroutine, as the
\ whole circle is off-screen to the top

STA P+2                \ Store the high byte in P+2, so now we have:
\
\   P(2 1) = K4(1 0) + K
\
\ i.e. the maximum y-coordinate of the circle on-screen
\ (which we return)

LDA K4                 \ Set X = K4 - K
SEC
SBC K
TAX

LDA K4+1               \ Set A = K4+1 - 0 - any carry from above, so this
SBC #0                 \ does the following:
\
\   (A X) = K4(1 0) - K
\
\ so A is the high byte of the y-coordinate of the top
\ edge of the circle

BMI PL44               \ If A is negative then the top edge of the circle is
\ above the top of the screen, and we already know the
\ bottom edge is either on-screen or below the bottom
\ of the screen, so skip to PL44 to clear the C flag and
\ return from the subroutine using a tail call, as part
\ of the circle definitely appears on-screen

BNE PL21               \ If A is non-zero, then the top edge of the circle is
\ below the bottom of the screen, so jump to PL21 to set
\ the C flag and return from the subroutine, as the
\ whole circle is off-screen to the bottom

```

Code variation 1 of 2Specific to an individual platform

Tap on a block to expand it, and tap it again to revert.

```Cassette, Flight, Docked, 6502SP, ElectronMaster CPX #2*Y-1             \ If we get here then A is zero, which means the top
CPX Yx2M1              \ If we get here then A is zero, which means the top
```
```                        \ edge of the circle is within the screen boundary, so
\ now we need to check whether it is in the space view
\ (in which case it is on-screen) or the dashboard (in
\ which case the top of the circle is hidden by the
\ dashboard, so the circle isn't on-screen). We do this
\ by checking the low byte of the result in X against

```

Code variation 2 of 2A variation in the comments only

Tap on a block to expand it, and tap it again to revert.

```Cassette, Flight, Docked, 6502SP, ElectronMaster                        \ 2 * #Y - 1, and returning the C flag from this
\ comparison. The constant #Y is the y-coordinate of the
\ mid-point of the space view, so 2 * #Y - 1, the
\ y-coordinate of the bottom pixel row of the space
\ view. So this does the following:
\ Yx2M1, and returning the C flag from this comparison.
\ The value in Yx2M1 is the y-coordinate of the bottom
\ pixel row of the space view, so this does the
\ following:
```
```                        \
\   * The C flag is set if coordinate (A X) is below the
\     bottom row of the space view, i.e. the top edge of
\     the circle is hidden by the dashboard
\
\   * The C flag is clear if coordinate (A X) is above
\     the bottom row of the space view, i.e. the top
\     edge of the circle is on-screen

RTS                    \ Return from the subroutine

```