Jump to content
IGNORED

Question about VBLANK


PacManPlus

Recommended Posts

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

Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...