/*
 *			I N T E R P - H . G
 *
 *  Note that "lread/lwrite" are for lores, "read/write" for word
 *  mode, and "hread/hwrite" for hires.
 *
 *  -Mike Muuss
 */

/* (y)<<>16 */
#define putpixel(x, y, s) { \
	reserve MDR, MAR; \
 \
	MDR = s; \
	MAR = ((x) | HR(y))$ \
	hwrite mash; \
}
/* getpixel is a macro for reading a pixel from frame buffer memory */
#define getpixel(x, y, val) { \
	reserve MAR; 			/* protect the MAR */ \
	MAR = (HR (y)| (x))$	 	/* calculate the address */ \
	hread mash$ 			/* assert the bus function code and \
					   force a new instruction */ \
	val = BUS; 			/* gate the data off the bus into the \
					   result register */ \
	}

main()
{
	doit(256);
/* 	doit(512); */
}

#define a2(a,b,s)	((((((a>>s)&0xFF)+((b>>s)&0xFF))>>1)&0xFF)<<s)
#define avg2(a,b)	(a2(a,b,0) | a2(a,b,8) | a2(a,b,16))

#define a4(a,b,c,d,s)	(((((a>>s)&0xFF)+((b>>s)&0xFF)+((c>>s)&0xFF)+ \
			   ((d>>s)&0xFF)>>2)&0xFF)<<s)
#define avg4(a,b,c,d)	(a4(a,b,c,d,0) | a4(a,b,c,d,8) | a4(a,b,c,d,16))

doit(size)
int size;
{
	register int ul, ur;	/* upper left, upper right */
	register int ll, lr;	/* lower left, lower right */
	register int val;
	register int x2,y2;
	register int x,y;

	for( y=size-1; y>0; y-- )  {
		y2 = y<<1;
		for( x=size-1; x>0; x-- )  {
			x2 = x<<1;
			getpixel( x-1, y-1, ul );
			getpixel( x-1, y,   ll );
			getpixel( x,   y-1, ur );
			getpixel( x,   y,   lr );

			val = avg4(ul,ll,ur,lr);
			putpixel( x2,   y2,   val );
			val = avg2(ll,lr);
			putpixel( x2,   y2+1, val );
			val = avg2(ur,lr);
			putpixel( x2+1, y2,   val );
			putpixel( x2+1, y2+1, lr );
		}
		putpixel( 0, y2, ll );
		putpixel( 0, y2+1, ll );
		putpixel( 1, y2, ll );
		putpixel( 1, y2+1, ll );
	}
	for( x=size-1; x>=0; x-- )  {
		x2 = x<<1;
		getpixel( x, 0, lr );
		putpixel( x2, 0, lr );
		putpixel( x2, 1, lr );
		putpixel( x2+1, 0, lr );
		putpixel( x2+1, 1, lr );
	}
}
