# Dashboard: UpdateIndicator (Part 7 of 15)

```       Name: UpdateIndicator (Part 7 of 15)                          [Show more]
Type: Subroutine
Category: Dashboard
Summary: Calculations for the vertical speed indicator (indicator 4)
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 vertical speed from (yVelocityTop yVelocityHi) and
reduces it to the range -40 to +40, before passing it to the DrawIndicatorHand
routine to update the on-screen vertical speed indicator.

.uind8

\ If we get here then the indicator number in X is 4

LDA yVelocityHi        \ Set (A T) = (yVelocityTop yVelocityHi)
STA T                  \           = yVelocity
LDA yVelocityTop

BPL uind9              \ If the vertical speed is positive, jump down to uind9

LDA #0                 \ The vertical speed is negative, so we make it positive
SEC                    \ by calculating:
SBC T                  \
STA T                  \   (A T) = (0 0) - (A T)
\
\ starting with the low bytes

LDA #0                 \ And then the high bytes
SBC yVelocityTop

.uind9

\ By this point, (A T) = |yVelocity|

LSR A                  \ Set (A T) = (A T) / 8
ROR T                  \           = |yVelocity| / 8
LSR A
ROR T
LSR A
ROR T

CMP #0                 \ If A = 0, so (A T) = (0 T) = T, so jump to uind10 to
BEQ uind10             \ skip the following as T contains the correct value of
\ |yVelocity| / 8

LDA #255               \ A is non-zero, which means that (A T) > 255, so set
STA T                  \ T = 255 so that T has a maximum value of 255

.uind10

\ At this point, T contains |yVelocity| / 8, capped to a
\ maximum value of 255

\ We now calculate A = T * n / 256 with a hardcoded n,

LDA T                  \ Set A = T

LSR A                  \ Bit 0 of n is 0

CLC                    \ Bit 1 of n is 1
ROR A

LSR A                  \ Bit 2 of n is 0

LSR A                  \ Bit 3 of n is 0

LSR A                  \ Bit 4 of n is 0

CLC                    \ Bit 5 of n is 1
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 = %00100010 (34), so we just
\ calculated:
\
\   A = (T * n / 256) << 1
\     = (T * 34 / 256) << 1
\     = T * 68 / 256
\
\ which takes |yVelocity| / 8 in the range 0 to 255
\ and reduces it to the range 0 to 68

CMP #40                \ If A < 40, jump to uind11 to skip the following
BCC uind11             \ instruction

LDA #40                \ Set A = 40, so A has a maximum of 40 and is now in the
\ range 0 to 40

.uind11

BIT yVelocityTop       \ If the top byte in yVelocityTop is positive (and
BPL uind12             \ therefore so is the vertical speed), jump to uind12 to
\ skip the following

STA T                  \ Negate the value in A by calculating:
LDA #0                 \
SEC                    \   A = 0 - A
SBC T

\ So by now, A is in the range -40 to +40
\
\ In terms of the original value of yVelocity, this
\ means that:
\
\   yVelocity / 8 * (68 / 256) = A
\
\ so:
\
\   yVelocity = A * (256 / 68) * 8
\          = A * 2048 / 68
\
\ If A is 40 then this shows as a vertical speed of
\ 4000 feet per minute on the indicator, so if v is the
\ vertical speed in feet per minute, A = v / 100, and:
\
\   yVelocity = A * 2048 / 68
\          = (v / 100) * 2048 / 68
\          = v * 2048 / 6800
\          = v * 128 / 425
\
\ so yVelocity is stored as 128 / 425 * the vertical
\ speed in feet per minute

.uind12

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
```