Skip to navigation

Aviator on the BBC Micro

Flight model: ApplyAerodynamics (Part 1 of 3)

Name: ApplyAerodynamics (Part 1 of 3) [Show more] Type: Subroutine Category: Flight model Summary: Set up various variables to use in the aerodynamics calculations Deep dive: The flight model
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * ApplyFlightModel (Part 2 of 7) calls ApplyAerodynamics

This part does the following: * Set a number of variables that are used by the calculations in part 3: xLiftDrag = xVelocityP * 2 yLiftDrag = yVelocityP * 2 zLiftDrag = zVelocityP * 2 (J I) = |yVelocityP| * 4 (SS RR) = max(|velocityP|) * 2 * ~yPlaneHi / 256
Arguments: L The current value of onGround: * 0 = we are not on the ground * 1 = we are on the ground
.ApplyAerodynamics \ We start by finding the maximum velocity from the \ perspective of the plane, across all three axes \ \ We do this by finding the maximum of |xVelocityP|, \ |yVelocityP| and |zVelocityP| LDA #0 \ Set (SS RR) = 0, so we can use it to capture the STA RR \ maximum value of |xVelocityP|, |yVelocityP| and STA SS \ |zVelocityP| LDX #2 \ Set a counter in X to work through the three axes (the \ comments below cover the iteration for the x-axis) .aero1 LDA xVelocityPLo,X \ Set P = xVelocityPLo STA P ASL A \ Set xLiftDrag = xVelocityP << 1 STA xLiftDragLo,X \ = xVelocityP * 2 LDA xVelocityPHi,X \ PHA \ and push xVelocityPHi onto the stack ROL A STA xLiftDragHi,X PLA \ Set A = xVelocityPHi, so we have \ \ (A P) = (xVelocityPHi xVelocityPLo) \ = xVelocityP BPL aero2 \ If A is positive, then skip the following as (A P) is \ already positive LDA #0 \ Set (A P) = -(A P) SEC \ SBC P \ so by this point we have (A P) = |xVelocityP| STA P LDA #0 SBC xVelocityPHi,X .aero2 STA Q \ Set (Q P) = (A P) \ = |xVelocityP| CPX #1 \ If X <> 1, jump to aero3 to skip the following, so BNE aero3 \ (J I) only gets set on the y-axis iteration LDA P \ Set (A I) = (Q P) STA I \ = |yVelocityP| LDA Q ASL I \ Set (A I) = (A I) << 2 ROL A \ = (Q P) << 2 ASL I \ = |yVelocityP| * 4 ROL A STA J \ Set (J I) = (A I) \ = |yVelocityP| * 4 LDA Q \ Set A to the high byte of (Q P), so we have \ (A P) = |xVelocityP| once again .aero3 \ We now compare the two 16-bit values in (A P) and \ (SS RR), by first comparing the high bytes, and if \ they are equal, comparing the low bytes \ \ It then sets (SS RR) to the higher value, so this does \ the following: \ \ (SS RR) = max((SS RR), (Q P)) \ = max((SS RR), |xVelocityP|) \ \ Note that at this point, (A P) and (Q P) are the same CMP SS \ If A < SS, jump to aero5 to leave (SS RR) alone, as BCC aero5 \ (SS RR) is the higher value BNE aero4 \ If A <> SS, i.e. A > SS, jump to aero4 with A = Q, so \ we set (SS RR) to (Q P), as (Q P) is the higher value \ If we get here then A = SS, so now we compare the low \ bytes LDA P \ If P < RR, jump to aero5 to leave (SS RR) alone, as CMP RR \ (SS RR) is the higher value BCC aero5 LDA Q \ If we get here then A = SS and P >= RR, so set A = Q \ so we set (SS RR) to (Q P), as (Q P) is the higher \ value .aero4 STA SS \ Set (SS RR) = (A P) LDA P \ = max((SS RR), |xVelocityP|) STA RR .aero5 DEX \ Decrement the loop counter to move to the next axis BPL aero1 \ Loop back until we have processed all three axes \ So we now have the following: \ \ xLiftDrag = xVelocityP * 2 \ \ yLiftDrag = yVelocityP * 2 \ \ zLiftDrag = zVelocityP * 2 \ \ (J I) = |yVelocityP| * 4 \ \ (SS RR) = max(0, |xVelocityP|, |yVelocityP|, \ |zVelocityP|) \ \ Let's call this last one max(|velocityP|) ASL RR \ Set (SS RR) = (SS RR) << 1 ROL SS \ = max(|velocityP|) * 2 LDY SS \ Set (Y X) = (SS RR) LDX RR \ = max(|velocityP|) * 2 JSR ScaleByAltitude \ Set (Y X V) = (Y X) * ~yPlaneHi \ = max(|velocityP|) * 2 * ~yPlaneHi STY SS \ Set (SS RR) = (Y X) STX RR \ = max(|velocityP|) * 2 * ~yPlaneHi / 256