Skip to navigation

Revs on the BBC Micro

Drawing the track: DrawVergeByteRight

Name: DrawVergeByteRight [Show more] Type: Subroutine Category: Drawing the track Summary: Draw two bytes into the screen buffer in the second and third dash data blocks for the edge Deep dive: Drawing the track verges
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * DrawShallowToLeft calls DrawVergeByteRight * DrawShallowToRight calls DrawVergeByteRight * DrawSteepToLeft calls DrawVergeByteRight * DrawSteepToRight calls DrawVergeByteRight

This routine draws a single byte of a verge edge in the second dash data block of the three that we set up in DrawSegmentEdge. It also draws a second byte to the right, in the third dash data block, using the fill colour so the screen gets filled to the right of the verge edge.
Arguments: X The pixel number of the edge within the pixel byte, with 0 being the first pixel (at the left end of the byte) to 3 as the last pixel (at the right end of the byte) Y The track line to draw on (0 to 79) 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 (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
Returns: C flag The C flag is cleared Y Incremented or decremented, depending on which way the verge goes (decremented if the verge goes down, incremented is it goes up) A A is unchanged
.DrawVergeByteRight STA II \ Store A in II so we can retrieve it later .verb1 NOP \ This instruction is modified by the DrawSegmentEdge \ routine, to be NOP, INY or DEY, to move on to the next \ track line as appropriate CPY RR \ If Y = RR, we have reached the pitch angle of the BEQ StopDrawingEdge \ current edge, so jump to StopDrawingEdge to stop \ drawing the edge LDA UU \ Set A = UU, the number of the dash data block where we \ want to draw .verb2 STA &7000,Y \ This instruction is modified by the DrawVergeEdge \ routine to point to the relevant table for the edge \ we are drawing: \ \ * leftVergeStart \ \ * leftTrackStart \ \ * rightVergeStart \ \ * rightGrassStart \ \ So this stores the dash data block number for the \ previous edge in the relevant verge table for track \ line Y LDA (P),Y \ Set A to the current contents of track line Y in \ (Q P), which is the dash data block containing the \ previous edge BNE verb6 \ If the current contents of the screen buffer is \ non-zero, then it already contains something, so jump \ to verb6 to merge our edge with the existing pixels LDA objectPalette,X \ Set A to the X-th entry from the object palette, which \ contains a background colour byte with the first X \ pixels in the foreground colour .verb3 STA (P),Y \ Store the pixel byte in the dash data block LDA JJ \ Store the pixel byte in JJ in the next dash data block STA (MM),Y \ to fill the pixel byte to the right of the edge byte \ with the background colour in JJ (so this fills to the \ right of the edge as we draw it) .verb4 LDA II \ Retrieve the value of A we stored above, so A is \ unchanged by the routine .verb5 INY \ This instruction is modified by the DrawSegmentEdge \ routine, to be NOP, INY or DEY, to move on to the next \ track line as appropriate CLC \ Clear the C flag RTS \ Return from the subroutine .verb6 \ If we get here then the pixel byte we are drawing into \ is non-empty CPY #44 \ If Y >= 44, jump to verb7 to skip the following check, BCS verb7 \ as offsets of 44 and above are always within a dash \ data block JSR CheckDashData \ Check whether offset Y points to dash data within \ block UU, clearing the C flag if it does BCC verb4 \ If offset Y does not point to dash data, jump to verb4 \ to return from the subroutine without drawing anything .verb7 \ If we get here then the pixel byte we are drawing into \ is non-empty and is a valid part of the screen buffer CMP #&55 \ If the current contents of the screen buffer is not BNE verb8 \ &55, then it does not denote black, so skip the \ following LDA #0 \ The current contents of the screen buffer is &55, \ which denotes black, so set A to 0 so we merge with a \ pixel byte of black .verb8 AND pixelsToLeft,X \ AND the current contents with the X-th pixel mask from \ pixelsToLeft, which is a pixel byte with all the \ pixels set to the left of the X-th pixel, so this \ clears all pixels in the existing screen buffer byte \ from the X-th pixel and to the right \ \ In other words, this clears the track edge and to the \ right, but keeps content to the left of the edge ORA vergeEdgeRight,X \ We set up vergeEdgeRight to contain the pixel bytes \ from objectPalette, but masked to only include the \ rightmost 4, 3, 2 and 1 pixels, so this inserts the \ edge and all the pixels to the right of the edge into \ the pixels that we just cleared, thus drawing the edge \ on top of what's already on-screen BNE verb3 \ If the resulting pixel byte in A is non-zero, then we \ are ready to poke it into the screen buffer, so jump \ to verb3 LDA #&55 \ The resulting pixel byte is zero, which is a black \ pixel byte, and we represent this in the screen buffer \ with &55, so set A to &55 so we poke this into the \ screen buffer instead of zero BNE verb3 \ Jump to verb3 (this BNE is effectively a JMP as A is \ never zero)