Skip to navigation

Elite on the BBC Micro and NES

Version analysis of LL118

This code appears in the following versions (click to see it in the source code):

Code variations between these versions are shown below.

Name: LL118 Type: Subroutine Category: Drawing lines Summary: Move a point along a line until it is on-screen Deep dive: Line-clipping
Given a point (x1, y1), a gradient and a direction of slope, move the point along the line until it is on-screen, so this effectively clips the (x1, y1) end of a line to be on the screen. See the deep dive on "Line-clipping" for more details.
Arguments: XX15(1 0) x1 as a 16-bit coordinate (x1_hi x1_lo) XX15(3 2) y1 as a 16-bit coordinate (y1_hi y1_lo) XX12+2 The line's gradient * 256 (so 1.0 = 256) XX12+3 The direction of slope: * Positive (bit 7 clear) = top left to bottom right * Negative (bit 7 set) = top right to bottom left T The gradient of slope: * 0 if it's a shallow slope * &FF if it's a steep slope
Returns: XX15 x1 as an 8-bit coordinate XX15+2 y1 as an 8-bit coordinate
Other entry points: LL118-1 Contains an RTS
.LL118 LDA XX15+1 \ If x1_hi is positive, jump down to LL119 to skip the BPL LL119 \ following STA S \ Otherwise x1_hi is negative, i.e. off the left of the \ screen, so set S = x1_hi JSR LL120 \ Call LL120 to calculate: \ \ (Y X) = (S x1_lo) * XX12+2 if T = 0 \ = x1 * gradient \ \ (Y X) = (S x1_lo) / XX12+2 if T <> 0 \ = x1 / gradient \ \ with the sign of (Y X) set to the opposite of the \ line's direction of slope TXA \ Set y1 = y1 + (Y X) CLC \ ADC XX15+2 \ starting with the low bytes STA XX15+2 TYA \ And then adding the high bytes ADC XX15+3 STA XX15+3 LDA #0 \ Set x1 = 0 STA XX15 STA XX15+1 TAX \ Set X = 0 so the next instruction becomes a JMP .LL119 BEQ LL134 \ If x1_hi = 0 then jump down to LL134 to skip the \ following, as the x-coordinate is already on-screen \ (as 0 <= (x_hi x_lo) <= 255) STA S \ Otherwise x1_hi is positive, i.e. x1 >= 256 and off DEC S \ the right side of the screen, so set S = x1_hi - 1 JSR LL120 \ Call LL120 to calculate: \ \ (Y X) = (S x1_lo) * XX12+2 if T = 0 \ = (x1 - 256) * gradient \ \ (Y X) = (S x1_lo) / XX12+2 if T <> 0 \ = (x1 - 256) / gradient \ \ with the sign of (Y X) set to the opposite of the \ line's direction of slope TXA \ Set y1 = y1 + (Y X) CLC \ ADC XX15+2 \ starting with the low bytes STA XX15+2 TYA \ And then adding the high bytes ADC XX15+3 STA XX15+3 LDX #255 \ Set x1 = 255 STX XX15 INX STX XX15+1 .LL134 \ We have moved the point so the x-coordinate is on \ screen (i.e. in the range 0-255), so now for the \ y-coordinate LDA XX15+3 \ If y1_hi is positive, jump down to LL119 to skip BPL LL135 \ the following STA S \ Otherwise y1_hi is negative, i.e. off the top of the \ screen, so set S = y1_hi LDA XX15+2 \ Set R = y1_lo STA R JSR LL123 \ Call LL123 to calculate: \ \ (Y X) = (S R) / XX12+2 if T = 0 \ = y1 / gradient \ \ (Y X) = (S R) * XX12+2 if T <> 0 \ = y1 * gradient \ \ with the sign of (Y X) set to the opposite of the \ line's direction of slope TXA \ Set x1 = x1 + (Y X) CLC \ ADC XX15 \ starting with the low bytes STA XX15 TYA \ And then adding the high bytes ADC XX15+1 STA XX15+1 LDA #0 \ Set y1 = 0 STA XX15+2 STA XX15+3 .LL135

Code variation 1 of 1A variation in the comments only

This variation is blank in the Disc (flight), Disc (docked) and Electron versions.

\BNE LL139 \ This instruction is commented out in the original \ source
 LDA XX15+2             \ Set (S R) = (y1_hi y1_lo) - screen height
 SEC                    \
 SBC #Y*2               \ starting with the low bytes
 STA R

 LDA XX15+3             \ And then subtracting the high bytes
 SBC #0
 STA S

 BCC LL136              \ If the subtraction underflowed, i.e. if y1 < screen
                        \ height, then y1 is already on-screen, so jump to LL136
                        \ to return from the subroutine, as we are done

.LL139

                        \ If we get here then y1 >= screen height, i.e. off the
                        \ bottom of the screen

 JSR LL123              \ Call LL123 to calculate:
                        \
                        \   (Y X) = (S R) / XX12+2      if T = 0
                        \         = (y1 - screen height) / gradient
                        \
                        \   (Y X) = (S R) * XX12+2      if T <> 0
                        \         = (y1 - screen height) * gradient
                        \
                        \ with the sign of (Y X) set to the opposite of the
                        \ line's direction of slope

 TXA                    \ Set x1 = x1 + (Y X)
 CLC                    \
 ADC XX15               \ starting with the low bytes
 STA XX15

 TYA                    \ And then adding the high bytes
 ADC XX15+1
 STA XX15+1

 LDA #Y*2-1             \ Set y1 = 2 * #Y - 1. The constant #Y is 96, the
 STA XX15+2             \ y-coordinate of the mid-point of the space view, so
 LDA #0                 \ this sets Y2 to 191, the y-coordinate of the bottom
 STA XX15+3             \ pixel row of the space view

.LL136

 RTS                    \ Return from the subroutine