Skip to navigation

Aviator on the BBC Micro

Maths: AddScaled

Name: AddScaled [Show more] Type: Subroutine Category: Maths Summary: Add or subtract a scaled amount to a variable
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * ApplyAerodynamics (Part 2 of 3) calls AddScaled * ApplyFlightModel (Part 3 of 7) calls AddScaled

Add a scaled value to the 16-bit variable specified in X. Specifically, we add (A 0) right-shifted by Y + 1 places, so this calculates: variable = variable + (A 0) >> (Y + 1) Arguments: A The top byte of the value to scale and add X The offset from xTurnHi of the low byte of the variable to zero: * &02 = (zTurnTop zTurnHi) * &6A = (xControlsScTop xControlsScHi) * &6B = (yControlsScTop yControlsScHi) * &6C = (zControlsScTop zControlsScHi) * &EC = (zRotationHi zRotationLo) * &EE = (yPlaneHi yPlaneLo) Y The scale factor N flag If this is set, invert A, so we calculate: variable = variable + ~(A 0) >> (Y + 1) C flag If this is set, subtract the scaled value, so we calculate: variable = variable - (A 0) >> (Y + 1)
.AddScaled PHP \ Store the processor flags on the stack, so we can \ retrieve them later BPL adds1 \ If the N flag is clear (i.e. we called this routine \ after loading or processing a positive number), skip \ the following instruction EOR #&FF \ Set A = ~A \ \ so if we call the routine after loading or processing \ a negative number in A, then A is now positive, \ i.e. A = |A| .adds1 STA G \ Set (G A) = (A 0) LDA #0 \ We now shift (G A) right by Y + 1 places .adds2 LSR G \ Set (G A) = (G A) >> 1 ROR A DEY \ Decrement the shift counter in Y BPL adds2 \ Loop back until we have shifted right by Y + 1 places STA W \ Set (G W) = (G A) \ = (A 0) right-shifted by Y + 1 places \ = (A 0) / 2^(Y+1) PLP \ Retrieve the flags from the original call to the \ routine BCC adds3 \ If we called the routine with the C flag clear, skip \ the following instruction JSR Negate16Bit \ We know the C flag is set at this point as we just \ passed through a BCC, so this negates (G W) .adds3 LDA W \ Add (G W) to the variable specified in X, starting CLC \ with the low bytes ADC xTurnHi,X STA xTurnHi,X LDA G \ And then the high bytes ADC xTurnTop,X STA xTurnTop,X RTS \ Return from the subroutine