/* :bk=0 */

/****************************************************************************
 *
 *							BLIT.C
 *
 ***************************************************************************/

#include "exec/types.h"
#include "exec/memory.h"
#include "graphics/copper.h"
#include "graphics/gfx.h"
#include "graphics/view.h"
#include "graphics/rastport.h"
#include "hardware/blit.h"
#include "hardware/custom.h"

/*---------------------------------------------------------------------------
 * define some stuff for blitter operations 
 *--------------------------------------------------------------------------*/
typedef struct
{
	UBYTE *blt_apt, *blt_bpt, *blt_cpt, *blt_dpt;
	UWORD blt_amod, blt_bmod, blt_cmod, blt_dmod;   /* offset in bytes */

	UWORD blt_afwm, blt_alwm;	 		/* first and last word masks */
	UWORD blt_con0;						/* control register 0 */
	UWORD blt_con1;						/* control register 1 */

	UWORD blt_size;						/* # of WORDS to move */
} bltnode;

/* define the minterm for a blit thru a mask */
/* regA is the src data, regB is the mask, regC = regD = the destination */
#define COOKIE_CUT 0xc2

extern struct Custom custom;		/* define the custom chips address */
struct Custom *chips = &custom;

bltnode blit;

/*---------------------------------------------------------------------------
 * BlitBitMapMask() -- blit a bitmap thru a mask to another bitmap
 *		both BitMap's must be the same size
 *--------------------------------------------------------------------------*/
BlitBitMapMask( src, dst, mask )
struct BitMap *src,*dst;
UBYTE *mask;
{
	register UBYTE **src_plane;
	register UBYTE **dst_plane;
	register int i;

	/* initialize the blitter control structure */
	blit.blt_afwm = 0xffff;
	blit.blt_alwm = 0xffff;

	blit.blt_bpt = mask;			/* reg B is the mask plane */
	blit.blt_amod = 0;				/* no modulos */
	blit.blt_bmod = 0;
	blit.blt_cmod = 0;
	blit.blt_dmod = 0;

	blit.blt_con1 = 0;				/* control register 1 */
	blit.blt_con0 = DEST | SRCC |SRCB | SRCA | COOKIE_CUT;

	/* set the size register from the bit map height and width */
	blit.blt_size = ( ((src->Rows & VSIZEMASK) << 6 ) | ((src->BytesPerRow >> 1) & HSIZEMASK) );

	src_plane = &src->Planes[0];
	dst_plane = &dst->Planes[0];
	for( i = src->Depth; i; i-- )
	{
		blit.blt_apt = *src_plane;
		blit.blt_cpt = *dst_plane;
		blit.blt_dpt = *dst_plane;
		DoBlit( &blit );
		src_plane++;
		dst_plane++;
	}
}

/*---------------------------------------------------------------------------
 * DoBlit() -- do one blitter operation
 *--------------------------------------------------------------------------*/
DoBlit( blt )
register bltnode *blt;			/* the control struct for blitter operation */
{
	register struct Custom *cp;	/* the custom chips address */

	cp = chips;

	OwnBlitter();

	/* set the blitter data address's */
	cp->bltapt   = (APTR)blt->blt_apt;
	cp->bltbpt   = (APTR)blt->blt_bpt;
	cp->bltcpt   = (APTR)blt->blt_cpt;
	cp->bltdpt   = (APTR)blt->blt_dpt;

	/* set the blitter modulo values */
	cp->bltamod  = blt->blt_amod;
	cp->bltbmod  = blt->blt_bmod;
	cp->bltcmod  = blt->blt_cmod;
	cp->bltdmod  = blt->blt_dmod;

	/* set the first and last word mask values */
	cp->bltafwm  = blt->blt_afwm;
	cp->bltalwm  = blt->blt_alwm;

	/* set control registers */
	cp->bltcon0  = blt->blt_con0;
	cp->bltcon1  = blt->blt_con1;

	cp->bltsize  = blt->blt_size;   /* go for it !!! */

	WaitBlit();
	DisownBlitter();
}

