.spat1 ADD_CYCLES_CLC 4 ; Add 4 to the cycle count JMP SendNametableNow ; Jump to SendNametableNow to start sending nametable ; entries to the PPU immediately .spat2 JMP spat21 ; Jump down to part 4 to start sending pattern data ; until we run out of cycles .SendPatternsToPPU SUBTRACT_CYCLES 182 ; Subtract 182 from the cycle count BMI spat3 ; If the result is negative, jump to spat3 to stop ; sending PPU data in this VBlank, as we have run out of ; cycles (we will pick up where we left off in the next ; VBlank) JMP spat4 ; The result is positive, so we have enough cycles to ; keep sending PPU data in this VBlank, so jump to spat4 ; to start sending pattern data to the PPU .spat3 ADD_CYCLES 141 ; Add 141 to the cycle count JMP RTS1 ; Return from the subroutine (as RTS1 contains an RTS) .spat4 LDA lastPattern,X ; Set A to the number of the last pattern number to send ; for this bitplane BNE spat5 ; If it is zero (i.e. we have no free tiles), then set LDA #255 ; A to 255, so we can use A as an upper limit .spat5 STA lastToSend ; Store the result in lastToSend, as we want to stop ; sending patterns once we have reached this pattern LDA ppuNametableAddr+1 ; Set the high byte of the following calculation: SEC ; SBC nameBufferHiAddr,X ; (ppuToBuffNameHi 0) = (ppuNametableAddr+1 0) STA ppuToBuffNameHi,X ; - (nameBufferHiAddr 0) ; ; So ppuToBuffNameHi for this bitplane contains a high ; byte that we can add to a PPU nametable address to get ; the corresponding address in the nametable buffer LDY patternBufferLo,X ; Set Y to the low byte of the address of the pattern ; buffer for sendingPattern in bitplane X (i.e. the ; address of the next pattern we want to send) ; ; We can use this as an index when copying data from ; the pattern buffer, as we know the pattern buffers ; start on page boundaries, so the low byte of the ; address of the start of each buffer is zero LDA patternBufferHi,X ; Set the high byte of dataForPPU(1 0) to the high byte STA dataForPPU+1 ; of the pattern buffer for this bitplane, as we want ; to copy data from the pattern buffer to the PPU LDA sendingPattern,X ; Set A to the number of the next pattern we want to ; send from the pattern buffer for this bitplane STA patternCounter ; Store the number in patternCounter, so we can keep ; track of which pattern we are sending SEC ; Set A = A - lastToSend SBC lastToSend ; = patternCounter - lastToSend BCS spat1 ; If patternCounter >= lastToSend then we have already ; sent all the patterns (right up to the last one), so ; jump to spat1 to move on to sending the nametable ; entries LDX ppuCtrlCopy ; If ppuCtrlCopy is zero then we are not worried about BEQ spat6 ; keeping PPU writes within VBlank, so jump to spat6 to ; skip the following and crack on with sending as much ; pattern data as we can to the PPU ; The above subtraction underflowed, as it cleared the C ; flag, so the result in A is a negative number and we ; should interpret $BF in the following as a signed ; integer, -65 CMP #$BF ; If A < $BF BCC spat2 ; ; i.e. patternCounter - lastToSend < -65 ; lastToSend - patternCounter > 65 ; ; Then we have 65 or more patterns to sent to the PPU, ; so jump to part 4 (via spat2) to send them until we ; run out of cycles, without bothering to check for the ; last tile (as we have more patterns to send than we ; can fit into one VBlank) ; ; Otherwise we have 64 or fewer patterns to send, so ; fall through into part 2 to send them one pattern at a ; time, checking each one to see if it's the last oneName: SendPatternsToPPU (Part 1 of 6) [Show more] Type: Subroutine Category: PPU Summary: Calculate how many patterns we need to send and jump to the most efficient routine for sending them Deep dive: Drawing vector graphics using NES tilesContext: See this subroutine in context in the source code References: This subroutine is called as follows: * ConsiderSendTiles calls SendPatternsToPPU * SendBuffersToPPU (Part 2 of 3) calls SendPatternsToPPU * SendTilesToPPU calls SendPatternsToPPU
[X]
Macro ADD_CYCLES (category: Drawing the screen)
Add a specified number to the cycle count
[X]
Macro ADD_CYCLES_CLC (category: Drawing the screen)
Add a specified number to the cycle count
[X]
Entry point RTS1 in subroutine ConsiderSendTiles (category: PPU)
Contains an RTS
[X]
Macro SUBTRACT_CYCLES (category: Drawing the screen)
Subtract a specified number from the cycle count
[X]
Entry point SendNametableNow in subroutine SendNametableToPPU (category: PPU)
Send the nametable without checking the cycle count
[X]
Variable dataForPPU in workspace ZP
An address pointing to data that we send to the PPU
[X]
Variable lastPattern in workspace ZP
The number of the last pattern entry to send from pattern buffer 0 to bitplane 0 of the PPU pattern table in the NMI handler
[X]
Variable lastToSend in workspace ZP
The last tile or pattern number to send to the PPU, potentially potentially overwritten by the flags
[X]
Variable nameBufferHiAddr (category: Drawing the screen)
The high bytes of the addresses of the two nametable buffers
[X]
Variable patternBufferHi in workspace WP
(patternBufferHi patternBufferLo) contains the address of the pattern buffer for the pattern we are sending to the PPU from bitplane 0 (i.e. for pattern number sendingPattern in bitplane 0)
[X]
Variable patternBufferLo in workspace ZP
(patternBufferHi patternBufferLo) contains the address of the pattern buffer for the pattern we are sending to the PPU from bitplane 0 (i.e. for pattern number sendingPattern in bitplane 0)
[X]
Variable patternCounter in workspace ZP
Counts patterns as they are written to the PPU pattern table in the NMI handler
[X]
Variable ppuCtrlCopy in workspace ZP
Contains a copy of PPU_CTRL, so we can check the PPU configuration without having to access the PPU
[X]
Variable ppuNametableAddr in workspace ZP
Address of the current PPU nametable
[X]
Variable ppuToBuffNameHi in workspace WP
A high byte that we can add to an address in nametable buffer 0 to get the corresponding address in the PPU nametable
[X]
Variable sendingPattern in workspace ZP
The number of the most recent pattern that was sent to the PPU pattern table by the NMI handler for bitplane 0 (or the number of the first pattern to send if none have been sent)
[X]
Label spat1 is local to this routine
[X]
Label spat2 is local to this routine
[X]
Label spat21 in subroutine SendPatternsToPPU (Part 4 of 6)
[X]
Label spat3 is local to this routine
[X]
Label spat4 is local to this routine
[X]
Label spat5 is local to this routine
[X]
Label spat6 in subroutine SendPatternsToPPU (Part 2 of 6)