Skip to navigation

Revs on the BBC Micro

Drawing the track: DrawSteepToLeft

Name: DrawSteepToLeft [Show more] Type: Subroutine Category: Drawing the track Summary: Draw a verge edge with a steep gradient from right to left Deep dive: Drawing the track verges
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * DrawSegmentEdge (Part 6 of 7) calls DrawSteepToLeft * DrawShallowToLeft calls via strl10

Arguments: X The pixel number to start drawing from, in the range 0 to 7, as it is measured across the two edge bytes that we draw in this routine Y The track line to draw on (0 to 79) SS The scaled yaw delta along the edge to draw TT The scaled pitch delta along the edge to draw RR The pitch angle of the current segment (we stop drawing the edge when Y reaches this value) UU The number of the dash data block where we start drawing JJ The right pixel byte when drawing the edge in the screen buffer, i.e. the fill byte to the right of the edge (S R) Address of the first dash data block in the memory page containing the pixels at the start of the previous edge (Q P) Address of the second dash data block in the memory page containing the pixels at the start of the previous edge (NN MM) Address of the third dash data block in this sequence, i.e. the first memory page of the next dash data block
Other entry points: strl10 Finish drawing the verge edge by updating the background table for this track line
.DrawSteepToLeft LDA jumpSteepLeft,X \ Modify the BCC instruction at strl1 below so that STA strl1+1 \ it jumps to the destination given in the X-th entry in \ the jumpSteepLeft lookup table LDA TT \ Set A = -TT EOR #&FF \ CLC \ This is the starting value for the cumulative slope ADC #1 \ error, which we tally up in A CLC \ Clear the C flag so the next instruction effectively \ becomes a JMP .strl1 BCC strl2 \ This instruction was modified above, so it jumps to \ the address specified in the jumpSteepLeft table, as \ follows: \ \ * strl9 when X = 0 \ * strl8 when X = 1 \ * strl7 when X = 2 \ * strl6 when X = 3 \ * strl5 when X = 4 \ * strl4 when X = 5 \ * strl3 when X = 6 \ * strl2 when X = 7 .strl2 LDX #3 \ Draw the edge in pixel 3 of the second dash data block JSR DrawVergeByteRight \ (the rightmost pixel) and draw a fill byte in the \ third dash data block \ \ If we have reached the pitch angle of the current \ segment, then we have reached the end of the edge to \ draw, in which case DrawVergeByteRight will jump to \ StopDrawingEdge to abort this edge and return us two \ routines up the call stack, to DrawSegmentEdge \ We now do the slope error calculation for pixel 3 of \ the second dash data block ADC SS \ Set A = A + SS, to add the yaw delta to the slope \ error BCC strl2 \ If the addition didn't overflow, skip to the next \ pixel to step along the y-axis, as the cumulative \ pitch deltas haven't yet added up to a multiple of TT \ If we get here then the pitch deltas have added up to \ a whole line and the addition has overflowed, so we \ need to draw a pixel SBC TT \ If we get here then the cumulative yaw deltas in SS \ have added up to a multiple of the pitch delta in TT, \ so we subtract TT from the slope error (which we can \ do as we know the C flag is set) .strl3 LDX #2 \ Draw the edge in pixel 2 of the second dash data block JSR DrawVergeByteRight \ (the third pixel) and draw a fill byte in the third \ dash data block, or abort the drawing and return to \ DrawSegmentEdge if we've finished drawing the edge ADC SS \ Repeat the slope error calculation for pixel 2 BCC strl3 \ of the second dash data block SBC TT .strl4 LDX #1 \ Draw the edge in pixel 1 of the second dash data block JSR DrawVergeByteRight \ (the second pixel) and draw a fill byte in the third \ dash data block, or abort the drawing and return to \ DrawSegmentEdge if we've finished drawing the edge ADC SS \ Repeat the slope error calculation for pixel 1 BCC strl4 \ of the second dash data block SBC TT .strl5 LDX #0 \ Draw the edge in pixel 0 of the second dash data block JSR DrawVergeByteRight \ (the leftmost pixel) and draw a fill byte in the third \ dash data block, or abort the drawing and return to \ DrawSegmentEdge if we've finished drawing the edge ADC SS \ Repeat the slope error calculation for pixel 0 BCC strl5 \ of the second dash data block SBC TT DEC UU \ Decrement UU so we now draw in the left pair of dash \ data blocks (i.e. the first and second dash data \ blocks of the three that we set up) .strl6 LDX #3 \ Draw the edge in pixel 3 of the first dash data block JSR DrawVergeByteLeft \ (the rightmost pixel) and draw a fill byte in the \ second dash data block, or abort the drawing and \ return to DrawSegmentEdge if we've finished drawing \ the edge ADC SS \ Repeat the slope error calculation for pixel 3 BCC strl6 \ of the first dash data block SBC TT .strl7 LDX #2 \ Draw the edge in pixel 2 of the first dash data block JSR DrawVergeByteLeft \ (the third pixel) and draw a fill byte in the second \ dash data block, or abort the drawing and return to \ DrawSegmentEdge if we've finished drawing the edge ADC SS \ Repeat the slope error calculation for pixel 2 BCC strl7 \ of the first dash data block SBC TT .strl8 LDX #1 \ Draw the edge in pixel 1 of the first dash data block JSR DrawVergeByteLeft \ (the second pixel) and draw a fill byte in the second \ dash data block, or abort the drawing and return to \ DrawSegmentEdge if we've finished drawing the edge ADC SS \ Repeat the slope error calculation for pixel 1 BCC strl8 \ of the first dash data block SBC TT .strl9 LDX #0 \ Draw the edge in pixel 0 of the first dash data block JSR DrawVergeByteLeft \ (the leftmost pixel) and draw a fill byte in the \ second dash data block, or abort the drawing and \ return to DrawSegmentEdge if we've finished drawing \ the edge ADC SS \ Repeat the slope error calculation for pixel 0 BCC strl9 \ of the first dash data block SBC TT DEC S \ Decrement S to move (S R) on to the previous page, to \ move it left by two dash data blocks DEC Q \ Decrement Q to move (Q P) on to the previous page, to \ move it left by two dash data blocks DEC NN \ Decrement NN to move (NN MM) on to the previous page, \ to move it left by two dash data blocks DEC UU \ Decrement UU to the number of the previous dash data \ block to the left LDX S \ If (S R) hasn't yet reached the leftmost dash data CPX #HI(dashData0)-1 \ block (i.e. it hasn't gone past block 0, which is at CLC \ the left edge of the screen), then jump back to strl2 BNE strl2 \ to keep drawing (with the C flag cleared, as it gets \ set by the comparison) .strl10 \ If we get here then we have drawn our steep edge to \ the left, all the way to the left edge of the screen, \ so we now need to update the background table for this \ track line \ \ First, though, we need to alter the track line in Y so \ it points to the correct line, which we do by moving \ the track line up or down by one step, in the same \ direction as the edge we are drawing LDA verl1 \ Fetch the instruction that is run at the start of the \ DrawVergeByteLeft routine, which will be an INY or DEY \ instruction (this is the instruction that is run on \ entry into the DrawVergeByteLeft routine, and which \ moves the track line on to the next line in the \ correct up/down direction for the edge we are drawing) STA strl11 \ Store the instruction we just fetched into the next \ address, so we execute the same instruction before \ falling into UpdateBackground .strl11 NOP \ This instruction is modified by the above code to be \ the same INY or DEY that is executed at the start of \ the DrawVergeByteLeft routine, so it moves the track \ line on by one in the correct direction for the edge \ we are drawing \ Fall through into UpdateBackground to update the \ background colour table