//#include <PITypes.h>
//#include <PIExtension.h>
//#include <ESDisplay.h>
#include "DirectBits.h"


GlobalData theGlobalData = {NULL, 0x00808080, 0x4210};


/* Pascal mode 'cause the original is in assembly. Might change this. */
pascal void AddDirect8 (const unsigned long *sPtr,
						unsigned char *dPtr,
						const unsigned long *mPtr,
						int16 rows,
						int16 rowSize,
						int16 sRowBytes,
						int16 dRowBytes)
	{
	long row, col32;

	for (row = 0; row < rows; row++)
		{

		for (col32 = 0; col32 < rowSize; col32++)
			{
			unsigned long mask = mPtr[col32] & sPtr[col32];
			unsigned char *destTemp = dPtr + 32 * col32;
			
			while (mask != 0)
				{
				
				if (mask & 0x80000000)
					*destTemp = 255 - *destTemp;

				mask <<= 1;
				destTemp += 1;
				
				}		

			}

		sPtr = (unsigned long *)((unsigned char *)sPtr + sRowBytes);
		dPtr += dRowBytes;
		/* mPtr is not updated. */

		}
	}

pascal void AddDirect16 (const unsigned long *sPtr,
						 unsigned short *dPtr,
						 const unsigned long *mPtr,
						 int16 rows,
						 int16 rowSize,
						 int16 sRowBytes,
						 int16 dRowBytes)
	{
	long row, col32;
	unsigned short mask16 = theGlobalData.g16Mask;

	for (row = 0; row < rows; row++)
		{

		for (col32 = 0; col32 < rowSize; col32++)
			{
			unsigned long mask = mPtr[col32] & sPtr[col32];
			unsigned short *destTemp = dPtr + 32 * col32;
			
			while (mask != 0)
				{
				
				if (mask & 0x80000000)
					*destTemp = *destTemp ^ mask16;

				mask <<= 1;
				destTemp += 1;
				
				}		

			}

		sPtr = (unsigned long *)((unsigned char *)sPtr + sRowBytes);
		dPtr = (unsigned short *)((unsigned char *)dPtr + dRowBytes);
		/* mPtr is not updated. */

		}

	}

pascal void AddDirect32 (const unsigned long *sPtr,
						 unsigned long *dPtr,
						 const unsigned long *mPtr,
						 int16 rows,
						 int16 rowSize,
						 int16 sRowBytes,
						 int16 dRowBytes)
	{
	long row, col32;
	unsigned long mask24 = theGlobalData.g24Mask;

	for (row = 0; row < rows; row++)
		{

		for (col32 = 0; col32 < rowSize; col32++)
			{
			unsigned long mask = mPtr[col32] & sPtr[col32];
			unsigned long *destTemp = dPtr + 32 * col32;
			
			while (mask != 0)
				{
				
				if (mask & 0x80000000)
					*destTemp = *destTemp ^ mask24;

				mask <<= 1;
				destTemp += 1;
				
				}		

			}

		sPtr = (unsigned long *)((unsigned char *)sPtr + sRowBytes);
		dPtr = (unsigned long *)((unsigned char *)dPtr + dRowBytes);
		/* mPtr is not updated. */

		}

	}

pascal void DoClearLongs(unsigned long *dPtr,
						 int16 countArg)
	{
	long count = countArg;

	while (count-- > 0)
		*dPtr++ = 0;
	}

pascal void DoInvertBits(unsigned long *dPtr,
						 int16 countArg,
						 int16 offset)
	{
	long count = countArg;
	unsigned long mask;

	dPtr += offset >> 5;
	offset = offset & 31;

	if (offset != 0)
		{
		mask = (0xffffffffU >> offset);

		if ((count + offset) < 32)
			{
			mask &= (0xffffffffU << (32 - (count + offset)));
			count = 0;
			}
		else
			count -= (32 - offset);

		*dPtr++ ^= mask;
		}

	while (count > 32)
		{
		*dPtr = ~*dPtr;
		++dPtr;
		count -= 32;
		}

	if (count != 0)
		*dPtr ^= (0xffffffffU << (32 - count));
		
	}
