Aviator on the BBC Micro

# Drawing lines: DrawVectorLine (Part 3 of 3)

```       Name: DrawVectorLine (Part 3 of 3)                            [Show more]
Type: Subroutine
Category: Drawing lines
Summary: Plot a pixel at (I, J)
Context: See this subroutine in context in the source code
References: No direct references to this subroutine in this source file

.dvec11

\ When we first arrive here:
\
\   * QQ = 0, where we will tally up the fractional part
\          of the move along the shortest axis
\   * RR = pixel byte table
\   * VV = longest side of delta triangle
\   * PP = 0 (shallow horizontal)
\          VV (steep vertical)
\
\ so we now draw a line from (I, J), moving one pixel
\ at a time along the longest side of the delta triangle

LDA I                  \ Set X = I / 4
LSR A                  \
LSR A                  \ so X is the number of the character block containing
TAX                    \ pixel (I, J), as each character block is 4 pixels wide

LDA J                  \ Set Y = J / 8
LSR A                  \
LSR A                  \ so Y is the number of the character row containing
LSR A                  \ pixel (I, J), as each character row is 8 pixels high
TAY

LDA yLookupLo,Y        \ Set P = Y-th byte of yLookupLo
CLC                    \         + X-th byte of xLookupLo
STA P

LDA yLookupHi,Y        \ Set Q = Y-th byte of yLookupHi
ADC xLookupHi,X        \         + X-th byte of xLookupHi
STA Q                  \       = HI(screen address) + HI(X * 8)

\ So (Q P) is the screen address of the pixel row
\ containing pixel (I, J), out by 8 bytes for each row
\ above or below the top of the dashboard

LDA #159               \ Set Y = 159 - J
SEC                    \
SBC J                  \ so Y is the number of pixels that (I, J) is above
TAY                    \ (+ve) or below (-ve) the top of the dashboard, where a
\ value of 0 is the bottom pixel inside the canopy, and
\ a value of -1 is the white horizontal edge at the
\ bottom of the canopy

LDA I                  \ Set X = bits 0 and 1 of I
AND #%00000011         \       = I mod 4
TAX                    \       = pixel number within the 4-pixel byte

BIT N                  \ If bit 7 of N is set, jump to dvec12 to erase the line
BMI dvec12             \ with EOR logic instead of drawing it with OR logic

LDA RR,X               \ Fetch the X-th byte of RR, which is a pixel byte with
\ the X-th pixel set to white

ORA (P),Y              \ OR it with (Q P) + Y, which is the screen address of
\ the pixel row containing (I, J)
\
\ This will keep all pixels the same except the X-th
\ pixel, which is set to white, so this will plot a
\ pixel at (I, J) when stored in screen memory

\ instructions

.dvec12

LDA RR,X               \ Fetch the X-th byte of RR, which is a pixel byte with
\ the X-th pixel set to white

EOR #%11111111         \ Invert all the bits, so A is now a pixel byte that is
\ all white except for the X-th pixel, which is black

AND (P),Y              \ AND it with (Q P) + Y, which is the screen address of
\ pixel (I, J)
\
\ This will keep all pixels the same except the X-th
\ pixel, which is set to black, so this will erase the
\ pixel at (I, J) when stored in screen memory

.dvec13

STA (P),Y              \ Store the byte in A in screen memory at (Q P) + Y,
\ which sets all four pixels to the pixel pattern in A,
\ which either draws or erases the pixel at (I, J)

DEC VV                 \ Decrement VV to step one pixel along the longer axis

BNE dvec7              \ If VV is non-zero, jump up to dvec7 to calculate the
\ coordinate of the next pixel in the line

RTS                    \ Return from the subroutine
```