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
\ 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 object, 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
```