Skip to navigation


Drawing pixels: PIXEL

[Commodore 64 version]

Name: PIXEL [Show more] Type: Subroutine Category: Drawing pixels Summary: Draw a one-pixel dot, two-pixel dash or four-pixel square Deep dive: Drawing pixels in the Commodore 64 version
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * DOEXP calls PIXEL * PTCLS2 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.
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, with bigger distances drawing smaller points: * ZZ < 80 Double-height four-pixel square * 80 <= ZZ <= 143 Single-height two-pixel dash * ZZ > 143 Single-height one-pixel dot
Returns: Y Y is preserved
Other entry points: PX4 Contains an RTS
.PIXEL STY T1 ; Store Y in T1 so we can restore it at the end of the ; subroutine TAY ; Copy the screen y-coordinate from A into 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 CLC ; The ylookup table lets us look up the 16-bit address ADC ylookupl,Y ; of the start of a character row containing a specific STA SC ; pixel, so this fetches the address for the start of LDA ylookuph,Y ; the character row containing the y-coordinate in Y, ADC #0 ; and adds it to the row offset we just calculated in A STA SC+1 ; So SC(1 0) now contains the address of the first pixel ; in the character block containing the (x, y) TYA ; Set Y = Y mod 8, which is the pixel row within the AND #7 ; character block at which we want to draw our pixel TAY ; (as each character block has 8 rows) TXA ; Set X = X mod 8, which is the horizontal pixel number AND #7 ; within the character block where the pixel lies (as TAX ; each pixel line in the character block is 8 pixels ; wide) LDA ZZ ; If distance in ZZ >= 144, then this point is a very CMP #144 ; long way away, so jump to PX3 to fetch a one-pixel BCS PX3 ; point from TWOS and EOR it into SC+Y LDA TWOS2,X ; Otherwise fetch a two-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 ; two-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 ; four-pixel square DEY ; Reduce Y by 1 to point to the pixel row above the one BPL PX3 ; we just plotted, and if it is still positive, jump to ; PX3 to draw our second two-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 .PX3 LDA TWOS2,X ; Fetch a two-pixel dash from TWOS2 and EOR it into this EOR (SC),Y ; second row to make a four-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