home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mgr / sparcmgr / src.zoo / src / blit / blit.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-01-24  |  15.2 KB  |  583 lines

  1. /*                        Copyright (c) 1988 Bellcore
  2.  *                            All Rights Reserved
  3.  *       Permission is granted to copy or use this program, EXCEPT that it
  4.  *       may not be sold for profit, the copyright notice must be reproduced
  5.  *       on copies, and credit should be given to Bellcore where it is due.
  6.  *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
  7.  */
  8. /*    $Header: blit.C,v 4.1 88/06/21 13:19:02 bianchi Exp $
  9.     $Source: /tmp/mgrsrc/src/blit/RCS/blit.C,v $
  10. */
  11. static char    RCSid_[] = "$Source: /tmp/mgrsrc/src/blit/RCS/blit.C,v $$Revision: 4.1 $";
  12.  
  13. /* bitblit code for 68020's */
  14.  
  15. #include <stdio.h>
  16. #include "bitmap.h"
  17. #include "asm.h"
  18.  
  19. #define UP        0x10    /* direction bottom up */
  20. #define LEFT    0x20    /* direction right to left */
  21. #define SMALL    0x40    /* > 32 bits */
  22.  
  23. #define NSRC    1        /* no source required */
  24.  
  25. /* multiword source <op> destination, long aligned on destination */
  26.  
  27. #define ROP_TOP(name) \
  28.         GOTO(LL4!name); \
  29.     LABEL(LL1!name)
  30.  
  31. #define ROP_BOTTOM(how,name) \
  32.         how($d_skip,$d_base); \
  33.         how($s_skip,$s_offset); \
  34.     LABEL(LL4!name); \
  35.         LOOP($count,LL1!name)
  36.  
  37. /* bits at left edge of long boundary */
  38.  
  39. #define ROP_LEFT(how,op1,op2) \
  40.         MOVE($l_width,$i); \
  41.         MOVE($l_width,$T_DST); \
  42.         NEG($T_DST); \
  43.         BF_EXT($T_DST,$d_base,$T_DST,$i); \
  44.         BF_EXT($T_SRC,$s_base,$s_offset,$i); \
  45.         op1($T_DST,$T_SRC); \
  46.         op2($T_DST,$T_SRC); \
  47.         MOVE($l_width,$T_DST); \
  48.         NEG($T_DST); \
  49.         BF_INS($T_SRC,$d_base,$T_DST,$i)
  50.  
  51. /* full words in middle Left to Right */
  52.  
  53. #define ROP_LR(how,op1,op2,name) \
  54.         ADD($i,$s_offset); \
  55.         MOVE($words,$i); \
  56.         GOTO(LL3!name); \
  57.     LABEL(LL2!name); \
  58.         BF_EXT($T_SRC,$s_base,$s_offset,IMM(0)); \
  59.         MOVE(IND($d_base),$T_DST); \
  60.         op1($T_DST,$T_SRC); \
  61.         op2($T_DST,$T_SRC); \
  62.         MOVE($T_SRC,INCR($d_base)); \
  63.         ADD(IMM(32),$s_offset); \
  64.     LABEL(LL3!name); \
  65.         LOOP($i,LL2!name)
  66.  
  67. /* full words in middle Right to Left */
  68.  
  69. #define ROP_RL(how,op1,op2,name) \
  70.         MOVE($words,$i); \
  71.         GOTO(LL3!name); \
  72.     LABEL(LL2!name); \
  73.         SUB(IMM(32),$s_offset); \
  74.         BF_EXT($T_SRC,$s_base,$s_offset,IMM(0)); \
  75.         MOVE(DECR($d_base),$T_DST); \
  76.         op1($T_DST,$T_SRC); \
  77.         op2($T_DST,$T_SRC); \
  78.         MOVE($T_SRC,IND($d_base)); \
  79.     LABEL(LL3!name); \
  80.         LOOP($i,LL2!name); \
  81.         MOVE($l_width,$i); \
  82.         SUB($i,$s_offset);
  83.  
  84. /* bits at right edge of long boundary */
  85.  
  86. #define ROP_RIGHT(how,op1,op2) \
  87.         MOVE($r_width,$i); \
  88.         BF_EXT($T_SRC,$s_base,$s_offset,$i); \
  89.         BF_EXT($T_DST,$d_base,IMM(0),$i); \
  90.         op1($T_DST,$T_SRC); \
  91.         op2($T_DST,$T_SRC); \
  92.         BF_INS($T_SRC,$d_base,IMM(0),$i);
  93.  
  94. /* multiword set/clear/invert - top half */
  95.  
  96. #define ROP1(how,name) \
  97.             GOTO(L4!name); \
  98.          LABEL(L1!name);\
  99.                 MOVE($l_width,$i); \
  100.                 MOVE($l_width,$T_DST); \
  101.                 NEG($T_DST); \
  102.                 how($d_base,$T_DST,$i);\
  103.                MOVE($words,$i);\
  104.                GOTO(L3!name);\
  105.          LABEL(L2!name)
  106.  
  107. /* multiword set/clear/invert - bottom half */
  108.  
  109. #define ROP2(how,name) \
  110.          LABEL(L3!name); \
  111.                LOOP($i,L2!name); \
  112.             MOVE($r_width,$i); \
  113.             how($d_base,IMM(0),$i);\
  114.                ADD($d_skip,$d_base); \
  115.          LABEL(L4!name);\
  116.             LOOP($count,L1!name)
  117.  
  118. /* (<=32 bits) no source, used for SET, CLEAR and INVERT */
  119.  
  120. #define NO_SRC(func)            \
  121.           GOTO(L2!func);                        \
  122.         LABEL(L1!func);                        \
  123.           func($d_base,$words,$i);    \
  124.           ADD($d_skip,$words);            \
  125.         LABEL(L2!func);            \
  126.           LOOP($count,L1!func)
  127.  
  128. /*
  129.  *  (<=32 bits) DST doesn't count. Use for SRC, ~SRC.
  130.  *  how is ADD for top down, SUB for bottom up
  131.  */
  132.  
  133. #define NO_DST(how,op)    \
  134.           GOTO(L2!op!how); \
  135.         LABEL(L1!op!how); \
  136.           BF_EXT($T_SRC,$s_base,$s_offset,$i); \
  137.           op($T_DST,$T_SRC); \
  138.           BF_INS($T_SRC,$d_base,$words,$i); \
  139.           how($d_skip,$words); \
  140.           how($s_skip,$s_offset); \
  141.         LABEL(L2!op!how); \
  142.           LOOP($count,L1!op!how)
  143.  
  144. /*
  145.  * (<=32 bits) both SRC and DST count
  146.  *  how is ADD for top down, SUB for bottom up
  147.  */
  148.  
  149. #define ROP(how,op1,op2)    \
  150.           GOTO(L2!op1!op2!how); \
  151.         LABEL(L1!op1!op2!how); \
  152.           BF_EXT($T_SRC,$s_base,$s_offset,$i); \
  153.           BF_EXT($T_DST,$d_base,$words,$i); \
  154.           op1($T_DST,$T_SRC); \
  155.           op2($T_DST,$T_SRC); \
  156.           BF_INS($T_SRC,$d_base,$words,$i); \
  157.           how($d_skip,$words); \
  158.           how($s_skip,$s_offset); \
  159.         LABEL(L2!op1!op2!how); \
  160.           LOOP($count,L1!op1!op2!how)
  161.  
  162. /* generic case >32 bits */
  163.  
  164. #define ROP_CASE(op,name,op1,op2) \
  165.       case GET_OP(op):                    /* name  left->right top->bottom */\
  166.          ROP_TOP(name!td_lr);\
  167.          ROP_LEFT(ADD,op1,op2);\
  168.          ROP_LR(ADD,op1,op2,name!td_lr);\
  169.          ROP_RIGHT(ADD,op1,op2);\
  170.          ROP_BOTTOM(ADD,name!td_lr);\
  171.          break;\
  172.       case GET_OP(op) | UP:            /* name left->right  bottom->up */\
  173.          ROP_TOP(name!bu_lr);\
  174.          ROP_LEFT(SUB,op1,op2);\
  175.          ROP_LR(SUB,op1,op2,name!bu_lr);\
  176.          ROP_RIGHT(SUB,op1,op2);\
  177.          ROP_BOTTOM(SUB,name!bu_lr);\
  178.          break;\
  179.       case GET_OP(op) | LEFT:            /* name right->left  top->bottom */\
  180.          ROP_TOP(name!td_rl);\
  181.          ROP_RIGHT(ADD,op1,op2);\
  182.          ROP_RL(ADD,op1,op2,name!td_rl);\
  183.          ROP_LEFT(ADD,op1,op2);\
  184.          ROP_BOTTOM(ADD,name!td_rl);\
  185.          break;\
  186.       case GET_OP(op) | UP | LEFT:    /* name right->left  bottom->up */\
  187.          ROP_TOP(name!bu_rl);\
  188.          ROP_RIGHT(SUB,op1,op2);\
  189.          ROP_RL(SUB,op1,op2,name!bu_rl);\
  190.          ROP_LEFT(SUB,op1,op2);\
  191.          ROP_BOTTOM(SUB,name!bu_rl);\
  192.          break
  193.  
  194.             /* generic case <= 32 bits */
  195.  
  196. #define SMALL_CASE(op,op1,op2) \
  197.         case GET_OP(op) | SMALL:\
  198.             i = wide; \
  199.             ROP(ADD,op1,op2);\
  200.             break;\
  201.         case GET_OP(op) | SMALL | UP:\
  202.             i = wide; \
  203.             ROP(SUB,op1,op2);\
  204.             break
  205.  
  206. #define dprintf if(Bdebug)fprintf
  207. int Bdebug = 0;
  208.  
  209. static char nsrc[16] = {        /* fold no source cases */
  210.     0,0,0,0,
  211.     0xf&~DST, 0xf&~DST, 0xf&~DST, 0xf&~DST,
  212.     0xf&DST, 0xf&DST, 0xf&DST, 0xf&DST, 
  213.     0xf, 0xf, 0xf, 0xf
  214.     };
  215.  
  216. static char zsrc[16] = {        /* no source req'd cases */
  217.     1,0,0,0,0,
  218.     1,0,0,0,0,
  219.     1,0,0,0,0,
  220.     1 };    
  221.  
  222. mem_rop(dst,x_dst,y_dst,wide,high,op,src,x_src,y_src)
  223. BITMAP *dst;                /* bitmaps */
  224. BITMAP *src;                /* bitmaps */
  225. int x_dst,y_dst;            /* destination coords */
  226. int x_src,y_src;            /* source coords */
  227. int wide,high;                /* bitmap size */
  228. int op;                        /* bitmap function */
  229.    {
  230.     /* address registers */
  231.  
  232.     register int *d_base;            /* destination bitmap base addresses */
  233.     register int *s_base;            /* source bitmap base addresses */
  234.  
  235.     /* data registers */
  236.  
  237.     register int s_offset;            /* source bit offset */
  238.     register int d_skip;                /* bytes to next line in dst */
  239.     register int s_skip;                /* bits to next line in src */
  240.    register int i = 0;                /* temporary data register */
  241.                                             /* width in bits (<= 32 bits) */
  242.     register int count=high;        /* # of rows */
  243.    register int words;                /* words across in inner loop (>32 bits) */
  244.                                             /* dest bit offset (<= 32 bits) */
  245.  
  246.     /* temporary address reg. storage for 'i' above (>32 bits only) */
  247.  
  248.    register int *l_width;            /* bits on left to next long boundary */
  249.    register int *r_width;            /* bits from last long boundary on right */
  250.  
  251.     /* clipping and argument checking */
  252.  
  253.     if (!src) {
  254.       if (Bdebug && op&0xf != 0xf&nsrc[op&0xf])
  255.            dprintf(stderr,"no src, setting op %d -> %d\n",op&0xf,nsrc[op&0xf]);
  256.       op = 0xf&nsrc[op&0xf];                        /* a NULL src sources 1's */
  257.         }
  258.  
  259.     else if (zsrc[op&0xf])                     {
  260.       if (Bdebug && src)
  261.            dprintf(stderr,"op=%d, setting src->NULL\n",op&0xf);
  262.         src == BIT_NULL;                            /* don't check no src cases */
  263.         }
  264.     
  265.     if (wide<0) {
  266.         dprintf(stderr,"Clip: w<0 (%d)\n",wide);
  267.         x_dst += wide;
  268.         wide = - wide;
  269.         }
  270.  
  271.     if (count<0) {
  272.         y_dst += count;
  273.         count = - count;
  274.         dprintf(stderr,"Clip: h<0 (%d)\n",count);
  275.         }
  276.  
  277.    if (x_dst < 0) {
  278.         dprintf(stderr,"Clip: x_dst<0 (%d)\n",x_dst);
  279.         if (src)
  280.             x_src -= x_dst;
  281.         wide += x_dst;
  282.         x_dst = 0;
  283.         }
  284.  
  285.    if (y_dst < 0) {
  286.         dprintf(stderr,"Clip: y_dst<0 (%d)\n",y_dst);
  287.         if (src)
  288.             y_src -= y_dst;
  289.         count += y_dst;
  290.         y_dst = 0;
  291.         }
  292.  
  293.     if (src) {
  294.         if (x_src < 0) {
  295.             dprintf(stderr,"Clip: x_src<0 (%d)\n",x_src);
  296.             x_dst -= x_src;
  297.             wide += x_src;
  298.             x_src = 0;
  299.             }
  300.  
  301.         if (y_src < 0) {
  302.             dprintf(stderr,"Clip: y_src<0 (%d)\n",y_src);
  303.             y_dst-=y_src;
  304.             count+=y_src;
  305.             y_src=0;
  306.             }
  307.             
  308.         if ((i = x_src+wide - src->wide) > 0) {
  309.             dprintf(stderr,"Clip: wide too big for src (%d->%d)\n",wide,wide-i);
  310.             wide -= i;
  311.             }
  312.  
  313.         if ((i = y_src+count - src->high) > 0) {
  314.             dprintf(stderr,"Clip: high too big for src (%d->%d)\n",count,count-i);
  315.             count -= i;
  316.             }
  317.  
  318.         x_src += src->x0;
  319.         y_src += src->y0;
  320.         }
  321.  
  322.     if ((i = x_dst + wide - dst->wide) > 0) {
  323.         dprintf(stderr,"Clip: wide too big for dst (%d->%d)\n",wide,wide-i);
  324.         wide -= i;
  325.         }
  326.     if ((i = y_dst + count - dst->high) > 0) {
  327.         dprintf(stderr,"Clip: high too big for dst (%d->%d)\n",count,count-i);
  328.         count -= i;
  329.         }
  330.  
  331.     if (wide<1 || count < 1) {
  332.         dprintf(stderr,"Clip: high or wide < 1 (%d,%d)\n",wide,count);
  333.         return(-1);
  334.         }
  335.     x_dst += dst->x0;
  336.     y_dst += dst->y0;
  337.  
  338.  
  339.     /* end of clipping code */
  340.  
  341.    /* set up common initial conditions */
  342.  
  343.     if (wide <= 32) {            /* small cases */
  344.         i = SMALL;
  345.         }
  346.     else {
  347.         i = 0;
  348.         l_width = (int *) (32 - (x_dst&31));    /* bits on left edge 1-32 */
  349.         r_width = (int *) ((x_dst + wide) & 31);    /* bits on right edge 0-31 */
  350.         words =   (wide - (int) l_width)>>5;    /* longs in middle */
  351.         if (!r_width) {                                /* change 0-31 to 1-32 */
  352.             r_width = (int *) 32;
  353.             words--;
  354.             }
  355.         }
  356.  
  357.    /* find bitblt direction */
  358.  
  359.    if (src && src->data == dst->data)  {
  360.       if (y_dst>y_src)
  361.          i |= UP;
  362.       if (x_dst>x_src && wide > 32)
  363.            i |= LEFT;
  364.         }
  365.        
  366.     /* set initial conditions */
  367.  
  368.    switch(i) {
  369.     case 0:                /* top->bottom        left->right */
  370.       d_base = dst->data +((BIT_LINE(dst)*y_dst+x_dst+32)>>5);
  371.        d_skip = (BIT_LINE(dst)>>3) - (words<<2);        /* bytes to next row */
  372.         if (src) {
  373.             s_base = src->data;
  374.             s_skip = BIT_LINE(src) - (wide - (int)r_width);        /* in bits */
  375.             s_offset = BIT_LINE(src) * y_src + x_src;                /* in bits */
  376.             }
  377.         /* dprintf(stderr,"RIGHT DOWN\n"); */
  378.       break;
  379.  
  380.     case UP:                /* bottom->top        left->right */
  381.       d_base = dst->data +((BIT_LINE(dst)*(y_dst+count-1)+x_dst+32)>>5);
  382.        d_skip = (BIT_LINE(dst)>>3) + (words<<2);        /* bytes to next row */
  383.         s_base = src->data;
  384.         s_skip = BIT_LINE(src) + (wide - (int)r_width);        /* in bits */
  385.         s_offset = BIT_LINE(src) * (y_src+count-1) + x_src;
  386.         /* dprintf(stderr,"RIGHT UP\n"); */
  387.       break;
  388.  
  389.     case LEFT:            /* top->bottom        right->left */
  390.       d_base = dst->data +((BIT_LINE(dst)*y_dst+x_dst+wide-1)>>5);
  391.        d_skip = (BIT_LINE(dst)>>3) + (words<<2);        /* bytes to next row */
  392.         s_base = src->data;
  393.         s_skip = BIT_LINE(src) + (words<<5) + (int) l_width;
  394.         s_offset = BIT_LINE(src)*y_src + x_src+wide-(int)r_width;
  395.         /* dprintf(stderr,"LEFT DOWN\n"); */
  396.       break;
  397.  
  398.     case UP|LEFT:        /* bottom->top        right->left */
  399.       d_base = dst->data +((BIT_LINE(dst)*(y_dst+count-1)+x_dst+wide-1)>>5);
  400.        d_skip = (BIT_LINE(dst)>>3) - (words<<2);        /* bytes to next row */
  401.         s_base = src->data;
  402.         s_skip = BIT_LINE(src) - (words<<5) - (int) l_width;
  403.         s_offset = BIT_LINE(src)*(y_src+count-1) + x_src+wide-(int)r_width;
  404.         /* dprintf(stderr,"LEFT UP\n"); */
  405.       break;
  406.  
  407.     case SMALL:            /* <= 32 bits */
  408.         d_base =  dst->data;    /* destination base address */
  409.         d_skip = BIT_LINE(dst->primary);    /* bits/row */
  410.         words = d_skip*y_dst+x_dst;
  411.         if (src) {
  412.             s_base = src->data; /* source base address */
  413.             s_skip = BIT_LINE(src->primary);    /* bits/row */
  414.             s_offset = s_skip*y_src+x_src;
  415.             }
  416.         /* dprintf(stderr,"SMALL DOWN\n"); */
  417.       break;
  418.  
  419.     case SMALL | UP:
  420.         d_base =  dst->data;    /* destination base address */
  421.         d_skip = BIT_WIDE(dst->primary);    /* bits/row */
  422.         words = d_skip*(y_dst+count-1)+x_dst;
  423.         s_base = (int *) src->data; /* source base address */
  424.         s_skip = BIT_WIDE(src->primary);    /* bits/row */
  425.         s_offset = s_skip*(y_src+count-1)+x_src;
  426.         /* dprintf(stderr,"SMALL UP\n"); */
  427.       break;
  428.  
  429.     default:
  430.         dprintf(stderr,"Invalid direction: 0x%x\n",i);
  431.         break;
  432.         }
  433.  
  434. /*
  435.    dprintf(stderr,"op:%d d_base:0x%x\td_skip:%d\    (%d %d*32 %d)\n",
  436.                         op&0xf,d_base,d_skip,(int)l_width,words,(int)r_width);                    
  437.    if (src)
  438.         dprintf(stderr,"\ts_base:0x%x\ts_skip:%d\ts_offset:%d\n",
  439.                         s_base,s_skip,s_offset);                    
  440.  
  441.     dprintf(stderr,"go %x\n",i);
  442. */
  443.  
  444.     /* @+        DON't DISTURB THIS COMMENT */
  445.  
  446.     switch(op&0xf | i) {
  447.  
  448.         /* no source involvement <= 32 bits */
  449.  
  450.         case GET_OP(BIT_SET) | SMALL:
  451.         case GET_OP(BIT_SET) | UP | SMALL:
  452.             i = wide;
  453.             NO_SRC(BF_SET);
  454.             break;    
  455.         case GET_OP(BIT_CLR) | SMALL:
  456.         case GET_OP(BIT_CLR) | UP | SMALL:
  457.             i = wide;
  458.             NO_SRC(BF_CLR);
  459.             break;    
  460.         case GET_OP(BIT_NOT(BIT_DST)) | SMALL:
  461.         case GET_OP(BIT_NOT(BIT_DST)) | UP | SMALL:
  462.             i = wide;
  463.             NO_SRC(BF_INV);
  464.             break;    
  465.  
  466.         /* no dest involement */
  467.  
  468.         case GET_OP(BIT_SRC) | SMALL:
  469.             i = wide;
  470.             NO_DST(ADD,NOP);
  471.             break;
  472.         case GET_OP(~BIT_SRC) | SMALL:
  473.             i = wide;
  474.             NO_DST(ADD,NOT_SRC);
  475.             break;
  476.  
  477.         case GET_OP(BIT_SRC) | UP | SMALL:
  478.             i = wide;
  479.             NO_DST(SUB,NOP);
  480.             break;
  481.         case GET_OP(~BIT_SRC) | UP | SMALL:
  482.             i = wide;
  483.             NO_DST(SUB,NOT_SRC);
  484.             break;
  485.  
  486.         /* source and dest  and cases */
  487.  
  488.         SMALL_CASE(BIT_SRC&BIT_DST,AND,NOP);
  489.         SMALL_CASE(~(BIT_SRC&BIT_DST),AND,NOT_SRC);
  490.         SMALL_CASE(~BIT_SRC&BIT_DST,NOT_SRC,AND);
  491.         SMALL_CASE(BIT_SRC&~BIT_DST,NOT_DST,AND);
  492.  
  493.         /* source and dest  or cases */
  494.  
  495.         SMALL_CASE(BIT_SRC|BIT_DST,OR,NOP);
  496.         SMALL_CASE(~(BIT_SRC|BIT_DST),OR,NOT_SRC);
  497.         SMALL_CASE(~BIT_SRC|BIT_DST,NOT_SRC,OR);
  498.         SMALL_CASE(BIT_SRC|~BIT_DST,NOT_DST,OR);
  499.  
  500.         /* source and dest  xor cases */
  501.  
  502.         SMALL_CASE(BIT_SRC^BIT_DST,XOR,NOP);
  503.         SMALL_CASE(~(BIT_SRC^BIT_DST),XOR,NOT_SRC);
  504.  
  505.  
  506.         /****************************************************************
  507.          * > 32 bits
  508.          */
  509.  
  510.         /* no source involvement */
  511.  
  512.         case GET_OP(BIT_SET):
  513.         case GET_OP(BIT_SET) | UP:
  514.         case GET_OP(BIT_SET) | LEFT:
  515.         case GET_OP(BIT_SET) | UP | LEFT:
  516.             MOVEQ(0,$T_SRC);
  517.          NOT($T_SRC);
  518.           ROP1(BF_SET,set);
  519.          MOVE($T_SRC,INCR($d_base));
  520.            ROP2(BF_SET,set);
  521.             break;    
  522.  
  523.         case GET_OP(BIT_CLR):
  524.         case GET_OP(BIT_CLR) | UP:
  525.         case GET_OP(BIT_CLR) | LEFT:
  526.         case GET_OP(BIT_CLR) | UP | LEFT:
  527.             MOVEQ(0,$T_SRC);
  528.           ROP1(BF_CLR,clear);
  529.          MOVE($T_SRC,INCR($d_base));
  530.           ROP2(BF_CLR,clear);
  531.             break;    
  532.  
  533.         case GET_OP(~BIT_DST):
  534.         case GET_OP(~BIT_DST) | UP:
  535.         case GET_OP(~BIT_DST) | LEFT:
  536.         case GET_OP(~BIT_DST) | UP | LEFT:
  537.           ROP1(BF_INV,invert);
  538.            MOVE(IND($d_base),$T_SRC);
  539.           NOT($T_SRC);
  540.          MOVE($T_SRC,INCR($d_base));
  541.           ROP2(BF_INV,invert);
  542.             break;    
  543.  
  544.         /* source involvement, no DST  (this could be better) */
  545.       /* The optimizer doesn't toss the un-needed loads of the destination */
  546.  
  547.         ROP_CASE(BIT_SRC,src,NOP,NOP);
  548.         ROP_CASE(~BIT_SRC,not_src,NOP,NOT_SRC);
  549.  
  550.         /* source involvement  - and operations */
  551.  
  552.         ROP_CASE(BIT_SRC&BIT_DST,and,AND,NOP);
  553.         ROP_CASE(~(BIT_SRC&BIT_DST),not_and,AND,NOT_SRC);
  554.         ROP_CASE(~BIT_SRC&BIT_DST,mask,NOT_SRC,AND);
  555.         ROP_CASE(BIT_SRC&~BIT_DST,not_mask,NOT_DST,AND);
  556.  
  557.         /* source involvement  - or operations */
  558.  
  559.         ROP_CASE(BIT_SRC|BIT_DST,or,OR,NOP);
  560.         ROP_CASE(~(BIT_SRC|BIT_DST),not_or,OR,NOT_SRC);
  561.         ROP_CASE(~BIT_SRC|BIT_DST,project,NOT_SRC,OR);
  562.         ROP_CASE(BIT_SRC|~BIT_DST,not_project,NOT_DST,OR);
  563.  
  564.         /* source involvement  - xor operations */
  565.  
  566.         ROP_CASE(BIT_SRC^BIT_DST,xor,XOR,NOP);
  567.         ROP_CASE(~(BIT_SRC^BIT_DST),not_xor,XOR,NOT_SRC);
  568.  
  569.         /* no-op cases */
  570.  
  571.         case GET_OP(DST) :    
  572.         case GET_OP(DST) | LEFT:
  573.         case GET_OP(DST) | SMALL:
  574.         case GET_OP(DST) | UP | SMALL:
  575.             break;
  576.  
  577.       default:                                    /* not implemented */
  578.          fprintf(stderr,"operation 0x%x not implemented\n",op);
  579.          break;
  580.         }
  581.     return(0);
  582.       }
  583.