Skip to navigation

Elite on the BBC Micro

Drawing pixels: CPIX2 [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 \ already on-screen 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 \ jump to CP1 to draw it 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 \ Refetch 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