.DOWN LDA T2 ; Set T2 = 7 - T2 EOR #7 ; STA T2 ; T2 contains the number of the pixel row within the ; character block, from 0 at the top to 7 at the bottom ; ; We're going to be drawing a line that goes downwards, ; so this calculation enables us to use T2 as a pixel ; row counter, stepping down one pixel line at a time LDA SWAP ; If SWAP = 0 then we didn't swap the coordinates above, BEQ LI9 ; so jump down to LI9 to skip plotting the first pixel DEX ; Decrement the counter in X because we're about to plot ; the first pixel .LIL3 ; 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 .LI9 ASL R ; Shift the single pixel in R to the left to step along ; the x-axis, so the next pixel we plot will be at the ; next x-coordinate along (we shift left because the ; pixels in the high-resolution screen are the opposite ; way around than the bits in the pixel byte) BPL LI10 ; If the pixel didn't fall out of the left end of the ; pixel bits in R into the palette bit in bit 7, then ; jump to LI10 LDA #%00000001 ; Otherwise we need to move over to the next character STA R ; block, so set R = %00000001 to move the pixel to the ; left end of the next pixel byte INY ; And increment Y to move on to the next character block ; along to the right .LI10 LDA S ; Set S = S + Q to update the slope error ADC Q STA S BCC LIC3 ; If the addition didn't overflow, jump to LIC3 DEC T2 ; Otherwise we just overflowed, so decrement the pixel ; row counter within the character block, which is in ; T2, as we are moving to a new pixel line BMI LI21 ; If T2 is negative then the counter just ran down and ; we are no longer within the same character block, so ; jump to LI21 to move to the top pixel row in the ; character row below ; We now need to move down into the pixel row below LDA SC+1 ; Add 4 to the high byte of SC(1 0), so this does the ADC #3 ; following: STA SC+1 ; ; SC(1 0) = SC(1 0) + $400 ; ; The ADC adds 4 rather than 3 because the C flag is ; set, as we passed through the BCC above ; ; So this sets SC(1 0) to the address of the pixel row ; below the one we just drew in, as each pixel row ; within the character row is spaced out by $400 bytes ; in screen memory .LIC3 DEX ; Decrement the counter in X BNE LIL3 ; If we haven't yet reached the right end of the line, ; loop back to LIL3 to plot the next pixel along LDY YSAV ; Restore Y from YSAV, so that it's preserved RTS ; Return from the subroutine .LI21 ; If we get here then we need to move down into the top ; pixel row in the character block below LDA #7 ; Set the pixel line number within the character row STA T2 ; (which we store in T2) to 7, which is the bottom pixel ; row of the character block above STX T ; Store the current character row number in T, so we can ; restore it below LDX T1 ; Increment the number of the character row in T1, as we INX ; are moving down a row STX T1 LDA SCTBL,X ; Set SC(1 0) to the X-th entry from (SCTBH SCTBL), so STA SC ; it contains the address of the start of the top pixel LDA SCTBH,X ; row in character row X in screen memory (so that's the STA SC+1 ; top pixel row in the character row we just moved down ; into) LDX T ; Restore the value of X that we stored, so X contains ; the previous character row number, from before we ; moved down a row (we need to do this as the following ; jump returns us to a point where the previous row ; number is still in X) JMP LIC3 ; Jump back to keep drawing the lineName: LOIN (Part 4 of 7) [Show more] Type: Subroutine Category: Drawing lines Summary: Draw a shallow line going right and down or left and up 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: * The line is going right and down (no swap) or left and up (swap) * X1 < X2 and Y1 <= Y2 * Draw from (X1, Y1) at top left to (X2, Y2) at bottom right, omitting the first pixel
[X]
Label LI10 is local to this routine
[X]
Label LI21 is local to this routine
[X]
Label LI9 is local to this routine
[X]
Label LIC3 is local to this routine
[X]
Label LIL3 is local to this routine
[X]
Variable SCTBH (category: Drawing the screen)
Lookup table for converting a character row number to the address of the top pixel line in that character row (high byte)
[X]
Variable SCTBL (category: Drawing the screen)
Lookup table for converting a character row number to the address of the top or bottom pixel line in that character row (low byte)