/* * 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 blit. */ 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 ; } } /* * 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. */ blit(aaddress, ax, ay, baddress, bx, by, caddress, cx, cy, daddress, dx, dy, modulo, xsize, ysize, function) short *aaddress, *baddress, *caddress, *daddress ; int ax, ay, bx, by, cx, cy, dx, dy, modulo, xsize, ysize, function ; { short *t ; /* * Divide the modulo by 16 because we need words. */ modulo >>= 4 ; /* * Wait for the blitter to finish whatever it needs to do. */ WaitBlit() ; /* * Calculate the real addresses for d and c. */ blitter->dsource = daddress + modulo * dy + (dx >> 4) ; blitter->csource = caddress + modulo * cy + (cx >> 4) ; /* * Mask out the low order bits of dx; add these to the xsize. (The * first bits will be masked using the first word mask.) */ dx &= 15 ; xsize += dx ; blitter->afwm = fwma[dx] ; blitter->alwm = lwma[(xsize - 1) & 15] ; /* * Now calculate the shifts for the a and b operands. The barrel * shifter counts appear to be to the left instead of the more * intuitive to the right. Note that I take dx into account. */ t = aaddress + modulo * ay + (ax >> 4) ; ax = dx - (ax & 15) ; if (ax < 0) { t++ ; ax += 16 ; } blitter->asource = t ; t = baddress + modulo * by + (bx >> 4) ; bx = dx - (bx & 15) ; if (bx < 0) { t++ ; bx += 16 ; } blitter->bsource = t ; /* * Now calculate the two control words. If you want to do * the addresses in reverse order, set the appropriate bit in con1. */ blitter->con0 = (ax << 12) + (touse[function] << 8) + function ; blitter->con1 = (bx << 12) ; /* * Calculate the final total xsize in words, and the modulos. The * modulos are in bytes when written from the 68000. */ xsize = (xsize + 15) >> 4 ; blitter->amod = blitter->bmod = blitter->cmod = blitter->dmod = 2 * (modulo - xsize) ; /* * This last assignment starts up the blitter. */ blitter->bltsize = (ysize << 6) + xsize ; }