Jump to content

Question about VBLANK


5 replies to this topic

#1  

    River Patroller

  • 3,166 posts
  • Joined: 19-June 02
  • Location:Naples, Florida

Posted Thu Mar 11, 2010 5:42 AM

Hi Guys:

I'm a little confused about something.

There's a routine I use to wait for VBLANK to ensure that things happen only one per frame (I have a MAIN routine loop, and the last line in that loop is 'JSR WAITVBL'. This is the WAITVBL routine:
;  A ROUTINE TO WAIT TILL VBLANK
WAITVBL
          BIT     MSTAT                  ;IS VBLANK STARTED YET?
          BPL     WAITVBL
          BIT     MSTAT                  ;IS VBLANK STILL STARTED?
          BPL     WAITVBL
          RTS

I took that directly from the Ms. Pac-Man source code.

I found out today that this is not the case. I have a routine that increments an animation counter (supposedly) once per frame. I made sure that no other routines call this animation routine, and it's only called directly before the 'JSR WAITVBL' in the main loop. After putting display statements in the program, I found that it was getting called up to 10 times per frame. I then put in a variable to check against a frame counter called 'RTLOCAL' that is incremented only during the bottom DLI. I add '1' to this new variable each time to ensure that the animation routine only gets processed once per frame. It then works as expected. I just don't understand how this routine can get processed more than once per frame if there is a JSR to a WAITVBL routine directly after it.

How is this possible?

Here is the main routine so far:

RPD
          JSR     SEEBALL
          LDX     #$00
          JSR     PLAYERMOVE
          LDX     #$02
          JSR     SHOTMOVE
          INX
          JSR     SHOTMOVE
          JSR     ANIMATEROB
          JSR     WAITVBL
          JMP     RPD

'ANIMATEROB' is the routine in question.

Here is that routine, without the new check I put in:

;  ANIMATEROB - ANIMATE THE CURRENT ROBOT
;  INPUT: ROBOTCURR - THE ROBOT TO WORK ON
;  USES: A, X, Y
ANIMATEROB
          LDX     ROBOTCURR
          LDA     ROBOTMOVE,X            ;IF THE ROBOT IS MOVING, SKIP TO THE 'ROBOT MOVING' SECTION
          BNE     ARDIR
          LDA     ROBOTTYPE,X            ;GET THE ROBOT TYPE (01=SKELETON, 02=EYEBALL, 03=ROBOT)
          TAY
          LDA     OFFSETBMP,Y
          CLC
          ADC     ROBOTANIM,X
          TAY
          LDA     STILLBMP,Y
          STA     ROBOTSTMP,X
          INC     ROBOTANIM,X
          INY
          LDA     STILLBMP,Y
          BPL     ARSRTS
          LDA     #$00
          STA     ROBOTANIM,X
ARSRTS
          CPX     #$00
          BNE     ARDIR
          LDX     ROBOTANIM
          JSR     DISPLAYHEX
          RTS
ARDIR
          RTS

The 'DISPLAYHEX' routine is the one I put in to display what the animation variable contains.

I appreciate the help.
Bob

#2  

    7800 Developer

  • 5,459 posts
  • Joined: 20-November 08
  • Busy bee!
  • Location:North, England

Posted Thu Mar 11, 2010 5:57 AM

I use the following waiting for VBL routine without any problems :-

WaitForVBlank:
L1:
    bit MSTAT
    bmi L1    

L2:
    bit MSTAT
    bpl L2
    rts



#3  

    Stargunner

  • 1,745 posts
  • Joined: 03-May 04
  • Location:Northern CA

Posted Thu Mar 11, 2010 11:39 AM

View PostPacManPlus, on Thu Mar 11, 2010 5:42 AM, said:

There's a routine I use to wait for VBLANK to ensure that things happen only one per frame (I have a MAIN routine loop, and the last line in that loop is 'JSR WAITVBL'. This is the WAITVBL routine:
;  A ROUTINE TO WAIT TILL VBLANK
WAITVBL
          BIT     MSTAT                  ;IS VBLANK STARTED YET?
          BPL     WAITVBL
          BIT     MSTAT                  ;IS VBLANK STILL STARTED?
          BPL     WAITVBL
          RTS

I took that directly from the Ms. Pac-Man source code.

That code tests the same condition twice. It will fall through whenever VBLANK is active. As written, there's nothing to keep it from falling through multiple times per frame, as long as the same VBLANK interval is still active.
The 2nd test is pointless - one of those BPLs is probably supposed to be a BMI.. but that "STILL STARTED?" comment makes me wonder what they were trying to do.


The code I've used is identical to groovy's, but I like my labels better :)
;-------------------------------------------
;-- WaitVBlank(OffOn)			--
;-- -----------------			--
;-- Waits for vblank and then returns.	--
;-- No DMA occurs during vblank.	--
;-- OffOn version waits for beginning	--
;-- of a fresh VBlank cycle.		--
;--	Changes: N, Z, C		--
;--	Returns: N=1			--
;-------------------------------------------
WaitVBlankOffOn:		;s	t
	bit	MSTAT		;3	4	copies contents of MSTAT bit7 to N.
	bmi	WaitVBlankOffOn	;2	3	as long as that bit is 1, it's still vblank time.
WaitVBlank:
	bit	MSTAT		;3	4	copies contents of MSTAT bit7 to N.  MSTAT = $28
	bpl	WaitVBlank	;2	3	as long as that bit is 0, it's not vblank time.
	rts			;1	6	it's finally vblank time.
				;11

So if you want to ensure something only happens at the *beginning* of vblank, and only once per frame, then you'd call WaitVBlankOffOn. If you don't care, then you'd just call WaitVBlank.

#4  

    River Patroller

  • 3,166 posts
  • Joined: 19-June 02
  • Location:Naples, Florida

Posted Fri Mar 12, 2010 5:28 AM

Thanks, Guys

I always thought that the routine WAITVBL made no sense logically, but I figured it was GCC, and they knew what they were doing... :ponder:

Anyway, your routine worked, and it makes much more sense to me - thanks!

Bob

#5  

    River Patroller

  • 4,151 posts
  • Joined: 11-June 01
  • Location:Wallingford, CT

Posted Fri Mar 12, 2010 7:53 AM

View PostPacManPlus, on Fri Mar 12, 2010 5:28 AM, said:

Thanks, Guys

I always thought that the routine WAITVBL made no sense logically, but I figured it was GCC, and they knew what they were doing... :ponder:

Anyway, your routine worked, and it makes much more sense to me - thanks!

Bob
I think you're going to have to except that you are surpassing the original GCC programmer's knowledge about the 7800. You will be soon sitting in the main chair of Mt. Olympus of the Atari 7800. :)

Allan

#6  

    Stargunner

  • 1,856 posts
  • Joined: 25-April 01
  • Location:Atlanta, GA

Posted Fri Mar 12, 2010 4:29 PM

Hi there,

I've seen those routines too but I thought they were used when starting up the game to be sure that things happen during VBLANK because you don't know the state when the cart starts up.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users