Elite on the BBC Micro and NES

# Drawing pixels: CPIX2

## [Acorn Electron version]

```       Name: CPIX2                                                   [Show more]
Type: Subroutine
Category: Drawing pixels
Summary: Draw a single-height dash on the dashboard
Deep dive: Drawing pixels in the Electron version
Context: See this subroutine in context in the source code
Variations: See code variations for this subroutine in the different versions
References: This subroutine is called as follows:
* CPIX4 calls CPIX2
* DOT calls CPIX2

Draw a single-height mode 4 dash (1 pixel high, 4 pixels wide).

Arguments:

X1                   The screen pixel x-coordinate of the dash

Y1                   The screen pixel y-coordinate of the dash

.CPIX2

LDY #128               \ Set SC = 128 for use in the calculation below
STY SC

LDA Y1                 \ Fetch the y-coordinate into A

\ We now calculate the address of the character block
\ containing the pixel (x, y) and put it in SC(1 0), as
\ follows:
\
\   SC = &5800 + (y div 8 * 256) + (y div 8 * 64) + 32
\
\ See the deep dive on "Drawing pixels in the Electron
\ version" for details

LSR A                  \ Set A = A >> 3
LSR A                  \       = y div 8
LSR A                  \       = character row number

\ Also, as SC = 128, we have:
\
\   (A SC) = (A 128)
\          = (A * 256) + 128
\          = 4 * ((A * 64) + 32)
\          = 4 * ((char row * 64) + 32)

STA SC+1               \ Set SC+1 = A, so (SC+1 0) = A * 256
\                           = char row * 256

LSR A                  \ Set (A SC) = (A SC) / 4
ROR SC                 \            = (4 * ((char row * 64) + 32)) / 4
LSR A                  \            = char row * 64 + 32
ROR SC

ADC SC+1               \ Set SC(1 0) = (A SC) + (SC+1 0) + &5800
ADC #&58               \             = (char row * 64 + 32)
STA SC+1               \               + char row * 256
\               + &5800
\
\ which is what we want, so SC(1 0) contains the address
\ of the first visible pixel on the character row
\ containing the point (x, y)

LDA X1                 \ Each character block contains 8 pixel rows, so to get
AND #%11111000         \ the address of the first byte in the character block
\ that we need to draw into, as an offset from the start
\ of the row, we clear bits 0-2

ADC SC                 \ And add the result to SC(1 0) to get the character
STA SC                 \ block on the row we want

BCC P%+4               \ If the addition of the low bytes overflowed, increment
INC SC+1               \ the high byte

\ So SC(1 0) now contains the address of the first pixel
\ in the character block containing the (x, y), taking
\ the screen borders into consideration

LDA Y1                 \ Set Y to just bits 0-2 of the y-coordinate, which will
AND #%00000111         \ be the number of the pixel row we need to draw into
TAY                    \ within the character block

LDA X1                 \ Set X to just bits 0-2 of the x-coordinate, which will
AND #%00000111         \ be the pixel number within the character row we need
TAX                    \ to draw

LDA TWOS,X             \ Fetch a mode 4 1-pixel byte with the pixel position
\ at X

EOR (SC),Y             \ Draw the pixel on-screen using EOR logic, so we can
STA (SC),Y             \ remove it later without ruining the background that's

JSR P%+3               \ Run the following code twice, incrementing X each
\ time, so we draw a two-pixel dash

INX                    \ Increment X to get the next pixel along

LDA TWOS,X             \ Fetch a mode 4 1-pixel byte with the pixel position
\ at X

BPL CP1                \ The CTWOS table is followed by the TWOS2 table, whose
\ first entry is %11000000, so if we have not just
\ fetched that value, then the right pixel of the dash
\ is in the same character block as the left pixel, so

LDA SC                 \ Otherwise the left pixel we drew was at the last
CLC                    \ position of four in this character block, so we add
ADC #8                 \ 8 to the screen address to move onto the next block
STA SC                 \ along (as there are 8 bytes in a character block)

BCC P%+4               \ If the addition we just did overflowed, then increment
INC SC+1               \ the high byte of SC(1 0), as this means we just moved
\ into the right half of the screen row

LDA TWOS,X             \ Re-fetch the mode 4 1-pixel byte from before, as we
\ just overwrote A

.CP1

EOR (SC),Y             \ Draw the dash's right pixel according to the mask in
STA (SC),Y             \ A, using EOR logic, just as above

RTS                    \ Return from the subroutine
```