Revs on the BBC Micro

# Maths (Arithmetic): MultiplyCoords

```       Name: MultiplyCoords                                          [Show more]
Type: Subroutine
Category: Maths (Arithmetic)
Summary: Multiply a 16-bit coordinate value and a 16-bit factor, optionally
tallying or changing the sign of the result
Context: See this subroutine in context in the source code
References: This subroutine is called as follows:
* RotateVector calls MultiplyCoords
* ApplySteeringForce calls entry point MultiplyCoords+7
* ApplySteeringSpeed calls entry point MultiplyCoords+7

This routine multiplies two 16-bit values and stores the result, optionally
negating the result, or adding it to the existing contents of the destination.

The first number (specified by parameter N, so let's call it variableN) is a
16-bit signed integer, while the second number (specified by parameter X, so
let's call it variableX) is a 16-bit sign-magnitude number with the sign in
bit 0 of the low byte. The result is stored in the variable specified by
parameter K, so let's call it variableK.

The values of bits 6 and 7 of A affect the result as follows:

* If A = %00000000, then we calculate the following:

variableK = variableN * variableX

* If A = %01000000, then we calculate the following:

variableK = variableK + variableN * variableX

* If A = %10000000, then we calculate the following:

variableK = - variableN * variableX

* If A = %11000000, then we calculate the following:

variableK = variableK - variableN * variableX

Arguments:

N                    Offset of the 16-bit signed number to multiply:

* 0 = xPlayerSpeed

* 1 = zPlayerSpeed

* 6 = xPlayerAccel

* 7 = zPlayerAccel

* 8 = xVelocity

* 9 = zVelocity

* 10 = xTyreForceNose

* 12 = zTyreForceNose

X                    Offset of the 16-bit sign-magnitude value to multiply:

* 0 = sinYawAngle

* 1 = cosYawAngle

* 2 = (steeringHi steeringLo)

K                    Offset of the variable to store the result in:

* 3 = xAcceleration

* 4 = zAcceleration

* 8 = xVelocity

* 9 = zVelocity

* 12 = zTyreForceNose

* 14 = xSteeringForce

A                    Details of the operation to perform:

* Bit 6 defines whether we add or store:

* 0 = store the result in the variable defined by K,
overwriting the existing contents

* 1 = add the result to the variable defined by K

* Bit 7 defines the sign to apply to the result:

* 0 = do not negate the multiplication

* 1 = negate the multiplication

Other entry points:

MultiplyCoords+7     Use the following variables instead of the above:

* Y = Offset of the 16-bit signed number to multiply

* A = Offset of the variable to store the result in

* H = Details of the operation to perform

.MultiplyCoords

LDY N                  \ Set Y to the offset of the 16-bit signed number

STA H                  \ Store the details of the operation to perform in H

\ point

\ This is where we join the subroutine when called via
\ MultiplyCoords+7

STA K                  \ Set K to the offset of the variable to store the
\ result in

.mcoo1

LDA xPlayerSpeedHi,Y   \ Set (QQ PP) to the 16-bit signed number pointed to by
STA PP                 \ Y (variableY)
LDA xPlayerSpeedTop,Y
STA QQ

LDA sinYawAngleLo,X    \ Set (SS RR) to the 16-bit sign-magnitude number
STA RR                 \ pointed to by X (variableX)
LDA sinYawAngleHi,X
STA SS

JSR Multiply16x16      \ Set (A T) = (QQ PP) * (SS RR)
\
\ And apply the sign from bit 7 of H

STA U                  \ Set (U T) = (A T)
\           = (QQ PP) * (SS RR)

LDY K                  \ Set Y to K, so we can store the result in the variable
\ pointed to by K