Aviator on the BBC Micro

# Drawing lines: DrawClippedLine (Part 2 of 6)

```       Name: DrawClippedLine (Part 2 of 6)                           [Show more]
Type: Subroutine
Category: Drawing lines
Summary: Work out whether the line's start point is on-screen
Context: See this subroutine in context in the source code
References: No direct references to this subroutine in this source file

.draw3

LDA #0                 \ The next step is to work out where the line's
\ coordinates lie in relation to the visible screen,
\ i.e. are the coordinates to the right or left of the
\ screen bounds, or above or below
\
\ We will capture this information for a single
\ coordinate in the top 4 bits of A, so we start by
\ setting A = 0 so we can populate it with information
\ of how the line's coordinates relate to the screen
\ edges

\ We start by looking at the y-coordinate for the start
\ point, and will store the result in bits 4 and 5 of
\ the final result in A

LDX S                  \ Set (Y X) = (SS S)
LDY SS                 \           = the y-coordinate of the line's start point

BEQ draw4              \ If the high byte in Y is zero, jump to draw4

PHP                    \ Set X = 0, but without affecting the processor flags,
LDX #0                 \ which will still be set according to the value of the
PLP                    \ high byte in Y

CLC                    \ Clear the C flag

BMI draw5              \ If the high byte in Y is negative, jump to draw5

DEX                    \ Decrement X from 0 to 255

.draw4

SEC                    \ Set the C flag

.draw5

\ By this point we have the following, depending on the
\ value of the high byte of the start point's
\ y-coordinate:
\
\   * If SS < 0, C = 0 and X = 0
\   * If SS = 0, C = 1 and X = S
\   * If SS > 0, C = 1 and X = 255

ROR A                  \ Put the C flag into bit 7 of A, which will end up
\ being bit 4 in the final result (as we are going to
\ shift three more bits into A). Note that we flip this
\ bit in the EOR below

CPX #152               \ The result of this comparison depends on the value
\ that we gave to X above:
\
\   * If SS < 0, X = 0 and 0 < 152, so C = 0
\   * If SS = 0, X = S, so if S < 152, C = 0
\                          if S >= 152, C = 1
\   * If SS > 0, X = 255 and 255 >= 152, so C = 1

ROR A                  \ Rotate the C flag into bit 7 of A, which will end up
\ being bit 5 in the final result (as we are going to
\ shift two more bits into A)

EOR #%01000000         \ Flip bit 6

\ We now have the following in bits 6 and 7, which will
\ be shifted down to bits 4 and 5 in the final result:
\
\   * Bit 6 (4) is set   if SS < 0
\                  clear if SS >= 0
\
\   * Bit 7 (5) is clear if SS < 0
\                        or SS = 0 and S < 152
\                    set if SS = 0 and S >= 152
\                        or SS > 0
\
\ The visible part of the canopy screen has its origin
\ (0, 0) at the bottom-left corner of the canopy, just
\ above the dashboard, and it is 19 character blocks
\ high, which is 8 * 19 = 152 pixels high, so this sets
\ bits 0 and 1 in the final result depending on whether
\ the start y-coordinate is within this range, and if
\ not, whether it is above or below the range - in other
\ words, it determines whether this coordinate is
\ on-screen or off-screen, as follows:
\
\                             Bit 6 (4)     Bit 7 (5)
\   Off top of screen            0             1
\   On-screen                    0             0
\   Off bottom of screen         1             0
\
\ We never have both bits set

\ We now repeat the above process for the start point's
\ x-coordinate in (RR R), putting the result into bits 6
\ and 7 of A while shifting the above result into bits 4
\ and 5
\
\ The process is slightly different as this time the
\ on-screen x-coordinate range is 4 to 155

LDX R                  \ Set (Y X) = (RR R)
LDY RR                 \           = the x-coordinate of the line's start point

BEQ draw6              \ If the high byte in Y is zero, jump to draw6

PHP                    \ Set X = 0, but without affecting the processor flags,
LDX #0                 \ which will still be set according to the value of the
PLP                    \ high byte in Y

BMI draw6              \ If the high byte in Y is negative, jump to draw6

DEX                    \ Decrement X from 0 to 255

.draw6

\ By this point we have the following, depending on the
\ value of the high byte of the start point's
\ x-coordinate:
\
\   * If RR < 0, X = 0
\   * If RR = 0, X = R
\   * If RR > 0, X = 255

CPX #4                 \ The result of this comparison depends on the value
\ that we gave X above:
\
\   * If RR < 0, X = 0 and 0 < 4, so C = 0
\   * If RR = 0, X = R, so if R < 4, C = 0
\                          if R >= 4, C = 1
\   * If RR > 0, X = 255 and 255 >= 4, so C = 1

ROR A                  \ Rotate the C flag into bit 7 of A, which will end up
\ being bit 6 in the final result (as we are going to
\ shift one more bit into A). Note that we flip this
\ bit in the EOR below

CPX #156               \ The result of this comparison depends on the value
\ that we gave X above:
\
\   * If RR < 0, X = 0 and 0 < 156, so C = 0
\   * If RR = 0, X = R, so C = 0 if R < 156,
\                          C = 1 if R >= 156
\   * If RR > 0, X = 255 and 255 >= 156, so C = 1

ROR A                  \ Rotate the C flag into bit 7 of A, which is where it
\ will stay

EOR #%01000000         \ Flip bit 6

\ We now have the following in bits 6 and 7:
\
\   * Bit 6 is clear if RR > 0
\                    or RR = 0 and R >= 4
\                    i.e. if (RR R) >= 4
\              set   if RR < 0
\                    or RR = 0 and R < 4
\                    i.e. if (RR R) < 4
\
\   * Bit 7 is clear if RR < 0
\                    or RR = 0 and R < 156
\                    i.e. if (RR R) < 156
\                set if RR = 0 and R >= 156
\                    or RR > 0
\                    i.e. if (RR R) >= 156
\
\ The visible part of the canopy screen has its origin
\ (0, 0) at the bottom-left corner of the canopy, just
\ above the dashboard, but the rivets and the left edge
\ of the canopy take up the first four pixels, so the
\ leftmost x-coordinate inside the canopy is 4
\
\ Similarly, the right edge of the canopy is four pixels
\ wide, and the whole screen is 160 pixels wide, so the
\ rightmost x-coordinate inside the canopy is 155
\
\ So the above sets bits 6 and 7 in the final result
\ depending on whether the start x-coordinate is within
\ this range, and if not, whether it is to the left or
\ right of the range - in other words, it determines
\ whether this coordinate is on-screen or off-screen,
\ as follows:
\
\                             Bit 6     Bit 7
\   Off right of screen         0         1
\   On-screen                   0         0
\   Off left of screen          1         0
\
\ We never have both bits set

STA TT                 \ Store A in TT
\
\ So TT contains the clipping requirements for the start
\ point, in bits 4 to 7, as follows:
\
\                             Bit 4     Bit 5
\   Off top of screen           0         1
\   On-screen                   0         0
\   Off bottom of screen        1         0
\
\                             Bit 6     Bit 7
\   Off right of screen         0         1
\   On-screen                   0         0
\   Off left of screen          1         0
```