How To Create a Ready Timer For Pong

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
hundonostudy
Posts: 23
Joined: Sat Jan 14, 2017 8:40 am

How To Create a Ready Timer For Pong

Post by hundonostudy »

Hi All!

I'm still working on these Nerdy Nights tutorials and I'm almost done : ) I'm having some trouble though working out a feature. Any help would be appreciated. I'm trying to add a timer to the release of the ball. For example, currently when the play screen is loaded the ball immediately begins moving towards a paddle. I instead would like the play screen to load, and the ball NOT appear for a few seconds to allow the players to ready themselves. To achieve this, I came up with a timer that I insert before the ball sprite initialization code. I have separated the code into sections to make this easier to read. Here is the timer. The amount of time the timer waits is controlled by the Constant SETREADYFRAMES

Code: Select all

ReadyTimer:
  LDX #$00
  ReadyTimerInnerLoop:
  LDA #$00
  STA ReadyFrameCount
  ReadyTimerInc:
  INC ReadyFrameCount
  LDA ReadyFrameCount
  CMP #SETREADYFRAMES ;;Currently Set to 200
  BNE ReadyTimerInc
  INX
  CPX #$0A
  BNE ReadyTimerInnerLoop
I then try to combine the timer with the subroutine LoadInitialBallstats. This subroutine stores the initial stats that the program needs to update the sprite positions in order to move the ball on screen.

Code: Select all

LoadInitialBallStats:
  ReadyTimer:
  LDX #$00
  ReadyTimerInnerLoop:
  LDA #$00
  STA ReadyFrameCount
  ReadyTimerInc:
  INC ReadyFrameCount
  LDA ReadyFrameCount
  CMP #SETREADYFRAMES
  BNE ReadyTimerInc
  INX
  CPX #$0A
  BNE ReadyTimerInnerLoop
;Timer Done. Now Set The Initial Ball Stats and Starting Paddle Position
  LDA #$01
  STA balldown
  STA ballright
  LDA #$00
  STA ballup
  STA ballleft

  LDA #$50
  STA bally

  LDA #$80
  STA ballx

  LDA #$01
  STA ballspeedx
  STA ballspeedy
LoadInitialBallStatsDone:
  RTS
Unfortunately, my timer just isn't doing what I want it to do. When I test the timer in the FCEUX debugger it is counting up the way I want it too, so in theory I think it should work, but in practice it isn't. When I set the timer to a lower framecount using SETREADYFRAMES, like below 200, the ball immediately moves on the screen without the delay I want. When I set the timer at 200 or above, the ball will not appear at all.

Any help with this problem would be very much appreciated : )

Thanks All!

-Hundo
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Re: How To Create a Ready Timer For Pong

Post by Disch »

Code executes as fast as the CPU can run it. Your 'ReadyTimerInc' loop is not waiting any significant amount of time --- each iteration does not represent a 'frame' like you seem to want it to.

To wait for a full frame to pass, the general approach is to wait for an NMI to trigger. Another approach is to spin on a $2002 read loop until the vblank flag raises -- but that is imperfect and can cause some frames to be missed (ie: you might end up waiting longer than you want)
hundonostudy
Posts: 23
Joined: Sat Jan 14, 2017 8:40 am

Re: How To Create a Ready Timer For Pong

Post by hundonostudy »

Disch wrote:Code executes as fast as the CPU can run it. Your 'ReadyTimerInc' loop is not waiting any significant amount of time --- each iteration does not represent a 'frame' like you seem to want it to.

To wait for a full frame to pass, the general approach is to wait for an NMI to trigger. Another approach is to spin on a $2002 read loop until the vblank flag raises -- but that is imperfect and can cause some frames to be missed (ie: you might end up waiting longer than you want)
OK, how then would you suggest that I go about constructing something to wait for say 120 frames (2 seconds to pass) by utilizing the NMI. Is there a DOC you can point me to that would be helpful to read. BTW I read your document on NMI and VBLANK (3 times actually). Super interesting, and probably what I need to solve this problem, however I'm not experienced enough yet to pull out the knowledge I need to construct this timer.

Can you give me a small code example so I can get started in the right direction?

Thank You
Hundo
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: How To Create a Ready Timer For Pong

Post by rainwarrior »

A common way is to change some value in the NMI routine, and then make a loop that checks that value until it changes.

Code: Select all

; nmi routine, address placed in vector table at end of ROM
nmi:
	inc frame
	rti

; wait routine
wait_nmi:
	lda frame
:
	cmp frame
	beq :-
	rts

; call when you need to wait:
	jsr wait_nmi
hundonostudy
Posts: 23
Joined: Sat Jan 14, 2017 8:40 am

Re: How To Create a Ready Timer For Pong

Post by hundonostudy »

rainwarrior wrote:A common way is to change some value in the NMI routine, and then make a loop that checks that value until it changes.

Code: Select all

; nmi routine, address placed in vector table at end of ROM
nmi:
	inc frame
	rti

; wait routine
wait_nmi:
	lda frame
:
	cmp frame
	beq :-
	rts

; call when you need to wait:
	jsr wait_nmi
Thank you Rainwarrior and Disch! Your suggestions helped immensly!
Post Reply