Skip to navigation

Revs on the BBC Micro

Screen buffer: GetColour (Part 1 of 3)

Name: GetColour (Part 1 of 3) [Show more] Type: Subroutine Category: Screen buffer Summary: Calculate the colour of a specific pixel byte in the screen buffer
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * DrawObjectEdge (Part 4 of 5) calls GetColour * FillAfterObject calls GetColour

Arguments: Y The track line number of the pixel byte to check blockNumber The dash data block number of the pixel byte to check (Q P) The address of the dash data block containing the pixel byte we want to check
Returns: A The colour of this pixel byte in the screen buffer
IF _ACORNSOFT OR _4TRACKS .GetColour CPY horizonLine \ If Y <= horizonLine then the byte we want to check is BCC gcol1 \ below the horizon, so jump to gcol1 to work out the BEQ gcol1 \ byte's colour LDA horizonLine \ Set A to the track line number of the horizon JSR SetMarker+3 \ Call SetMarker+3 to insert a marker value at the \ horizon line LDA colourPalette+1 \ Otherwise the byte is in the sky, so set A to logical \ colour 1 (blue) from the colour palette RTS \ Return from the subroutine .gcol1 LDA #0 \ Set T = 0, to use for storing the results of the STA T \ following comparisons LDA blockNumber \ Set A to the block number containing the pixel byte \ that we want to check CMP leftVergeStart,Y \ If A >= leftVergeStart for this track line, rotate a ROL T \ 1 into T, otherwise rotate a 0 into T CMP leftTrackStart,Y \ If A >= leftTrackStart for this track line, rotate a ROL T \ 1 into T, otherwise rotate a 0 into T CMP rightVergeStart,Y \ If A >= rightVergeStart for this track line, rotate a ROL T \ 1 into T, otherwise rotate a 0 into T CMP rightGrassStart,Y \ If A >= rightGrassStart for this track line, rotate a LDA T \ 1 into the result, otherwise rotate a 0, and copy the ROL A \ results from all four comparisons into A, so we have: \ \ * Bit 0: 1 if blockNumber >= rightGrassStart \ 0 if blockNumber < rightGrassStart \ \ * Bit 1: 1 if blockNumber >= rightVergeStart \ 0 if blockNumber < rightVergeStart \ \ * Bit 2: 1 if blockNumber >= leftTrackStart \ 0 if blockNumber < leftTrackStart \ \ * Bit 3: 1 if blockNumber >= leftVergeStart \ 0 if blockNumber < leftVergeStart BNE gcol7 \ If A is non-zero, then the block number containing the \ pixel we want to check is greater than at least one \ of the verge edges, so jump to gcol7 \ If we get here then blockNumber is less than all the \ track verge block numbers LDA backgroundColour,Y \ Set A to the background colour for the track line \ containing the pixel we want to check AND #%11101100 \ Extract the following bits: \ \ * Bits 5-7 and 2: records which routine set this \ colour \ \ * Bit 3: contains the verge type that was being \ drawn when this colour was set \ \ * 0 = leftVergeStart, rightVergeStart \ \ * 1 = leftTrackStart, rightGrassStart CMP #%01000000 \ If this colour matches these bits: BEQ gcol2 \ \ * Bits 5-7 and 2 = %010 0 \ \ * Bit 3 = 0 \ \ then the colour was set by UpdateBackground to the \ value in backgroundRight when drawing leftVergeStart \ or rightVergeStart, so jump to gcol2 CMP #%10001000 \ If this colour matches these bits: BEQ gcol2 \ \ * Bits 5-7 and 2 = %100 0 \ \ * Bit 3 = 1 \ \ then the colour was set by UpdateBackground to the \ value in backgroundLeft when drawing leftTrackStart \ or rightGrassStart, so jump to gcol2 CMP #%00000100 \ If this colour matches these bits: BEQ gcol2 \ \ * Bits 5-7 and 2 = %000 1 \ \ * Bit 3 = 0 \ \ then the colour was set by SetVergeBackground when \ drawing leftVergeStart or rightVergeStart, so jump to \ gcol2 LDA rightGrassStart,Y \ Set A to the block number containing the right edge of \ the right verge BPL gcol3 \ If A is positive then jump to gcol3 BMI gcol4 \ Jump to gcol4 to return the background colour for this \ track line as the pixel's colour (this BMI is \ effectively a JMP, as we just passed through a BPL) .gcol2 LDA backgroundColour,Y \ Set A to the background colour for the track line \ containing the pixel we want to check AND #%00010000 \ If bit 4 of the background colour is set, then the BNE gcol3 \ verge being drawn when the colour was set was \ rightVergeStart or rightGrassStart, so jump to gcol3 JSR gcol8 \ Call gcol8 to process the left verge JMP gcol4 \ Jump to gcol4 to return the background colour for this \ track line as the pixel's colour .gcol3 JSR gcol12 \ Call gcol12 to process the right verge .gcol4 LDA backgroundColour,Y \ Set A to the background colour for the track line \ containing the pixel we want to check AND #%00000011 \ Extract the colour number from bits 0-1 of A into X TAX LDA colourPalette,X \ Set A to logical colour X from the colour palette RTS \ Return from the subroutine .gcol5 LDA colourPalette \ Set A to logical colour 0 (black) from the colour \ palette RTS \ Return from the subroutine .gcol6 LDA colourPalette+3 \ Set A to logical colour 3 (green) from the colour \ palette RTS \ Return from the subroutine .gcol7 \ If we get here then the block number containing the \ pixel we want to check is greater than at least one \ of the verge edges, and we have the following: \ \ * Bit 0: 1 if blockNumber >= rightGrassStart \ 0 if blockNumber < rightGrassStart \ \ * Bit 1: 1 if blockNumber >= rightVergeStart \ 0 if blockNumber < rightVergeStart \ \ * Bit 2: 1 if blockNumber >= leftTrackStart \ 0 if blockNumber < leftTrackStart \ \ * Bit 3: 1 if blockNumber >= leftVergeStart \ 0 if blockNumber < leftVergeStart LSR A \ If blockNumber >= rightGrassStart, jump to gcol6 to BCS gcol6 \ return from the subroutine with the colour green LSR A \ If blockNumber >= rightVergeStart, jump to gcol12 BCS gcol12 LSR A \ If blockNumber >= leftTrackStart, jump to gcol5 to BCS gcol5 \ return from the subroutine with the colour black \ If we get here then blockNumber >= leftVergeStart, as \ we only jump to gcol7 if at least one of the four bits \ is set, so by a process of elimination, it must be \ bit 3