Elite on the BBC Micro and NES

Drawing pixels: PIXEL

[Acorn Electron version]

```       Name: PIXEL                                                   [Show more]
Type: Subroutine
Category: Drawing pixels
Summary: Draw a 1-pixel dot, 2-pixel dash or 4-pixel square
Deep dive: Drawing monochrome pixels in mode 4
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:
* DOEXP calls PIXEL
* TT22 calls PIXEL
* PIXEL2 calls via PX4

Draw a point at screen coordinate (X, A) with the point size determined by the
distance in ZZ. This applies to the top part of the screen (the space view).

Arguments:

X                    The screen x-coordinate of the point to draw

A                    The screen y-coordinate of the point to draw

ZZ                   The distance of the point (further away = smaller point)

Returns:

Y                    Y is preserved

Other entry points:

PX4                  Contains an RTS

.PIXEL

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

STY T1                 \ Store Y in T1

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

TAY                    \ Copy A into Y, for use later

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

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)

TXA                    \ 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

TYA                    \ Set Y = Y AND %111
AND #%00000111
TAY

TXA                    \ Set X = X AND %111
AND #%00000111
TAX

LDA ZZ                 \ If distance in ZZ >= 144, then this point is a very
CMP #144               \ long way away, so jump to PX14 to fetch a 2-pixel dash
BCS PX14               \ from TWOS2 and EOR it into SC+Y

LDA TWOS2,X            \ Otherwise fetch a 2-pixel dash from TWOS2 and EOR it
EOR (SC),Y             \ into SC+Y
STA (SC),Y

LDA ZZ                 \ If distance in ZZ >= 80, then this point is a medium
CMP #80                \ distance away, so jump to PX13 to stop drawing, as a
BCS PX13               \ 2-pixel dash is enough

\ Otherwise we keep going to draw another 2 pixel point
\ either above or below the one we just drew, to make a
\ 4-pixel square

DEY                    \ Reduce Y by 1 to point to the pixel row above the one
BPL PX14               \ we just plotted, and if it is still positive, jump to
\ PX14 to draw our second 2-pixel dash

LDY #1                 \ Reducing Y by 1 made it negative, which means Y was
\ 0 before we did the DEY above, so set Y to 1 to point
\ to the pixel row after the one we just plotted

.PX14

LDA TWOS2,X            \ Fetch a 2-pixel dash from TWOS2 and EOR it into this
EOR (SC),Y             \ second row to make a 4-pixel square
STA (SC),Y

.PX13

LDY T1                 \ Restore Y from T1, so Y is preserved by the routine

.PX4

RTS                    \ Return from the subroutine
```