Skip to navigation

Revs on the BBC Micro

Drawing objects: FillAfterObjectSup

Name: FillAfterObjectSup [Show more] Type: Subroutine Category: Drawing objects Summary: Fill the block to the right of an object Deep dive: Creating objects from edges
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * DrawObjectEdge (Part 4 of 5) calls FillAfterObjectSup

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
IF _SUPERIOR OR _REVSPLUS .FillAfterObjectSup 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 sedg10 \ number, so jump to sedg10 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 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) 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 sedg9 \ Jump into the following loop at the entry point sedg9 \ to draw the fill from the top byte to the bottom byte .sedg1 \ This part of the loop, between segd1 and segd5, is \ only used by the GetTyreDashEdgeSup 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 sedg2 \ (colour 0), so set A = 0 so it's the correct pixel LDA #0 \ byte for the current buffer contents .sedg2 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) .sedg3 DEY \ Decrement the track line counter in Y to move down to \ the next pixel line on-screen CPY blockOffset \ If Y = blockOffset then we have reached the bottom of BEQ sedg10 \ the objec, so jump back to sedg10 to return from the \ subroutine .sedg4 LDA (P),Y \ Fetch the current byte from the screen buffer .sedg5 BNE sedg8 \ If the current byte in the screen buffer is non-zero, \ then it is not empty, so jump to sedg8 to move on to \ the next byte, as we only need to fill empty bytes \ \ Gets modified by the GetTyreDashEdge routine: \ \ * BNE sedg1 when GetTyreDashEdge is called with \ Y = &EF \ \ * BNE sedg8 when GetTyreDashEdge is called with \ Y = &09 JSR GetColourSup \ The current byte in the screen buffer is zero, which \ means it should inherit the colour of the byte to the \ left, so call GetColourSup to work out what this \ byte's colour would be on-screen, and put it into A BNE sedg7 \ If the result is non-zero, then jump to sedg7 to skip \ the following instruction .sedg6 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 .sedg7 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) .sedg8 DEY \ Decrement the track line counter in Y to move down to \ the next pixel line on-screen .sedg9 \ This is the entry point for the loop, which is between \ sedg4 and the loop's end logic in the next instruction CPY blockOffset \ If Y <> blockOffset then we haven't reached the bottom BNE sedg4 \ of the object yet, so jump back to sedg4 to fill the \ next byte down .sedg10 RTS \ Return from the subroutine ENDIF