back
Frame-Timing

Introduction to asnychronous timing by Pezac/Nature



Some people seem to have problems with timing in their intros/demos/whatever, so my aim for this tutorial is to share my knowledge in this subject. I have divided this tutorial into two parts so that those who know how to use interrupts can skip the first part:



Setting up and using interrupts

This is for everyone who doesn't know how to setup/use an intterupt. An interrupt is quite easy to setup though, this example is for a VBL-interrupt. VBL means Vertical Blanking, the interrupt will start every time the monitorbeam is at the top of the screen:

CurrentVBR holds the VBR (VectorBaseRegister) and VBL_int is the code you want to make every time the interrupt starts. a6 is ofcourse loaded with $dff000:
	move.l	CurrentVBR,a0
	move.l	#VBL_int,$6c(a0)
	move.w	#$c020,intena(a6)
VBL_int:
	movem.l	d0-d7/a0-a6,-(a7)	;save all registers
	...
	bsr	P61_Music		;.. or something else nice :)
	...
	lea	$dff000,a6
	move.w	#$0020,intreq(a6)	;clear IRQ flags
	move.w	#$0020,intreq(a6)	;twice to avoid A4000 problems
	movem.l	(a7)+,d0-d7/a0-a6	;return all registers
	rte				;rte and not rts (e = exception)

A note: my experience shows that if you are using a Copper-interrupt, you'll have to clear the IRQ flags three times to avoid A4000 problems.


Frame Timing

With frame timing I mean the way to make any effects run with the same speed on all computers. Not speed measured by frames per second (fps), but speed measured in the amount of frames you want to do per effect. Here is an example of what will happen if one doesn't do frame timing: Take a 3d scene engine and say you made a 3d scene that was 1000 frames long, timed it for your computer and put it n your demo. Let's also say another person who has a computer twice as slow as yours watched the demo. The result would be that it took twice the time to calculate one frame in the scene, and your scene engine would only render 500 frames instead of the intended 1000 frames. Oops, the person would only see half of the scene and wonder what the scene was all about, that is if you made a scene with some meaning :).

So we want the same amount of frames whether it is a vanilla (clean) Amiga1200 or an A4000/060 we are running on. The solution to this problem is framecounting. We use a framecounter that counts up to know which frame we should render. To do this we must also use something that runs at exactly the same speed on every single Amiga. Yes, interrupts!

I think the two usable interrupts for this are VBL and Copper (VERTB and COPER in the Hardware Reference Manual). It is as simple as increment our framecounter every interrupt time. Back to our example about the 3d scene. On the slower computer that runs at twice the speed, twice the amount of interrupts will be started for each scene frame thus making the framecounter to be running at the same speed on both computers.

Now to a implementation example, a routine of some sort where we want to render a number of frames:
Interrupt:
	...
	move.l	#FRAMECOUNT,d0		;number of frames we have
	move.l	framecounter,d1		;the framecounter
	cmp.l	d0,d1
	bge	.skip_add
	add.l	#1,framecounter
.skip_add:
	...

The second implementation example is a blur routine, a tricky one that often is left out for the sake of optimizing. Without modifications, the routine blurs slower on slower computers thus making the effect too blurry. If that is a big problem frametiming is important: (Not a very good example)
	move.w	blursubctr,d1
	move.w	#0,blursubctr

.yloop:
.xloop:
	...
	cmp.w	d1,d0		;d0 is the pixel to be set
	blt	.putpixel
	sub.w	d1,d0
.putpixel
	...
	dbf	.xloop
	dbf	.yloop

And in the interrupt we just add one to the sub-counter:
Interrupt:
	...
	add.w	#1,blursubctr
	...

There is however one problem. If your frame render is very slow, you might get overflow (d0 lower than zero). I told you it was a bad example :)


Last words: don't use interrupts without thinking first. Blitting a scroll in an interrupt is not a good idea for example. If you are uncertain if your timing is causing problems on slower/faster computers, you could always try to lower or raise the amount of pixels that you render. This is to "emulate" a slower or faster computer.






Last change: 16.01.2001
For questions referring to this page mail to: (Pezac/Nature)