Skip to navigation

Aviator on the BBC Micro

Drawing lines: DrawCanopyLine (Part 4 of 9)

Name: DrawCanopyLine (Part 4 of 9) [Show more] Type: Subroutine Category: Drawing lines Summary: Draw a part of the line, working down the screen
Context: See this subroutine in context in the source code References: No direct references to this subroutine in this source file

The code in this routine is modified by the ModifyDrawRoutine, and by the DrawCanopyLine routine itself. The default code (i.e. the unmodified version in the source) is run when: * The current colour cycle is drawing in colour 1, using the pixel bitmaps at colour1L2R and OR logic for updating the screen
.dlin12 \ This forms the start of a loop that works its way \ along the line. We only jump to this part from the end \ of the loop, which is joined at different points from \ part 3 above \ \ The loop is joined with A already set to SS, which \ keeps track of the slope error as we step along the \ x-axis one pixel at a time \ \ So SS keeps track of the y-axis position by adding \ the y-delta in U, and when adding U to A overflows \ because the slope error has reached a whole number \ (i.e. 256), we move down to the next a pixel row \ \ The following commentary assumes we are moving along \ the x-axis from left to right, and down the screen. \ The code is modified in-place for drawing in the \ other directions, which is note in the commentary \ \ In the following, X is used to store the offset of the \ pixel byte we are going to draw, from the colour1L2R \ table (this is modified to cater for different colour \ cycles, but for simplicity we just consider the case \ of drawing from left to right in colour 1) CLC \ Clear the C flag to reset the carry for the additions \ below LDA SS \ Set A = SS, so it contains the current slope error .dlin13 LDX #0 \ Set X = 0 to point to pixel 0, which is the pixel \ byte 1000 when drawing from left to right ADC U \ Set A = A + U, to add the y-delta to the slope error BCC dlin15 \ If the addition didn't overflow, jump to dlin15 to \ increment X to move to the second pixel along, \ which is the pixel byte 1100 when drawing from left \ to right JSR dlin32 \ Otherwise the slope error just overflowed, so we need \ to move down a pixel row, so call dlin32 to draw the \ pixel byte pointed to by X and move down to the next \ character row .dlin14 \ If we get here then we either just draw the first \ pixel in the pixel byte, i.e. 1000, and moved up or \ down a pixel row, or we just jumped here from part 3 \ \ In both cases, we want to start drawing the next pixel \ byte from the second pixel along, i.e. 0100 LDX #3 \ Set X = 3 so the next instruction increments X to 4, \ which is the pixel byte 0100 when drawing from left \ to right .dlin15 INX \ Increment X to set the next pixel in the pixel byte \ (i.e. step through the colour1L2R table) ADC U \ Set A = A + U, to add the y-delta to the slope error BCC dlin17 \ If the addition didn't overflow, jump to dlin17 to \ increment X to move to the third pixel along, \ which is the pixel byte 1110 when drawing from left \ to right JSR dlin32 \ Otherwise the slope error just overflowed, so we need \ to move down a pixel row, so call dlin32 to draw the \ pixel byte pointed to by X and move down to the next \ character row .dlin16 \ If we get here then we either just draw the second \ pixel in the pixel byte, i.e. 0100 or 1100, and moved \ down a pixel row, or we just jumped here from part 3 \ \ In both cases, we want to start drawing the next pixel \ byte from the second pixel along, i.e. 0010 LDX #6 \ Set X = 6 so the next instruction increments X to 7, \ which is the pixel byte 0010 when drawing from left \ to right .dlin17 INX \ Increment X to set the next pixel in the pixel byte \ (i.e. step through the colour1L2R table) ADC U \ Set A = A + U, to add the y-delta to the slope error BCC dlin19 \ If the addition didn't overflow, jump to dlin19 to \ increment X to move to the fourth pixel along, \ which is the pixel byte 1111 when drawing from left \ to right JSR dlin32 \ Otherwise the slope error just overflowed, so we need \ to move down a pixel row, so call dlin32 to draw the \ pixel byte pointed to by X and move down to the next \ character row .dlin18 \ If we get here then we either just draw the third \ pixel in the pixel byte, i.e. 0010 or 0110 or 1110, \ and moved down a pixel row, or we just jumped here \ from part 3 \ \ In both cases, we want to start drawing the next pixel \ byte from the second pixel along, i.e. 0001 LDX #8 \ Set X = 8 so the next instruction increments X to 9, \ which is the pixel byte 0001 when drawing from left \ to right .dlin19 INX \ Increment X to set the next pixel in the pixel byte \ (i.e. step through the colour1L2R table) ADC U \ Set A = A + U, to add the y-delta to the slope error .dlin20 BCC dlin22 \ If the addition didn't overflow, jump to dlin22 to \ draw the pixel byte but without going down a row, as \ we have reached the end of the pixel byte and need to \ draw it before moving on the next pixel byte to the \ right \ \ Gets modified by the DrawCanopyLine routine: \ \ * BCC dlin22 when bit 7 of V is clear \ \ * BCC dlin27 when bit 7 of V is set \ \ In other words, this instruction has already been \ modified to implement the current drawing direction JSR dlin32 \ Otherwise the slope error just overflowed, so we need \ to move down a pixel row, so call dlin32 to draw the \ pixel byte pointed to by X and move down to the next \ character row .dlin21 BNE dlin25 \ Jump to dlin25 to move on to the next character block, \ as we just moved down a pixel row after drawing the \ fourth pixel in the pixel byte, so we need to move on \ to the next pixel byte along \ \ The dlin32 routine ends with a BEQ just before the RTS \ so this BNE is effectively a JMP, as we had to pass \ through the BEQ in dlin32 to return from the above \ call \ \ Gets modified by the DrawCanopyLine routine: \ \ * BNE dlin25 when bit 7 of V is clear \ \ * BNE dlin30 when bit 7 of V is set \ \ In other words, this instruction has already been \ modified to implement the current drawing direction .dlin22 \ If we get here then we need to draw the current pixel \ byte as pointed to by X, and then move to the next \ character block along, without going down a row STA SS \ Set SS = A to store the updated slope error in SS .dlin23 LDA colour1L2R,X \ Fetch the X-th pixel byte from colour1L2R \ \ Gets modified by the ModifyDrawRoutine routine: \ \ * LDA colour1L2R,X when colourLogic = %10000000 \ \ * LDA colour2L2R,X when colourLogic = %01000000 \ \ * LDA colour1Row,X when colourLogic = %00000000 \ and colourCycle = %00001111 \ \ * LDA colour2Row,X when colourLogic = %00000000 \ and colourCycle = %11110000 \ \ In other words, this instruction has already been \ modified to implement the current colour cycle .dlin24 ORA (P),Y \ OR the pixel byte with the current screen contents \ \ Gets modified by the ModifyDrawRoutine routine: \ \ * ORA (P),Y when colourLogic = %01000000 \ \ * AND (P),Y when colourLogic = %00000000 \ \ In other words, this instruction has already been \ modified to implement the current drawing logic STA (P),Y \ Update the Y-th byte of (Q P) with the result, which \ sets 4 pixels to the pixel pattern in A .dlin25 LDA P \ Set (Q P) = (Q P) + 8 CLC \ ADC #8 \ starting with the low bytes STA P BCC dlin26 \ And then the high bytes, so (Q P) now points to the INC Q \ next character block to the right .dlin26 INC QQ \ Increment QQ, which contains the current character \ block number LDA QQ \ If QQ <> I, then we haven't yet reached the right edge CMP I \ edge of the screen (whose character block number we BNE dlin12 \ set in I in part 2), so jump back to dlin12 to keep \ drawing the line JMP dlin65 \ Otherwise we have reached the edge of the screen, so \ jump to dlin65 to process the clipped part of the \ line, if applicable