PacManPlus Posted March 11, 2010 Share Posted March 11, 2010 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 Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted March 11, 2010 Share Posted March 11, 2010 I use the following waiting for VBL routine without any problems :- WaitForVBlank: L1: bit MSTAT bmi L1 L2: bit MSTAT bpl L2 rts 1 Quote Link to comment Share on other sites More sharing options...
gdement Posted March 11, 2010 Share Posted March 11, 2010 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. 1 Quote Link to comment Share on other sites More sharing options...
PacManPlus Posted March 12, 2010 Author Share Posted March 12, 2010 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... Anyway, your routine worked, and it makes much more sense to me - thanks! Bob Quote Link to comment Share on other sites More sharing options...
+Allan Posted March 12, 2010 Share Posted March 12, 2010 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... 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 Quote Link to comment Share on other sites More sharing options...
DEBRO Posted March 12, 2010 Share Posted March 12, 2010 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.