Aviator on the BBC Micro

# Drawing lines: ClipStartOfLine (Part 4 of 5)

```       Name: ClipStartOfLine (Part 4 of 5)                           [Show more]
Type: Subroutine
Category: Drawing lines
Summary: Calculate where to clip the line
Context: See this subroutine in context in the source code
References: No direct references to this subroutine in this source file

Division algorithm of some kind, I think it's this for a shallow horizontal /

(QQ G) = (UU TT) * (PP N) / (Q P)
=   (start_x + start_y - 159) * (|x-delta| + 1)
/ (|x-delta| + |y-delta|)

This calculates the delta to add to the coordinates in the final part, but I
haven't got to the bottom of this

1. Double (Q P) and (PP N) until Q >= UU
If Q = UU and P < TT, repeat until P >= TT
i.e. repeat until (Q P) >= (UU TT)

2. Halve (Q P K) and (PP N VV) until Q < UU
i.e. repeat until (Q P K) < (UU TT H)

3. If (Q P K) = 0, done
Otherwise add 0.5 to (PP N) using a third byte (so add 128)
(UU TT H) = (UU TT 0) - (Q P K)
Jump back to step 2 while (UU TT H) >= 2

.clip12

LDA #128               \ Set W = 128, to use in (QQ G W)
STA W

LDA #0                 \ Set VV = 0, to use as the third byte in (PP N VV)
STA VV

STA K                  \ Set K = 0, to use as the third byte in (Q P K)

STA H                  \ Set H = 0, to use as the third byte in (UU TT H)

STA QQ                 \ Set QQ = 0, to use in (QQ G W)

STA G                  \ Set G = 0, so now we have:
\
\   (QQ G W) = 128

BEQ clip14             \ Jump to clip14 (this BEQ is effectively a JMP as A is
\ always zero)

.clip13

ASL P                  \ Set (Q P) = (Q P) * 2
ROL Q

ASL N                  \ Set (PP N) = (PP N) * 2
ROL PP

.clip14

LDA Q                  \ If Q < UU, jump up to clip13 to double the values of
CMP UU                 \ (Q P) and (PP N) until Q >= UU
BCC clip13

BNE clip15             \ If Q <> UU, i.e. Q > U, then jump to clip15

LDA P                  \ If we get here then Q = UU, so if P < TT, jump back to
CMP TT                 \ clip13 to keep on doubling until P >= TT
BCC clip13

.clip15

LSR Q                  \ Set (Q P K) = (Q P K) / 2
ROR P
ROR K

LSR PP                 \ Set (PP N VV) = (PP N VV) / 2
ROR N
ROR VV

.clip16

LDA Q                  \ If Q < UU, jump down to clip17
CMP UU
BCC clip17

BNE clip15             \ If Q <> UU, i.e. Q > U, jump back to clip15 to keep on
\ halving until Q < UU or Q = UU

LDA P                  \ If we get here then Q = UU, so if P < TT, jump down to
CMP TT                 \ clip17
BCC clip17

BNE clip15             \ If P <> TT, i.e. P > TT, jump back to clip15 to keep
\ on halving until Q < UU, or Q = UU and P <= TT

LDA K                  \ If K <= H, jump down to clip17
CMP H
BCC clip17
BEQ clip17

LDA Q                  \ If (Q P K) <> 0, jump back to clip15
ORA P
ORA K
BNE clip15

BEQ clip18             \ (Q P K) = 0 so jump to clip18 (this BEQ is effectively
\ a JMP as we just passed through a BNE)

.clip17

\ The first time we get here, QQ = G = 0 and W = 128, so
\ the following sum is (QQ G W) = 128 + (PP N VV)

LDA W                  \ Set (QQ G W) = (QQ G W) + (PP N VV)
CLC                    \
ADC VV                 \ starting with the low bytes
STA W

LDA G                  \ Then the middle bytes
STA G

LDA QQ                 \ And then the high bytes
STA QQ

\ The first time we get here, H = 0, so the
\ following sum is (UU TT H) = (UU TT 0) - (Q P K)

LDA H                  \ Set (UU TT H) = (UU TT H) - (Q P K)
SEC                    \
SBC K                  \ starting with the low bytes
STA H

LDA TT                 \ Then the middle bytes
SBC P
STA TT

LDA UU                 \ And then the high bytes
SBC Q
STA UU

\ The following comparisons jump back to clip16 if
\ (UU TT H) >= 2

BNE clip16             \ If UU <> 0, jump back to clip16

LDA TT                 \ If TT <> 0, jump back to clip16
BNE clip16

LDA H                  \ If H >= 2, jump back to clip16
CMP #2
BCS clip16

\ By the time we get here, (UU TT H) is 1 or 0
```