This code appears in the following versions (click to see it in the source code):
Code variations between these versions are shown below.
Name: SCAN Type: Subroutine Category: Dashboard Summary: Display the current ship on the scanner Deep dive: The 3D scanner
This is used both to display a ship on the scanner, and to erase it again.
Arguments: INWK The ship's data block
This variation is blank in the Cassette, Disc (flight), 6502 Second Processor and Electron versions.
.SCAN LDA INWK+31 \ Fetch the ship's scanner flag from byte #31
In the original versions, ships are shown on the scanner with a green stick, while missiles are shown in yellow (if an escape pod is fitted, they are shown in cyan and white respectively). In the advanced versions, each ship has its own colour for when it is shown on the scanner, as defined in the scacol table.
This variation is blank in the Electron version.
Tap on a block to expand it, and tap it again to revert.
\ If we get here, we know x_hi, y_hi and z_hi are all \ 63 (%00111111) or less \ Now, we convert the x_hi coordinate of the ship into \ the screen x-coordinate of the dot on the scanner, \ using the following: \ \ X1 = 123 + (x_sign x_hi) LDA INWK+1 \ Set A = x_hi CLC \ Clear the C flag so we can do addition below LDX INWK+2 \ Set X = x_sign BPL SC2 \ If x_sign is positive, skip the following EOR #%11111111 \ x_sign is negative, so flip the bits in A and add 1 ADC #1 \ to make it a negative number (bit 7 will now be set \ as we confirmed above that bits 6 and 7 are clear). So \ this gives A the sign of x_sign and gives it a value \ range of -63 (%11000001) to 0
This variation is blank in the Cassette, Disc (flight), 6502 Second Processor and Electron versions.
CLC \ Clear the C flag so we can do addition below
.SC2
In most versions, ships that are exactly ahead of us or behind us are shown on the 3D scanner so the stick goes from the dot onto the centre line of the ellipse, but in the Master version the dot is moved over to the right so the stick goes from the dot just to the right of the centre line.
Tap on a block to expand it, and tap it again to revert.
\ Next, we convert the z_hi coordinate of the ship into \ the y-coordinate of the base of the ship's stick, \ like this: \ \ SC = 220 - (z_sign z_hi) / 4 \ \ though the following code actually does it like this: \ \ SC = 255 - (35 + z_hi / 4) LDA INWK+7 \ Set A = z_hi / 4 LSR A \ LSR A \ So A is in the range 0-15 CLC \ Clear the C flag for the addition below
BPL SC3 \ If z_sign is positive, skip the following EOR #%11111111 \ z_sign is negative, so flip the bits in A and set the SEC \ C flag. As above, this makes A negative, this time \ with a range of -16 (%11110000) to -1 (%11111111). And \ as we are about to do an ADC, the SEC effectively adds \ another 1 to that value, giving a range of -15 to 0 .SC3 ADC #35 \ Set A = 35 + A to give a number in the range 20 to 50
\ Now for the stick height, which we calculate using the \ following: \ \ A = - (y_sign y_hi) / 2 LDA INWK+4 \ Set A = y_hi / 2 LSR A CLC \ Clear the C flag
BMI SCD6 \ If y_sign is negative, skip the following, as we \ already have a positive value in A EOR #%11111111 \ y_sign is positive, so flip the bits in A and set the SEC \ C flag. This makes A negative, and as we are about to \ do an ADC below, the SEC effectively adds another 1 to \ that value to implement two's complement negation, so \ we don't need to add another 1 here .SCD6 \ We now have all the information we need to draw this \ ship on the scanner, namely: \ \ X1 = the screen x-coordinate of the ship's dot \ \ SC = the screen y-coordinate of the base of the \ stick \ \ A = the screen height of the ship's stick, with the \ correct sign for adding to the base of the stick \ to get the dot's y-coordinate \ \ First, though, we have to make sure the dot is inside \ the dashboard, by moving it if necessary
CMP #194 \ If A >= 194, skip the following instruction, as 194 is BCS P%+4 \ the minimum allowed value of A LDA #194 \ A < 194, so set A to 194, the minimum allowed value \ for the y-coordinate of our ship's dot CMP #247 \ If A < 247, skip the following instruction, as 246 is BCC P%+4 \ the maximum allowed value of A
LDA #246 \ A >= 247, so set A to 246, the maximum allowed value \ for the y-coordinate of our ship's dot
The Master version's 3D scanner draws a dash at the end of each stick (i.e. one pixel high, two pixels wide), while the other versions draw a full dot (i.e. two pixels high, two pixels wide).
See below for more variations related to this code.
Tap on a block to expand it, and tap it again to revert.
\ result is negative (i.e. the stick length is negative) \ and sets it if the result is positive (i.e. the stick \ length is negative) \ So now we have the following: \ \ X1 = the screen x-coordinate of the ship's dot, \ clipped to fit into the dashboard \ \ Y1 = the screen y-coordinate of the ship's dot, \ clipped to fit into the dashboard \ \ SC = the screen y-coordinate of the base of the \ stick \ \ A = the screen height of the ship's stick, with the \ correct sign for adding to the base of the stick \ to get the dot's y-coordinate \ \ C = 0 if A is negative, 1 if A is positive \ \ and we can get on with drawing the dot and stick
Code variation 16 of 24
See variation 14 above for details.
This variation is blank in the 6502 Second Processor and Master versions.
PHP \ Store the flags (specifically the C flag) from the \ above subtraction
This variation is blank in the Disc (flight), 6502 Second Processor, Master and Electron versions.
\BCS SC48 \ These instructions are commented out in the original \EOR #&FF \ source. They would negate A if the C flag were set, \ADC #1 \ which would reverse the direction of all the sticks, \ so you could turn your joystick around. Perhaps one of \ the authors' test sticks were easier to use upside \ down? Who knows...
Code variation 18 of 24
See variation 14 above for details.
This variation is blank in the 6502 Second Processor and Master versions.
.SC48 PHA \ Store the stick height in A on the stack JSR CPIX4 \ Draw a double-height dot at (X1, Y1). This also leaves \ the following variables set up for the dot's top-right \ pixel, the last pixel to be drawn (as the dot gets \ drawn from the bottom up): \ \ SC(1 0) = screen address of the pixel's character \ block \ \ Y = number of the character row containing the pixel \ \ X = the pixel's number (0-3) in that row \ \ We can use there as the starting point for drawing the \ stick, if there is one
Code variation 19 of 24
See variation 14 above for details.
This variation is blank in the 6502 Second Processor and Master versions.
Tap on a block to expand it, and tap it again to revert.
PLP \ Restore the flags from above, so the C flag once again \ reflects the sign of the stick height TAX \ Copy the stick height into X BEQ RTS \ If the stick height is zero, then there is no stick to \ draw, so return from the subroutine (as RTS contains \ an RTS) BCC RTS+1 \ If the C flag is clear then the stick height in A is \ negative, so jump down to RTS+1 .VLL1 \ If we get here then the stick length is positive (so \ the dot is below the ellipse and the stick is above \ the dot, and we need to draw the stick upwards from \ the dot) DEY \ We want to draw the stick upwards, so decrement the \ pixel row in Y BPL VL1 \ If Y is still positive then it correctly points at the \ line above, so jump to VL1 to skip the following LDY #7 \ We just decremented Y up through the top of the \ character block, so we need to move it to the last row \ in the character above, so set Y to 7, the number of \ the last row
This variation is blank in the 6502 Second Processor and Master versions.
Tap on a block to expand it, and tap it again to revert.
EOR (SC),Y \ Draw the stick on row Y of the character block using STA (SC),Y \ EOR logic DEX \ Decrement the (positive) stick height in X BNE VLL1 \ If we still have more stick to draw, jump up to VLL1 \ to draw the next pixel .RTS RTS \ Return from the subroutine \ If we get here then the stick length is negative (so \ the dot is above the ellipse and the stick is below \ the dot, and we need to draw the stick downwards from \ the dot)