Skip to navigation

Revs on the BBC Micro

Drawing the track: DrawShallowToRight

Name: DrawShallowToRight [Show more] Type: Subroutine Category: Drawing the track Summary: Draw a verge edge with a shallow gradient from left to right 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 DrawShallowToRight

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
.DrawShallowToRight LDA jumpShallowRight,X \ Modify the BCC instruction at shlr1 below so that STA shlr1+1 \ it jumps to the destination given in the X-th entry in \ the jumpShallowRight lookup table LDX #128 \ Set X = 128, so we can detect at the end of the \ routine whether X has been altered (which only happens \ if we draw something) LDA SS \ Set A = -SS 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 .shlr1 BCC shlr2 \ This instruction was modified above, so it jumps to \ the address specified in the jumpShallowRight table, \ as follows: \ \ * shlr4 when X = 0 \ * shlr6 when X = 1 \ * shlr8 when X = 2 \ * shlr10 when X = 3 \ * shlr13 when X = 4 \ * shlr15 when X = 5 \ * shlr17 when X = 6 \ * shlr19 when X = 7 \ \ These jump-points start by drawing a pixel byte before \ moving on to the slope error calculations \ \ The following entry points are also supported, though \ these don't appear to be used, as the routine is only \ called with X in the range 0 to 7: \ \ * shlr3 when X = 8 \ * shlr5 when X = 9 \ * shlr7 when X = 10 \ * shlr9 when X = 11 \ * shlr12 when X = 12 \ * shlr14 when X = 13 \ * shlr16 when X = 14 \ * shlr18 when X = 15 \ \ These jump-points start with the slope error \ calculations rather than a call to the draw routine, \ they would presumably omit the first pixel byte of the \ line, were they to be used .shlr2 LDX #128 \ Set X = 128, so we can detect at the end of the \ routine whether X has been altered (which only happens \ if we draw something) .shlr3 \ We start with the slope error calculation for pixel 0 \ of the first dash data block ADC TT \ Set A = A + TT, to add the pitch delta to the slope \ error BCC shlr5 \ If the addition didn't overflow, skip to the next \ pixel to step along the x-axis, as the cumulative \ pitch deltas haven't yet added up to a multiple of SS \ 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 SS \ If we get here then the cumulative pitch deltas in TT \ have added up to a multiple of the yaw delta in SS, so \ we subtract SS from the slope error (which we can do \ as we know the C flag is set) .shlr4 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 \ \ 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 DrawVergeByteLeft will jump to \ StopDrawingEdge to abort this edge and return us two \ routines up the call stack, to DrawSegmentEdge .shlr5 ADC TT \ Repeat the slope error calculation for pixel 1 BCC shlr7 \ of the first dash data block SBC SS .shlr6 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 .shlr7 ADC TT \ Repeat the slope error calculation for pixel 2 BCC shlr9 \ of the first dash data block SBC SS .shlr8 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 .shlr9 ADC TT \ Repeat the slope error calculation for pixel 3 BCC shlr11 \ of the first dash data block SBC SS .shlr10 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 .shlr11 JSR DrawGrassLeft \ If nothing has been drawn in the first dash data \ block (in which case X will still be 128), then fill \ the byte with green grass INC UU \ Increment UU so we now draw in the right pair of dash \ data blocks (i.e. the second and third dash data \ blocks of the three that we set up) .shlr12 ADC TT \ Repeat the slope error calculation for pixel 0 BCC shlr14 \ of the second dash data block SBC SS .shlr13 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 .shlr14 ADC TT \ Repeat the slope error calculation for pixel 1 BCC shlr16 \ of the second dash data block SBC SS .shlr15 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 .shlr16 ADC TT \ Repeat the slope error calculation for pixel 2 BCC shlr18 \ of the second dash data block SBC SS .shlr17 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 .shlr18 ADC TT \ Repeat the slope error calculation for pixel 3 BCC shlr20 \ of the second dash data block SBC SS .shlr19 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, or abort the drawing and return \ to DrawSegmentEdge if we've finished drawing the edge .shlr20 JSR DrawGrassRight \ If nothing has been drawn in the second dash data \ block (in which case X will still be 128), then fill \ the byte with green grass INC S \ Increment S to move (S R) on to the next page, to move \ it right by two dash data blocks INC Q \ Increment Q to move (Q P) on to the next page, to move \ it right by two dash data blocks INC NN \ Increment NN to move (NN MM) on to the next page, to \ move it right by two dash data blocks INC UU \ Increment UU to the number of the next dash data block \ to the right LDX S \ If (S R) hasn't yet reached the rightmost dash data CPX #HI(dashData39)+1 \ block (i.e. it hasn't gone past block 39, which is at BNE shlr2 \ the right edge of the screen), then jump back to shlr2 \ to keep drawing RTS \ Return from the subroutine