home *** CD-ROM | disk | FTP | other *** search
- /* :ts=8 bk=0
- *
- * oddblit.c: Custom blitter routine. Stolen from Tomas Rokicki's LIFE
- * program and mashed up beyond all recognition. Nearly all
- * comments are Tom's.
- *
- * Leo L. Schwab 8706.4
- */
-
- #include <exec/types.h>
-
- /*
- * This include file includes the defines for all the blitter functions.
- * It only allows use of the `blit' operations; for area fills or line
- * drawing, it will need to be extended.
- *
- * Information gleaned from the Hardware Reference Manual.
- */
- #define BLTADD (0xdff040L)
-
- /*
- * This structure contains everything we need to know.
- * Do not do a structure copy into this! Instead, assign
- * each field. The last field assigned must be bltsize; that
- * starts up the blitter. Also note that all of these are
- * write only, and you can't read them.
- */
- struct bltstruct {
- short con0;
- short con1;
- short afwm;
- short alwm;
- short *csource, *bsource, *asource, *dsource;
- short bltsize;
- short dmy1, dmy2, dmy3;
- short cmod, bmod, amod, dmod;
- } *blitter = BLTADD;
-
- /*
- * We need an array which tells what to use for all 256 possible operations.
- */
- #define USEA (0x8)
- #define USEB (0x4)
- #define USEC (0x2)
- #define USED (0x1)
-
- char touse[256];
- char fwma[16];
- char lwma[16];
-
- /*
- * Call initblitdata() once on startup before you ever call oddblit.
- */
- initblitdata()
- {
- register int i;
- register int s;
-
- for (i=0; i<256; i++) {
- s = USED;
- if ((i >> 4) != (i & 15))
- s += USEA;
- if (((i >> 2) & 51) != (i & 51))
- s += USEB;
- if (((i >> 1) & 85) != (i & 85))
- s += USEC;
- touse[i] = s;
- }
- s = 0xffff;
- for (i=0; i<16; i++) {
- fwma[i] = s;
- s = (s >> 1) & ~0x8000 ;
- lwma[i] = 0xffff - s;
- }
- }
-
- /*
- * (Tom's original speech:)
- * This is the major user interface. Takes addresses and offsets for
- * all four locations, a modulo and sizes, and a function.
- * Assumes the modulos for all sources and destination are the same.
- * You might want to add some arguments or delete some.
- *
- * All arguments are in pixels (except the addresses and function.)
- *
- * Before you call this routine, call OwnBlitter(); after you have
- * called it as many times as you need, call DisownBlitter(). Remember
- * that you cannot do any printf's or anything else which requires the
- * blitter when you own the blitter, so be careful with the debug code.
- * The machine will lock but will not crash.
- */
-
- /*
- * Leo here. This is the bit I mashed to pieces. Using Tom's BlitLab
- * program (wonderful thing), I figured out what it was I wanted to do.
- * So sit back, relax, and enjoy the narrative to follow...
- *
- * It is assumed that src and dest bitmap are identically sized,
- * and that the noise bitmap is larger than both of them.
- * All x,y parameters are in pixels.
- *
- * Note that this does NOT do a general arbitrary rectangle to rectangle
- * logic function. It's just a quick hack to OR random bits from one
- * bitplane with another, and place the result into a third location.
- */
-
- oddblit (src, dest, sdx, sdy,
- noise, nx, ny,
- xoff, yoff, minterm)
- short *src, *dest, *noise;
- int sdx, sdy, nx, ny, xoff, yoff;
- int minterm;
- {
- int noisemod;
-
- /* Compute width of bitplanes in words */
- sdx = (sdx + 15) >> 4;
- nx = (nx + 15) >> 4;
-
- /* noisemod is in bytes */
- noisemod = (nx - sdx) * 2;
-
- /* Wait for blitter to finish whatever it may be doing */
- WaitBlit ();
-
- /* Start tromping the blitter */
- blitter -> bsource = src;
- blitter -> dsource = dest;
- blitter -> afwm = blitter -> alwm = 0xffff;
-
- /* Compute start address into noise plane */
- blitter -> asource = noise + yoff * nx + (xoff >> 4);
-
- /* Compute desired shift for noise plane */
- xoff &= 15;
-
- /* Comnpute and write control words */
- blitter -> con0 = (xoff << 12) + (touse[minterm] << 8) + minterm;
- blitter -> con1 = 0; /* No shifts on B source or flags */
-
- /* Write out the modulos */
- blitter -> amod = noisemod;
- blitter -> bmod = 0; /* These are sized precisely */
- blitter -> dmod = 0;
-
- /*
- * This last assignment starts up the blitter.
- */
- blitter->bltsize = (sdy << 6) + sdx;
- }
-