Aviator on the BBC Micro

# Dashboard: ArtificialHorizon

```       Name: ArtificialHorizon                                       [Show more]
Type: Subroutine
Category: Dashboard
Summary: Vector line calculation for the artificial horizon on indicator 7
Context: See this subroutine in context in the source code
References: This subroutine is called as follows:
* UpdateIndicator (Part 11 of 15) calls ArtificialHorizon

The commentary in this routine is a work in progress.

matrix4Lo, matrix4Lo+2, matrix4Lo+3, matrix4Lo+4 are only used to provide
signs in bit 0:
Negative if bit 0 is set, positive if clear

matrix4Hi, matrix4Hi+3 provide values for T calculations
matrix4Hi+2, matrix4Hi+4 provide values for U calculations

matrix4Hi+3 = current roll orientation, 0-&FF for 0 to 45 degrees
matrix4Lo+3 = direction of roll

Y = 0, K = 0:
T = (matrix4Lo matrix4Hi) / 4
U = -(matrix4Lo+2 matrix4Hi+2) / 4
Return (T + U) / 8 with the sign bits retained = x-coord of start

Y = 0, K = 1:
T = -(matrix4Lo matrix4Hi) / 4
U = -(matrix4Lo+2 matrix4Hi+2) / 4
Return (T + U) / 8 with the sign bits retained = y-coord of start

Y = 3, K = 0:
T = (matrix4Lo+3 matrix4Hi+3) / 4
U = -(matrix4Lo+4 matrix4Hi+4) / 4
Return (T + U) / 8 with the sign bits retained = x-delta

Y = 3, K = 1:
T = -(matrix4Lo+3 matrix4Hi+3) / 4
U = -(matrix4Lo+4 matrix4Hi+4) / 4
Return (T + U) / 8 with the sign bits retained = y-delta

The line is returned relative to the origin (0, 0), so that's as if the centre
of the artificial horizon indicator were at (0, 0). This means that the deltas
that are calculated are the equivalent to the end point of the line. The line
itself gets moved to the location of the on-screen indicator in part 11 of
UpdateIndicator.

Arguments:

K                    The axis to calculate:

* 0 = x-axis

* 1 = y-axis

Y                    The value to calculate:

* 0 = coordinate of starting point

* 3 = deltas (i.e. coordinates of end point)

Returns:

A                    Depending on the values of K and Y:

* K = 0, Y = 0: returns the x-coordinate of the
artificial horizon's starting point

* K = 0, Y = 3: returns the y-coordinate of the
artificial horizon's starting point

* K = 1, Y = 0: returns the x-delta of the artificial
horizon

* K = 1, Y = 3: returns the y-delta of the artificial
horizon

.ArtificialHorizon

LDA matrix4Hi,Y        \ Set A = matrix4Hi (Y = 0) or matrix4Hi+3 (Y = 3)

LSR A                  \ Set A = A / 4
LSR A

CPY #0                 \ If Y = 3, halve A again, so A = A / 8
BNE arhi1
LSR A

.arhi1

STA T                  \ Set T = A, so T = A / 4 or A / 8

LDA matrix4Lo,Y        \ Set A = matrix4Lo (Y = 0) or matrix4Lo+3 (Y = 3)

EOR K                  \ If K = 1, flip bit 0 of A

AND #1                 \ If bit 0 of A is zero, jump to arhi2 to skip the
BEQ arhi2              \ following

LDA #0                 \ Set T = 0 - T
SEC
SBC T
STA T

.arhi2

LDA matrix4Hi+2,Y      \ Set A = matrix4Hi+2 (Y = 0) or matrix4Hi+4 (Y = 3)

LSR A                  \ Set A = A / 4
LSR A

CPY #0                 \ If Y = 3, halve A again, so A = A / 8
BNE arhi3
LSR A

.arhi3

STA U                  \ Set U = A, so U = A / 4 or A / 8

LDA matrix4Lo+2,Y      \ Set A = matrix4Lo+2 (Y = 0) or matrix4Lo+4 (Y = 3)

CPY #0                 \ If Y = 0, flip bit 0 of A
BNE arhi4
EOR #1

.arhi4

AND #1                 \ If bit 0 of A is zero, jump to arhi5 to skip the
BEQ arhi5              \ following

LDA #0                 \ Set U = 0 - U
SEC
SBC U
STA U

.arhi5

CLC                    \ A = T + U
LDA T

BMI arhi6

LSR A                  \ A = A / 8
LSR A
LSR A

ADC #0                 \ Round up the A/8 division

RTS                    \ Return from the subroutine

.arhi6

SEC                    \ A = A / 8 + with bits 5-7 set
ROR A
SEC
ROR A
SEC
ROR A

ADC #0                 \ Round up the A / 8 division

RTS                    \ Return from the subroutine
```