Skip to navigation

Scanner/energy row: UpdateScannerNow

Name: UpdateScannerNow [Show more] Type: Subroutine Category: Scanner/energy row Summary: Update the scanner to a new state
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * ProcessPauseKeys calls UpdateScannerNow * UpdateScanner calls UpdateScannerNow * UpdateScanner calls via scan6

Arguments: A The new state of the scanner: * 0 = fill scanner with black * 4 = fill the scanner with static in colour 3 * 8 = fill scanner with green
Other entry points: scan6 Contains an RTS
.UpdateScannerNow STA lastScannerState \ Store the new state of the scanner in lastScannerState \ so we can use this to check for when the scanner state \ changes in the future STA scannerState \ Store the new state of the scanner in scannerState so \ we can refer to it (and possibly change it) during the \ routine \ We start by calculating the screen address of the \ scanner, which is 79 bytes before the start of the \ player's scrolling landscape view (79 bytes represents \ ten character blocks of eight bytes each, less one \ byte, so the scanner address is the second pixel row \ in the character block that's ten blocks from the \ right end of the energy icon and scanner row at the \ top of the screen (the top pixel row contains the \ scanner box border) \ \ viewScreenAddr(1 0) contains the address of the \ latter, so we can simply subtract 79 LDA viewScreenAddr \ Set (A screenAddr) = viewScreenAddr(1 0) - &004F SEC \ = viewScreenAddr(1 0) - 79 SBC #&4F STA screenAddr LDA viewScreenAddr+1 SBC #&00 CMP #&60 \ If the high byte in A < &60 then the new address is BCS scan1 \ before the start of screen memory, so add &20 to the ADC #&20 \ high byte so the address wraps around within the range \ of screen memory between &6000 and &8000 .scan1 STA screenAddr+1 \ Store the high byte of the result, so we now have: \ \ screenAddr(1 0) = viewScreenAddr(1 0) - 79 \ \ with the address wrapped around as required LDA #8 \ The inside portion of the scanner consists of eight STA scannerBlock \ character blocks (the box edges on either side are \ outside of these eight blocks), so set scannerBlock \ to 8 so we can use it to count through the character \ blocks as we draw the scanner .scan2 \ Each character block contains one pixel row at the top \ for the top scanner box edge, then four pixel rows of \ scanner content, followed by another pixel row for the \ bottom scanner box edge \ \ We now draw the four pixel rows of scanner content, \ avoiding drawing over the top and bottom edges LDY #3 \ Set Y = 3 to use as a counter for drawing four pixel \ rows in the drawing loop JSR GetRandomNumber \ Set A to a random number to seed the drawing loop, of \ which we use two bits for each of the four pixel bytes \ we draw JMP scan4 \ Jump to scan4 to join the drawing loop .scan3 LDA scannerStatic \ Shift the random number in scannerStatic to the right LSR A \ by two places LSR A .scan4 STA scannerStatic \ Store the random number in scannerStatic (on the first \ iteration this is the full random number, while on \ subsequent iterations the number is shifted right by \ two places on each loop) AND #%00000011 \ Extract bits 0 and 1 from the random number, so we \ get two different random bits on each iteration and \ a value of A in the range 0 to 3 ORA scannerState \ Add the scanner state to the two random bits to get \ the following: \ \ * If scannerState = 0 then this leaves A in the \ range 0 to 3 \ \ * If scannerState = 4 then this sets A into the \ range 4 to 7 \ \ * If scannerState = 8 then this sets A into the \ range 8 to 11 TAX \ Copy A into X so we can use it as an index into the \ scannerPixelByte table LDA scannerPixelByte,X \ Set A to the X-th pixel byte from the relevant part of \ the scannerPixelByte lookup table, which will return a \ pixel byte containing black, random static or green, \ according to the value of scannerState STA (screenAddr),Y \ Draw the Y-th pixel row for this character block in \ the scanner DEY \ Decrement the pixel row counter in Y BPL scan3 \ Loop back to scan3 to draw the next pixel row until we \ have drawn all four pixel rows \ We now move along the scanner to draw the next \ character block to the right LDA screenAddr \ Set (A screenAddr) = screenAddr(1 0) + 8 CLC ADC #&08 STA screenAddr LDA screenAddr+1 ADC #&00 CMP #&80 \ If the high byte in A >= &80 then the new address is BCC scan5 \ past the end of screen memory, so subtract &20 from SBC #&20 \ the high byte so the address wraps around within the \ range of screen memory between &6000 and &8000 .scan5 STA screenAddr+1 \ Store the high byte of the result, so we now have: \ \ screenAddr(1 0) = screenAddr(1 0) + 8 \ \ with the address wrapped around as required \ \ This updates screenAddr(1 0) to point to the next \ character block to the right, so we move along the \ scanner DEC scannerBlock \ Decrement scannerBlock to move on to the next block \ in the scanner BEQ scan6 \ If we have drawn all eight columns, jump to scan6 to \ return LDA scannerBlock \ If scannerBlock <> 4 then loop back to scan2 to keep CMP #4 \ drawing the scanner BNE scan2 \ If we get here then scannerBlock = 4, so we have drawn \ the left half of the scanner LDA playerTileIsHidden \ If playerTileIsHidden <> 64 then the player's tile is CMP #64 \ not hidden from the Sentinel or sentry doing the scan, BNE scan2 \ so loop back to scan2 to keep drawing the scanner LDA #0 \ If we get here then playerTileIsHidden = 64, so the STA scannerState \ player's tile is hidden from the Sentinel or sentry \ doing the scan \ \ We represent this by only filling the left half of the \ scanner and leaving the right half blank, so set \ scannerState to zero so the rest of the fill routine \ fills the right half with black BEQ scan2 \ Jump back to scan2 to keep drawing the scanner (this \ BEQ is effectively a JMP as A is always zero) .scan6 RTS \ Return from the subroutine