Skip to navigation

BBC Micro Elite

Drawing lines: LL118

Name: LL118 [View in context] Type: Subroutine Category: Drawing lines Summary: Move a point along a line until it is on-screen
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. For example, if x1 is negative, i.e. off the left edge of the screen, we move the point right along the line until x1 = 0. We calculate the new y1 by multiplying the distance travelled in the x-direction by the gradient. Similar logic is applied when the point is off-screen to the right, top or bottom. Also, because the gradient is always stored as a fractional value (it's less than 1.0, just expressed as a byte), then when the line is more vertical than horizontal, the value stored is actually 1 / gradient, as that way it fits into the byte. Because of this, if T = 0, we have to divide by the gradient rather than multiply to get the same result. 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 type of slope: * 0 if it's more vertical than horizontal * &FF if it's more horizontal than vertical 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 BPL LL119 \ the 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 \BNE LL139 \ This instruction is commented out in the original \ source LDA XX15+2 \ Set (S R) = (y1_hi y1_lo) - 192 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 < 192, 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 >= 192, i.e. off the bottom of \ the screen JSR LL123 \ Call LL123 to calculate: \ \ (Y X) = (S R) / XX12+2 if T = 0 \ = (y1 - 192) / gradient \ \ (Y X) = (S R) * XX12+2 if T <> 0 \ = (y1 - 192) * 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 }