Skip to navigation

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