Jump to content
IGNORED

Request for Advice: Real World VBI Programming


snicklin

Recommended Posts

Hi,

 

I'm looking for some general advice on programming the VBI.

 

While I am able to program vertical blank interrupts, I would like advice on how to use them.

 

For example, what are the best ways of synchronising what you are doing outside the VBI with what is going on within the VBI?

 

How about avoiding modifications to addresses within the vbi which are used outside?

 

Should I try to do as much / as little as possible within the VBI and then as much / as little as possible outside the VBI?

 

What are the best techniques for obtaining smooth gameplay?

 

Are there any best practices maybe for buffering data from the VBI to use outside?

 

Cheers,

Steve

 

Link to comment
Share on other sites

For example, what are the best ways of synchronising what you are doing outside the VBI with what is going on within the VBI?

i use a label called sync; a runtime subroutine called sync_wait zeroes it and sits there waiting for the value to be changed by an interrupt before continuing.

 

How about avoiding modifications to addresses within the vbi which are used outside?

S'probably best to either use the shadow registers or your own mirrors, write to those at runtime and let the interrupt take care of stuffing the new values into the actual registers.

 

Should I try to do as much / as little as possible within the VBI and then as much / as little as possible outside the VBI?

Personally, i feel the interrupts should be used just as a framework to set smooth scroll values, sprite positions, colour registers, font pointers and so on with the game code itself executing at runtime. (i've done it both ways on the C64 and you end up jumping through a stupid number of hoops if the main game code is hanging off the interrupt!)

 

What are the best techniques for obtaining smooth gameplay?

Never update something whilst it's drawing and try to keep it all synchronised to the frame refresh by taking the timing from the VBI or a DLI; if you want to check everything is working, INC a spare part of the display once a frame on the interrupt and DEC it from runtime, if the latter is dropping frames you'll see that display area changing when it happens.

 

You can keep an eye on how much time your routines are taking by changing the background colour as well, most of mine are rainbows whilst i figure out the basic timing of stuff!

 

Are there any best practices maybe for buffering data from the VBI to use outside?

If you keep the majority of the processing to runtime code rather than interrupt, there's very few places where it can conflict.

Link to comment
Share on other sites

Syncing mainline code with VBI pretty easy. You can simply use the lowest byte of RTCLOK ($14) in a comparison on itself.

 

Either have a wait loop or copy it to a work variable. Alternatively, have a flag that your VBI sets, then have the mainline code clear it when it's "per frame" processing is complete then a wait loop simply sits until it becomes nonzero again.

 

Processing inside the VBI - it's best to minimize what gets done in Stage 1 Immediate (vector $222) since too much will delay the storing of shadow registers to the hardware. If too much delay occurs one of the main problems can be that the DLIST pointer gets stored during an active screen which can cause the screen to move around.

 

Problem with Stage 2 Deferred ($224) is that there's no guarantee it actually gets run but it is the better place to do the majority of VBlank processing. If an IRQ is being serviced or IRQs are disabled or the CRITIC ($42) flag is nonzero then Stage 2 processing is skipped.

You can ensure the skipping doesn't occur by making sure those conditions don't occur. Keyboard interrupt will be the main problem in a game - you can disable the keyboard IRQ and still read the keyboard, it just takes a bit more programming.

 

Alternative to VBlank, you can do the vast majority of the game logic in the main loop if you wanted. Use the flag/RTCLOK method described before to maintain timing.

 

Alternative #2 to VBlank is to do that processing in a DLI that occurs near end of screen.

Normal VBlank processing starts just after the active display, ie after the 240 scanlines Antic normally allows you to show data in.

So long as you're mindful that some things you do there could affect onscreen display in an unwanted way, it's a valid technique.

Added bonus is that you will have more CPU time before the display is active again.

Edited by Rybags
  • Like 1
Link to comment
Share on other sites

What Rybags said.

No syncing variable needed as you either have RTCLK available or your own frame counter when you disable OS VBI (which you should do!).

Using a sync variable might be faster in the mainloop, however, you would be "busy waiting" anyway. So there is no point AFAIKS

 

 

To make the decision easy what todo in the VBI:

EVERYTHING what MUST be handled once per frame goes into the VBI!

That includes all sprite movements, color changes (when not done in a DLI).

Music playback should be placed here, however, I am not sure if anyone will notice if the music "skips a beat".

 

Stuff that SHOULD run once per frame should be in the main loop.

For example updating score board or collision checking (in some cases).

 

 

Well, at least that is my take on that matter.

Edited by Creature XL
Link to comment
Share on other sites

  • 4 weeks later...

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...