IF _ACORNSOFT OR _4TRACKS .FillAfterObject LDA blockNumber \ Set A to the dash data block number in blockNumber CMP #40 \ If A >= 40 then this is not a valid dash data block BCS edge12 \ number, so jump to edge12 to return from the \ subroutine \ We now calculate the start address of dash data block \ A, which will be at dashData + &80 * A (because the \ dash data blocks occur every &80 bytes from dashData) \ \ We do this using the following simplification: \ \ dashData + &80 * A \ = dashData + 256 / 2 * A \ = HI(dashData) << 8 + LO(dashData) + A << 7 \ \ LO(dashData) happens to be zero (as dashData = &3000), \ so we can keep going: \ \ = HI(dashData) << 8 + A << 7 \ = (HI(dashData) << 1 + A) << 7 \ = ((HI(dashData) << 1 + A) << 8) >> 1 \ \ In other words, if we build a 16-bit number with the \ high byte set to HI(dashData) << 1 + A, and then shift \ the whole thing right by one place, we have our result \ \ We do this below, storing the 16-bit number in (Q P) CLC \ Set A = A + HI(dashData) << 1 ADC #HI(dashData)<<1 \ \ so our 16-bit number is (A 0), and we want to shift \ right by one place LSR A \ Shift (A 0) right by 1, shifting bit 0 of A into the \ C flag STA Q \ Set Q = A, to store the high byte of the result in Q STA edge9+2 \ Modify the high byte of the address in the instruction \ at edge9 to Q LDA #0 \ Shift the C flag into bit 7 of A, so A now contains ROR A \ the low byte of our result STA P \ Set P = A, to store the low byte of the result in P, \ giving the result we wanted in (Q P) STA edge9+1 \ Modify the low byte of the address in the instruction \ at edge9 to P, so if we have the following: \ \ LDX &3000,Y -> LDX #(Q P),Y \ \ This is pseudo-code, but it means we have modified the \ instruction to load the Y-th byte from the dash data \ block address we just calculated, i.e. load the Y-th \ byte of dash data block A (i.e. dash data block \ blockNumber) LDY blockOffset \ Set Y to the dash data offset for the edge to draw LDA (P),Y \ Set W to the byte in the dash data offset from this STA W \ block, which is the byte before the actual dash data LDA #&AA \ Store &AA in this byte, so it can act as a marker for STA (P),Y \ when we work our way through the data below LDY topTrackLine \ Set Y to the number of the top track line, so we work \ down from this byte within the data block, moving down \ in memory until we reach the marker \ \ So we are working down the screen, going backwards in \ memory from byte topTrackLine to the marker that we \ just placed at the start of the dash data JMP edge4 \ Jump into the following loop at the entry point edge4 \ to draw the fill from the top byte to the bottom byte .edge1 \ This part of the loop, between edge1 and edge5, is \ only used by the GetTyreDashEdge routine, which \ modifies the loop to copy pixels instead of filling \ them CMP #&55 \ If the current byte is &55, then this represents black BNE edge2 \ (colour 0), so set A = 0 so it's the correct pixel LDA #0 \ byte for the current buffer contents .edge2 STA (R),Y \ Store the pixel byte we fetched from the screen buffer \ in the Y-th byte of (S R), which copies the byte from \ the screen buffer into the address set up in the \ CopyTyreDashEdges routine (i.e. this copies the edges \ into tyreRightEdge or dashRightEdge) .edge3 DEY \ Decrement the byte counter to move down the screen \ within the dash data block .edge4 LDA (P),Y \ Fetch the Y-th byte from the dash data block BNE edge10 \ If the current byte in the screen buffer is non-zero, \ then it is not empty, so jump to edge10 to move on to \ the next byte, as we only need to fill empty bytes .edge5 JSR GetColour \ The current byte in the screen buffer is zero, which \ means it should inherit the colour of the byte to the \ left, so call GetColour to work out what this byte's \ colour would be on-screen, and put it into A BNE edge7 \ If the colour byte is non-zero, skip the following \ instruction .edge6 LDA #&55 \ Set A = &55, which is the value we use to represent \ colour 0 (black) in the screen buffer \ \ Gets modified by the GetTyreDashEdge routine: \ \ * LDA #0 when GetTyreDashEdge is called with \ A = 0 \ \ * LDA #&55 when GetTyreDashEdge is called with \ A = &55 .edge7 STA (P),Y \ Draw the resulting pixel byte into the screen buffer \ by writing it to the Y-th byte of the relevant dash \ data block \ \ Gets modified by the GetTyreDashEdge routine: \ \ * STA (R),Y when GetTyreDashEdge is called with \ X = LO(R) \ \ * STA (P),Y when GetTyreDashEdge is called with \ X = LO(P) .edge8 DEY \ Decrement the byte counter to move down the screen \ within the dash data block .edge9 LDX &3000,Y \ Set X to the Y-th byte in the screen buffer, which is \ the next byte down the screen after the one we just \ draw \ \ Gets modified at the start of part 2 as follows: \ \ LDX &3000,Y -> LDX #(Q P),Y \ \ In other words, we have modified the instruction to \ load the Y-th byte from the dash data block address \ for the edge we are drawing, i.e. load the Y-th byte \ of dash data block blockNumber BEQ edge7 \ If the next byte down the screen is zero, then loop \ back to edge7 to draw the edge in this byte as well, \ so we keep drawing the edge downwards while the \ existing contents of the screen buffer are empty TXA \ The next byte down the screen is non-zero, so copy the \ value into A .edge10 CMP #&AA \ Check to see if the next byte is the marker for the \ bottom of the edge .edge11 BNE edge3 \ If this is not the marker for the bottom of the edge, \ loop back to edge3 to draw the next pixel byte over \ the top of this non-empty byte in the screen buffer \ \ Gets modified by the GetTyreDashEdge routine: \ \ * BNE edge1 when GetTyreDashEdge is called with \ Y = &DF \ \ * BNE edge3 when GetTyreDashEdge is called with \ Y = &E7 LDA #0 \ Overwrite the &AA value with 0 to remove the marker STA (P),Y CPY blockOffset \ If Y <> blockOffset then this can't be our marker, as BNE edge5 \ the marker is on line blockOffset, so jump back to \ edge5 to merge this byte with the correct background \ colour \ If we get here then we have reached our marker at the \ bottom of the edge LDA W \ Restore the entry in the dash data block that we STA (P),Y \ overwrote with the marker, whose original contents we \ stored in W .edge12 RTS \ Return from the subroutine ENDIFName: FillAfterObject [Show more] Type: Subroutine Category: Drawing objects Summary: Fill the block to the right of an object Deep dive: Creating objects from edgesContext: See this subroutine in context in the source code References: This subroutine is called as follows: * DrawObjectEdge (Part 4 of 5) calls FillAfterObject
Arguments: blockNumber The dash data block number to draw in (i.e. the block to the right of the object) blockOffset The dash data offset for the bottom of the edge to draw topTrackLine Top track line number, i.e. the number of the start byte in the dash data block
[X]
Subroutine GetColour (Part 1 of 3) (category: Screen buffer)
Calculate the colour of a specific pixel byte in the screen buffer
[X]
Variable blockNumber in workspace Zero page
The dash data block number for the current edge
[X]
Variable blockOffset in workspace Zero page
The dash data offset for the current edge
[X]
Configuration variable dashData = &3000
The address of the first code block that gets swapped in and out of screen memory, along with parts of the dashboard image
[X]
Label edge10 is local to this routine
[X]
Label edge12 is local to this routine
[X]
Label edge2 is local to this routine
[X]
Label edge3 is local to this routine
[X]
Label edge4 is local to this routine
[X]
Label edge5 is local to this routine
[X]
Label edge7 is local to this routine
[X]
Label edge9 is local to this routine
[X]
Variable topTrackLine in workspace Zero page
The top track line for the current object part