Aviator on the BBC Micro

# The Theme: GetTrailVectorStep

```       Name: GetTrailVectorStep                                      [Show more]
Type: Subroutine
Category: The Theme
Summary: Calculate 1/32 of the vector for a bullet trail
Deep dive: Detecting alien hits
Context: See this subroutine in context in the source code
References: This subroutine is called as follows:
* CheckIfAlienIsHit (Part 2 of 2) calls GetTrailVectorStep

Calculates one axis of the vector for the 1/32 of the specified bullet trail
and returns it in (A V R).

This is called ADIF in the original source code.

Arguments:

X                    The bullet trail to be calculated:

* 228 = left bullet trail

* 230 = right bullet trail

Returns:

X                    Updated to point to the next axis, so the first call
will return the x-axis of the vector, the second the
y-axis, and the third the z-axis

(A V R)               One axis of the vector for the specified bullet trail,
as a signed 24-bit number and divided by 32

.GetTrailVectorStep

LDA #0                 \ Set P = 0, to feed bits into the top bit of (A V R) in
STA P                  \ the final stage below

STA R                  \ Set R = 0, for use in constructing (A V R)

TXA                    \ Point X to the next axis (xObject, yObject, zObject)
CLC                    \
ADC #nextAxis          \ The first time that the routine is called is with
TAX                    \ X = 228 or 230, so this bumps X onto 268 or 260, which
\ gets truncated in the 8-bit register to 12 or 14, so
\ this moves X through the xObject, yObject and zObject
\ values for object 12 (when first called with X = 228)
\ or object 14 (when first called with X = 230)

\ We now subtract the following object coordinates:
\
\   * If first called with X = 228, we calculate object
\     13 - object 12 (i.e. the left bullet minus the
\     back end of the left bullet trail)
\
\   * If first called with X = 230, we calculate object
\     15 - object 13 (i.e. the right bullet minus the
\     back end of the right bullet trail)
\
\ In each case we end up with the vector of the relevant
\ bullet trail for axis Y in (A V)

LDA xObjectLo+1,X      \ Set (A V) = xObject+1 - xObject
SEC                    \
SBC xObjectLo,X        \ starting with the low bytes
STA V

LDA xObjectHi+1,X      \ And then the high bytes
SBC xObjectHi,X

BPL bulv1              \ If (A V) is negative, decrement P to &FF, so it is
DEC P                  \ full of bits of the correct polarity to shift into bit
\ 7 of A in (A V R)

.bulv1

\ We now have the number (A V 0) in (A V R), plus a byte
\ P made up of the correct sign bits, so the final stage
\ is to divide this by 32 by shifting right

LDY #4                 \ We want to shift the result right by five places to
\ divide the result by 32, so set a shift counter in Y

.bulv2

LSR P                  \ Shift (A V R) right by one place, shifting one of the
ROR A                  \ sign bits from P into bit 7 of of A
ROR V
ROR R

DEY                    \ Decrement the shift counter

BPL bulv2              \ Loop back until we have done all five shifts, so we
\ now have:
\
\   (A V R) = (A V R) / 32

RTS                    \ Return from the subroutine
```