home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff256.lzh / BlitDemons / bdblit.c < prev    next >
C/C++ Source or Header  |  1989-10-19  |  20KB  |  556 lines

  1. /*******************************************************************************
  2. *   BlitDemons by Walter Strickler
  3. *   This program and all its source code are in the public domain and are
  4. * freely distributable and usable for any purpose, private or commercial.
  5.  ******************************************************************************/
  6. #include "bdemon.h"
  7. #include <hardware/custom.h>
  8. #include <hardware/blit.h>
  9.  
  10.  
  11. /*  This is what it's all about:  THE ALGORITHM without the Intuition fluff */
  12.  
  13. /*******************************************************************************
  14.  *  Local prototypes...
  15.  ******************************************************************************/
  16. void BlitIncrement(struct DoBlitNode *, struct BDMainStruct *);
  17. void BlitCompare(struct DoBlitNode *, struct BDMainStruct *, int, int);
  18. void UpdateEqual(struct DoBlitNode *, struct BDMainStruct *);
  19. void BlitOutput(struct DoBlitNode *, struct BDMainStruct *);
  20. void InitBlitData();
  21. void Blit(struct DoBlitNode *,
  22.           WORD *, int, int, 
  23.           WORD *, int, int, 
  24.           WORD *, int,
  25.           WORD *, int,
  26.           int, int, int, int, int);
  27. void DoBlit(struct DoBlitNode *);
  28.  
  29.  
  30. /*******************************************************************************
  31.  *   These defines will be used in the Blit() calls in this file.
  32.  ******************************************************************************/
  33. #define NEG_A        NANBNC | NANBC | NABNC | NABC   /* Negate A */
  34. #define A_XOR_B      NABC | NABNC | ANBC | ANBNC     /* A ^ B */
  35. #define A_XOR_BANDC  ANBNC | ANBC | NABC | ABNC      /* A ^ (B&C) */ 
  36. #define A_EQUIV_B    NANBNC | NANBC | ABNC | ABC     /* ~(A^B) */
  37. #define COMPARE      NANBC | ABC
  38. #define OUTPUT_FUNC  ABC | NABC | NANBC | ABNC
  39.  
  40.  
  41. /*******************************************************************************
  42.  *   Define the number of blits in each step.
  43.  ******************************************************************************/
  44. #define INCR_BLITS          5
  45. #define COMPARE_BLITS       4
  46. #define UPDATE_BLITS        1     
  47. #define OUTPUT_BLITS        4
  48. #define TOTAL_BLITS     (INCR_BLITS + COMPARE_BLITS * 4 + OUTPUT_BLITS + \
  49.                         UPDATE_BLITS * 3)
  50.  
  51.  
  52. /**************************************************************************
  53.  *  OneGen() performs one demons generation on the planes in PlaneData,
  54.  * using the DoBlitNode pointed at by BlitNodes.  Performs TOTAL_BLITS
  55.  * blits.
  56.  *************************************************************************/
  57. void OneGen(BDSchtoff)
  58.     struct BDMainStruct *BDSchtoff;
  59.  
  60.     {
  61.     int i;
  62.     struct DoBlitNode *BlitNodes;
  63.  
  64.     OwnBlitter();
  65.     BlitNodes = BDSchtoff -> BDBlitNodes;
  66.     for (i = 0; i < TOTAL_BLITS; i++)
  67.         {
  68.         DoBlit(&(BlitNodes[i])); 
  69.         }
  70.     DisownBlitter();
  71.     }
  72.  
  73.  
  74. /**************************************************************************
  75.  *   InitBlits() allocates an array of DoBlitNodes, then fills it so that
  76.  * when OneGen() is run on this array, it does a demons generation on
  77.  * the given bitplanes.
  78.  *   The actual blitter algorithm came from the Apex version, written by
  79.  * Loren Blaney.
  80.  *************************************************************************/
  81. struct DoBlitNode *InitBlits (PlaneData)
  82.     struct BDMainStruct *PlaneData;
  83.     
  84.     {    
  85.     struct DoBlitNode *BlitData;
  86.     int                NodeCount;
  87.  
  88.     InitBlitData();   /* Need to do this somewhere */
  89.     BlitData = (struct DoBlitNode *) malloc(sizeof(struct DoBlitNode) * 
  90.      TOTAL_BLITS);
  91.     if (BlitData != NULL)
  92.         {
  93.         NodeCount = 0;
  94.         /* Step 1:  Increment Display[] into Incr[] 
  95.          *          Incr[] = Display[] + 1
  96.          */
  97.         BlitIncrement(&(BlitData[NodeCount]), PlaneData);
  98.         NodeCount = NodeCount + INCR_BLITS;
  99.     
  100.         /* Step 2:  Compare a cell's incremented value (Incr[]) 
  101.          *         with its 4 nearest neighbors.  If any are equal, then set
  102.          *         Equal[] flag.
  103.          */
  104.         BlitCompare(&(BlitData[NodeCount]), PlaneData, TO_EQUAL, UP_NEIGHBOR);
  105.         NodeCount = NodeCount + COMPARE_BLITS;
  106.        /*  Now Equal = (Incr == Up) */
  107.  
  108.         BlitCompare(&(BlitData[NodeCount]), PlaneData, TO_TEMP, LEFT_NEIGHBOR);
  109.         NodeCount = NodeCount + COMPARE_BLITS;
  110.         UpdateEqual(&(BlitData[NodeCount]), PlaneData);
  111.         NodeCount = NodeCount + UPDATE_BLITS;
  112.         /*  Now Equal = (Incr == Up) | (Incr == Left) */
  113.    
  114.         BlitCompare(&(BlitData[NodeCount]), PlaneData, TO_TEMP, RIGHT_NEIGHBOR);
  115.         NodeCount = NodeCount + COMPARE_BLITS;
  116.         UpdateEqual(&(BlitData[NodeCount]), PlaneData);
  117.         NodeCount = NodeCount + UPDATE_BLITS;
  118.         /*  Now Equal = (Incr == Up) | (Incr == Left) | (Incr == Right) */
  119.   
  120.         BlitCompare(&(BlitData[NodeCount]), PlaneData, TO_TEMP, DOWN_NEIGHBOR);
  121.         NodeCount = NodeCount + COMPARE_BLITS;
  122.         UpdateEqual(&(BlitData[NodeCount]), PlaneData);
  123.         NodeCount = NodeCount + UPDATE_BLITS;
  124.         /* Now Equal = 1 if ANY neighbor(s) is/are equal to Incr */
  125.    
  126.         /* Step 3:  Blit the results (Equal) to the display as follows:
  127.          *     if (Equal == 0) { Display[] = Display[]; }
  128.          *     else            { Display[] = Incr[]; }
  129.          */
  130.         BlitOutput(&(BlitData[NodeCount]), PlaneData);
  131.         /* Bimbo! */
  132.         }
  133.     else
  134.         {
  135.         BlitData = NULL;   /* Error return */
  136.         }    
  137.     return BlitData;
  138.     }
  139.  
  140.  
  141. /*******************************************************************************
  142.  *  BlitIncrement() increments the bitplane array pointed at by
  143.  * Planes -> Display, and stores the result in Planes -> Incr.  Uses the 
  144.  * blitter.  Make sure you own the blitter before calling this.
  145. *******************************************************************************/
  146. void BlitIncrement(BlitData, Planes)
  147.     struct DoBlitNode   *BlitData;
  148.     struct BDMainStruct *Planes;
  149.  
  150.     { 
  151.     WORD  **Disp,
  152.           **Incr,
  153.            *Temp;       
  154.  
  155.     Disp = Planes -> Display;
  156.     Incr = Planes -> Incr;
  157.     Temp = Planes -> Temp;
  158.  
  159.     /* Increment Blit #1.
  160.      * Incr[0] = ~Disp[0]
  161.      * D = ~A
  162.      */
  163.     Blit(&(BlitData[0]),
  164.          Disp[0], 0, 0,
  165.          NULL,   0, 0,
  166.          NULL, 0,
  167.          Incr[0], 0,
  168.          0, Planes -> Mod, Planes -> XSize, Planes -> YSize, NEG_A);
  169.  
  170.     /* Increment Blit #2.
  171.      * Incr[1] = Disp1 ^ Disp0 
  172.      * D = A ^ B
  173.      */
  174.     Blit(&(BlitData[1]),
  175.          Disp[1], 0, 0,
  176.          Disp[0], 0, 0,
  177.          NULL, 0,
  178.          Incr[1], 0,
  179.          0, Planes -> Mod, Planes -> XSize, Planes -> YSize, A_XOR_B);
  180.  
  181.     /* Increment Blit #3.
  182.      * Incr[2] = Disp[2] ^ (Disp[1] & Disp[0]) 
  183.      * D = A ^ (B & C)
  184.      */
  185.     Blit(&(BlitData[2]),
  186.          Disp[2], 0, 0,
  187.          Disp[1], 0, 0,
  188.          Disp[0], 0,
  189.          Incr[2], 0,
  190.          0, Planes -> Mod, Planes -> XSize, Planes -> YSize, A_XOR_BANDC);
  191.  
  192.     /* Increment Blit #4.    Determine if low 3 bits are set.
  193.      * Temp = (Disp[0] & Disp[1] & Disp[2])
  194.      * D = A & B & C
  195.      */
  196.     Blit(&(BlitData[3]),
  197.          Disp[0], 0, 0,
  198.          Disp[1], 0, 0,
  199.          Disp[2], 0,
  200.          Temp, 0,
  201.          0, Planes -> Mod, Planes -> XSize, Planes -> YSize, ABC);
  202.  
  203.     /* Blit 5.   Add in 3-bit carry.
  204.      * Incr[3] = (Disp3 ^ Temp)
  205.      * D = A ^ B 
  206.      */
  207.     Blit(&(BlitData[4]),
  208.          Disp[3], 0, 0,
  209.          Temp, 0, 0,
  210.          NULL, 0,
  211.          Incr[3], 0,
  212.          0, Planes -> Mod, Planes -> XSize, Planes -> YSize, A_XOR_B);
  213.     }
  214.  
  215.  
  216.  
  217. /*******************************************************************************
  218.  *   BlitCompare() compares, using the blitter, the 4 bitplane number at
  219.  * each pixel location in Incr with the 4 bitplanes in Neighbor.  Neighbor
  220.  * is one of 4 nearest neighbors (WhichNeighbor = UP_NEIGHBOR, DOWN_NEIGHBOR, 
  221.  * LEFT_NEIGHBOR, or RIGHT_NEIGHBOR) of pixels in Planes -> Display.  The 
  222.  * result is written to a bitplane (Temp or Equal) specified by WhereTo.
  223.  * A pixel is set in the result if Incr is equal to the neighbor, otherwise
  224.  * is is cleared.
  225. *******************************************************************************/
  226. void BlitCompare(BlitData, Planes, WhereTo, WhichNeighbor)
  227.     struct DoBlitNode   *BlitData;
  228.     struct BDMainStruct *Planes;
  229.     int                  WhereTo,
  230.                          WhichNeighbor;
  231.  
  232.     {
  233.     WORD **Source,
  234.          **Neighbor,
  235.           *Dest;
  236.     int    i,
  237.            ShiftX,
  238.            ShiftY;
  239.  
  240.     switch (WhichNeighbor)
  241.         {
  242.         case UP_NEIGHBOR:
  243.             ShiftX = 0;
  244.             ShiftY = -1;
  245.             break;
  246.         case LEFT_NEIGHBOR:
  247.             ShiftX = -1;
  248.             ShiftY = 0;
  249.             break;
  250.         case RIGHT_NEIGHBOR:
  251.             ShiftX = 1;
  252.             ShiftY = 0;
  253.             break;
  254.         case DOWN_NEIGHBOR:
  255.             ShiftX = 0;
  256.             ShiftY = 1;
  257.             break;
  258.         default:
  259.             assert(FALSE);       /* Shouldn't be here */
  260.             break;
  261.         }
  262.     Source = Planes -> Incr;
  263.     Neighbor = Planes -> Display;
  264.     switch (WhereTo)
  265.         {
  266.         case TO_EQUAL:
  267.             Dest = Planes -> Equal;
  268.             break;
  269.         case TO_TEMP:
  270.             Dest = Planes -> Temp;
  271.             break;
  272.         default:
  273.             assert(FALSE);       /* Shouldn't be here */
  274.             break;
  275.         }
  276.  
  277.     /* Compare Blit #1.  Set Dest if Neighbor[0] = Source[0]
  278.      * Dest = ~(Source[0] ^ Neighbor[0])
  279.      * D = ~(A ^ B) 
  280.      */
  281.     Blit(&(BlitData[0]),
  282.          Source[0], 0, 0,
  283.          Neighbor[0], ShiftX, ShiftY,   
  284.          NULL, 0,
  285.          Dest, 0,
  286.          0, Planes -> Mod, Planes -> XSize, Planes -> YSize, A_EQUIV_B);
  287.  
  288.     /* Compare Blit #2-4.  Compare bits 1-3 as in prev blit, but include Dest
  289.      * Dest = ~(Source[i] ^ Neighbor[i]) & Dest
  290.      * D = ~(A ^ B) & C
  291.      */
  292.     /* Do next blit on the upper 3 bitplanes */
  293.     for (i = 1; i <= 3; i++)
  294.         {
  295.         Blit(&(BlitData[i]),
  296.              Source[i], 0, 0,
  297.              Neighbor[i], ShiftX, ShiftY,
  298.              Dest, 0,
  299.              Dest, 0,
  300.              0, Planes -> Mod, Planes -> XSize, Planes -> YSize, COMPARE);
  301.         }
  302.      /*  NOW:  Dest = 1 if (Source[] == Neighbor[]) */
  303.     }
  304.  
  305.  
  306. /*******************************************************************************
  307.  *   UpdateEqual() is a quicky function whose entire purpose was to clean up
  308.  * OneGen().  It OR's the bitplanes (Planes -> Equal) and (Planes -> Temp)
  309.  * and stores the result in (Planes -> Equal).
  310. *******************************************************************************/
  311. void UpdateEqual(BlitData, Planes)
  312.     struct DoBlitNode   *BlitData;
  313.     struct BDMainStruct *Planes;
  314.  
  315.     {
  316.     Blit(BlitData,
  317.          Planes -> Equal, 0, 0,
  318.          Planes -> Temp, 0, 0,
  319.          NULL, 0,
  320.          Planes -> Equal, 0,
  321.          0, Planes -> Mod, Planes -> XSize, Planes -> YSize, A_OR_B);
  322.     }
  323.  
  324. /*******************************************************************************
  325.  *   Output to the display planes the final result, as follows:
  326.  *          if (Equal == 0) { Display[] = Display[]; }
  327.  *          else            { Display[] = Incr[]; }
  328.  *   By moving Equal to A and changing the function accordingly, we can mask
  329.  * a border out of A and leave it unchanged.  Intuition Borders have a width
  330.  * of two, but we'll use LRBorder just in case something changes.
  331. *******************************************************************************/
  332. void BlitOutput(BlitData, Planes)
  333.     struct DoBlitNode   *BlitData;
  334.     struct BDMainStruct *Planes;
  335.     {
  336.     int i;
  337.  
  338.     /* Display[i] = 
  339.      *  Equal&Incr[i]&Dis[i] | ~Equal&Incr[i]&Dis[i] | ~Equal&~Incr[i]&Dis[i] | 
  340.      *  Equal&Incr[i]&~Dis[i]
  341.      * Determined using a truth table.
  342.      */
  343.     /* Output displayed bitplane 0 */
  344.     for (i = 0; i <= 3; i++)
  345.         {
  346.         Blit(&(BlitData[i]),
  347.              Planes -> Equal, 0, 0,
  348.              Planes -> Incr[i], 0, 0,
  349.              Planes -> Display[i], 0, 
  350.              Planes -> Display[i], 0,
  351.              Planes -> LRBorder, Planes -> Mod, 
  352.              Planes -> XSize, Planes -> YSize, OUTPUT_FUNC);
  353.         }
  354.     }
  355.  
  356.  
  357. /**************************************************************************    
  358.  *   Blit() and InitBlitData() are based loosely on the ones by the same names
  359.  * from PopLife, written by Tomas Rockkiki(?) and/or Olaf Seibert.  I saw no 
  360.  * copyright notice or anything similar in that code, so I presume it's safe 
  361.  * to use.  
  362.  *   I simplified Blit() and changed InitBlitData() to suit.  
  363.  *                                                         -wss
  364. **************************************************************************/
  365.  
  366. /* --------------------------------------------------------------------- *
  367.  *
  368.  *   Static data for the BLITTER routine.
  369.  *
  370.  *   We need an array which tells what to use
  371.  *   for all 256 possible operations.
  372.  *
  373.  * --------------------------------------------------------------------- */
  374.  
  375. UBYTE ToUse[256];    /* Which DMA channels we need per minterm */
  376. UWORD FwmA[16];        /* First word mask for A source */
  377. UWORD LwmA[16];        /* Last word mask for A source */
  378.  
  379. /*
  380.  *   Call InitBlitData() once on startup before you ever call Blit().
  381.  *   Have a look in the Hardware Reference Manual for the mysterious
  382.  *   bit patterns. They are quite obvious then!
  383.  */
  384.  
  385. void InitBlitData()
  386.     {
  387.     register WORD i;
  388.     register UWORD s,
  389.                    First,
  390.                    Last;
  391.  
  392.     /*  I sure hope this works!  I have no idea what's going on here! -wss */
  393.     for (i=0; i<256; i++) 
  394.         {
  395.         s = DEST >> 8;
  396.         if ((i >> 4) != (i & 15))      /* 15 is 0000 1111 */
  397.             {
  398.             s += SRCA >> 8;
  399.             }
  400.         if (((i >> 2) & 51) != (i & 51))  /* 51 is 0011 0011 */
  401.             {
  402.             s += SRCB >> 8;
  403.             }
  404.         if (((i >> 1) & 85) != (i & 85))  /* 85 is 0101 0101 */
  405.             {
  406.             s += SRCC >> 8;
  407.             }
  408.         ToUse[i] = s;
  409.     }
  410.         /* 
  411.          *  I like the concept of having a FwmA[] & LwmA[], but not the 
  412.          * implementation.  This will define a left and right border
  413.          * for A.  (This just happens to be what I want.)
  414.          * Example:  Border = 2, then mask out 2 bits on the left 
  415.          * and 2 bits on the right of A. -wss
  416.          */
  417.         First = 0xFFFF;
  418.         Last  = 0xFFFF;
  419.     for (i=0; i<16; i++) {
  420.         FwmA[i] = First;
  421.         LwmA[i] = Last;
  422.         First = First >> 1;
  423.         Last = Last << 1;
  424.     }
  425. }
  426.  
  427. /* --------------------------------------------------------------------- *
  428.  *   Arguments:
  429.  *     BNode:      Pointer to a DoBlitNode structure to fill.
  430.  *     AAddress:   The address of the A source before shifting.
  431.  *     Ax:         Number of BITS to shift A left (-) or right (+).
  432.  *     Ay:         Number of LINES to shift A up (-) or down (+).
  433.  *     BAddress:   The address of the A source before shifting.
  434.  *     Ax:         Number of BITS to shift B left (-) or right (+).
  435.  *     By:         Number of LINES to shift B up (-) or down (+).
  436.  *     CAddress:   The address of the C source (no pun) before shifting.
  437.  *           WSS: Took out cx due to blitter limitations (no C shifting).
  438.  *               Actually, I could shift Cx/16 words.  If we need it...
  439.  *     Cy:         Number of LINES to shift C up (-) or down (+).
  440.  *     DAddress:   The address of the dest. before shifting.
  441.  *           WSS: Took out dx due to blitter limitations (no D shifting)
  442.  *               Actually, I could shift Cx/16 words.  If we need it...
  443.  *     Dy:         Number of LINES to shift D up (-) or down (+).
  444.  *     Border:(WSS)The number of pixels (0-15) to mask on either side of A.
  445.  *     Modulo:     The REAL modulo (see HRM) in bits.
  446.  *     XSize:      Horizontal size of the blit in pixels.
  447.  *     YSize:      Vertical size of the blit in pixels.
  448.  *     Function:   The function to perform (BLTLFx)
  449.  *
  450.  *   Blit() has changed quite alot since its PopLife days.  It now fills
  451.  * up one DoBlitNode (pointed at by BNode) structure with blitter register
  452.  * values, to be used by QBlit.
  453.  *                                                            -wss
  454.  * --------------------------------------------------------------------- */
  455.  
  456. void Blit      (BNode,
  457.                 AAddress, Ax, Ay,
  458.         BAddress, Bx, By,
  459.         CAddress,     Cy,
  460.         DAddress,     Dy,
  461.                 Border,
  462.         Modulo, XSize, YSize, Function)
  463.     struct DoBlitNode *BNode;
  464.     WORD *AAddress, *BAddress, *CAddress, *DAddress;
  465.     int Ax, Ay, Bx, By,  Cy,  Dy, Border, Modulo, XSize, YSize, Function;
  466.  
  467.     {
  468.     WORD *t,
  469.           AShiftBits,
  470.           BShiftBits;
  471.  
  472.     Modulo >>= 4;    /*   Divide the Modulo By 16 because we need words. */
  473.     /*   Poke the  addresses for D and C:   */
  474.     BNode -> dsource = DAddress;
  475.     BNode -> csource = CAddress;
  476.     /* WSS:  Create a nice little border around A:  */
  477.     BNode -> afwm = FwmA[Border];
  478.     BNode -> alwm = LwmA[Border];
  479.   /*
  480.    *   Now calculate the shifts for the A and B operands.  The barrel
  481.    *   shifter counts appear to be to the left instead of the more
  482.    *   intuitive to the right.  Note that I take Dx into account.
  483.    *     WSS:  No ya don't.  
  484.    *           Note that shift right = positive (relative to parameters
  485.    *         passed in).  Thus, word shift is "+= Ax / 16", and  bitshifting
  486.    *         requires negation of Ax, since pos. is to left for blitter.
  487.    */ 
  488.  
  489.     /* Gross shift of A by whole WORDS: */
  490.     t = AAddress + (Modulo + (XSize / 16)) * Ay + (Ax / 16);  
  491.     AShiftBits = (-Ax) & 0xf;  /* Too clever:  see big comment below */
  492.     if (Ax > 0)  /* Right shift */ 
  493.         {
  494.         t++;   /*  Add 16 bits to the right, then shift AShiftBits to the left.
  495.                 * Note that (X & 0xf) = 16 - (abs(X) & 0xf), if X is negative.
  496.                 * This is what we want in AShiftBits for right shifting!
  497.                 */
  498.     }
  499.     BNode -> asource = t;
  500.  
  501.     /* Repeat for B source: */
  502.     t = BAddress + (Modulo + (XSize / 16)) * By + (Bx / 16); 
  503.     BShiftBits = (-Bx) & 0xf; 
  504.     if (Bx > 0)    
  505.         {
  506.         t++;
  507.     }
  508.     BNode -> bsource = t;
  509. /*
  510.  *   Now calculate the two control words.  If you want to do
  511.  *   the addresses in reverse order, set the appropriate bit in con1.
  512.  */
  513.     BNode -> con0 = (AShiftBits << 12) + (ToUse[Function] << 8) + Function;
  514.     BNode -> con1 = (BShiftBits << 12);
  515. /*
  516.  *   Calculate the final total XSize in words, and the modulos.  The
  517.  *   modulos are in Bytes when written from the 68000.
  518.  */
  519.     XSize = (XSize + 15) >> 4;  /* Round up to next word */
  520.     BNode -> amod = BNode -> bmod = BNode -> cmod = BNode -> dmod =
  521.         2 * Modulo;       
  522. /*
  523.  *   This last assignment merely assigns the size value in the DoBlitNode.
  524.  */
  525.     BNode -> bltsize = (YSize << 6) + XSize;
  526.     }  /* End of Blit() */
  527.  
  528.  
  529. extern struct Custom custom;  /* I guess this comes from Amiga.lib... */
  530. struct Custom *HWRegs = &custom;  /* Alas:  must be external for Blink */
  531. /*******************************************************************************
  532.  *   DoBlit routine is quite simple.  It merely takes the register contents in 
  533.  * the DoBlitNode struct pointed at by BlitInfo and stuffs it into the blitter
  534.  * registers, kicking the blitter off with a poke to bltsize.
  535.  ******************************************************************************/
  536. void DoBlit(BlitInfo) 
  537.     struct DoBlitNode  *BlitInfo;
  538.  
  539.     {
  540.     WaitBlit();   /* Wait for the previous blit */
  541.     HWRegs -> bltcon0 = BlitInfo -> con0;
  542.     HWRegs -> bltcon1 = BlitInfo -> con1;
  543.     HWRegs -> bltafwm = BlitInfo -> afwm;
  544.     HWRegs -> bltalwm = BlitInfo -> alwm;
  545.     HWRegs -> bltcpt  = (APTR) BlitInfo -> csource;
  546.     HWRegs -> bltbpt  = (APTR) BlitInfo -> bsource;
  547.     HWRegs -> bltapt  = (APTR) BlitInfo -> asource;
  548.     HWRegs -> bltdpt  = (APTR) BlitInfo -> dsource;
  549.     HWRegs -> bltcmod  = BlitInfo -> cmod;
  550.     HWRegs -> bltbmod  = BlitInfo -> bmod;
  551.     HWRegs -> bltamod  = BlitInfo -> amod;
  552.     HWRegs -> bltdmod  = BlitInfo -> dmod;
  553.  
  554.     HWRegs -> bltsize  = BlitInfo -> bltsize;  /* This sets the blitter off */
  555.     }  
  556.