This code appears in the following versions (click to see it in the source code):
Code variations between these versions are shown below.
.STPX LDX X1 \ Set X = X1 CPX X2 \ If X1 < X2, jump down to LI3, as the coordinates are BCC LI3 \ already in the order that we want DEC SWAP \ Otherwise decrement SWAP from 0 to &FF, to denote that \ we are swapping the coordinates around LDA X2 \ Swap the values of X1 and X2 STA X1 STX X2 TAX \ Set X = X1 LDA Y2 \ Swap the values of Y1 and Y2 LDY Y1 STA Y1 STY Y2 .LI3 \ By this point we know the line is horizontal-ish and \ X1 < X2, so we're going from left to right as we go \ from X1 to X2Type: Subroutine Category: Drawing lines Summary: Draw a line: Line has a shallow gradient, step right along x-axis Deep dive: Bresenham's line algorithm
This routine draws a line from (X1, Y1) to (X2, Y2). It has multiple stages. If we get here, then: * |delta_y| < |delta_x| * The line is closer to being horizontal than vertical * We are going to step right along the x-axis * We potentially swap coordinates to make sure X1 < X2
LDA Y1 \ Set Y = Y1 mod 8, which is the pixel row within the AND #7 \ character block at which we want to draw the start of TAY \ our line (as each character block has 8 rows)
This variation is blank in the Electron version.
Tap on a block to expand it, and tap it again to revert.
STA SC \ Store this value in SC, so SC(1 0) now contains the \ screen address of the far left end (x-coordinate = 0) \ of the horizontal pixel row that we want to draw the \ start of our line on
Part 2 of the LOIN routine in the advanced versions uses logarithms to speed up the multiplication.
Tap on a block to expand it, and tap it again to revert.
The Master version omits half of the logarithm algorithm when compared to the 6502SP version.
See below for more variations related to this code.
This variation is blank in the Cassette, Disc (flight), Disc (docked), Master and Electron versions.
BMI LIlog4 \ If A > 127, jump to LIlog4
Code variation 8 of 10
See variation 7 above for details.
This variation is blank in the Cassette, Disc (flight), Disc (docked) and Electron versions.
Tap on a block to expand it, and tap it again to revert.
Code variation 9 of 10
See variation 7 above for details.
This variation is blank in the Cassette, Disc (flight), Disc (docked) and Electron versions.
Tap on a block to expand it, and tap it again to revert.
Code variation 10 of 10
See variation 7 above for details.
This variation is blank in the Cassette, Disc (flight), Disc (docked) and Electron versions.
.LIlog6 STA Q \ Store the result of the division in Q, so we have: \ \ Q = |delta_y| / |delta_x| LDX P \ Set X = P \ = |delta_x| BEQ LIEXS \ If |delta_x| = 0, return from the subroutine, as LIEXS \ contains a BEQ LIEX instruction, and LIEX contains an \ RTS INX \ Set X = P + 1 \ = |delta_x| + 1 \ \ We add 1 so we can skip the first pixel plot if the \ line is being drawn with swapped coordinates LDA Y2 \ If Y2 < Y1 then skip the following instruction CMP Y1 BCC P%+5 JMP DOWN \ Y2 >= Y1, so jump to DOWN, as we need to draw the line \ to the right and down