Aviator on the BBC Micro

# Flight model: ApplyFlightModel (Part 5 of 7)

```       Name: ApplyFlightModel (Part 5 of 7)                          [Show more]
Type: Subroutine
Category: Flight model
Summary: Calculate the forces for when we are on the ground
Deep dive: The flight model
On-ground calculations
Context: See this subroutine in context in the source code
References: No direct references to this subroutine in this source file

This part does the following:

* If we are on the ground, then:

* Apply ground steering to yTurn if the rudder is used and forward speed
is >= 20.

* Stop the plane from rolling by setting the roll rate in dzTurn to 0.

* If the undercarriage is up, prevent the plane from pitching forward
below the level of the ground.

* Calculate the effect of being on the ground on the forces and landing
status:

* If the plane is stationary, set landingStatus = %01000000 and skip
to the side velocity step below.

* If the plane is travelling forwards at a speed of 10 or less, set
side velocity step below.

* If the plane is on the runway, the undercarriage is down and the
brakes are off, set landingStatus = 0 and skip to the side
velocity step below.

* Otherwise, set landingStatus = 0 and subtract the following from
zLinearHi (from the least slowdown to the biggest slowdown):

* 7 if the plane is not on the runway and:
undercarriage is down and brakes are off

* 11 if the plane is on the runway and:
undercarriage is up
or undercarriage is down and brakes are on

* 50 if the plane is not on the runway and:
undercarriage is up
or undercarriage is down and brakes are on

* 248 if the plane is going backwards (zVelocityP < 0)

In other words, the following factors slow us down when travelling
forwards along the ground:

* Having the brakes on

* Having the undercarriage up

* Calculate the effect of side velocity on xLinear:

xLinear = -xVelocityPLo * 128

LDA L                  \ Fetch the value of onGround that we stored in L above

BNE fmod4              \ If onGround is non-zero then we are on the ground, so

JMP fmod17             \ We are not on the ground, so jump to fmod17 to move on
\ to the next part

.fmod4

\ We start by processing the effect of the rudder
\ control on the ground steering (as the rudder control
\ doubles up as the ground steering control)

LDX #0                 \ Set (X Y) = 0, to use as the value of yTurn below
LDY #0

LDA zVelocityPHi       \ If the forward airspeed is negative, jump to fmod6 to
BMI fmod6              \ set (X Y) = 0

BNE fmod5              \ If the high byte of the forward airspeed is non-zero,

\ If we get here then the high byte of the forward
\ airspeed is zero

LDA zVelocityPLo       \ If the low byte of the forward airspeed is less than
CMP #20                \ 20, jump to fmod6 to set (X Y) = 0
BCC fmod6

.fmod5

LDY rudderPosition     \ If the position of the rudder is positive, jump to
BPL fmod6              \ fmod6 to skip the following instruction

DEX                    \ Decrement X to &FF, so X contains the correct sign in
\ the 16-bit number:
\
\   (X Y) = rudderPosition

.fmod6

\ By the time we get here, (X Y) contains:
\
\   * 0 if the forward airspeed is negative or < 20
\
\   * rudderPosition otherwise
\
\ This is the effect of ground steering, which is
\ controlled by the rudder control when we are on the
\ ground, and only works when the plane is travelling
\ forward with a minimum speed of 20 (as it works by
\ applying brakes to the wheels, which needs speed to
\ work)
\
\ Let's call this figure groundSteering

STY yTurnHi            \ Set (A yTurnHi) = (X Y)
TXA                    \                 = groundSteering

LDX #1                 \ Set X as a shift counter in the following loop, so we
\ shift left by 2 places

.fmod7

ASL yTurnHi            \ Set (A yTurnHi) = (A yTurnHi) << 1
ROL A

DEX                    \ Decrement the shift counter

BPL fmod7              \ Loop back until we have shifted left by 2 places, so:
\
\   (A yTurnHi) = (A yTurnHi) * 4
\               = groundSteering * 4

STA yTurnTop           \ Set yTurn = (A yTurnHi)
\
\ So we have now set yTurn to groundSteering * 4, so the
\ plane steers on the ground when we apply the rudder

LDX #&82               \ Set (dzTurnTop dzTurnHi) = 0
JSR ResetVariable      \
\ This also sets A = 0

STA dzTurnLo           \ Set dzTurnLo = 0, so by now we have:
\
\   (dzTurnTop dzTurnHi dzTurnLo) = 0

\ We now work out the effect of the various landing
\ configurations to get the amount that the plane is
\ being slowed down by being on the ground

LDY ucStatus           \ If ucStatus is non-zero then the undercarriage is
BNE fmod9              \ down, so jump to fmod9 to move on to the brake checks

LDA xRotationHi        \ If the plane's rotation about the x-axis is positive
AND dxTurnTop          \ or the calculated rate of change of rotation around
BPL fmod8              \ x-axis is positive, jump to fmod8 skip the following

\ If we get here then both the following are negative:
\
\   * The plane's current rotation about the x-axis
\
\   * The calculated rate of change of rotation around
\     the x-axis
\
\ In other words, the nose has dipped below the forward
\ horizontal and is heading down further, which can't
\ happen when the undercarriage is up and we are on the
\ ground, so we now set dxTurn to 0 to stop the plane
\ from pitching any further into the ground

LDX #&80               \ Set (dxTurnTop dxTurnHi) = 0
JSR ResetVariable      \
\ This also sets A = 0

STA dxTurnLo           \ Set dxTurnLo = 0, so by now we have:
\
\   (dxTurnTop dxTurnHi dxTurnLo) = 0

.fmod8

JSR CheckPlaneOnRunway \ Check whether the plane is over the runway

BCC fmod10             \ If the plane is on the runway, then jump to fmod10 to
\ set A = 11

LDA #50                \ Set A = 50 and jump to fmodll (this BNE is effectively
BNE fmod11             \ a JMP as A is never zero)

.fmod9

LDX brakesStatus       \ If brakesStatus is non-zero then the brakes are on, so

\ If we get here then the brakes are off and the
\ undercarriage is down

JSR CheckPlaneOnRunway \ Check whether the plane is over the runway

BCC fmod15             \ If the plane is on the runway, then jump to fmod15 to
\ set landingStatus = 0

LDA #7                 \ Set A = 7 and jump to fmod11 (this BNE is effectively
BNE fmod11             \ a JMP as A is never zero)

.fmod10

LDA #11                \ Set A = 11

.fmod11

LDX zVelocityPHi       \ If the plane is going backwards, jump to fmod12 to set
BMI fmod12             \ A = 248

BNE fmod13             \ If the plane is moving forwards, jump to fmod13 to
\ subtract A from zLinearHi

\ If we get here then zVelocityPHi = 0

LDX zVelocityPLo       \ If the plane is stationary (i.e. both zVelocityPLo and
BEQ fmod14             \ zVelocityPHi = 0), jump to fmod14 to leave zLinear
\ untouched and set landingStatus = %01000000

CPX #11                \ If the plane is moving forwards at a speed of 11 or
BCS fmod13             \ more, jump to fmod13 to subtract A from zLinearHi

LDA #0                 \ Set zLinear = -256
STA zLinearLo
LDA #&FF
STA zLinearHi

BNE fmod14             \ Jump to fmod14 to set landingStatus = %01000000 (this
\ BNE is effectively a JMP as A is never zero)

.fmod12

LDA #248               \ Set A = 248

.fmod13

\ We do not reach this point if any of the following are
\ true:
\
\   * The plane is stationary, in which case we already
\     moved on with landingStatus = %01000000
\
\   * The plane is travelling forwards at a speed of 10
\     or less, in which case we already moved on with
\     zLinear = -256 and landingStatus = %01000000
\
\   * The plane is on the runway, the undercarriage is
\     down, the brakes are off, in which case we already
\     moved on with landingStatus = 0
\
\ Otherwise, we get here and A is one of the following:
\
\   * 248 if the plane is going backwards
\
\   * 11 if the plane is on the runway and:
\           either undercarriage is up
\           or undercarriage is down, brakes are on
\
\   * 50 if the plane is not on the runway and:
\           either undercarriage is up
\           or undercarriage is down, brakes are on
\
\   * 7 if the plane is not on the runway and:
\           undercarriage is down, brakes are off
\
\ We now subtract the value of A from zLinearHi

STA P                  \ Set zLinearHi = zLinearHi - A
SEC
LDA zLinearHi
SBC P
STA zLinearHi

.fmod14

LDA #%01000000         \ Set A = %01000000 to use as the value of landingStatus

BNE fmod16             \ Jump to fmod16 to set the value of landingStatus (this
\ BNE is effectively a JMP as A is never zero)

.fmod15

LDA #0                 \ Set A = 0 to use as the value of landingStatus

.fmod16

STA landingStatus      \ Set landingStatus to the value in A

LDA xVelocityPLo       \ Set P = xVelocityPLo / 2
LSR A                  \
STA P                  \ and shift bit 0 of xVelocityPLo into the C flag

LDX #0                 \ Set X = 0

STX slipRate           \ Set slipRate = 0

TXA                    \ Set A = 0

ROR A                  \ Shift the C flag into bit 7 of V, so bit 7 of V now
STA V                  \ contains the bit 0 of xVelocityPLo that we shifted
\ into the C flag above

LDA xVelocityPHi       \ Set Q = P with the sign bit from xVelocityPHi
AND #%10000000         \       = xVelocityPLo / 2 with the correct sign
ORA P
STA Q
\ If xVelocityPLo is %vvvvvvvv and the sign bit of
\ xVelocityPHi is %s, then this sets
\
\   (Q V) = %svvvvvvv v0000000
\
\ which is xVelocityPLo << 7, or xVelocityPLo * 128

TXA                    \ Set A = 0

SEC                    \ Set xLinear = (0 0) - (Q V)
SBC V                  \                = -xVelocityPLo * 128
STA xLinearLo          \
\ starting with the low bytes

TXA                    \ And then the high bytes
SBC Q
STA xLinearHi
```