BBC Micro Elite

# Moving: MVEIT (Part 5 of 9)

```       Name: MVEIT (Part 5 of 9)                               [View in context]
Type: Subroutine
Category: Moving
Summary: Move current ship: Rotate ship's location by our pitch and roll

This routine has multiple stages. This stage does the following:

* Rotate the ship's location in space by the amount of pitch and roll of
our ship. See below for a deeper explanation of this routine

LDX ALP1               \ Fetch the magnitude of the current roll into X, so
\ if the roll angle is alpha, X contains |alpha|

LDA INWK               \ Set P = ~x_lo (i.e. with all its bits flipped) so that
EOR #%11111111         \ we can pass x_lo to MLTU2 below)
STA P

LDA INWK+1             \ Set A = x_hi

JSR MLTU2-2            \ Set (A P+1 P) = (A ~P) * X
\               = (x_hi x_lo) * alpha

STA P+2                \ Store the high byte of the result in P+2, so we now
\ have:
\
\ P(2 1 0) = (x_hi x_lo) * alpha

LDA ALP2+1             \ Fetch the flipped sign of the current roll angle alpha
EOR INWK+2             \ from ALP2+1 and EOR with byte #2 (x_sign), so if the
\ flipped roll angle and x_sign have the same sign, A
\ will be positive, else it will be negative. So A will
\ contain the sign bit of x_sign * flipped alpha sign,
\ which is the opposite to the sign of the above result,
\ so we now have:
\
\ (A P+2 P+1) = - (x_sign x_hi x_lo) * alpha / 256

LDX #3                 \ Set (A P+2 P+1) = (y_sign y_hi y_lo) + (A P+2 P+1)
JSR MVT6               \                 = y - x * alpha / 256

STA K2+3               \ Set K2(3) = A = the sign of the result

LDA P+1                \ Set K2(1) = P+1, the low byte of the result
STA K2+1

EOR #%11111111         \ Set P = ~K2+1 (i.e. with all its bits flipped) so
STA P                  \ that we can pass K2+1 to MLTU2 below)

LDA P+2                \ Set K2(2) = A = P+2
STA K2+2

\ So we now have result 1 above:
\
\ K2(3 2 1) = (A P+2 P+1)
\           = y - x * alpha / 256

LDX BET1               \ Fetch the magnitude of the current pitch into X, so
\ if the pitch angle is beta, X contains |beta|

JSR MLTU2-2            \ Set (A P+1 P) = (A ~P) * X
\               = K2(2 1) * beta

STA P+2                \ Store the high byte of the result in P+2, so we now
\ have:
\
\ P(2 1 0) = K2(2 1) * beta

LDA K2+3               \ Fetch the sign of the above result in K(3 2 1) from
EOR BET2               \ K2+3 and EOR with BET2, the sign of the current pitch
\ rate, so if the pitch and K(3 2 1) have the same sign,
\ A will be positive, else it will be negative. So A
\ will contain the sign bit of K(3 2 1) * beta, which is
\ the same as the sign of the above result, so we now
\ have:
\
\ (A P+2 P+1) = K2(3 2 1) * beta / 256

LDX #6                 \ Set (A P+2 P+1) = (z_sign z_hi z_lo) + (A P+2 P+1)
JSR MVT6               \                 = z + K2 * beta / 256

STA INWK+8             \ Set z_sign = A = the sign of the result

LDA P+1                \ Set z_lo = P+1, the low byte of the result
STA INWK+6

EOR #%11111111         \ Set P = ~z_lo (i.e. with all its bits flipped) so that
STA P                  \ we can pass z_lo to MLTU2 below)

LDA P+2                \ Set z_hi = P+2
STA INWK+7

\ So we now have result 2 above:
\
\ (z_sign z_hi z_lo) = (A P+2 P+1)
\                    = z + K2 * beta / 256

JSR MLTU2              \ MLTU2 doesn't change Q, and Q was set to beta in
\ the previous call to MLTU2, so this call does:
\
\ (A P+1 P) = (A ~P) * Q
\           = (z_hi z_lo) * beta

STA P+2                \ Set P+2 = A = the high byte of the result, so we
\ now have:
\
\ P(2 1 0) = (z_hi z_lo) * beta

LDA K2+3               \ Set y_sign = K2+3
STA INWK+5

EOR BET2               \ EOR y_sign with BET2, the sign of the current pitch
EOR INWK+8             \ rate, and z_sign. If the result is positive jump to
BPL MV43               \ MV43, otherwise this means beta * z and y have
\ different signs, i.e. P(2 1) and K2(3 2 1) have
\ different signs, so we need to add them in order to
\ calculate K2(2 1) - P(2 1)

LDA P+1                \ Set (y_hi y_lo) = K2(2 1) + P(2 1)
STA INWK+3
LDA P+2
STA INWK+4

.MV43

LDA K2+1               \ Reversing the logic above, we need to subtract P(2 1)
SBC P+1                \ and K2(3 2 1) to calculate K2(2 1) - P(2 1), so this
STA INWK+3             \ sets (y_hi y_lo) = K2(2 1) - P(2 1)
LDA K2+2
SBC P+2
STA INWK+4

BCS MV44               \ If the above subtraction did not underflow, then

LDA #1                 \ Negate (y_sign y_hi y_lo) using two's complement,
SBC INWK+3             \ first doing the low bytes:
STA INWK+3             \
\ y_lo = 1 - y_lo

LDA #0                 \ Then the high bytes:
SBC INWK+4             \
STA INWK+4             \ y_hi = 0 - y_hi

EOR #%10000000
STA INWK+5

.MV44

\ So we now have result 3 above:
\
\ (y_sign y_hi y_lo) = K2(2 1) - P(2 1)
\                    = K2 - beta * z

LDX ALP1               \ Fetch the magnitude of the current roll into X, so
\ if the roll angle is alpha, X contains |alpha|

LDA INWK+3             \ Set P = ~y_lo (i.e. with all its bits flipped) so that
EOR #&FF               \ we can pass y_lo to MLTU2 below)
STA P

LDA INWK+4             \ Set A = y_hi

JSR MLTU2-2            \ Set (A P+1 P) = (A ~P) * X
\               = (y_hi y_lo) * alpha

STA P+2                \ Store the high byte of the result in P+2, so we now
\ have:
\
\ P(2 1 0) = (y_hi y_lo) * alpha

LDA ALP2               \ Fetch the correct sign of the current roll angle alpha
EOR INWK+5             \ from ALP2 and EOR with byte #5 (y_sign), so if the
\ correct roll angle and y_sign have the same sign, A
\ will be positive, else it will be negative. So A will
\ contain the sign bit of x_sign * correct alpha sign,
\ which is the same as the sign of the above result,
\ so we now have:
\
\ (A P+2 P+1) = (y_sign y_hi y_lo) * alpha / 256

LDX #0                 \ Set (A P+2 P+1) = (x_sign x_hi x_lo) + (A P+2 P+1)
JSR MVT6               \                 = x + y * alpha / 256

STA INWK+2             \ Set x_sign = A = the sign of the result

LDA P+2                \ Set x_hi = P+2, the high byte of the result
STA INWK+1

LDA P+1                \ Set x_lo = P+1, the low byte of the result
STA INWK

\ So we now have result 4 above:
\
\ x = x + alpha * y
\
\ and the rotation of (x, y, z) is done
```