BBC Micro Elite

# Drawing lines: LL118 (6502SP version)

```       Name: LL118                                             [View in context]
Type: Subroutine
Category: Drawing lines
Summary: Move a point along a line until it is on-screen

Given a point (x1, y1), a gradient and a direction of slope, move the point
along the line until it is on-screen, so this effectively clips the (x1, y1)
end of a line to be on the screen.

See the deep dive on "Line-clipping" for more details.

Arguments:

XX15(1 0)            x1 as a 16-bit coordinate (x1_hi x1_lo)

XX15(3 2)            y1 as a 16-bit coordinate (y1_hi y1_lo)

XX12+2               The line's gradient * 256 (so 1.0 = 256)

XX12+3               The direction of slope:

* Positive (bit 7 clear) = top left to bottom right

* Negative (bit 7 set) = top right to bottom left

T                    The type of slope:

* 0 if it's more vertical than horizontal

* &FF if it's more horizontal than vertical

Returns:

XX15                 x1 as an 8-bit coordinate

XX15+2               y1 as an 8-bit coordinate

Other entry points:

LL118-1              Contains an RTS

.LL118

LDA XX15+1             \ If x1_hi is positive, jump down to LL119 to skip
BPL LL119              \ the following

STA S                  \ Otherwise x1_hi is negative, i.e. off the left of the
\ screen, so set S = x1_hi

JSR LL120              \ Call LL120 to calculate:
\
\   (Y X) = (S x1_lo) * XX12+2      if T = 0
\
\   (Y X) = (S x1_lo) / XX12+2      if T <> 0
\
\ with the sign of (Y X) set to the opposite of the
\ line's direction of slope

TXA                    \ Set y1 = y1 + (Y X)
CLC                    \
ADC XX15+2             \ starting with the low bytes
STA XX15+2

TYA                    \ And then adding the high bytes
STA XX15+3

LDA #0                 \ Set x1 = 0
STA XX15
STA XX15+1

TAX                    \ Set X = 0 so the next instruction becomes a JMP

.LL119

BEQ LL134              \ If x1_hi = 0 then jump down to LL134 to skip the
\ following, as the x-coordinate is already on-screen
\ (as 0 <= (x_hi x_lo) <= 255)

STA S                  \ Otherwise x1_hi is positive, i.e. x1 >= 256 and off
DEC S                  \ the right side of the screen, so set S = x1_hi - 1

JSR LL120              \ Call LL120 to calculate:
\
\   (Y X) = (S x1_lo) * XX12+2      if T = 0
\         = (x1 - 256) * gradient
\
\   (Y X) = (S x1_lo) / XX12+2      if T <> 0
\         = (x1 - 256) / gradient
\
\ with the sign of (Y X) set to the opposite of the
\ line's direction of slope

TXA                    \ Set y1 = y1 + (Y X)
CLC                    \
ADC XX15+2             \ starting with the low bytes
STA XX15+2

TYA                    \ And then adding the high bytes
STA XX15+3

LDX #255               \ Set x1 = 255
STX XX15
INX
STX XX15+1

.LL134

\ We have moved the point so the x-coordinate is on
\ screen (i.e. in the range 0-255), so now for the
\ y-coordinate

LDA XX15+3             \ If y1_hi is positive, jump down to LL119 to skip
BPL LL135              \ the following

STA S                  \ Otherwise y1_hi is negative, i.e. off the top of the
\ screen, so set S = y1_hi

LDA XX15+2             \ Set R = y1_lo
STA R

JSR LL123              \ Call LL123 to calculate:
\
\   (Y X) = (S R) / XX12+2      if T = 0
\
\   (Y X) = (S R) * XX12+2      if T <> 0
\
\ with the sign of (Y X) set to the opposite of the
\ line's direction of slope

TXA                    \ Set x1 = x1 + (Y X)
CLC                    \
ADC XX15               \ starting with the low bytes
STA XX15

TYA                    \ And then adding the high bytes
STA XX15+1

LDA #0                 \ Set y1 = 0
STA XX15+2
STA XX15+3

.LL135

\BNE LL139              \ This instruction is commented out in the original
\ source

LDA XX15+2             \ Set (S R) = (y1_hi y1_lo) - 192
SEC                    \
SBC #Y*2               \ starting with the low bytes
STA R

LDA XX15+3             \ And then subtracting the high bytes
SBC #0
STA S

BCC LL136              \ If the subtraction underflowed, i.e. if y1 < 192, then
\ from the subroutine, as we are done

.LL139

\ If we get here then y1 >= 192, i.e. off the bottom of
\ the screen

JSR LL123              \ Call LL123 to calculate:
\
\   (Y X) = (S R) / XX12+2      if T = 0
\         = (y1 - 192) / gradient
\
\   (Y X) = (S R) * XX12+2      if T <> 0
\         = (y1 - 192) * gradient
\
\ with the sign of (Y X) set to the opposite of the
\ line's direction of slope

TXA                    \ Set x1 = x1 + (Y X)
CLC                    \
ADC XX15               \ starting with the low bytes
STA XX15

TYA                    \ And then adding the high bytes