#include "x.h"
#include "i8.h"
#include <string.h>

/* Move bytes according to rop.
 */
void near
copybytes(pdst, psrc, n, pmask)
unsigned char *psrc, *pdst;
int	n;			/* number of bytes */
int	pmask;			/* plane mask */
{
	memcpy(pdst, psrc, n);
}

void near
copyInvertedbytes(pdst, psrc, n, pmask)
unsigned char *psrc, *pdst;
int	n;			/* number of bytes */
int	pmask;
{
	while (n--)
		*pdst++ = ~*psrc++;
}

/* used for FillSolid */
void near
movebyte(pdst, src, n, rop, pmask)
unsigned char *pdst;
unsigned short src;
int	n;			/* number of bytes */
int	rop;
unsigned char pmask;
{

	if (pmask == 0xff && rop == GXcopy) {
		_asm	les	di,pdst
		_asm	mov	ax,src
		_asm	mov	cx,n
		_asm	shr	cx,1
		_asm	rep	stosw
		_asm	adc	cx,cx
		_asm	rep	stosb
		return;
	}
	if (rop == GXxor) {
		src &= pmask;
		_asm	les	di,pdst
		_asm	sub	ax,ax
		_asm	mov	bx,src
		_asm	mov	cx,n
		_asm	shr	cx,1
		_asm	adc	ax,ax
		_asm	jz	_L2
		_asm	mov	al,es:[di]
		_asm	xor	al,bl
		_asm	stosb
		_asm	_L2:
		_asm	jcxz	_L3
		_asm	_L1:
		_asm	mov	ax,es:[di]
		_asm	xor	ax,bx
		_asm	stosw
		_asm	loop	_L1
		_asm	_L3:
		/*
		while (n--)
			*pdst++ ^= (u_char)src;
		*/
		return;
	}
	switch (rop) {
	    case GXclear:
		if (pmask == 0xff)
		    memset(pdst, 0, n);
		else
		    while (n--)
			*pdst++ &= ~pmask;
		break;
	    case GXand:
		src |= ~pmask;
		while (n--)
			*pdst++ &= src;
		break;
	    case GXandReverse:
		if (pmask == 0xff)
		    while (n--)
			    *pdst++ = src & ~*pdst;
		else
		    while (n--)
			    *pdst++ = (src & ~*pdst & pmask) | (*pdst & ~pmask);
		break;
	    case GXcopy:
		while (n--)
			*pdst++ = (src & pmask) | (*pdst & ~pmask);
		break;
	    case GXandInverted:
		while (n--)
			*pdst++ &= ~src;
		break;
	    case GXnoop:
		break;
	    case GXor:
		while (n--)
			*pdst++ |= src;
		break;
	    case GXnor:
		while (n--)
			*pdst++ = ~src & ~*pdst;
		break;
	    case GXequiv:
		while (n--)
			*pdst++ ^= ~src;
		break;
	    case GXinvert:
		while (n--)
			*pdst++ = ~*pdst;
		break;
	    case GXorReverse:
		while (n--)
			*pdst++ = src | ~*pdst;
		break;
	    case GXcopyInverted:
		memset(pdst, ~src, n);
		break;
	    case GXorInverted:
		while (n--)
			*pdst++ |= ~src;
		break;
	    case GXnand:
		while (n--)
			*pdst++ = ~src | ~*pdst;
		break;
	    case GXset:
		memset(pdst, 0xff, n);
		break;
	}
}
