/* :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 /* * 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; }