This code appears in the following versions (click to see it in the source code):
Code variations between these versions are shown below.
Name: PIXEL Type: Subroutine Category: Drawing pixels
Arguments:
This variation is blank in the 6502 Second Processor version.
Tap on a block to expand it, and tap it again to revert.
.PIXEL
This variation is blank in the Cassette, Disc (flight), Disc (docked), Master and Electron versions.
LDY #0 \ Set Q to byte #0 from the block pointed to by OSSC, LDA (OSSC),Y \ which contains the size of the pixel buffer STA Q INY \ Increment Y to 2, so y now points at the data for the INY \ first pixel in the command block .PXLO LDA (OSSC),Y \ Set P to byte #2 from the Y-th pixel block in OSSC, STA P \ which contains the point's distance value (ZZ) AND #7 \ If ZZ is a multiple of 8 (which will be the case for BEQ PX5 \ pixels sent by the parasite's PIXEL routine), jump to \ PX5 to draw stardust particles and dots on the \ Long-range Chart \ Otherwise this pixel was sent by the parasite's PIXEL3 \ routine and will have an odd value of ZZ, and we use \ the distance value to determine the dot's colour and \ size, as this is an explosion particle TAX \ Set S to the ZZ-th value from the PXCL table, to get LDA PXCL,X \ the correct colour byte for this pixel, depending on STA S \ the distance INY \ Increment Y to 3 LDA (OSSC),Y \ Set X to byte #3 from the Y-th pixel block in OSSC, TAX \ which contains the pixel's x-coordinate INY \ Increment Y to 4 LDA (OSSC),Y \ Set Y to byte #4 from the Y-th pixel block in OSSC, STY T1 \ which contains the pixel's y-coordinate, and store Y, TAY \ the index of this pixel's y-coordinate, in T1, so we \ can restore it at the end of the subroutine
This variation is blank in the 6502 Second Processor version.
Tap on a block to expand it, and tap it again to revert.
The Master version doesn't draw single-pixel dots, as it omits the logic to check for distant dots and plot them using one pixel. The Long-range Chart is a good example of this, where the Master version draws a two-pixel yellow dash for every system.
See below for more variations related to this code.
This variation is blank in the 6502 Second Processor and Master versions.
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)
Dots in the Electron version, such as those shown for stardust particles, are always two pixels wide, while the cassette and disc versions also support one-pixel dots in their monochrome space views.
This variation is blank in the 6502 Second Processor and Master versions.
Tap on a block to expand it, and tap it again to revert.
Code variation 9 of 18
See variation 7 above for details.
Tap on a block to expand it, and tap it again to revert.
Code variation 10 of 18
See variation 7 above for details.
This variation is blank in the Cassette, Disc (flight), Disc (docked) and Electron versions.
Tap on a block to expand it, and tap it again to revert.
This variation is blank in the Cassette, Disc (flight), Disc (docked) and Electron versions.
Tap on a block to expand it, and tap it again to revert.
This variation is blank in the Cassette, Disc (flight), Disc (docked) and Electron versions.
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 \ already on-screen
This variation is blank in the Cassette, Disc (flight), Disc (docked) and Electron versions.
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 \ already on-screen DEY \ Reduce Y by 1 to point to the pixel row above the one BPL P%+4 \ we just plotted, and if it is still positive, skip the \ next instruction 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 \ We now draw our second dash
This variation is blank in the Cassette, Disc (flight), Disc (docked) and Electron versions.
Tap on a block to expand it, and tap it again to revert.
This variation is blank in the Cassette, Disc (flight), Disc (docked) and Electron versions.
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 \ already on-screen
This variation is blank in the Cassette, Disc (flight), Disc (docked) and Electron versions.
Tap on a block to expand it, and tap it again to revert.
This variation is blank in the Cassette, Disc (flight), Disc (docked), Master and Electron versions.
.PX3 \ If we get here, the dot is a long way away (at a \ distance that is > 127), so we want to draw a \ one-pixel dot LDA TWOS,X \ Fetch a mode 1 one-pixel byte with the pixel set as AND S \ in X, and AND with the colour byte we fetched into S \ so that pixel takes on the colour we want to draw \ (i.e. A is acting as a mask on the colour byte) 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 \ already on-screen LDY T1 \ Set Y to the index of this pixel's y-coordinate byte \ in the command block, which we stored in T1 above INY \ Increment Y, so it now points to the first byte of \ the next pixel in the command block CPY Q \ If the index hasn't reached the value in Q (which BNE PXLO \ contains the size of the pixel buffer), loop back to \ PXLO to draw the next pixel in the buffer RTS \ Return from the subroutine .PX5 \ If we get here then the pixel's distance value (ZZ) is \ a multiple of 8, as set by the parasite's PIXEL \ routine INY \ Increment Y to 3 LDA (OSSC),Y \ Set X to byte #3 from the Y-th pixel block in OSSC, TAX \ which contains the pixel's x-coordinate INY \ Increment Y to 4 LDA (OSSC),Y \ Set Y to byte #4 from the Y-th pixel block in OSSC, STY T1 \ which contains the pixel's y-coordinate, and store Y, TAY \ the index of this pixel's y-coordinate, in T1, so we \ can restore it at the end of the subroutine LDA ylookup,Y \ Look up the page number of the character row that STA SC+1 \ contains the pixel with the y-coordinate in Y, and \ store it in the high byte of SC(1 0) at SC+1 TXA \ Each character block contains 8 pixel rows, so to get AND #%11111100 \ the address of the first byte in the character block ASL A \ that we need to draw into, as an offset from the start \ of the row, we clear bits 0-1 and shift left to double \ it (as each character row contains two pages of bytes, \ or 512 bytes, which cover 256 pixels). This also \ shifts bit 7 of the x-coordinate into the C flag STA SC \ Store the address of the character block in the low \ byte of SC(1 0), so now SC(1 0) points to the \ character block we need to draw into BCC P%+4 \ If the C flag is clear then skip the next instruction INC SC+1 \ The C flag is set, which means bit 7 of X1 was set \ before the ASL above, so the x-coordinate is in the \ right half of the screen (i.e. in the range 128-255). \ Each row takes up two pages in memory, so the right \ half is in the second page but SC+1 contains the value \ we looked up from ylookup, which is the page number of \ the first memory page for the row... so we need to \ increment SC+1 to point to the correct page TYA \ Set Y = Y mod 8, which is the pixel row within the AND #7 \ character block at which we want to draw the start of TAY \ our line (as each character block has 8 rows) TXA \ Copy bits 0-1 of the x-coordinate to bits 0-1 of X, AND #%00000011 \ which will now be in the range 0-3, and will contain TAX \ the two pixels to show in the character row LDA P \ Fetch the pixel's distance from P CMP #80 \ If the pixel's ZZ distance is >= 80, then the dot is BCS PX6 \ a medium distance away, so jump to PX6 to draw a \ single pixel LDA TWOS2,X \ Fetch a mode 1 two-pixel byte with the pixels set as AND #WHITE \ in X, and AND with #WHITE to make it white (i.e. \ cyan/red) 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 \ already on-screen DEY \ Reduce Y by 1 to point to the pixel row above the one BPL P%+4 \ we just plotted, and if it is still positive, skip the \ next instruction 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 \ We now draw our second dash .PX6 LDA TWOS2,X \ Fetch a mode 1 two-pixel byte with the pixels set as AND #WHITE \ in X, and AND with #WHITE to make it white (i.e. \ cyan/red) 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 \ already on-screen LDY T1 \ Set Y to the index of this pixel's y-coordinate byte \ in the command block, which we stored in T1 above INY \ Increment Y, so it now points to the first byte of \ the next pixel in the command block CPY Q \ If the index has reached the value in Q (which BEQ P%+5 \ contains the size of the pixel buffer), skip the next \ instruction JMP PXLO \ We haven't reached the end of the buffer, so loop back \ to PXLO to draw the next pixel in the buffer RTS \ Return from the subroutine