.spat7 INC dataForPPU+1 ; Increment the high byte of dataForPPU(1 0) to point to ; the start of the next page in memory SUBTRACT_CYCLES 27 ; Subtract 27 from the cycle count JMP spat13 ; Jump down to spat13 to continue sending data to the ; PPU .spat8 JMP spat17 ; Jump down to spat17 to move on to sending nametable ; entries to the PPU .spat9 ; This is the entry point for part 3 LDX patternCounter ; We will now work our way through patterns, sending ; data for each one, so set a counter in X that starts ; with the number of the next pattern to send to the PPU .spat10 SUBTRACT_CYCLES 400 ; Subtract 400 from the cycle count BMI spat11 ; If the result is negative, jump to spat11 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 spat12 ; The result is positive, so we have enough cycles to ; keep sending PPU data in this VBlank, so jump to ; spat12 to send pattern data to the PPU .spat11 ADD_CYCLES 359 ; Add 359 to the cycle count JMP spat30 ; Jump to part 6 to save progress for use in the next ; VBlank and return from the subroutine .spat12 ; If we get here then we send pattern data to the PPU SEND_DATA_TO_PPU 8 ; Send 8 bytes from dataForPPU to the PPU, starting at ; index Y and updating Y to point to the byte after the ; block that is sent BEQ spat7 ; If Y = 0 then the next byte is in the next page in ; memory, so jump to spat7 to point dataForPPU(1 0) at ; the start of this next page, before returning here .spat13 LDA addr ; Set the following: CLC ; ADC #16 ; PPU_ADDR = addr(1 0) + 16 STA addr ; LDA addr+1 ; addr(1 0) = addr(1 0) + 16 ADC #0 ; STA addr+1 ; So PPU_ADDR and addr(1 0) both point to the next STA PPU_ADDR ; tile's pattern in the PPU for this bitplane, as each LDA addr ; tile has 16 bytes of pattern data (8 in each bitplane) STA PPU_ADDR INX ; Increment the tile number in X CPX lastToSend ; If we have reached the last pattern, jump to spat19 BCS spat8 ; (via spat8 and spat17) to move on to sending the ; nametable entries SEND_DATA_TO_PPU 8 ; Send 8 bytes from dataForPPU to the PPU, starting at ; index Y and updating Y to point to the byte after the ; block that is sent BEQ spat16 ; If Y = 0 then the next byte is in the next page in ; memory, so jump to spat16 to point dataForPPU(1 0) at ; the start of this next page, before returning here ; with the C flag clear, ready for the next addition .spat14 LDA addr ; Set the following: ADC #16 ; STA addr ; PPU_ADDR = addr(1 0) + 16 LDA addr+1 ; ADC #0 ; addr(1 0) = addr(1 0) + 16 STA addr+1 ; STA PPU_ADDR ; The addition works because the C flag is clear, either LDA addr ; because we passed through the BCS above, or because we STA PPU_ADDR ; jumped to spat16 and back ; ; So PPU_ADDR and addr(1 0) both point to the next ; tile's pattern in the PPU for this bitplane, as each ; tile has 16 bytes of pattern data (8 in each bitplane) INX ; Increment the tile number in X CPX lastToSend ; If we have reached the last pattern, jump to spat19 BCS spat18 ; (via spat18) to move on to sending the nametable ; entries SEND_DATA_TO_PPU 8 ; Send 8 bytes from dataForPPU to the PPU, starting at ; index Y and updating Y to point to the byte after the ; block that is sent BEQ spat20 ; If Y = 0 then the next byte is in the next page in ; memory, so jump to spat20 to point dataForPPU(1 0) at ; the start of this next page, before returning here ; with the C flag clear, ready for the next addition .spat15 LDA addr ; Set the following: ADC #16 ; STA addr ; PPU_ADDR = addr(1 0) + 16 LDA addr+1 ; ADC #0 ; addr(1 0) = addr(1 0) + 16 STA addr+1 ; STA PPU_ADDR ; The addition works because the C flag is clear, either LDA addr ; because we passed through the BCS above, or because we STA PPU_ADDR ; jumped to spat20 and back ; ; So PPU_ADDR and addr(1 0) both point to the next ; tile's pattern in the PPU for this bitplane, as each ; tile has 16 bytes of pattern data (8 in each bitplane) INX ; Increment the tile number in X CPX lastToSend ; If we have reached the last pattern, jump to spat19 to BCS spat19 ; move on to sending the nametable entries JMP spat10 ; Otherwise we still have patterns to send, so jump back ; to spat10 to check the cycle count and potentially ; send the next batch .spat16 INC dataForPPU+1 ; Increment the high byte of dataForPPU(1 0) to point to ; the start of the next page in memory SUBTRACT_CYCLES 29 ; Subtract 29 from the cycle count CLC ; Clear the C flag so the addition works at spat14 JMP spat14 ; Jump up to spat14 to continue sending data to the PPU .spat17 ADD_CYCLES_CLC 224 ; Add 224 to the cycle count JMP spat19 ; Jump to spat19 to move on to sending nametable entries ; to the PPU .spat18 ADD_CYCLES_CLC 109 ; Add 109 to the cycle count .spat19 ; If we get here then we have sent the last tile's ; pattern data, so we now move on to sending the ; nametable entries to the PPU ; ; Before jumping to SendNametableToPPU, we need to store ; the following variables, so they can be picked up by ; the new routine: ; ; * (patternBufferHi patternBufferLo) ; ; * sendingPattern ; ; Incidentally, these are the same variables that we ; save when storing progress for the next VBlank, which ; makes sense STX patternCounter ; Store X in patternCounter to use below NOP ; This looks like code that has been removed LDX nmiBitplane ; Set (patternBufferHi patternBufferLo) for this STY patternBufferLo,X ; bitplane to dataForPPU(1 0) + Y (which is the address LDA dataForPPU+1 ; of the next byte of data to be sent from the pattern STA patternBufferHi,X ; buffer) LDA patternCounter ; Set sendingPattern for this bitplane to the value of STA sendingPattern,X ; X we stored above (which is the number / 8 of the next ; pattern to be sent from the pattern buffer) JMP SendNametableToPPU ; Jump to SendNametableToPPU to start sending the ; nametable to the PPU .spat20 INC dataForPPU+1 ; Increment the high byte of dataForPPU(1 0) to point to ; the start of the next page in memory SUBTRACT_CYCLES 29 ; Subtract 29 from the cycle count CLC ; Clear the C flag so the addition works at spat15 JMP spat15 ; Jump up to spat14 to continue sending data to the PPUName: SendPatternsToPPU (Part 3 of 6) [Show more] Type: Subroutine Category: PPU Summary: Send pattern data to the PPU for one pattern at a time, checking after each one to see if is the last one Deep dive: Drawing vector graphics using NES tilesContext: See this subroutine in context in the source code References: No direct references to this subroutine in this source file
[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]
Configuration variable PPU_ADDR = $2006
The PPU address register, which is used to set the destination address within the PPU when sending data to the PPU
[X]
Macro SEND_DATA_TO_PPU (category: Drawing the screen)
Send a specified block of memory to the PPU
[X]
Macro SUBTRACT_CYCLES (category: Drawing the screen)
Subtract a specified number from the cycle count
[X]
Subroutine SendNametableToPPU (category: PPU)
Send the tile nametable to the PPU if there are enough cycles left in the current VBlank
[X]
Variable dataForPPU in workspace ZP
An address pointing to data that we send to the PPU
[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 nmiBitplane in workspace ZP
The number of the bitplane (0 or 1) that is currently being processed in the NMI handler during VBlank
[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 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 spat10 is local to this routine
[X]
Label spat11 is local to this routine
[X]
Label spat12 is local to this routine
[X]
Label spat13 is local to this routine
[X]
Label spat14 is local to this routine
[X]
Label spat15 is local to this routine
[X]
Label spat16 is local to this routine
[X]
Label spat17 is local to this routine
[X]
Label spat18 is local to this routine
[X]
Label spat19 is local to this routine
[X]
Label spat20 is local to this routine
[X]
Label spat30 in subroutine SendPatternsToPPU (Part 6 of 6)
[X]
Label spat7 is local to this routine
[X]
Label spat8 is local to this routine