/* these are register offsets (bytes) from base address */
#define PATT0 	0x4400
#define OPATT0 	0x4600
#define PATTOFF	0x0020

static int update_fill_pattern(source,dest,first_plane,num_planes)
unsigned char *source;
unsigned short *dest;
int first_plane, num_planes;
/*
	load source, which is 4x4 pixel-major, 
		into dest, which is 16x16 plane-major 

	source		input	pointer to 4x4 byte array
	dest		input	pointer to 16x16x8 bit array
				(accessed as 16-bit words, 1 word/row/plane)
	first_plane	input	first plane to load (0..7)
	num_planes	input	number of planes to load
*/
{
	register unsigned char *src_ptr, *ptr;
	register unsigned short *dest_ptr;
	register unsigned short reg,bit,mask,work,plane,lim;

	dest_ptr = dest + (first_plane << 4);
	ptr = source;
	lim = num_planes;

	/* run loop for each plane to be loaded */
	for (plane=0; plane < lim; plane++)
	{
		/* mask will extract correct bit from each source byte */
		mask = 1 << plane;
		src_ptr = ptr;

		/* for each pixel in the y direction */
		for (reg=0; reg<4; reg++)
		{
			/* clear working register */
			work = 0;

			/* for each pixel in the x direction */
			for (bit=0; bit<4; bit++)
			{
				/* shift working register */
				work <<= 1;

				/* if in source, put bit into work register */
				if (*src_ptr++ & mask)
					work |= 1;
			}

			/* replicate working register 4x in x direction 
				(4 bits -> 16 bits) */
			work |= work << 4;
			work |= work << 8;

			/* write result to destination array, 
				replicating 4x in y direction */
			*dest_ptr = work;
			*(dest_ptr+4) =  work;
			*(dest_ptr+8) =  work;
			*(dest_ptr+12) = work;

			/* advance destination pointer to next row */
			dest_ptr++;
		}

		/* skip over the 3 other copies of the data */
		dest_ptr += 12;
	}
}
