Skip to navigation


Drawing lines: LOIN (Part 6 of 7)

[BBC Micro disc version, Docked]

Name: LOIN (Part 6 of 7) [Show more] Type: Subroutine Category: Drawing lines Summary: Draw a steep line going up and left or down and right Deep dive: Bresenham's line algorithm
Context: See this subroutine in context in the source code Variations: See code variations for this subroutine in the different versions 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: * The line is going up and left (no swap) or down and right (swap) * X1 < X2 and Y1 >= Y2 * Draw from (X1, Y1) at top left to (X2, Y2) at bottom right, omitting the first pixel
CLC \ Clear the C flag LDA SWAP \ If SWAP = 0 then we didn't swap the coordinates above, BEQ LI17 \ so jump down to LI17 to skip plotting the first pixel DEX \ Decrement the counter in X because we're about to plot \ the first pixel .LIL5 \ We now loop along the line from left to right, using X \ as a decreasing counter, and at each count we plot a \ single pixel using the pixel mask in R LDA R \ Fetch the pixel byte from R EOR (SC),Y \ Store R into screen memory at SC(1 0), using EOR STA (SC),Y \ logic so it merges with whatever is already on-screen .LI17 DEY \ Decrement Y to step up along the y-axis BPL LI16 \ If Y is positive we are still within the same \ character block, so skip to LI16 DEC SCH \ Otherwise we need to move up into the character block LDY #7 \ above, so decrement the high byte of the screen \ address and set the pixel line to the last line in \ that character block .LI16 LDA S \ Set S = S + P to update the slope error ADC P STA S BCC LIC5 \ If the addition didn't overflow, jump to LIC5 LSR R \ Otherwise we just overflowed, so shift the single \ pixel in R to the right, so the next pixel we plot \ will be at the next x-coordinate along BCC LIC5 \ If the pixel didn't fall out of the right end of R \ into the C flag, then jump to LIC5 ROR R \ Otherwise we need to move over to the next character \ block, so first rotate R right so the set C flag goes \ back into the left end, giving %10000000 LDA SC \ Add 8 to SC, so SC(1 0) now points to the next ADC #8 \ character along to the right STA SC .LIC5 DEX \ Decrement the counter in X BNE LIL5 \ If we haven't yet reached the right end of the line, \ loop back to LIL5 to plot the next pixel along LDY YSAV \ Restore Y from YSAV, so that it's preserved RTS \ Return from the subroutine