Skip to navigation

Elite on the BBC Micro and NES

Maths (Geometry): TAS2

[BBC Micro disc version, Docked]

Name: TAS2 [Show more] Type: Subroutine Category: Maths (Geometry) Summary: Normalise the three-coordinate vector in K3
Context: See this subroutine in context in the source code References: No direct references to this subroutine in this source file

Normalise the vector in K3, which has 16-bit values and separate sign bits, and store the normalised version in XX15 as a signed 8-bit vector. A normalised vector (also known as a unit vector) has length 1, so this routine takes an existing vector in K3 and scales it so the length of the new vector is 1. This is used in two places: when drawing the compass, and when applying AI tactics to ships. We do this in two stages. This stage shifts the 16-bit vector coordinates in K3 to the left as far as they will go without losing any bits off the end, so we can then take the high bytes and use them as the most accurate 8-bit vector to normalise. Then the next stage (in routine NORM) does the normalisation.
Arguments: K3(2 1 0) The 16-bit x-coordinate as (x_sign x_hi x_lo), where x_sign is just bit 7 K3(5 4 3) The 16-bit y-coordinate as (y_sign y_hi y_lo), where y_sign is just bit 7 K3(8 7 6) The 16-bit z-coordinate as (z_sign z_hi z_lo), where z_sign is just bit 7
Returns: XX15 The normalised vector, with: * The x-coordinate in XX15 * The y-coordinate in XX15+1 * The z-coordinate in XX15+2
Other entry points: TA2 Calculate the length of the vector in XX15 (ignoring the low coordinates), returning it in Q
.TAS2 LDA K3 \ OR the three low bytes and 1 to get a byte that has ORA K3+3 \ a 1 wherever any of the three low bytes has a 1 ORA K3+6 \ (as well as always having bit 0 set), and store in ORA #1 \ K3+9 STA K3+9 LDA K3+1 \ OR the three high bytes to get a byte in A that has a ORA K3+4 \ 1 wherever any of the three high bytes has a 1 ORA K3+7 \ (A K3+9) now has a 1 wherever any of the 16-bit \ values in K3 has a 1 .TAL2 ASL K3+9 \ Shift (A K3+9) to the left, so bit 7 of the high byte ROL A \ goes into the C flag BCS TA2 \ If the left shift pushed a 1 out of the end, then we \ know that at least one of the coordinates has a 1 in \ this position, so jump to TA2 as we can't shift the \ values in K3 any further to the left ASL K3 \ Shift K3(1 0), the x-coordinate, to the left ROL K3+1 ASL K3+3 \ Shift K3(4 3), the y-coordinate, to the left ROL K3+4 ASL K3+6 \ Shift K3(6 7), the z-coordinate, to the left ROL K3+7 BCC TAL2 \ Jump back to TAL2 to do another shift left (this BCC \ is effectively a JMP as we know bit 7 of K3+7 is not a \ 1, as otherwise bit 7 of A would have been a 1 and we \ would have taken the BCS above) .TA2 LDA K3+1 \ Fetch the high byte of the x-coordinate from our left- LSR A \ shifted K3, shift it right to clear bit 7, stick the ORA K3+2 \ sign bit in there from the x_sign part of K3, and STA XX15 \ store the resulting signed 8-bit x-coordinate in XX15 LDA K3+4 \ Fetch the high byte of the y-coordinate from our left- LSR A \ shifted K3, shift it right to clear bit 7, stick the ORA K3+5 \ sign bit in there from the y_sign part of K3, and STA XX15+1 \ store the resulting signed 8-bit y-coordinate in \ XX15+1 LDA K3+7 \ Fetch the high byte of the z-coordinate from our left- LSR A \ shifted K3, shift it right to clear bit 7, stick the ORA K3+8 \ sign bit in there from the z_sign part of K3, and STA XX15+2 \ store the resulting signed 8-bit z-coordinate in \ XX15+2 \ Now we have a signed 8-bit version of the vector K3 in \ XX15, so fall through into NORM to normalise it