Skip to navigation


Dashboard: UpdateIndicator (Part 4 of 15)

Name: UpdateIndicator (Part 4 of 15) [Show more] Type: Subroutine Category: Dashboard Summary: Calculations for the altimeter's small "hour" hand (indicator 2) Deep dive: Hard-coded division in the dashboard routines
Context: See this subroutine in context in the source code References: No direct references to this subroutine in this source file

This section takes the altitude from (yPlaneHi yPlaneLo) and reduces it to the range 0 to 254, before passing it to the DrawIndicatorHand to update the small hand of the on-screen altimeter. It also sets altitudeMinutes to the low byte of the altitude, reduced to the range 0 to 104, so it can be used in part 5 to update the large hand of the on-screen altimeter.
.uind4 \ If we get here then the indicator number in X is 2 LDA yPlaneLo \ Set (A R) = (yPlaneHi yPlaneLo) STA R LDA yPlaneHi LSR A \ Set (S R) = (A R) / 4 ROR R \ = (yPlaneHi yPlaneLo) / 4 LSR A \ = altitude ROR R \ STA S \ so (S R) is the altitude in feet, as the value stored \ in (yPlaneHi yPlaneLo) is the actual altitude x 4 LDA #0 \ Set T = 0 STA T \ We now calculate A = R * n / 256 with a hardcoded n, \ using unrolled shift-and-add multiplication LDA R \ Set A = R LSR A \ Bit 0 of n is 0 LSR A \ Bit 1 of n is 0 CLC \ Bit 2 of n is 1 ADC R ROR A LSR A \ Bit 3 of n is 0 CLC \ Bit 4 of n is 1 ADC R ROR A CLC \ Bit 5 of n is 1 ADC R ROR A LSR A \ Bit 6 of n is 0 \ Bit 7 of n is 0 and the final right shift is missing \ From the above, n = %000110100 (52), so we just \ calculated: \ \ A = (R * n / 256) << 1 \ = (R * 52 / 256) << 1 \ = R * 104 / 256 \ \ which is the low byte of the altitude in (S R), \ reduced to a range of 0 to 104 to represent the whole \ dial's range of 0 to 1,000 feet STA altitudeMinutes \ Store the result in altitudeMinutes, so we can draw \ the altimeter's minute hand in indicator 3 \ We now calculate A = S * n / 256 with a hardcoded n, \ using unrolled shift-and-add multiplication and \ keeping the overspill from the result LDA S \ Set A = S LSR A \ Bit 0 of n is 0 ROR T LSR A \ Bit 1 of n is 0 ROR T CLC \ Bit 2 of n is 1 ADC S ROR A ROR T LSR A \ Bit 3 of n is 0 ROR T CLC \ Bit 4 of n is 1 ADC S ROR A ROR T CLC \ Bit 5 of n is 1 ADC S ROR A ROR T LSR A \ Bit 6 of n is 0 ROR T \ Bit 7 of n is 0 and the final right shift is missing \ From the above, n = %00110100 (52), so we just \ calculated: \ \ A = (S * n / 256) << 1 \ = (S * 52 / 256) << 1 \ = S * 104 / 256 \ \ and T contains the overspill from the result STA U \ Set U = S * 104 / 256 LDA T \ Set (U A) = (U altitudeMinutes) + (0 T) CLC \ ADC altitudeMinutes \ by adding the low bytes BCC uind5 \ And, if the addition overflowed, incrementing the high INC U \ byte in U \ So we have just calculated: \ \ (U A) = (U altitudeMinutes) + (0 T) \ \ and we already know that: \ \ U = S * 104 / 256 \ \ altitudeMinutes = R * 104 / 256 \ \ so plugging these into the above, we get: \ \ (U A) = (U altitudeMinutes) + (0 T) \ = (S*104 R*104) / 256 + (0 T) \ = (S R) * 104 / 256 .uind5 LSR U \ Set (U A) = (U A) / 16 ROR A \ = ((S R) * 104 / 256) / 16 LSR U \ = (S R) * 6.5 / 256 ROR A \ LSR U ROR A LSR U ROR A \ So by now, A is in the range 0 to 254 - here's why: \ \ The maximum altitude that the altimeter can show is \ 10,000 feet (after which it just wraps around), so the \ final result of all these calculations is that the \ altitude in (S R) has been reduced from a range of 0 \ to 10,000 to a range of 0 to 254 in (U A), as: \ \ 10000 * 6.5 / 256 = 254 \ \ and that value is in A alone, as (U A) < 255, so U = 0 JMP DrawIndicatorHand \ Apply min and max limits to the value in A and update \ the indicator on-screen, returning from the subroutine \ using a tail call