Elite on the BBC Micro and NES

# Version analysis of LL123

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

Code variations between these versions are shown below.

```       Name: LL123
Type: Subroutine
Category: Maths (Arithmetic)
Summary: Calculate (Y X) = (S R) / XX12+2 or (S R) * XX12+2

Calculate the following:

* If T = 0, this is a shallow slope, so calculate (Y X) = (S R) / XX12+2

* If T <> 0, this is a steep slope, so calculate (Y X) = (S R) * XX12+2

giving (Y X) the opposite sign to the slope direction in XX12+3.

Arguments:

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

XX12+3               The direction of slope:

* Bit 7 clear means top left to bottom right

* Bit 7 set means top right to bottom left

* 0 if it's a shallow slope

* &FF if it's a steep slope

Other entry points:

LL121                Calculate (Y X) = (S R) / Q and set the sign to the
opposite of the top byte on the stack

LL133                Negate (Y X) and return from the subroutine

LL128                Contains an RTS

.LL123

JSR LL129              \ Call LL129 to do the following:
\
\   Q = XX12+2
\
\   A = S EOR XX12+3
\     = S EOR slope direction
\
\   (S R) = |S R|
\
\ So A contains the sign of S * slope direction

PHA                    \ Store A on the stack so we can use it later

LDX T                  \ If T is non-zero, then it's a steep slope, so jump up
BNE LL122              \ to LL122 to calculate this instead:
\
\   (Y X) = (S R) * Q

.LL121

\ The following calculates:
\
\   (Y X) = (S R) / Q
\
\ using the same shift-and-subtract algorithm that's
\ documented in TIS2

LDA #%11111111         \ Set Y = %11111111
TAY

ASL A                  \ Set X = %11111110
TAX

\ This sets (Y X) = %1111111111111110, so we can rotate
\ through 15 loop iterations, getting a 1 each time, and
\ then getting a 0 on the 16th iteration... and we can
\ also use it to catch our result bits into bit 0 each
\ time

.LL130

ASL R                  \ Shift (S R) to the left
ROL S

LDA S                  \ Set A = S

BCS LL131              \ If bit 7 of S was set, then jump straight to the
\ subtraction

CMP Q                  \ If A < Q (i.e. S < Q), skip the following subtractions
BCC LL132

.LL131

SBC Q                  \ A >= Q (i.e. S >= Q) so set:
STA S                  \
\   S = (A R) - Q
\     = (S R) - Q
\
\ starting with the low bytes (we know the C flag is
\ set so the subtraction will be correct)

LDA R                  \ And then doing the high bytes
SBC #0
STA R

SEC                    \ Set the C flag to rotate into the result in (Y X)

.LL132

TXA                    \ Rotate the counter in (Y X) to the left, and catch the
ROL A                  \ result bit into bit 0 (which will be a 0 if we didn't
TAX                    \ do the subtraction, or 1 if we did)
TYA
ROL A
TAY

BCS LL130              \ If we still have set bits in (Y X), loop back to LL130
\ to do the next iteration of 15, until we have done the
\ whole division

PLA                    \ Restore A, which we calculated above, from the stack

BMI LL128              \ If A is negative jump to LL128 to return from the
\ subroutine with (Y X) as is

.LL133

```

Code variation 1 of 1A variation in the comments only

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

```Cassette, 6502SP, MasterFlight, Docked, Electron TXA                    \ Otherwise negate (Y X) using two's complement by first
EOR #%11111111         \ setting the low byte to ~X + 1
\CLC                    \
ADC #1                 \ The CLC instruction is commented out in the original
TAX                    \ source. It would have no effect as we know the C flag
\ is clear from when we passed through the BCS above
TXA                    \ Otherwise negate (Y X) using two's complement by first
EOR #%11111111         \ setting the low byte to ~X + 1
``` TYA                    \ Then set the high byte to ~Y + C