Skip to navigation

Aviator on the BBC Micro

Dashboard: GetRadarVector

Name: GetRadarVector [Show more] Type: Subroutine Category: Dashboard Summary: Calculate the radar line vector for a line (the runway) or a dot (an alien)
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * DrawRadarBlip calls GetRadarVector

Arguments: A For the runway line only, this is either the current compass direction from yRotationHi (if we are drawing the radar line), or a previous compass direction (if we are erasing the existing radar line) X The type of radar line to calculate: * 0 = runway line * Non-zero = alien (shown as a dot)
Returns: T Magnitude of x-coordinate of line's vector |x-delta| U Magnitude of y-coordinate of line's vector |y-delta| V The direction of the line (runway), or an arbitrary direction for the dot, because it doesn't matter (alien) * Bit 7 is the direction of the x-delta * Bit 6 is the direction of the y-delta Direction is like a clock, so positive (clear) is up and right
.GetRadarVector CPX #0 \ If X = 0, jump to rvec1 to calculate the line vector BEQ rvec1 \ for the runway \ Otherwise we return the deltas for a dot, T = U = 1, \ and don't worry about setting the direction in V as \ it gets ignored when drawing dots LDY #1 \ Set Y = 1 to return as the y-delta in U BNE rvec2 \ Jump down to rvec2 to set X = 1 and return from the \ subroutine (this BNE is effectively a JMP as Y is \ never zero) .rvec1 \ We now want to calculate the vector for the runway \ line on the radar \ \ The runway runs north-south, so our compass direction \ in A lets us work out the direction of the runway line \ on the radar. The value of our compass in A is: \ \ * 0 = north \ * 64 = east \ * 128 = south \ * 192 = west STA previousCompass \ Store A in previousCompass, so we can pass it to this \ routine again when we want to erase the line we are \ about to draw CLC \ Set A = A + 16 ADC #16 \ \ This rotates the compass needle clockwise by 16, or \ 22.5 degrees, so if the needle is just anticlockwise \ of a cardinal compass point (e.g. NNW, ENE) it will be \ bumped along to the quadrant and will inherit the \ correct direction bit in bit 7. At the cardinal \ points, A now contains the following: \ \ * 16 = north -> bit 7 clear \ * 80 = east -> bit 7 clear \ * 144 = south -> bit 7 set \ * 208 = west -> bit 7 set \ \ So bit 7 contains the direction of the needle along \ the x-axis, with 0 to the right and 1 to the left ASL A \ Shift bit 7 of the result into the C flag, which we \ will use below as the direction of the line's x-delta STA P \ Store the result in P, so: \ \ P = (A + 16) << 1 \ \ which looks like this: \ \ * %00100000 = north \ * %10100000 = east \ * %00100000 = south \ * %10100000 = west \ \ We use this below to work out the line's vector PHP \ Store the flags on the stack, in particular the C \ flag from the above operation, which gives us the \ direction of the line's x-delta ROR A \ Shift the C flag back into bit 7 of A, so bit 7 once \ again contains the direction of the x-delta SEC \ Set A = A - 64 SBC #64 \ \ This rotates the compass needle anticlockwise by 64, \ or 90 degrees, which will change bit 7 from being the \ direction of the x-delta to the being the direction of \ the y-delta PLP \ Retrieve the C flag from above, which contains the \ direction of the x-delta ROR A \ Shift the direction of the x-delta into bit 7 of A, \ and at the same time shift the y-delta from bit 7 to \ bit 6 EOR #%11000000 \ Reverse both deltas by flipping bits 6 and 7 of A \ (I am not sure why this is done) STA V \ Store the result in V to set the direction of the line \ vector \ Above, we stored a value in P like this: \ \ * %00100000 = north \ * %10100000 = east \ * %00100000 = south \ * %10100000 = west \ \ We can use this below to work out the vector of the \ line to show, as follows: \ \ * A set bit 6 means the line is between the cardinal \ points, e.g. northeast, southwest and so on, so \ the line is diagonal \ \ * A set bit 7 means the line is generally east-west, \ which is horizontal \ \ * A clear bit 7 means the line is generally north- \ south, which is vertical \ \ We use this to set the vector in T and U to the \ following: \ \ * Diagonal: x-delta = 2, y-delta = 4 \ \ * Horizontal: x-delta = 2, y-delta = 1 \ \ * Vertical: x-delta = 1, y-delta = 4 \ \ The y-delta is twice the x-delta because the pixels \ in mode 5 are twice as wide as they are tall LDX #2 \ Set X = 2 to return as the x-delta in T for a diagonal LDY #4 \ Set Y = 4 to return as the y-delta in U for a diagonal BIT P \ If bit 6 of P is set, jump to rvec3 to return these BVS rvec3 \ values as the deltas (i.e. 2 and 4), as the runway \ line is diagonal BPL rvec2 \ If bit 7 of P is clear, jump to rvec2 to return an \ x-delta of 1 and a y-delta of 4, as the runway line is \ vertical LDY #1 \ Otherwise set Y = 1 and jump to rvec3 to return an BNE rvec3 \ x-delta of 2 and a y-delta of 1, as the runway line is \ horizontal .rvec2 LDX #1 \ Set X = 1 to return as the x-delta in T .rvec3 STX T \ Return X as the x-delta in T STY U \ Return Y as the y-delta in U RTS \ Return from the subroutine