                        Using the Blitter
                        -----------------


Using the blitter
-----------------

If you are using the blitter in your code and you are leaving the
system intact (as you should) always use the graphics.library
functions OwnBlitter() and DisownBlitter() to take control
of the blitter. Remember to free it for system use, many system
functions (including floppy disk data decoding) use the blitter.

OwnBlitter() does not trash any registers. I guess DisownBlitter()
doesn't either, although Chris may well correct me on this, and
they are fast enough to use around your blitter code, so don't
just OwnBlitter() at the beginning of your code and DisownBlitter()
at the end, only OwnBlitter() when you need to.

Another big mistake I've seen is with blitter/processor timing.

Assuming that a particular routine will be slow enough that a blitter
wait is not needed is silly. Always check for blitter finished, and
wait if you need to.

Don't assume the blitter will always run at the same speed too. Think
about how your code would run if the processor or blitter were running
at 100 times the current speed. As long as you keep this in mind,
you'll be in a better frame of mind for writing compatible code.

Another big source of blitter problems is using the blitter in interrupts.

Most demos do all processing in the interrupt, with only a

.wt	   btst	   #6,$bfe001		; is left mouse button clicked?
	   bne.s   .wt

loop outside of the interrupt. However, some demos do stuff outside the
interrupt too. Warning. If you use blitter in both your interrupt
and your main code, (or for that matter if you use the blitter via the
copper and also in your main code), you may have big problems....

Take this for example:

	lea	$dff000,a5
	move.l	GfxBase,a6
	jsr	   _LVOWaitBlit(a6)
	move.l	#-1,BLTAFWM(a5)		; set FWM and LWM in one go
	move.l	#source,BLTAPT(a5)
	move.l	#dest,BLTDPT(a5)
	move.w	#%100111110000,BLTCON0(a5)
	move.w	#0,BLTCON1(a5)
	move.w	#64*height+width/2,BLTSIZE(a5)	; trigger blitter

There is *nothing* stopping an interrupt, or copper, triggering a
blitter operation between the WaitBlit call and
your final BLTSIZE blitter trigger. This can lead to total system blowup.

Code that may, by luck, work on standard speed machines may die horribly
on faster processors due to timing differences causing this type of
problem to occurr.

The safest way to avoid this is to keep all your blitter calls together,
use the copper exclusively, or write a blitter-interrupt routine to
do your blits for you, which is very good because you avoid getting
stuck in a waitblit-loop.

Always use the graphics.library WaitBlit() routine for your
end of blitter code. It does not change any registers, it takes into
account any revision of blitter chip and any unusual circumstances,
and on an Amiga 1200 will execute faster (because in 32-bit ROM)
than any code that you could write in chipram.


Another thing concerning the blitter:

Instead of calculating your LF-bytes all the time you can do this

A	EQU	%11110000
B	EQU	%11001100
C	EQU	%10101010

So when you need an lf-byte you can just type:

	move.w	#(A!B)&C,d0

Blitter clears
--------------
If you use the blitter to clear large areas, you can generally
improve speed on higher processors (68020+) by replacing it by
a cache-loop that clears with movem.l instead:

        moveq	#0,d0
	:
        moveq	#0,d6
        sub.l	a0,a0
	:
	sub.l	a5,a5

        lea	EndOfView,a6
	move.w	#number of movements - 1,d7
.Clear
	movem.l	d0-d6/a0-a5,-(a6)
	dbf	d7,.Clear

This loop was (on my 1200) almost three times faster than
the blitter.

With 68000-68010 you can gain some time by NOT using blitter-
nasty and the movem-loop.

