Elite on the BBC Micro

# Maths (Geometry): LL51 (6502SP version)

```       Name: LL51                                              [View in context]
Type: Subroutine
Category: Maths (Geometry)
Summary: Calculate the dot product of XX15 and XX16

Calculate following dot products:

XX12(1 0) = XX15(5 0) . XX16(5 0)
XX12(3 2) = XX15(5 0) . XX16(11 6)
XX12(5 4) = XX15(5 0) . XX16(12 17)

storing the results as sign-magnitude numbers in XX12 through XX12+5.

When called from part 5 of LL9, XX12 contains the vector [x y z] to the ship
we're drawing, and XX16 contains the orientation vectors, so it returns:

[ x ]   [ sidev_x ]         [ x ]   [ roofv_x ]         [ x ]   [ nosev_x ]
[ y ] . [ sidev_y ]         [ y ] . [ roofv_y ]         [ y ] . [ nosev_y ]
[ z ]   [ sidev_z ]         [ z ]   [ roofv_z ]         [ z ]   [ nosev_z ]

When called from part 6 of LL9, XX12 contains the vector [x y z] of the vertex
we're analysing, and XX16 contains the transposed orientation vectors with
each of them containing the x, y and z elements of the original vectors, so it
returns:

[ x ]   [ sidev_x ]         [ x ]   [ sidev_y ]         [ x ]   [ sidev_z ]
[ y ] . [ roofv_x ]         [ y ] . [ roofv_y ]         [ y ] . [ roofv_z ]
[ z ]   [ nosev_x ]         [ z ]   [ nosev_y ]         [ z ]   [ nosev_z ]

Arguments:

XX15(1 0)            The ship (or vertex)'s x-coordinate as (x_sign x_lo)

XX15(3 2)            The ship (or vertex)'s y-coordinate as (y_sign y_lo)

XX15(5 4)            The ship (or vertex)'s z-coordinate as (z_sign z_lo)

XX16 to XX16+5       The scaled sidev (or _x) vector, with:

* x, y, z magnitudes in XX16, XX16+2, XX16+4

* x, y, z signs in XX16+1, XX16+3, XX16+5

XX16+6 to XX16+11    The scaled roofv (or _y) vector, with:

* x, y, z magnitudes in XX16+6, XX16+8, XX16+10

* x, y, z signs in XX16+7, XX16+9, XX16+11

XX16+12 to XX16+17   The scaled nosev (or _z) vector, with:

* x, y, z magnitudes in XX16+12, XX16+14, XX16+16

* x, y, z signs in XX16+13, XX16+15, XX16+17

Returns:

XX12(1 0)            The dot product of [x y z] vector with the sidev (or _x)

XX12(3 2)            The dot product of [x y z] vector with the roofv (or _y)

XX12(5 4)            The dot product of [x y z] vector with the nosev (or _z)

.LL51

LDX #0                 \ Set X = 0, which will contain the offset of the vector
\ to use in the calculation, increasing by 6 for each
\ new vector

LDY #0                 \ Set Y = 0, which will contain the offset of the
\ result bytes in XX12, increasing by 2 for each new
\ result

.ll51

LDA XX15               \ Set Q = x_lo
STA Q

LDA XX16,X             \ Set A = |sidev_x|

JSR FMLTU              \ Set T = A * Q / 256
STA T                  \       = |sidev_x| * x_lo / 256

LDA XX15+1             \ Set S to the sign of x_sign * sidev_x
EOR XX16+1,X
STA S

LDA XX15+2             \ Set Q = y_lo
STA Q

LDA XX16+2,X           \ Set A = |sidev_y|

JSR FMLTU              \ Set Q = A * Q / 256
STA Q                  \       = |sidev_y| * y_lo / 256

LDA T                  \ Set R = T
STA R                  \       = |sidev_x| * x_lo / 256

LDA XX15+3             \ Set A to the sign of y_sign * sidev_y
EOR XX16+3,X

JSR LL38               \ Set (S T) = (S R) + (A Q)
STA T                  \           = |sidev_x| * x_lo + |sidev_y| * y_lo

LDA XX15+4             \ Set Q = z_lo
STA Q

LDA XX16+4,X           \ Set A = |sidev_z|

JSR FMLTU              \ Set Q = A * Q / 256
STA Q                  \       = |sidev_z| * z_lo / 256

LDA T                  \ Set R = T
STA R                  \       = |sidev_x| * x_lo + |sidev_y| * y_lo

LDA XX15+5             \ Set A to the sign of z_sign * sidev_z
EOR XX16+5,X

JSR LL38               \ Set (S A) = (S R) + (A Q)
\           = |sidev_x| * x_lo + |sidev_y| * y_lo
\             + |sidev_z| * z_lo

STA XX12,Y             \ Store the result in XX12+Y(1 0)
LDA S
STA XX12+1,Y

INY                    \ Set Y = Y + 2
INY

TXA                    \ Set X = X + 6
CLC