.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 X2 ; The following section calculates: ; ; Q2 = Q2 / P2 ; = |delta_y| / |delta_x| ; ; using the log tables at logL and log to calculate: ; ; A = log(Q2) - log(P2) ; = log(|delta_y|) - log(|delta_x|) ; ; by first subtracting the low bytes of the logarithms ; from the table at LogL, and then subtracting the high ; bytes from the table at log, before applying the ; antilog to get the result of the division and putting ; it in Q2 LDX Q2 ; Set X = |delta_y| BEQ LIlog7 ; If |delta_y| = 0, jump to LIlog7 to return 0 as the ; result of the division LDA logL,X ; Set A = log(Q2) - log(P2) LDX P2 ; = log(|delta_y|) - log(|delta_x|) SEC ; SBC logL,X ; by first subtracting the low bytes of ; log(Q2) - log(P2) BMI LIlog4 ; If A > 127, jump to LIlog4 LDX Q2 ; And then subtracting the high bytes of LDA log,X ; log(Q2) - log(P2) so now A contains the high byte of LDX P2 ; log(Q2) - log(P2) SBC log,X BCS LIlog5 ; If the subtraction fitted into one byte and didn't ; underflow, then log(Q2) - log(P2) < 256, so we jump to ; LIlog5 to return a result of 255 TAX ; Otherwise we set A to the A-th entry from the antilog LDA antilog,X ; table so the result of the division is now in A JMP LIlog6 ; Jump to LIlog6 to return the result .LIlog5 LDA #255 ; The division is very close to 1, so set A to the BNE LIlog6 ; closest possible answer to 256, i.e. 255, and jump to ; LIlog6 to return the result (this BNE is effectively a ; JMP as A is never zero) .LIlog7 LDA #0 ; The numerator in the division is 0, so set A to 0 and BEQ LIlog6 ; jump to LIlog6 to return the result (this BEQ is ; effectively a JMP as A is always zero) .LIlog4 LDX Q2 ; Subtract the high bytes of log(Q2) - log(P2) so now A LDA log,X ; contains the high byte of log(Q2) - log(P2) LDX P2 SBC log,X BCS LIlog5 ; If the subtraction fitted into one byte and didn't ; underflow, then log(Q2) - log(P2) < 256, so we jump to ; LIlog5 to return a result of 255 TAX ; Otherwise we set A to the A-th entry from the LDA antilogODD,X ; antilogODD so the result of the division is now in A .LIlog6 STA Q2 ; Store the result of the division in Q2, so we have: ; ; Q2 = |delta_y| / |delta_x| CLC ; This instruction has no effect as the value of the C ; flag is overridden by the CPY in the following LDY Y1 ; If Y2 < Y1 then skip the following instruction CPY Y2 BCS P%+5 JMP DOWN ; Y2 >= Y1, so jump to DOWN, as we need to draw the line ; to the right and downName: LOIN (Part 2 of 7) [Show more] Type: Subroutine Category: Drawing lines Summary: Draw a line: Line has a shallow gradient, step right along x-axis Deep dive: Bresenham's line algorithmContext: See this subroutine in context in the source code References: No direct references to this subroutine in this source file
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
[X]
Label DOWN in subroutine LOIN (Part 4 of 7)
[X]
Label LI3 is local to this routine
[X]
Label LIlog4 is local to this routine
[X]
Label LIlog5 is local to this routine
[X]
Label LIlog6 is local to this routine
[X]
Label LIlog7 is local to this routine
[X]
Variable antilog (category: Maths (Arithmetic))
Binary antilogarithm table
[X]
Variable antilogODD (category: Maths (Arithmetic))
Binary antilogarithm table
[X]
Variable log (category: Maths (Arithmetic))
Binary logarithm table (high byte)
[X]
Variable logL (category: Maths (Arithmetic))
Binary logarithm table (low byte)