Hi All,
I'm nearing completion of my PONG game but I'm having trouble understanding how to properly wait for VBLANK. When my game is over I am blanking the screen and loading a new name table in that says game over.
The problem is, when I blank the screen and turn it back on, rendering is starting halfway down the screen instead of at the beginning of the screen where it should be.
The code I'm using to load in the new screen is this.
This code actually works but it shouldn't, for two reasons based on my understanding. The first is the VblankWaitLoop at the bottom of the screen is improperly coded. Its actually an infinite loop. This causes the screen to render in the appropriate location, but why?
In my mind, I should be using this code for the VblankWaitLoop
But the code that makes sense to me does not actually work. Any thoughts guys?
I'm nearing completion of my PONG game but I'm having trouble understanding how to properly wait for VBLANK. When my game is over I am blanking the screen and loading a new name table in that says game over.
The problem is, when I blank the screen and turn it back on, rendering is starting halfway down the screen instead of at the beginning of the screen where it should be.
The code I'm using to load in the new screen is this.
Code:
UpdateToGameOver:
;; Turn Screen Off
LDA #%00000000
STA $2001
JSR BlankSprites
;; Load Palettes for Game Area
LoadPalettes3:
LDA $2002 ; read PPU status to reset the high/low latch
LDA #$3F
STA $2006 ; write the high byte of $3F00 address
LDA #$00
STA $2006 ; write the low byte of $3F00 address
LDX #$00 ; start out at 0
LoadPalettesLoop3:
LDA palette3, x ; load data from address (palette + the value in x)
; 1st time through loop it will load palette+0
; 2nd time through loop it will load palette+1
; 3rd time through loop it will load palette+2
; etc
STA $2007 ; write to PPU
INX ; X = X + 1
CPX #$10 ; Compare X to hex $10, decimal 16 - copying 16 bytes = 4 sprites
BNE LoadPalettesLoop3 ; Branch to LoadPalettesLoop if compare was Not Equal to zero
; if compare was equal to 32, keep going down
LoadGameOverBackground:
LDA $2002 ;Read PPU status to reset hi/lo latch
LDA #$20
STA $2006 ;write the high byte of $2000 address
LDA #$00
STA $2006 ;write the low byte of the $2000 address
LoadGameOverLoop:
LDA #$00
STA pointer2 ; put the low byte of the address of background into pointer --- This equals 00?
LDA #HIGH(gameoverscreen) ;What does the #HIGH signify? Its not a constant. Is this pulling the tile number from the nametable below?
STA pointer2+1 ; put the high byte of the address into pointer. Do we now have $2400?
LDX #$00 ; start at pointer + 0
LDY #$00
OutsideLoopGameOver:
InsideLoopGameOver:
LDA [pointer2], y ; copy one background byte from address in pointer plus Y
STA $2007 ; this runs 256 * 4 times
INY ; inside loop counter
CPY #$00
BNE InsideLoopGameOver ; run the inside loop 256 times before continuing down
INC pointer2+1 ; low byte went 0 to 256, so high byte needs to be changed now
INX
CPX #$04
BNE OutsideLoopGameOver ; run the outside loop 256 times before continuing down
;;Remove Sprites OnScreen By Filling Their Tile Values with Blank Sprites
;;use this loop to give the ppu time to VBLANK
VblankWaitLoop:
LDX #$30
DEX
CPX #$01
BNE VblankWaitLoop
GameOverDone:
RTS
;; Turn Screen Off
LDA #%00000000
STA $2001
JSR BlankSprites
;; Load Palettes for Game Area
LoadPalettes3:
LDA $2002 ; read PPU status to reset the high/low latch
LDA #$3F
STA $2006 ; write the high byte of $3F00 address
LDA #$00
STA $2006 ; write the low byte of $3F00 address
LDX #$00 ; start out at 0
LoadPalettesLoop3:
LDA palette3, x ; load data from address (palette + the value in x)
; 1st time through loop it will load palette+0
; 2nd time through loop it will load palette+1
; 3rd time through loop it will load palette+2
; etc
STA $2007 ; write to PPU
INX ; X = X + 1
CPX #$10 ; Compare X to hex $10, decimal 16 - copying 16 bytes = 4 sprites
BNE LoadPalettesLoop3 ; Branch to LoadPalettesLoop if compare was Not Equal to zero
; if compare was equal to 32, keep going down
LoadGameOverBackground:
LDA $2002 ;Read PPU status to reset hi/lo latch
LDA #$20
STA $2006 ;write the high byte of $2000 address
LDA #$00
STA $2006 ;write the low byte of the $2000 address
LoadGameOverLoop:
LDA #$00
STA pointer2 ; put the low byte of the address of background into pointer --- This equals 00?
LDA #HIGH(gameoverscreen) ;What does the #HIGH signify? Its not a constant. Is this pulling the tile number from the nametable below?
STA pointer2+1 ; put the high byte of the address into pointer. Do we now have $2400?
LDX #$00 ; start at pointer + 0
LDY #$00
OutsideLoopGameOver:
InsideLoopGameOver:
LDA [pointer2], y ; copy one background byte from address in pointer plus Y
STA $2007 ; this runs 256 * 4 times
INY ; inside loop counter
CPY #$00
BNE InsideLoopGameOver ; run the inside loop 256 times before continuing down
INC pointer2+1 ; low byte went 0 to 256, so high byte needs to be changed now
INX
CPX #$04
BNE OutsideLoopGameOver ; run the outside loop 256 times before continuing down
;;Remove Sprites OnScreen By Filling Their Tile Values with Blank Sprites
;;use this loop to give the ppu time to VBLANK
VblankWaitLoop:
LDX #$30
DEX
CPX #$01
BNE VblankWaitLoop
GameOverDone:
RTS
This code actually works but it shouldn't, for two reasons based on my understanding. The first is the VblankWaitLoop at the bottom of the screen is improperly coded. Its actually an infinite loop. This causes the screen to render in the appropriate location, but why?
In my mind, I should be using this code for the VblankWaitLoop
Code:
LDX #$30
VblankWaitLoop:
DEX
CPX #$01
BNE VblankWaitLoop
VblankWaitLoop:
DEX
CPX #$01
BNE VblankWaitLoop
But the code that makes sense to me does not actually work. Any thoughts guys?