.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 subroutineName: UpdateScannerNow [Show more] Type: Subroutine Category: Scanner/energy row Summary: Update the scanner to a new stateContext: 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
[X]
Subroutine GetRandomNumber (category: Maths (Arithmetic))
Set A to a random number
[X]
Variable lastScannerState in workspace Main variable workspace
The state of the scanner the last time that it was updated
[X]
Label scan1 is local to this routine
[X]
Label scan2 is local to this routine
[X]
Label scan3 is local to this routine
[X]
Label scan4 is local to this routine
[X]
Label scan5 is local to this routine
[X]
Entry point scan6 in subroutine UpdateScannerNow (category: Scanner/energy row)
Contains an RTS
[X]
Variable scannerBlock (category: Scanner/energy row)
A counter for the eight character blocks that make up the scanner
[X]
Variable scannerPixelByte (category: Scanner/energy row)
Pixel bytes for the three states of the scanner (black, static and green)
[X]
Variable scannerState (category: Scanner/energy row)
The current state of the scanner (black, static or green)
[X]
Variable scannerStatic (category: Scanner/energy row)
Storage for a random number that's used to generate static in the scanner
[X]
Variable screenAddr in workspace Zero page
Storage for a screen address
[X]
Variable viewScreenAddr in workspace Main variable workspace
The screen address of the player's scrolling landscape view, which is just below the icon and scanner row at the top of the screen