This code appears in the following versions (click to see it in the source code):
Code variations between these versions are shown below.
Name: HANGER Type: Subroutine Category: Ship hangar
The hangar background is made up of two parts: * The hangar floor consists of 11 screen-wide horizontal lines, which start out quite spaced out near the bottom of the screen, and bunch ever closer together as the eye moves up towards the horizon, where they merge to give a sense of perspective * The back wall of the hangar consists of 15 equally spaced vertical lines that join the horizon to the top of the screen The ships in the hangar have already been drawn by this point, so the lines are drawn so they don't overlap anything that's already there, which makes them look like they are behind and below the ships. This is achieved by drawing the lines in from the screen edges until they bump into something already on-screen. For the horizontal lines, when there are multiple ships in the hangar, this also means drawing lines between the ships, as well as in from each side.
Other entry points: HA3 Contains an RTS
.HANGER \ We start by drawing the floor
This variation is blank in the Disc (docked) and 6502 Second Processor versions.
LDA #%00001111 \ Set bits 1 and 2 of the Access Control Register at STA VIA+&34 \ SHEILA &34 to switch screen memory into &3000-&7FFF
.HAL1
LDA #130 \ Set A = 130
LDX XSAV \ Retrieve the loop counter from XSAV
STX Q \ Set Q to the value of the loop counter
\ \ (P R) = 256 * A / Q \ = 256 * 130 / Q \ \ so P = 130 / Q, and as the counter Q goes from 2 to \ 12, P goes 65, 43, 32 ... 13, 11, 10, with the \ difference between two consecutive numbers getting \ smaller as P gets smaller \ \ We can use this value as a y-coordinate to draw a set \ of horizontal lines, spaced out near the bottom of the \ screen (high value of P, high y-coordinate, lower down \ the screen) and bunching up towards the horizon (low \ value of P, low y-coordinate, higher up the screen)
LDA P \ Set the low byte of SC(1 0) to the y-coordinate mod 8, AND #7 \ which determines the pixel row in the character block STA SC \ we need to draw in (as each character row is 8 pixels \ high), so SC(1 0) now points to the address of the \ start of the horizontal line we want to draw LDY #0 \ Set Y = 0 so the call to HAS2 starts drawing the line \ in the first byte of the screen row, at the left edge \ of the screen JSR HAS2 \ Draw a horizontal line from the left edge of the \ screen, going right until we bump into something \ already on-screen, at which point stop drawing
LDY #248 \ Set Y = 248 so the call to HAS3 starts drawing the \ line in the last byte of the screen row, at the right \ edge of the screen JSR HAS3 \ Draw a horizontal line from the right edge of the \ screen, going left until we bump into something \ already on-screen, at which point stop drawing
\ If we get here then there are multiple ships in the \ hangar, so we also need to draw the horizontal line in \ the gap between the ships
.HA2 \ We have finished threading our horizontal line behind \ the ships already on-screen, so now for the next line
CPX #13 \ If the loop counter is less than 13 (i.e. 2 to 12) BCC HAL1 \ then loop back to HAL1 to draw the next line \ The floor is done, so now we move on to the back wall
The ship hangar in the advanced versions draws the vertical lines for the backdrop 60 times, when it only needs to do this 15 times. Is this a quick way of making the hangar display hang around for longer, or is it just a mistake?
This variation is blank in the Disc (docked) version.
LDA #60 \ Set S = 60, so we run the following 60 times (though I STA S \ have no idea why it's 60 times, when it should be 15, \ as this has the effect of drawing each vertical line \ four times, each time starting one character row lower \ on-screen)
LDA #16 \ We want to draw 15 vertical lines, one every 16 pixels \ across the screen, with the first at x-coordinate 16, \ so set this in A to act as the x-coordinate of each \ line as we work our way through them from left to \ right, incrementing by 16 for each new line
LDX #&40 \ Set X = &40, the high byte of the start of screen STX R \ memory (the screen starts at location &4000) and the \ page number of the first screen row
.HAL6
LDY #1 \ We are going to start drawing the line from the second \ pixel from the top (to avoid drawing on the one-pixel \ border), so set Y to 1 to point to the second row in \ the first character block .HAL7 TXA \ Copy the pixel mask to A AND (SC),Y \ If the pixel we want to draw is non-zero (using A as a BNE HA6 \ mask), then this means it already contains something, \ so jump to HA6 to stop drawing this line TXA \ Copy the pixel mask to A again
STA (SC),Y \ Store the updated pixel in screen memory INY \ Increment Y to point to the next row in the character \ block, i.e. the next pixel down CPY #8 \ Loop back to HAL7 to draw this next pixel until we BNE HAL7 \ have drawn all 8 in the character block
LDY #0 \ Set Y = 0 to point to the first row in this character \ block BEQ HAL7 \ Loop back up to HAL7 to keep drawing the line (this \ BEQ is effectively a JMP as Y is always zero) .HA6
BNE HAL6 \ Loop back to HAL6 until we have run through the loop \ 60 times, by which point we are most definitely done
This variation is blank in the Disc (docked) and 6502 Second Processor versions.
IF _SNG47 LDA #%00001001 \ Clear bits 1 and 2 of the Access Control Register at STA VIA+&34 \ SHEILA &34 to switch main memory back into &3000-&7FFF RTS \ Return from the subroutine (this instruction is not \ needed as we could just fall through into the RTS at \ HA3 below) ELIF _COMPACT JMP away \ Jump to away to switch main memory back into \ &3000-&7FFF and return from the subroutine ENDIF
RTS \ Return from the subroutine