Annotation of 43BSDTahoe/new/X/libibm/bitblt/bitblt_subr.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char *rcsid_bitblt_subr_c = "$Header: bitblt_subr.c,v 10.1 86/11/19 10:51:21 jg Exp $";
        !             3: #endif lint
        !             4: /*
        !             5:  *             Copyright (c) 1986 Brown University
        !             6:  *
        !             7:  * Permission to use, copy, modify and distribute this software and its
        !             8:  * documentation for any purpose and without fee is hereby granted, provided
        !             9:  * that the above copyright notice appear in all copies, and that both
        !            10:  * that copyright notice and this permission notice appear in supporting
        !            11:  * documentation, and that the name of Brown University not be used in
        !            12:  * advertising or publicity pertaining to distribution of the software without
        !            13:  * specific, written prior permission. Brown University makes no
        !            14:  * representations about the suitability of this software for any purpose.
        !            15:  * It is provided "as-is" without express or implied warranty.
        !            16:  *
        !            17:  * Written by Daniel Stone, Brown University/IRIS  (des@iris)
        !            18:  */
        !            19: 
        !            20: /*
        !            21:  * CURRENT HISTORY:
        !            22:  *
        !            23:  * $Log:       bitblt_subr.c,v $
        !            24:  * Revision 10.1  86/11/19  10:51:21  jg
        !            25:  * Device dependent code for IBM displays.  General blitter...
        !            26:  * 
        !            27:  * Revision 4.0  86/09/25  10:03:10  des
        !            28:  * Version 4.0. Works with all IBM screens.
        !            29:  * 
        !            30:  * Revision 3.6  86/09/22  16:47:44  des
        !            31:  * Added a third argument to blt_init.
        !            32:  * 
        !            33:  * Revision 3.5  86/09/22  13:37:29  des
        !            34:  * Version 3.5. Removed all ifdef's that did not pertain to X.
        !            35:  * 
        !            36:  * Revision 3.0  86/09/17  10:29:59  des
        !            37:  * Version 3.0.  Works but has ifdef's for all systems.
        !            38:  * 
        !            39:  * Revision 7.0  86/07/03  10:40:03  des
        !            40:  * Release 7.0.
        !            41:  * 
        !            42:  * Revision 6.1  86/07/03  10:29:10  des
        !            43:  * Replaced certain mask rules.
        !            44:  * 
        !            45:  * Revision 6.0  86/06/18  11:19:59  des
        !            46:  * Changed unsigned short pointers to unsigned char pointers for efficiency
        !            47:  * reasons.  This change ment multiplying by 2 every variable added to
        !            48:  * these pointers.
        !            49:  * 
        !            50:  * Revision 5.0  86/05/21  14:26:02  des
        !            51:  * Revision 5.0.  No longer uses unsigned short pointers.
        !            52:  * 
        !            53:  * Revision 4.7  86/05/15  16:03:45  des
        !            54:  * Latest and faster version of the new copyBitPos loop.  Runs 5% to 7% faster
        !            55:  * than the old loop.
        !            56:  * 
        !            57:  * Revision 4.6  86/05/14  10:54:46  des
        !            58:  * Changed smallcopyBitPos_LOOP so that it checks for 1 or 2 words changed
        !            59:  * and branches to that loop.
        !            60:  * 
        !            61:  * Revision 4.5  86/05/14  10:31:57  des
        !            62:  * bitblt with NEW_LOOP (needs work.)
        !            63:  * 
        !            64:  * Revision 4.0  86/05/09  13:52:25  des
        !            65:  * Revision 4.0.  Apa-16 hardware enhancements Version 0.6.
        !            66:  * 
        !            67:  * Revision 3.2  86/04/30  15:34:16  des
        !            68:  * This version has smallcopyBitPos and the old copyBitPos.  The new copyBitPos
        !            69:  * took off .1 second on a 111 second blt. (new: 111.1 old:111.2) so what right?
        !            70:  * The old copyBitPos did not need smallcopyBitPos around so I figured it was
        !            71:  * better.
        !            72:  * 
        !            73:  * Revision 2.2  86/04/29  16:31:53  des
        !            74:  * Added the smallcopyBitPos routine for speeding up small blts.
        !            75:  * 
        !            76:  * Revision 3.0  86/04/28  16:59:20  des
        !            77:  * Runs with X. Version 0.5.
        !            78:  * 
        !            79:  * Revision 2.2  86/04/09  09:36:41  des
        !            80:  * Fixed APA-8 and APA-8C software locator problem.
        !            81:  * 
        !            82:  * Revision 2.1  86/04/04  12:19:38  des
        !            83:  * Moved copyBitNeg,copyBitPos,copyTile,maskBitNeg,maskBitPos,maskTile,
        !            84:  * clip_and_maskBitNeg,clip_and_maskBitPos and clip_and_maskTile to
        !            85:  * bitblt_subr.c.
        !            86:  */
        !            87: 
        !            88: #ifndef lint
        !            89: static char rcsid[] =
        !            90: "$Header: bitblt_subr.c,v 10.1 86/11/19 10:51:21 jg Exp $ (Brown/IRIS)";
        !            91: #endif
        !            92: 
        !            93: #include "bitblt_int.h"
        !            94: 
        !            95: /*
        !            96:  * Keep track of the first and one beyond the last address of the screen,
        !            97:  * so that current_screen.firstaddr <= some_base < current_screen.lastaddr
        !            98:  * is true if some_base is a pointer to a section of the screen.
        !            99:  */
        !           100: Blt_screen_info blt_cur_screen;
        !           101:  
        !           102: static Blt_Tile blt_black = {
        !           103:        0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
        !           104:        0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff
        !           105: };
        !           106: 
        !           107: extern Blt_Rectangle changed_rect;/* describes the area changed by the bltter */
        !           108: 
        !           109: /*
        !           110:  * Set 'ans' to the largest value and set 'diff' equal to the difference
        !           111:  * between 'ans' and 'a'.
        !           112:  */
        !           113: #define max_a(a,b,c,ans,diff) {                \
        !           114:        if (a >= b) {                   \
        !           115:                if (a >= c) {           \
        !           116:                        diff = 0;       \
        !           117:                        ans = a;        \
        !           118:                }                       \
        !           119:                else {                  \
        !           120:                        diff = c - a;   \
        !           121:                        ans = c;        \
        !           122:                }                       \
        !           123:        }                               \
        !           124:        else if (b > c) {               \
        !           125:                diff = b - a;           \
        !           126:                ans = b;                \
        !           127:        }                               \
        !           128:        else {                          \
        !           129:                diff = c - a;           \
        !           130:                ans = c;                \
        !           131:        }                               \
        !           132: }
        !           133: 
        !           134: /*
        !           135:  * Set 'ans' to the smallest value and set 'diff' equal to the difference
        !           136:  * between 'ans' and 'a'.
        !           137:  */
        !           138: #define min_a(a,b,c,ans,diff) {                \
        !           139:        if (a <= b) {                   \
        !           140:                if (a <= c) {           \
        !           141:                        diff = 0;       \
        !           142:                        ans = a;        \
        !           143:                }                       \
        !           144:                else {                  \
        !           145:                        diff = a - c;   \
        !           146:                        ans = c;        \
        !           147:                }                       \
        !           148:        }                               \
        !           149:        else if (b < c) {               \
        !           150:                diff = a - b;           \
        !           151:                ans = b;                \
        !           152:        }                               \
        !           153:        else {                          \
        !           154:                diff = a - c;           \
        !           155:                ans = c;                \
        !           156:        }                               \
        !           157: }
        !           158: 
        !           159: /* 
        !           160:  * Initialize the bitblt so that it knows where in the address space the 
        !           161:  * screen is and whether or not it uses a hardware or software cursor. 
        !           162:  */
        !           163: bitblt_init(screen_base,screen_wd,screen_ht,flags)
        !           164: unsigned short *screen_base;   /* The first address of the bitmap */
        !           165: long screen_wd;                        /* Screen width in BITS (will round up) */
        !           166: long screen_ht;                        /* Screen height in scan lines */
        !           167: unsigned long flags;           /* Indicates the type of cursor on the screen.*/
        !           168: {
        !           169:        blt_cur_screen.firstaddr = screen_base;
        !           170:        blt_cur_screen.lastaddr = (unsigned short *)((long)screen_base +
        !           171:                                  (((screen_wd+7)/8) * screen_ht));
        !           172:        blt_cur_screen.cursortype = flags;
        !           173: }
        !           174: 
        !           175: /*
        !           176:  * Blt_setup takes information from the user data and creates data
        !           177:  * to be used internally.  Specificly it creates clipped source rectangle
        !           178:  * if a source combination rule is given, a clipped destination rectangle
        !           179:  * the number of destination words to be changed across a scanline
        !           180:  * (nshorts) and masking bitmap rectangle masking is to be done.
        !           181:  * Finally the width and height and rule are filled in as width,
        !           182:  * height and rule.
        !           183:  * 
        !           184:  * If a bad pointer was encountered  (or something else is wrong) then
        !           185:  * blt_setup returns -1. Returns 0 if combination rule was a no-op and
        !           186:  * 1 if blt_setup finished ok.
        !           187:  */
        !           188: blt_setup(u_info,s_info)
        !           189: register Blt_userdata *u_info; /* User bitblt data */
        !           190: register Blt_sysdata *s_info;  /* bitblt internal data (This is modified
        !           191:                                   bitblt user data depending on the clipping
        !           192:                                   to be done. */
        !           193: {
        !           194:        register int x_orig,y_orig;/* because the destination x,y origin
        !           195:                                      is used so much, it will be put in
        !           196:                                      registers. */
        !           197:        register int Oxdiff,Cxdiff;/* If the destination rectangle is clipped
        !           198:                                      then these variables contain the
        !           199:                                      difference between the destination
        !           200:                                      rectangle and the rectangle used
        !           201:                                      to clip. */
        !           202:        register int Oydiff,Cydiff;/* If the destination rectangle is clipped
        !           203:                                      then these variables contain the
        !           204:                                      difference between the destination
        !           205:                                      rectangle and the rectangle used
        !           206:                                      to clip. */
        !           207: 
        !           208:        DEBUGF((blt_debug > 1),
        !           209:               printf("Enter blt_setup.0x%x\r\n",u_info->blt_flags));
        !           210: 
        !           211:        /*
        !           212:         * Set up the internal bltters combination rule.
        !           213:         */
        !           214:        s_info->rule = u_info->comb_rule;
        !           215: 
        !           216:        /*
        !           217:         * Set a flag indicating that the rule uses the source.
        !           218:         */
        !           219:        s_info->is_src = IS_SRC(s_info->rule);
        !           220: 
        !           221:        /*
        !           222:         * Make sure s_info->tile_ptr = 0. 
        !           223:         */
        !           224:        s_info->tile_ptr = (unsigned short *)0;
        !           225: 
        !           226:        /*
        !           227:         * Check the bltstruct to make sure every pointer is valid.
        !           228:         */
        !           229:        if (u_info == (Blt_userdata *)0) {
        !           230:                printf("Error: NULL bltstruct given!\n");
        !           231:                return(-1);
        !           232:        }
        !           233: 
        !           234:        if (u_info->dst_bitmap.base == (unsigned short *)0) {
        !           235:                printf("Error: NULL destination bitmap!\n");
        !           236:                return(-1);
        !           237:        }
        !           238: 
        !           239:        /*
        !           240:         * If a source combination rule was given and no bitmap was given then
        !           241:         * we assume the user wants US to assume that the source is infinitely
        !           242:         * large and is set to all one's.  This is the same thing as using
        !           243:         * the coorisponding tile rule and an all black tile.
        !           244:         */
        !           245:        if (s_info->is_src && u_info->src_bitmap.base == (unsigned short *)0) {
        !           246:                s_info->is_src = 0;
        !           247:                s_info->rule += SRC_TO_TILE;
        !           248:                s_info->tile_ptr = &blt_black.tile[0];
        !           249:        }
        !           250: 
        !           251:        /*
        !           252:         * Check the rule and if its a no-op then return immediately.
        !           253:         */
        !           254:        if (s_info->rule == DstCopy || s_info->rule == TileDstCopy) {
        !           255:                return(0);
        !           256:        }
        !           257: 
        !           258:        if (u_info->blt_flags & BLT_CLIPON) {
        !           259:                /* DEBUGF(blt_debug,printf("Clip.\r\n")); */
        !           260:                /*
        !           261:                 * Do some clipping.  We clip to the clipping rectangle,
        !           262:                 * the destination bitmap's rect and the destination
        !           263:                 * rectangle.  NOTE that if the destination rectangle
        !           264:                 * is clipped in any way then the source rectangle must
        !           265:                 * also be changed, thats why we keep track of the difference
        !           266:                 * in Oxdiff.
        !           267:                 *
        !           268:                 * Set the origin to be a zero based coorinate system.
        !           269:                 */
        !           270:                max_a(u_info->dst_rect.origin_x,
        !           271:                      u_info->clp_rect.origin_x,
        !           272:                      u_info->dst_bitmap.rect.origin_x,
        !           273:                      x_orig,Oxdiff);
        !           274: 
        !           275:                x_orig -= u_info->dst_bitmap.rect.origin_x;
        !           276: 
        !           277:                /*
        !           278:                 * Take the min value of the clipping rectangle X corner
        !           279:                 * coord, bitmap rectangle X corner coord. and the
        !           280:                 * destination rectangle X corner coord.. Cxdiff
        !           281:                 * contains the difference between dst_rect.corner_x and
        !           282:                 * the value returned.  Then convert to a zero based
        !           283:                 * coordinate system.
        !           284:                 */
        !           285:                min_a(u_info->dst_rect.corner_x,
        !           286:                      u_info->clp_rect.corner_x,
        !           287:                      u_info->dst_bitmap.rect.corner_x,
        !           288:                      s_info->dst.rect.corner_x,Cxdiff);
        !           289: 
        !           290:                s_info->dst.rect.corner_x -= u_info->dst_bitmap.rect.origin_x;
        !           291: 
        !           292:                /*
        !           293:                 * Take the max value of the clipping rectangle Y origin
        !           294:                 * coord, bitmap rectangle Y origin coord. and the
        !           295:                 * destination rectangle Y origin coord..  Oydiff
        !           296:                 * contains the difference between dst_rect.origin_y and
        !           297:                 * the value returned.  Then convert to a zero based
        !           298:                 * coordinate system.
        !           299:                 */
        !           300:                max_a(u_info->dst_rect.origin_y,
        !           301:                      u_info->clp_rect.origin_y,
        !           302:                      u_info->dst_bitmap.rect.origin_y,
        !           303:                      y_orig,Oydiff);
        !           304: 
        !           305:                y_orig -= u_info->dst_bitmap.rect.origin_y;
        !           306: 
        !           307:                /*
        !           308:                 * Take the min value of the clipping rectangle Y corner
        !           309:                 * coord, bitmap rectangle Y corner coord. and the
        !           310:                 * destination rectangle Y corner coord..  Cydiff
        !           311:                 * contains the difference between dst_rect.corner_y and
        !           312:                 * the value returned.  Then convert to a zero based
        !           313:                 * coordinate system.
        !           314:                 */
        !           315:                min_a(u_info->dst_rect.corner_y,
        !           316:                      u_info->clp_rect.corner_y,
        !           317:                      u_info->dst_bitmap.rect.corner_y,
        !           318:                      s_info->dst.rect.corner_y,Cydiff);
        !           319: 
        !           320:                s_info->dst.rect.corner_y -= u_info->dst_bitmap.rect.origin_y;
        !           321: /*
        !           322:  *             printf("dst:\t%4d,%4d,%4d,%4d\n",x_orig,
        !           323:  *                     y_orig,s_info->dst.rect.corner_x,
        !           324:  *                     s_info->dst.rect.corner_y);
        !           325:  *             printf("diffs:\t%4d,%4d,%4d,%4d\n",Oxdiff,Oydiff,Cxdiff,Cydiff);
        !           326:  */
        !           327: 
        !           328:                /*
        !           329:                 * Adjust source if necessary. (May only be using a tile.)
        !           330:                 */
        !           331:                if (s_info->is_src) {
        !           332:                        /*
        !           333:                         * We may have done some clipping. If X was clipped
        !           334:                         * then the section of the source that would have
        !           335:                         * been mapped to the clipped section of the
        !           336:                         * destination must also be clipped.
        !           337:                         *      In other words if one clips the destination one
        !           338:                         * must also clip the source.  Anyways 'Oxdiff' is set
        !           339:                         * to the difference.  Then we subtract the rect
        !           340:                         * of the source bitmap so as to get the source into
        !           341:                         * the same coordinate system as the destination,
        !           342:                         * a zero based system.
        !           343:                         */ 
        !           344:                        s_info->src.rect.origin_x = u_info->src_rect.origin_x +
        !           345:                                                    Oxdiff -
        !           346:                                               u_info->src_bitmap.rect.origin_x;
        !           347: 
        !           348:                        /*
        !           349:                         * If Y was clipped then the section of source
        !           350:                         * that would have mapped to the clipped section
        !           351:                         * of the destination must also be clipped.
        !           352:                         */
        !           353:                        s_info->src.rect.origin_y = u_info->src_rect.origin_y +
        !           354:                                                    Oydiff -
        !           355:                                               u_info->src_bitmap.rect.origin_y;
        !           356: 
        !           357:                        /*
        !           358:                         * Now clip to the source bitmap's origin which is
        !           359:                         * now 0,0 because we subtracted its origin above.
        !           360:                         */
        !           361:                        if (s_info->src.rect.origin_x < 0) {
        !           362:                                /*
        !           363:                                 * The source rectangle has been clipped so
        !           364:                                 * the destination rectangle must also be
        !           365:                                 * clipped.
        !           366:                                 */
        !           367:                                x_orig -= s_info->src.rect.origin_x;
        !           368:                                s_info->src.rect.origin_x = 0;
        !           369:                        }
        !           370:                        if (s_info->src.rect.origin_y < 0) {
        !           371:                                /*
        !           372:                                 * The source rectangle has been clipped so
        !           373:                                 * the destination rectangle must also be
        !           374:                                 * clipped.
        !           375:                                 */
        !           376:                                y_orig -= s_info->src.rect.origin_y;
        !           377:                                s_info->src.rect.origin_y = 0;
        !           378:                        }
        !           379: 
        !           380:                        /*
        !           381:                         * Calculate the source rectangle's corner rect.
        !           382:                         * NOTE: We are not setting these rect to a zero
        !           383:                         *       based system yet.
        !           384:                         */
        !           385:                        s_info->src.rect.corner_x = u_info->src_rect.corner_x -
        !           386:                                                    Cxdiff;
        !           387:                        s_info->src.rect.corner_y = u_info->src_rect.corner_y -
        !           388:                                                    Cydiff;
        !           389: 
        !           390:                        /*
        !           391:                         * Clip these rect to the corner of the source
        !           392:                         * bitmap corner rect.
        !           393:                         */
        !           394:                        if (s_info->src.rect.corner_x >
        !           395:                                             u_info->src_bitmap.rect.corner_x) {
        !           396:                                s_info->src.rect.corner_x =
        !           397:                                               u_info->src_bitmap.rect.corner_x;
        !           398:                        }
        !           399:                        if (s_info->src.rect.corner_y >
        !           400:                                             u_info->src_bitmap.rect.corner_y) {
        !           401:                                s_info->src.rect.corner_y =
        !           402:                                               u_info->src_bitmap.rect.corner_y;
        !           403:                        }
        !           404: 
        !           405:                        /*
        !           406:                         * Now set these rect to a zero based coordinate
        !           407:                         * system.
        !           408:                         */
        !           409:                        s_info->src.rect.corner_x -=
        !           410:                                               u_info->src_bitmap.rect.origin_x;
        !           411:                        s_info->src.rect.corner_y -=
        !           412:                                               u_info->src_bitmap.rect.origin_y;
        !           413: 
        !           414:                        /*
        !           415:                         * Calculate the width in pixels of the blt area
        !           416:                         * using the smaller of the two widths found in
        !           417:                         * the source and destination rectangles.
        !           418:                         */
        !           419:                        if ((s_info->src.rect.corner_x -
        !           420:                             s_info->src.rect.origin_x) >
        !           421:                            (s_info->dst.rect.corner_x - x_orig)) {
        !           422:                                s_info->width = s_info->dst.rect.corner_x -
        !           423:                                                x_orig;
        !           424:                        }
        !           425:                        else {
        !           426:                                s_info->width = s_info->src.rect.corner_x -
        !           427:                                                s_info->src.rect.origin_x;
        !           428: 
        !           429:                                /*
        !           430:                                 * Must change the destination corner.
        !           431:                                 */
        !           432:                                s_info->dst.rect.corner_x = x_orig +
        !           433:                                                            s_info->width;
        !           434:                        }
        !           435: 
        !           436:                        /*
        !           437:                         * Calculate the height in scanlines of the blt area
        !           438:                         * using the smaller of the two heights found in 
        !           439:                         * the source and destination rectangles.
        !           440:                         */
        !           441:                        if ((s_info->src.rect.corner_y -
        !           442:                             s_info->src.rect.origin_y) >
        !           443:                            (s_info->dst.rect.corner_y - y_orig)) {
        !           444:                                s_info->height = s_info->dst.rect.corner_y -
        !           445:                                                 y_orig;
        !           446:                        }
        !           447:                        else {
        !           448:                                s_info->height = s_info->src.rect.corner_y -
        !           449:                                                 s_info->src.rect.origin_y;
        !           450: 
        !           451:                                /*
        !           452:                                 * Must change the destination corner.
        !           453:                                 */
        !           454:                                s_info->dst.rect.corner_y = y_orig +
        !           455:                                                            s_info->height;
        !           456:                        }
        !           457: 
        !           458:                        /*
        !           459:                         * Set up source corners to BE CLOSED CORNERS.
        !           460:                         * This is done because alot of -1's are being used in
        !           461:                         * calculations of pointers when copying bitmaps from
        !           462:                         * corner_y to origin_y, corner_x to origin_x.
        !           463:                         * (for copyBitNeg(), see calculateOffsets())
        !           464:                         */
        !           465:                        s_info->src.rect.origin_x = s_info->src.rect.origin_x;
        !           466:                        s_info->src.rect.origin_y = s_info->src.rect.origin_y;
        !           467:                        s_info->src.rect.corner_x = s_info->src.rect.origin_x +
        !           468:                                                    s_info->width - 1;
        !           469:                        s_info->src.rect.corner_y = s_info->src.rect.origin_y +
        !           470:                                                    s_info->height - 1;
        !           471:                }
        !           472:                else {
        !           473:                        /*
        !           474:                         * Calculate the width in pixels and the height in
        !           475:                         * scanlines.
        !           476:                         */
        !           477:                        s_info->width = s_info->dst.rect.corner_x - x_orig;
        !           478:                        s_info->height = s_info->dst.rect.corner_y - y_orig;
        !           479:                }
        !           480:        }
        !           481:        else {
        !           482:                /*
        !           483:                 * Assume that the user has set everything up legally and
        !           484:                 * all we have to do is set up our bltter (internal)
        !           485:                 * coordinates.
        !           486:                 *
        !           487:                 * Set up the x origin and width.
        !           488:                 */
        !           489:                x_orig = u_info->dst_rect.origin_x;
        !           490:                s_info->width = u_info->dst_rect.corner_x - x_orig;
        !           491: 
        !           492:                /*
        !           493:                 * Set up y origin and height.
        !           494:                 */
        !           495:                y_orig = u_info->dst_rect.origin_y;
        !           496:                s_info->height = u_info->dst_rect.corner_y - y_orig;
        !           497: 
        !           498:                /*
        !           499:                 * Convert to zero based coordinate system.
        !           500:                 */
        !           501:                x_orig -= u_info->dst_bitmap.rect.origin_x;
        !           502:                y_orig -= u_info->dst_bitmap.rect.origin_y;
        !           503: 
        !           504:                /*
        !           505:                 * Set up the destination corners.
        !           506:                 */
        !           507:                s_info->dst.rect.corner_x = x_orig + s_info->width;
        !           508:                s_info->dst.rect.corner_y = y_orig + s_info->height;
        !           509: 
        !           510: 
        !           511:                /*
        !           512:                 * Adjust source if necessary. (May only be using a tile.)
        !           513:                 */
        !           514:                if (s_info->is_src) {
        !           515:                        /*
        !           516:                         * We must have source and destination coordinates
        !           517:                         * which are in the same coordinate system, a
        !           518:                         * zero-based coordinate system in this case.
        !           519:                         */
        !           520:                        s_info->src.rect.origin_x = u_info->src_rect.origin_x -
        !           521:                                               u_info->src_bitmap.rect.origin_x;
        !           522:                        s_info->src.rect.origin_y = u_info->src_rect.origin_y -
        !           523:                                               u_info->src_bitmap.rect.origin_y;
        !           524: 
        !           525:                        /*
        !           526:                         * Set up source corners to BE CLOSED CORNERS.
        !           527:                         * This is done because alot of -1's are being used in
        !           528:                         * calculations of pointers when copying bitmaps from
        !           529:                         * corner_y to origin_y, corner_x to origin_x.
        !           530:                         * (for copyBitNeg(), see calculateOffsets())
        !           531:                         */
        !           532:                        s_info->src.rect.corner_x = s_info->src.rect.origin_x +
        !           533:                                                    s_info->width - 1;
        !           534:                        s_info->src.rect.corner_y = s_info->src.rect.origin_y +
        !           535:                                                    s_info->height - 1;
        !           536:                }
        !           537:        }
        !           538: 
        !           539:        /*
        !           540:         * Keep the final rectangle for outside use.  (Others can extern
        !           541:         * changed_rect.)
        !           542:         */
        !           543:        changed_rect.origin_x = x_orig;
        !           544:        changed_rect.origin_y = y_orig;
        !           545:        changed_rect.corner_x = s_info->dst.rect.corner_x;
        !           546:        changed_rect.corner_y = s_info->dst.rect.corner_y;
        !           547: 
        !           548:        /*
        !           549:         * Set up destination corners to BE CLOSED CORNERS.  This is done
        !           550:         * because alot of -1's are being used in calculations of pointers when 
        !           551:         * copying bitmaps from corner_y to origin_y, corner_x to
        !           552:         * origin_x. (for copyBitNeg(), see calculateOffsets())
        !           553:         */
        !           554:        s_info->dst.rect.corner_x -= 1;
        !           555:        s_info->dst.rect.corner_y -= 1;
        !           556: 
        !           557:        /*
        !           558:         * Set up the number of words across the destination that will be
        !           559:         * affected. (Because we subracted one we don't have to subtract one
        !           560:         * from dst.rect.corner_x.)
        !           561:         */
        !           562:        if ((s_info->nshorts = (DIV_BPW(s_info->dst.rect.corner_x) -
        !           563:            DIV_BPW(x_orig)) + 1) < 1) {
        !           564:                /*
        !           565:                 * nshorts should always be positive.
        !           566:                 */
        !           567:                DEBUGF((blt_debug),
        !           568:                        printf("dst cx,ox: %d,%d nshorts = %d - %d\n",
        !           569:                                s_info->dst.rect.corner_x,x_orig,
        !           570:                                DIV_BPW(s_info->dst.rect.corner_x),
        !           571:                                DIV_BPW(x_orig)));
        !           572:                return(0);
        !           573:        }
        !           574:        DEBUGF((blt_debug),
        !           575:                        printf("dst cx,ox: %d,%d nshorts = %d - %d, (IS %d)\n",
        !           576:                                s_info->dst.rect.corner_x,x_orig,
        !           577:                                DIV_BPW(s_info->dst.rect.corner_x),
        !           578:                                DIV_BPW(x_orig),s_info->nshorts));
        !           579: 
        !           580:        /*
        !           581:         * NOTE: This program ASSUMES that msk_bitmap's bounds are within
        !           582:         *       the bounds of the msk_bitmap.  If not, bummer.
        !           583:         *
        !           584:         * Mask bitmap specified?? Set up mask corners.
        !           585:         */
        !           586:        if (u_info->blt_flags & BLT_MASKON) {
        !           587:                /*
        !           588:                 * Currently, the msk_bitmap's rect is in destination
        !           589:                 * coordinates and msk_bitmap.rect picks out the area of the
        !           590:                 * mask to be used.
        !           591:                 * 
        !           592:                 * Align the mask bitmap with the destination rectangle.
        !           593:                 * Because the x_orig is zero based and the
        !           594:                 * msk_bitmap box is not we add back the dst_bitmap.rect.
        !           595:                 * This has the effect of putting the mask corners into
        !           596:                 * a zero based coordinate system.
        !           597:                 */
        !           598:                s_info->msk.rect.origin_x = x_orig +
        !           599:                                            u_info->dst_bitmap.rect.origin_x -
        !           600:                                            u_info->msk_bitmap.rect.origin_x;
        !           601:                s_info->msk.rect.corner_x = s_info->msk.rect.origin_x +
        !           602:                                            s_info->width - 1;
        !           603:                s_info->msk.rect.origin_y = y_orig +
        !           604:                                            u_info->dst_bitmap.rect.origin_y -
        !           605:                                            u_info->msk_bitmap.rect.origin_y;
        !           606:                s_info->msk.rect.corner_y = s_info->msk.rect.origin_y +
        !           607:                                            s_info->height - 1;
        !           608: 
        !           609:                /*
        !           610:                 * At some point it may be smart to check the clip flag and
        !           611:                 * clip this also.
        !           612:                 *
        !           613:                 * if (u_info->blt_flags & BLT_CLIPON) {
        !           614:                 * }
        !           615:                 */
        !           616:        }
        !           617: 
        !           618:        /*
        !           619:         * Set the temp varibles into the system data structure.
        !           620:         */
        !           621:        s_info->dst.rect.origin_x = x_orig;
        !           622:        s_info->dst.rect.origin_y = y_orig;
        !           623: 
        !           624:        return(1);
        !           625: }
        !           626: 
        !           627: /*
        !           628:  * This part of this file should be moved to another file someday.
        !           629:  */
        !           630: 
        !           631: #define MSK_SKEW 0x01
        !           632: #define SRC_SKEW 0x02
        !           633: 
        !           634: /*
        !           635:  * Macros for the operations.
        !           636:  */
        !           637: 
        !           638: #define SrcCopy_MASK(src,dst,mask)    dst = ((dst) & ~(mask)) |  \
        !           639:                                            ((src) & mask)
        !           640: 
        !           641: /*
        !           642:  * Old SrcOr rule.
        !           643:  * #define SrcOr_MASK(src,dst,mask)      dst = ((dst) & ~(mask)) |  \
        !           644:  *                                         (((dst) | (src)) & mask)
        !           645:  */
        !           646: #define SrcOr_MASK(src,dst,mask)      dst = ((dst) | ((src) & mask))
        !           647: 
        !           648: /*
        !           649:  * Old SrcXor rule.
        !           650:  * #define SrcXor_MASK(src,dst,mask)     dst = ((dst) & ~(mask)) |  \
        !           651:  *                                         (((dst) ^ (src)) & mask)
        !           652:  */
        !           653: #define SrcXor_MASK(src,dst,mask)     dst = ((dst) ^ ((src) & mask))
        !           654: 
        !           655: #define SrcAnd_MASK(src,dst,mask)      dst = ((dst) & ~(mask)) |  \
        !           656:                                            (((dst) & (src)) & mask)
        !           657: 
        !           658: #define NotSrcCopy_MASK(src,dst,mask) dst = ((dst) & ~(mask)) |  \
        !           659:                                            (~(src) & mask)
        !           660: 
        !           661: /*
        !           662:  * Old NotSrcOr rule.
        !           663:  * #define NotSrcOr_MASK(src,dst,mask)   dst = ((dst) & ~(mask)) |  \
        !           664:  *                                         (((dst) | ~(src)) & mask)
        !           665:  */
        !           666: #define NotSrcOr_MASK(src,dst,mask)   dst = ((dst) | (~(src) & mask))
        !           667: 
        !           668: /*
        !           669:  * Old NotSrcXor rule.
        !           670:  * #define NotSrcXor_MASK(src,dst,mask)  dst = ((dst) & ~(mask)) |  \
        !           671:  *                                         (((dst) ^ ~(src)) & mask)
        !           672:  */
        !           673: #define NotSrcXor_MASK(src,dst,mask)  dst = ((dst) ^ (~(src) & mask))
        !           674: 
        !           675: #define NotSrcAnd_MASK(src,dst,mask)  dst = ((dst) & ~(mask)) |  \
        !           676:                                            (((dst) & ~(src)) & mask)
        !           677: /*
        !           678:  * DstCopy is a no-op.
        !           679:  */
        !           680: 
        !           681: #define SrcAndNotDst_MASK(src,dst,mask) dst = ((dst) & ~(mask)) |  \
        !           682:                                              ((~(dst) & (src)) & mask)
        !           683: 
        !           684: #define SrcOrNotDst_MASK(src,dst,mask)     dst = ((dst) & ~(mask)) |  \
        !           685:                                                 ((~(dst) | (src)) & mask)
        !           686: 
        !           687: #define NotDstCopy_MASK(src,dst,mask)      dst = ((dst) & ~(mask)) | \
        !           688:                                                 (~(dst) & (mask))
        !           689: 
        !           690: #define NotSrcAndNotDst_MASK(src,dst,mask) dst = ((dst) & ~(mask)) |  \
        !           691:                                                 ((~(dst) & ~(src)) & mask)
        !           692: 
        !           693: #define NotSrcOrNotDst_MASK(src,dst,mask)  dst = ((dst) & ~(mask)) |  \
        !           694:                                                 ((~(dst) | ~(src)) & mask)
        !           695: 
        !           696: #define SrcCopy_OP(src,dst)    dst = (src)
        !           697: #define SrcOr_OP(src,dst)      dst = (dst) | (src)
        !           698: #define SrcXor_OP(src,dst)     dst = (dst) ^ (src)
        !           699: #define SrcAnd_OP(src,dst)     dst = (dst) & (src)
        !           700: #define NotSrcCopy_OP(src,dst) dst = ~(src)
        !           701: #define NotSrcOr_OP(src,dst)   dst = (dst) | ~(src)
        !           702: #define NotSrcXor_OP(src,dst)  dst = (dst) ^ ~(src)
        !           703: #define NotSrcAnd_OP(src,dst)  dst = (dst) & ~(src)
        !           704: /*
        !           705:  * DstCopy is a no-op (dst = (dst)).
        !           706:  */
        !           707: #define SrcOrNotDst_OP(src,dst)     dst = (~(dst) | (src))
        !           708: #define SrcAndNotDst_OP(src,dst)    dst = (~(dst) & (src))
        !           709: #define NotDstCopy_OP(src,dst)      dst = ~(dst)
        !           710: #define NotSrcOrNotDst_OP(src,dst)  dst = (~(dst) | ~(src))
        !           711: #define NotSrcAndNotDst_OP(src,dst) dst = (~(dst) & ~(src))
        !           712: 
        !           713: /*
        !           714:  * Make the mask and operation macros for tiles.
        !           715:  */
        !           716: #define TileCopy_MASK(tile,dst,mask)    dst = ((dst) & ~(mask)) |  \
        !           717:                                              ((tile) & mask)
        !           718: 
        !           719: #define TileOr_MASK(tile,dst,mask)      dst = ((dst) & ~(mask)) |  \
        !           720:                                              (((dst) | (tile)) & mask)
        !           721: 
        !           722: #define TileXor_MASK(tile,dst,mask)     dst = ((dst) & ~(mask)) |  \
        !           723:                                              (((dst) ^ (tile)) & mask)
        !           724: 
        !           725: #define NotTileAnd_MASK(tile,dst,mask)  dst = ((dst) & ~(mask)) |  \
        !           726:                                              (((dst) & ~(tile)) & mask)
        !           727: 
        !           728: #define NotTileCopy_MASK(tile,dst,mask) dst = ((dst) & ~(mask)) |  \
        !           729:                                              (~(tile) & mask)
        !           730: 
        !           731: #define NotTileOr_MASK(tile,dst,mask)   dst = ((dst) & ~(mask)) |  \
        !           732:                                              (((dst) | ~(tile)) & mask)
        !           733: 
        !           734: #define NotTileXor_MASK(tile,dst,mask)  dst = ((dst) & ~(mask)) |  \
        !           735:                                              (((dst) ^ ~(tile)) & mask)
        !           736: 
        !           737: #define TileAnd_MASK(tile,dst,mask)     dst = ((dst) & ~(mask)) |  \
        !           738:                                              (((dst) & (tile)) & mask)
        !           739: 
        !           740: #define TileOrNotDst_MASK(tile,dst,mask)      dst = ((dst) & ~(mask)) |  \
        !           741:                                                    ((~(dst) | (tile)) & mask)
        !           742: 
        !           743: #define NotTileAndNotDst_MASK(tile,dst,mask)  dst = ((dst) & ~(mask)) |  \
        !           744:                                                    ((~(dst) & ~(tile)) & mask)
        !           745: 
        !           746: #define NotTileOrNotDst_MASK(tile,dst,mask)   dst = ((dst) & ~(mask)) |  \
        !           747:                                                    ((~(dst) | ~(tile)) & mask)
        !           748: 
        !           749: #define TileAndNotDst_MASK(tile,dst,mask)     dst = ((dst) & ~(mask)) |  \
        !           750:                                                    ((~(dst) & (tile)) & mask)
        !           751: 
        !           752: #define TileCopy_OP(tile,dst)   dst = (tile)
        !           753: #define TileOr_OP(tile,dst)     dst = (dst) | (tile)
        !           754: #define TileXor_OP(tile,dst)    dst = (dst) ^ (tile)
        !           755: #define NotTileAnd_OP(tile,dst)         dst = (dst) & ~(tile)
        !           756: #define NotTileCopy_OP(tile,dst) dst = ~(tile)
        !           757: #define NotTileOr_OP(tile,dst)  dst = (dst) | ~(tile)
        !           758: #define NotTileXor_OP(tile,dst)         dst = (dst) ^ ~(tile)
        !           759: #define TileAnd_OP(tile,dst)    dst = (dst) & (tile)
        !           760: 
        !           761: #define TileOrNotDst_OP(tile,dst)      dst = ~(dst) | (tile)
        !           762: #define NotTileAndNotDst_OP(tile,dst)  dst = ~(dst) & ~(tile)
        !           763: #define NotTileOrNotDst_OP(tile,dst)   dst = ~(dst) | ~(tile)
        !           764: #define TileAndNotDst_OP(tile,dst)     dst = ~(dst) & (tile)
        !           765: 
        !           766: #if (APA8 || APA8C)
        !           767: /*
        !           768:  * Defines for how a pointer is incremented.  This is needed because one must
        !           769:  * increment a pointer to the APA-8 bitmap by 2.
        !           770:  */
        !           771: #define DECR_SRC(src)  src -= src_plus
        !           772: #define DECR_DST(dst)  dst -= dst_plus
        !           773: #define INCR_SRC(src)  src += src_plus
        !           774: #define INCR_DST(dst)  dst += dst_plus
        !           775: #define MINUS_SRC(src) ((unsigned short *)(src - src_plus))
        !           776: #define PLUS_SRC(src)  ((unsigned short *)(src + src_plus))
        !           777: #else no APA8 stuff
        !           778: /*
        !           779:  * Defines for how normal pointers are incremented.
        !           780:  */
        !           781: #define DECR_SRC(src)  (src -= 2)
        !           782: #define DECR_DST(dst)  (dst -= 2)
        !           783: #define INCR_SRC(src)  (src += 2)
        !           784: #define INCR_DST(dst)  (dst += 2)
        !           785: #define MINUS_SRC(src) ((unsigned short *)(src - 2))
        !           786: #define PLUS_SRC(src)  ((unsigned short *)(src + 2))
        !           787: #endif
        !           788: 
        !           789: #define SRC    ((unsigned short *)src)
        !           790: #define DST    ((unsigned short *)dst)
        !           791: #define TILE   ((unsigned short *)tile)
        !           792: #define MSK    ((unsigned short *)msk)
        !           793: #define CLP    ((unsigned short *)clp)
        !           794: 
        !           795: #define DECR_MSK(msk)  (msk -= 2)
        !           796: #define INCR_MSK(msk)  (msk += 2)
        !           797: #define MINUS_MSK(msk) ((unsigned short *)(msk - 2))
        !           798: #define PLUS_MSK(msk)  ((unsigned short *)(msk + 2))
        !           799: 
        !           800: #define DECR_CLP(clp)  (clp -= 2)
        !           801: #define INCR_CLP(clp)  (clp += 2)
        !           802: #define MINUS_CLP(clp) ((unsigned short *)(clp - 2))
        !           803: #define PLUS_CLP(clp)  ((unsigned short *)(clp + 2))
        !           804: 
        !           805: /*
        !           806:  * Macro to increment the tile pointer.  If last_ptr is reached then the
        !           807:  * pointer is decremented back to the beginning of the tile struct.
        !           808:  */
        !           809: #define INCR_TILE_PTR(ptr,last_ptr) ((ptr==last_ptr) ? (ptr -= 30) : (ptr += 2))
        !           810: 
        !           811: /*
        !           812:  * This loop copies bits from right to left, bottom to top.  It takes as
        !           813:  * arguments 1 of 8 masking macros and the coorisponding generic macro.
        !           814:  * The general scheme is this:
        !           815:  *     Foreach row do
        !           816:  *             Take care of the first word priming if necessary. (Done because
        !           817:  *                     the first word uses the RIGHT edge mask.)
        !           818:  *
        !           819:  *             If there is a skew then (Means parts of 2 source words make one
        !           820:  *                     destination word.)
        !           821:  *                     For each word between the first and last word do
        !           822:  *                             Shift the source word and source word -1 and
        !           823:  *                                     write the word to the destination.
        !           824:  *                     endfor
        !           825:  *
        !           826:  *                     Take care of the last word. (Done here and not in 
        !           827:  *                             the loop because the last word uses the 
        !           828:  *                             LEFT edge mask.)
        !           829:  * 
        !           830:  *             else  The skew is zero meaning 1 source word per destination
        !           831:  *                   word.
        !           832:  * 
        !           833:  *                     For each word between the first and last word do
        !           834:  *                             Write the source word into the destination word.
        !           835:  *                     endfor
        !           836:  *
        !           837:  *                     Take care of the last word. (Done here and not in 
        !           838:  *                             the loop because the last word uses the 
        !           839:  *                             LEFT edge mask.)
        !           840:  *             endif
        !           841:  *
        !           842:  *             DECREMENT the source and destination pointers to point to the
        !           843:  *                     next row.
        !           844:  *     endfor
        !           845:  *
        !           846:  */
        !           847: #define copyBitNeg_LOOP(EDGE_OP,OP) {                                  \
        !           848:        while (--s_info->height) {                                      \
        !           849:                wordnum = s_info->nshorts;                              \
        !           850:                if (s_info->preload_src) {                              \
        !           851:                        EDGE_OP((*SRC >> skew_src) |                    \
        !           852:                                (*(MINUS_SRC(src)) << (inv_skew_src)),  \
        !           853:                                *DST,s_info->right_mask);               \
        !           854:                        DECR_SRC(src);                                  \
        !           855:                }                                                       \
        !           856:                else {                                                  \
        !           857:                        EDGE_OP((*SRC << (inv_skew_src)),*DST,          \
        !           858:                                s_info->right_mask);                    \
        !           859:                }                                                       \
        !           860:                if (--wordnum != 0) {                                   \
        !           861:                        DECR_DST(dst);                                  \
        !           862:                        if (skew_src & 0xf) {                           \
        !           863:                                while (wordnum > 1) {                   \
        !           864:                                        OP((*SRC >> skew_src) |         \
        !           865:                                           (*(MINUS_SRC(src))<<(inv_skew_src)),\
        !           866:                                           *DST);                       \
        !           867:                                        DECR_SRC(src);                  \
        !           868:                                        DECR_DST(dst);                  \
        !           869:                                        wordnum--;                      \
        !           870:                                }                                       \
        !           871:                                EDGE_OP((*SRC >> skew_src) |            \
        !           872:                                        (*(MINUS_SRC(src)) << (inv_skew_src)),\
        !           873:                                        *DST,s_info->left_mask);        \
        !           874:                                DECR_SRC(src);                          \
        !           875:                        }                                               \
        !           876:                        else {                                          \
        !           877:                                while (wordnum > 1) {                   \
        !           878:                                        DECR_SRC(src);                  \
        !           879:                                        OP(*SRC,*DST);                  \
        !           880:                                        DECR_DST(dst);                  \
        !           881:                                        wordnum--;                      \
        !           882:                                }                                       \
        !           883:                                DECR_SRC(src);                          \
        !           884:                                EDGE_OP(*SRC,*DST,s_info->left_mask);   \
        !           885:                        }                                               \
        !           886:                }                                                       \
        !           887:        src -= s_info->src.nextline;                                    \
        !           888:        dst -= s_info->dst.nextline;                                    \
        !           889:        }                                                               \
        !           890: }
        !           891: 
        !           892: /*
        !           893:  * Do setup and dereferencing of 5 of the most important Blt_sysdata variables.
        !           894:  * Then do a switch on the combination rule to do the correct loop.  Each loop
        !           895:  * copies from right to left, bottom to top.
        !           896:  */
        !           897: copyBitNeg(s_info)
        !           898: register Blt_sysdata *s_info;
        !           899: {
        !           900:        register unsigned char *src; /* Register pointers are declared as  */
        !           901:                                     /* unsigned char pointers. This is an */
        !           902:        register unsigned char *dst; /* optimization to get around extra   */
        !           903:                                     /* addressing in the assembler.       */
        !           904: #if (APA8 || APA8C)
        !           905:        register int src_plus;
        !           906:        register int dst_plus;
        !           907: #endif
        !           908:        register int wordnum;
        !           909:        register int skew_src;
        !           910:        register int inv_skew_src;
        !           911: 
        !           912: #if (APA8 || APA8C)
        !           913:        src_plus = s_info->src_plus;
        !           914:        dst_plus = s_info->dst_plus;
        !           915: #endif
        !           916: 
        !           917:        src = (unsigned char *)s_info->src.data;
        !           918:        dst = (unsigned char *)s_info->dst.data;
        !           919: 
        !           920:        /*
        !           921:         * Set up the inverted skew number which is used to shift stuff the
        !           922:         * other direction.
        !           923:         */
        !           924:        skew_src = s_info->skew_src;
        !           925:        inv_skew_src = BPW - skew_src;
        !           926: 
        !           927:        DEBUGF(blt_debug,
        !           928:                printf("Enter copyBitNeg s:%d,p:%d,ws:%d r:%d\r\n",
        !           929:                        s_info->skew_src,s_info->preload_src,
        !           930:                        s_info->nshorts,s_info->rule));
        !           931: 
        !           932:        /*
        !           933:         * Compiler optimization: a pre-decrement in a while loop saves a test
        !           934:         * in assembly language for every iteration.
        !           935:         */
        !           936:        s_info->height += 1;
        !           937:        switch (s_info->rule) {
        !           938:                case SrcCopy:
        !           939:                     copyBitNeg_LOOP(SrcCopy_MASK,SrcCopy_OP);
        !           940:                     break;
        !           941: 
        !           942:                case SrcOr:
        !           943:                     copyBitNeg_LOOP(SrcOr_MASK,SrcOr_OP);
        !           944:                     break;
        !           945: 
        !           946:                case SrcXor:
        !           947:                     copyBitNeg_LOOP(SrcXor_MASK,SrcXor_OP);
        !           948:                     break;
        !           949: 
        !           950:                case NotSrcAnd:   
        !           951:                     copyBitNeg_LOOP(NotSrcAnd_MASK,NotSrcAnd_OP);
        !           952:                     break;
        !           953: 
        !           954:                case NotSrcCopy:
        !           955:                     copyBitNeg_LOOP(NotSrcCopy_MASK,NotSrcCopy_OP);
        !           956:                     break;
        !           957: 
        !           958:                case NotSrcOr:
        !           959:                     copyBitNeg_LOOP(NotSrcOr_MASK,NotSrcOr_OP);
        !           960:                     break;
        !           961: 
        !           962:                case NotSrcXor:
        !           963:                     copyBitNeg_LOOP(NotSrcXor_MASK,NotSrcXor_OP);
        !           964:                     break;
        !           965: 
        !           966:                case SrcAnd:
        !           967:                     copyBitNeg_LOOP(SrcAnd_MASK,SrcAnd_OP);
        !           968:                     break;
        !           969: 
        !           970:                case SrcAndNotDst:
        !           971:                     copyBitNeg_LOOP(SrcAndNotDst_MASK,SrcAndNotDst_OP);
        !           972:                     break;
        !           973: 
        !           974:                case NotSrcAndNotDst:
        !           975:                     copyBitNeg_LOOP(NotSrcAndNotDst_MASK,NotSrcAndNotDst_OP);
        !           976:                     break;
        !           977: 
        !           978:                case SrcOrNotDst:
        !           979:                     copyBitNeg_LOOP(SrcOrNotDst_MASK,SrcOrNotDst_OP);
        !           980:                     break;
        !           981: 
        !           982:                case NotSrcOrNotDst:
        !           983:                     copyBitNeg_LOOP(NotSrcOrNotDst_MASK,NotSrcOrNotDst_OP);
        !           984:                     break;
        !           985: 
        !           986:                default:
        !           987:                     break;
        !           988:        }
        !           989: }
        !           990: 
        !           991: #if (APA8 || APA8C)
        !           992: #define I_SRC          src_plus
        !           993: #define I_DST          dst_plus
        !           994: #else no APA8 stuff
        !           995: #define I_SRC          2
        !           996: #define I_DST          2
        !           997: #endif
        !           998: 
        !           999: /*
        !          1000:  * This loop copies bits from left to right, top to bottom.  It takes as
        !          1001:  * arguments 1 of 8 masking macros and the coorisponding generic macro.
        !          1002:  * The general scheme is this:
        !          1003:  *     Foreach row do
        !          1004:  *             Take care of the first word priming if necessary. (Done because
        !          1005:  *                     the first word uses the LEFT edge mask.)
        !          1006:  *
        !          1007:  *             If there is a skew then (Means parts of 2 source words make one
        !          1008:  *                     destination word.)
        !          1009:  *                     For each word between the first and last word do
        !          1010:  *                             Shift the source word and source word +1 and
        !          1011:  *                                     write the word to the destination.
        !          1012:  *                     endfor
        !          1013:  *
        !          1014:  *                     Take care of the last word. (Done here and not in 
        !          1015:  *                             the loop because the last word uses the 
        !          1016:  *                             RIGHT edge mask.)
        !          1017:  * 
        !          1018:  *             else  The skew is zero meaning 1 source word per destination
        !          1019:  *                   word.
        !          1020:  * 
        !          1021:  *                     For each word between the first and last word do
        !          1022:  *                             Write the source word into the destination word
        !          1023:  *                     endfor
        !          1024:  *
        !          1025:  *                     Take care of the last word. (Done here and not in 
        !          1026:  *                             the loop because the last word uses the 
        !          1027:  *                             RIGHT edge mask.)
        !          1028:  *             endif
        !          1029:  *
        !          1030:  *             INCREMENT the source and destination pointers to point to the
        !          1031:  *                     next row.
        !          1032:  *     endfor
        !          1033:  *
        !          1034:  */
        !          1035: #define copyBitPos_LOOP(EDGE_OP,OP) {                                  \
        !          1036:        while (--s_info->height) {                                      \
        !          1037:                wordnum = s_info->nshorts;                              \
        !          1038:                if (s_info->preload_src) {                              \
        !          1039:                        EDGE_OP((*SRC << skew_src) |                    \
        !          1040:                                (*(PLUS_SRC(src)) >> (inv_skew_src)),*DST,\
        !          1041:                                s_info->left_mask);                     \
        !          1042:                        INCR_SRC(src);                                  \
        !          1043:                }                                                       \
        !          1044:                else {                                                  \
        !          1045:                        EDGE_OP((*SRC>>(inv_skew_src)),*DST,s_info->left_mask);\
        !          1046:                }                                                       \
        !          1047:                if (--wordnum != 0) {                                   \
        !          1048:                        INCR_DST(dst);                                  \
        !          1049:                        if (skew_src & 0xf) {                           \
        !          1050:                                while (wordnum-- > 1) {                 \
        !          1051:                                        OP((*SRC << skew_src) |         \
        !          1052:                                          (*(PLUS_SRC(src)) >> (inv_skew_src)),\
        !          1053:                                           *DST);                       \
        !          1054:                                        INCR_DST(dst);                  \
        !          1055:                                        INCR_SRC(src);                  \
        !          1056:                                }                                       \
        !          1057:                                EDGE_OP((*SRC << skew_src) |            \
        !          1058:                                        (*(PLUS_SRC(src)) >> (inv_skew_src)),\
        !          1059:                                        *DST,s_info->right_mask);          \
        !          1060:                                INCR_SRC(src);                             \
        !          1061:                        }                                                  \
        !          1062:                        else {                                             \
        !          1063:                                while (wordnum-- > 1) {                    \
        !          1064:                                        INCR_SRC(src);                     \
        !          1065:                                        OP(*SRC,*DST);                     \
        !          1066:                                        INCR_DST(dst);                     \
        !          1067:                                }                                          \
        !          1068:                                INCR_SRC(src);                             \
        !          1069:                                EDGE_OP(*SRC,*DST,s_info->right_mask);     \
        !          1070:                        }                                                  \
        !          1071:                }                                                          \
        !          1072:                src += s_info->src.nextline;                               \
        !          1073:                dst += s_info->dst.nextline;                               \
        !          1074:        }                                                                  \
        !          1075: }
        !          1076: 
        !          1077: /*
        !          1078:  * Do setup and dereferencing of 5 of the most important Blt_sysdata variables.
        !          1079:  * Then do a switch on the combination rule to do the correct loop.  Each loop
        !          1080:  * copies from left to right, top to bottom .
        !          1081:  */
        !          1082: copyBitPos(s_info)
        !          1083: register Blt_sysdata *s_info;
        !          1084: {
        !          1085:        register unsigned char *src; /* Register pointers are declared as  */
        !          1086:                                     /* unsigned char pointers. This is an */
        !          1087:        register unsigned char *dst; /* optimization to get around extra   */
        !          1088:                                     /* addressing in the assembler.       */
        !          1089: #if (APA8 || APA8C)
        !          1090:        register int src_plus;
        !          1091:        register int dst_plus;
        !          1092: #endif
        !          1093:        register int wordnum;
        !          1094:        register int skew_src;
        !          1095:        register int inv_skew_src;
        !          1096: 
        !          1097: #if (APA8 || APA8C)
        !          1098:        src_plus = s_info->src_plus;
        !          1099:        dst_plus = s_info->dst_plus;
        !          1100: #endif
        !          1101:        src = (unsigned char *)s_info->src.data;
        !          1102:        dst = (unsigned char *)s_info->dst.data;
        !          1103: 
        !          1104:        skew_src = s_info->skew_src;
        !          1105:        inv_skew_src = BPW - skew_src;
        !          1106: 
        !          1107:        DEBUGF(blt_debug,
        !          1108:                printf("Enter copyBitPos:%d,%d,%d,%d\r\n",s_info->skew_src,
        !          1109:                        inv_skew_src,s_info->preload_src,s_info->rule));
        !          1110: 
        !          1111:        /*
        !          1112:         * foreach row do.
        !          1113:         *
        !          1114:         * Compiler optimization: a pre-decrement in a while loop saves a test
        !          1115:         * in assembly language for every iteration.
        !          1116:         */
        !          1117:        s_info->height += 1;
        !          1118:        switch (s_info->rule) {
        !          1119:                case SrcCopy:
        !          1120:                     copyBitPos_LOOP(SrcCopy_MASK,SrcCopy_OP);
        !          1121:                     break;
        !          1122: 
        !          1123:                case SrcOr:
        !          1124:                     copyBitPos_LOOP(SrcOr_MASK,SrcOr_OP);
        !          1125:                     break;
        !          1126: 
        !          1127:                case SrcXor:
        !          1128:                     copyBitPos_LOOP(SrcXor_MASK,SrcXor_OP);
        !          1129:                     break;
        !          1130: 
        !          1131:                case NotSrcAnd:   
        !          1132:                     copyBitPos_LOOP(NotSrcAnd_MASK,NotSrcAnd_OP);
        !          1133:                     break;
        !          1134: 
        !          1135:                case NotSrcCopy:
        !          1136:                     copyBitPos_LOOP(NotSrcCopy_MASK,NotSrcCopy_OP);
        !          1137:                     break;
        !          1138: 
        !          1139:                case NotSrcOr:
        !          1140:                     copyBitPos_LOOP(NotSrcOr_MASK,NotSrcOr_OP);
        !          1141:                     break;
        !          1142: 
        !          1143:                case NotSrcXor:
        !          1144:                     copyBitPos_LOOP(NotSrcXor_MASK,NotSrcXor_OP);
        !          1145:                     break;
        !          1146: 
        !          1147:                case SrcAnd:
        !          1148:                     copyBitPos_LOOP(SrcAnd_MASK,SrcAnd_OP);
        !          1149:                     break;
        !          1150: 
        !          1151:                case SrcAndNotDst:
        !          1152:                     copyBitPos_LOOP(SrcAndNotDst_MASK,SrcAndNotDst_OP);
        !          1153:                     break;
        !          1154: 
        !          1155:                case NotSrcAndNotDst:
        !          1156:                     copyBitPos_LOOP(NotSrcAndNotDst_MASK,NotSrcAndNotDst_OP);
        !          1157:                     break;
        !          1158: 
        !          1159:                case SrcOrNotDst:
        !          1160:                     copyBitPos_LOOP(SrcOrNotDst_MASK,SrcOrNotDst_OP);
        !          1161:                     break;
        !          1162: 
        !          1163:                case NotSrcOrNotDst:
        !          1164:                     copyBitPos_LOOP(NotSrcOrNotDst_MASK,NotSrcOrNotDst_OP);
        !          1165:                     break;
        !          1166: 
        !          1167:                default:
        !          1168:                     break;
        !          1169:        }
        !          1170: }
        !          1171: 
        !          1172: #define MYDEBUG_PR(n,s)
        !          1173: #define smallcopyBitPos_LOOP(EDGE_OP,OP) {                             \
        !          1174:        if (s_info->preload_src) {                                      \
        !          1175:                if (s_info->nshorts == 2) {                             \
        !          1176:                        MYDEBUG_PR(blt_debug,printf("preload 2\r\n"));  \
        !          1177:                        while (--height) {                              \
        !          1178:                                EDGE_OP((*SRC << skew_src) |            \
        !          1179:                                        (*(PLUS_SRC(src)) >> (inv_skew_src)),\
        !          1180:                                         *DST,s_info->left_mask);       \
        !          1181:                                INCR_SRC(src);                          \
        !          1182:                                INCR_DST(dst);                          \
        !          1183:                                EDGE_OP((*SRC << skew_src) |            \
        !          1184:                                        (*(PLUS_SRC(src)) >> (inv_skew_src)),\
        !          1185:                                        *DST,s_info->right_mask);       \
        !          1186:                                src += (s_info->src.nextline + I_SRC);  \
        !          1187:                                dst += s_info->dst.nextline;            \
        !          1188:                        }                                               \
        !          1189:                }                                                       \
        !          1190:                else {                                                  \
        !          1191:                        MYDEBUG_PR(blt_debug,printf("preload 1\r\n"));  \
        !          1192:                        while (--height) {                              \
        !          1193:                                EDGE_OP((*SRC << skew_src) |            \
        !          1194:                                        (*(PLUS_SRC(src)) >> (inv_skew_src)),\
        !          1195:                                         *DST,s_info->left_mask);       \
        !          1196:                                src += (s_info->src.nextline + I_SRC);  \
        !          1197:                                dst += s_info->dst.nextline;            \
        !          1198:                        }                                               \
        !          1199:                }                                                       \
        !          1200:        }                                                               \
        !          1201:        else if (skew_src & 0xf) {                                      \
        !          1202:                if (s_info->nshorts == 2) {                             \
        !          1203:                        MYDEBUG_PR(blt_debug,printf("skew_src 2\r\n")); \
        !          1204:                        while (--height) {                              \
        !          1205:                                EDGE_OP((*SRC>>(inv_skew_src)),         \
        !          1206:                                        *DST,s_info->left_mask);        \
        !          1207:                                INCR_DST(dst);                          \
        !          1208:                                EDGE_OP((*SRC << skew_src) |            \
        !          1209:                                        (*(PLUS_SRC(src)) >> (inv_skew_src)),\
        !          1210:                                        *DST,s_info->right_mask);       \
        !          1211:                                src += (s_info->src.nextline + I_SRC);  \
        !          1212:                                dst += s_info->dst.nextline;            \
        !          1213:                        }                                               \
        !          1214:                }                                                       \
        !          1215:                else {                                                  \
        !          1216:                        MYDEBUG_PR(blt_debug,printf("skew_src 1\r\n")); \
        !          1217:                        while (--height) {                              \
        !          1218:                                EDGE_OP((*SRC>>(inv_skew_src)),         \
        !          1219:                                        *DST,s_info->left_mask);        \
        !          1220:                                src += s_info->src.nextline;            \
        !          1221:                                dst += s_info->dst.nextline;            \
        !          1222:                        }                                               \
        !          1223:                }                                                       \
        !          1224:        }                                                               \
        !          1225:        else if (s_info->nshorts == 2) {                                \
        !          1226:                MYDEBUG_PR(blt_debug,printf("lines up 2\r\n"));         \
        !          1227:                while (--height) {                                      \
        !          1228:                        EDGE_OP(*SRC,*DST,s_info->left_mask);           \
        !          1229:                        INCR_DST(dst);                                  \
        !          1230:                        INCR_SRC(src);                                  \
        !          1231:                        EDGE_OP(*SRC,*DST,s_info->right_mask);          \
        !          1232:                        src += s_info->src.nextline;                    \
        !          1233:                        dst += s_info->dst.nextline;                    \
        !          1234:                }                                                       \
        !          1235:        }                                                               \
        !          1236:        else {                                                          \
        !          1237:                MYDEBUG_PR(blt_debug,printf("lines up 1\r\n"));         \
        !          1238:                while (--height) {                                      \
        !          1239:                        EDGE_OP(*SRC,*DST,s_info->left_mask);           \
        !          1240:                        src += s_info->src.nextline;                    \
        !          1241:                        dst += s_info->dst.nextline;                    \
        !          1242:                }                                                       \
        !          1243:        }                                                               \
        !          1244: }
        !          1245: 
        !          1246: /*
        !          1247:  * Do setup and dereferencing of 5 of the most important Blt_sysdata variables.
        !          1248:  * Then do a switch on the combination rule to do the correct loop.  Each loop
        !          1249:  * copies from left to right, top to bottom .
        !          1250:  */
        !          1251: smallcopyBitPos(s_info)
        !          1252: register Blt_sysdata *s_info;
        !          1253: {
        !          1254:        register unsigned char *src; /* Register pointers are declared as  */
        !          1255:                                     /* unsigned char pointers. This is an */
        !          1256:        register unsigned char *dst; /* optimization to get around extra   */
        !          1257:                                     /* addressing in the assembler.       */
        !          1258: #if (APA8 || APA8C)
        !          1259:        register int src_plus;
        !          1260:        register int dst_plus;
        !          1261: #endif
        !          1262:        register long height;
        !          1263:        register int skew_src;
        !          1264:        register int inv_skew_src;
        !          1265: 
        !          1266: #if (APA8 || APA8C)
        !          1267:        src_plus = s_info->src_plus;
        !          1268:        dst_plus = s_info->dst_plus;
        !          1269: #endif
        !          1270:        src = (unsigned char *)s_info->src.data;
        !          1271:        dst = (unsigned char *)s_info->dst.data;
        !          1272: 
        !          1273:        height = s_info->height;
        !          1274:        skew_src = s_info->skew_src;
        !          1275:        inv_skew_src = BPW - skew_src;
        !          1276: 
        !          1277:        DEBUGF(blt_debug,
        !          1278:                printf("Enter smallcopyBitPos:%d,%d,%d,%d\r\n",skew_src,
        !          1279:                        inv_skew_src,s_info->preload_src,s_info->rule));
        !          1280: 
        !          1281:        /*
        !          1282:         * foreach row do.
        !          1283:         *
        !          1284:         * Compiler optimization: a pre-decrement in a while loop saves a test
        !          1285:         * in assembly language for every iteration.
        !          1286:         */
        !          1287:        height += 1;
        !          1288:        switch (s_info->rule) {
        !          1289:                case SrcCopy:
        !          1290:                     smallcopyBitPos_LOOP(SrcCopy_MASK,SrcCopy_OP);
        !          1291:                     break;
        !          1292: 
        !          1293:                case SrcOr:
        !          1294:                     smallcopyBitPos_LOOP(SrcOr_MASK,SrcOr_OP);
        !          1295:                     break;
        !          1296: 
        !          1297:                case SrcXor:
        !          1298:                     smallcopyBitPos_LOOP(SrcXor_MASK,SrcXor_OP);
        !          1299:                     break;
        !          1300: 
        !          1301:                case NotSrcAnd:   
        !          1302:                     smallcopyBitPos_LOOP(NotSrcAnd_MASK,NotSrcAnd_OP);
        !          1303:                     break;
        !          1304: 
        !          1305:                case NotSrcCopy:
        !          1306:                     smallcopyBitPos_LOOP(NotSrcCopy_MASK,NotSrcCopy_OP);
        !          1307:                     break;
        !          1308: 
        !          1309:                case NotSrcOr:
        !          1310:                     smallcopyBitPos_LOOP(NotSrcOr_MASK,NotSrcOr_OP);
        !          1311:                     break;
        !          1312: 
        !          1313:                case NotSrcXor:
        !          1314:                     smallcopyBitPos_LOOP(NotSrcXor_MASK,NotSrcXor_OP);
        !          1315:                     break;
        !          1316: 
        !          1317:                case SrcAnd:
        !          1318:                     smallcopyBitPos_LOOP(SrcAnd_MASK,SrcAnd_OP);
        !          1319:                     break;
        !          1320: 
        !          1321:                case SrcAndNotDst:
        !          1322:                     smallcopyBitPos_LOOP(SrcAndNotDst_MASK,SrcAndNotDst_OP);
        !          1323:                     break;
        !          1324: 
        !          1325:                case NotSrcAndNotDst:
        !          1326:                     smallcopyBitPos_LOOP(NotSrcAndNotDst_MASK,NotSrcAndNotDst_OP);
        !          1327:                     break;
        !          1328: 
        !          1329:                case SrcOrNotDst:
        !          1330:                     smallcopyBitPos_LOOP(SrcOrNotDst_MASK,SrcOrNotDst_OP);
        !          1331:                     break;
        !          1332: 
        !          1333:                case NotSrcOrNotDst:
        !          1334:                     smallcopyBitPos_LOOP(NotSrcOrNotDst_MASK,NotSrcOrNotDst_OP);
        !          1335:                     break;
        !          1336: 
        !          1337:                default:
        !          1338:                     break;
        !          1339:        }
        !          1340: }
        !          1341: 
        !          1342: /*
        !          1343:  * This loop copies the tile to the destination. It takes as
        !          1344:  * arguments 1 of 8 masking tile macros and the coorisponding generic
        !          1345:  * tile  macro. The general scheme is this:
        !          1346:  *     Foreach row do
        !          1347:  *             Copy the tile to the first word using the left edge mask.
        !          1348:  *
        !          1349:  *             For each word between the first and last word do
        !          1350:  *                     Copy the tile to the destination word.
        !          1351:  *             endfor
        !          1352:  *
        !          1353:  *             Copy the tile to the first word using the right edge mask.
        !          1354:  *
        !          1355:  *             INCREMENT the tile and destination pointers to point to the
        !          1356:  *                     next row.
        !          1357:  *     endfor
        !          1358:  *
        !          1359:  */
        !          1360: #define copyTile_LOOP(EDGE_OP,OP) {                    \
        !          1361:        while (--height) {                              \
        !          1362:                wordnum = s_info->nshorts;              \
        !          1363:                EDGE_OP(*TILE,*DST,s_info->left_mask);  \
        !          1364:                if (--wordnum != 0) {                   \
        !          1365:                        INCR_DST(dst);                  \
        !          1366:                        while (wordnum > 1) {           \
        !          1367:                                OP(*TILE,*DST);         \
        !          1368:                                INCR_DST(dst);          \
        !          1369:                                wordnum--;              \
        !          1370:                        }                               \
        !          1371:                        EDGE_OP(*TILE,*DST,s_info->right_mask);\
        !          1372:                }                                       \
        !          1373:                INCR_TILE_PTR(tile,last_tile);          \
        !          1374:                dst += s_info->dst.nextline;            \
        !          1375:        }                                               \
        !          1376: }
        !          1377: 
        !          1378: /*
        !          1379:  * Tiles the destination.
        !          1380:  */
        !          1381: copyTile(s_info)
        !          1382: register Blt_sysdata *s_info;
        !          1383: {
        !          1384:        /*
        !          1385:         * For optimization, these registers are placed in order of importance.
        !          1386:         */
        !          1387:        register unsigned char *dst; /* All register pointers are declared as */
        !          1388:                                     /* unsigned char pointers. This is an    */
        !          1389:                                     /* optimization to get around extra      */
        !          1390:                                     /* addressing in the assembler.          */
        !          1391:        register unsigned char *tile;
        !          1392: #if (APA8 || APA8C)
        !          1393:        register int dst_plus;
        !          1394: #endif
        !          1395:        register int wordnum;
        !          1396:        register unsigned char *last_tile;
        !          1397:        register long height;
        !          1398: 
        !          1399: #if (APA8 || APA8C)
        !          1400:        DEBUGF(blt_debug,
        !          1401:                printf("Enter copyTile r:%d p:%d, i:%d dw:%d\r\n",s_info->rule,
        !          1402:                        s_info->dst_plus,s_info->dst.nextline,s_info->nshorts));
        !          1403: #else
        !          1404:        DEBUGF(blt_debug,
        !          1405:                printf("Enter copyTile r:%d i:%d dw:%d\r\n",s_info->rule,
        !          1406:                        s_info->dst.nextline,s_info->nshorts));
        !          1407: #endif
        !          1408: 
        !          1409:        dst = (unsigned char *)s_info->dst.data;
        !          1410:        tile = (unsigned char *)&s_info->tile_ptr[
        !          1411:                                            MOD_BPW(s_info->dst.rect.origin_y)];
        !          1412:        last_tile = (unsigned char *)&s_info->tile_ptr[15];
        !          1413: 
        !          1414: #if (APA8 || APA8C)
        !          1415:        dst_plus = s_info->dst_plus;
        !          1416: #endif
        !          1417: 
        !          1418:        /*
        !          1419:         * Compiler optimization: a pre-decrement in a while loop saves a test
        !          1420:         * in assembly language for every iteration.
        !          1421:         */
        !          1422:        height = s_info->height + 1;
        !          1423:        switch (s_info->rule) {
        !          1424:                case DstClear:
        !          1425:                case DstSet:
        !          1426:                case TileDstClear:
        !          1427:                case TileDstSet:
        !          1428:                case TileCopy:
        !          1429:                     copyTile_LOOP(TileCopy_MASK,TileCopy_OP);
        !          1430:                     break;
        !          1431: 
        !          1432:                case TileOr:
        !          1433:                     copyTile_LOOP(TileOr_MASK,TileOr_OP);
        !          1434:                     break;
        !          1435: 
        !          1436:                case TileXor:
        !          1437:                     copyTile_LOOP(TileXor_MASK,TileXor_OP);
        !          1438:                     break;
        !          1439: 
        !          1440:                case NotTileAnd:
        !          1441:                     copyTile_LOOP(NotTileAnd_MASK,NotTileAnd_OP);
        !          1442:                     break;
        !          1443: 
        !          1444:                case NotTileCopy:
        !          1445:                     copyTile_LOOP(NotTileCopy_MASK,NotTileCopy_OP);
        !          1446:                     break;
        !          1447: 
        !          1448:                case NotTileOr:
        !          1449:                     copyTile_LOOP(NotTileOr_MASK,NotTileOr_OP);
        !          1450:                     break;
        !          1451: 
        !          1452:                case NotTileXor:
        !          1453:                     copyTile_LOOP(NotTileXor_MASK,NotTileXor_OP);
        !          1454:                     break;
        !          1455: 
        !          1456:                case TileAnd:
        !          1457:                     copyTile_LOOP(TileAnd_MASK,TileAnd_OP);
        !          1458:                     break;
        !          1459: 
        !          1460:                case TileNotDstCopy:
        !          1461:                case NotDstCopy:
        !          1462:                     copyTile_LOOP(NotDstCopy_MASK,NotDstCopy_OP);
        !          1463:                     break;
        !          1464: 
        !          1465:                case TileAndNotDst:
        !          1466:                     copyTile_LOOP(TileAndNotDst_MASK,TileAndNotDst_OP);
        !          1467:                     break;
        !          1468: 
        !          1469:                case NotTileAndNotDst:
        !          1470:                     copyTile_LOOP(NotTileAndNotDst_MASK,NotTileAndNotDst_OP);
        !          1471:                     break;
        !          1472: 
        !          1473:                case TileOrNotDst:
        !          1474:                     copyTile_LOOP(TileOrNotDst_MASK,TileOrNotDst_OP);
        !          1475:                     break;
        !          1476: 
        !          1477:                case NotTileOrNotDst:
        !          1478:                     copyTile_LOOP(NotTileOrNotDst_MASK,NotTileOrNotDst_OP);
        !          1479:                     break;
        !          1480: 
        !          1481:                default:
        !          1482:                     break;
        !          1483:        }
        !          1484: }
        !          1485: 
        !          1486: /*
        !          1487:  * This loop copies bits from right to left, bottom to top.  It takes as
        !          1488:  * arguments 1 of 8 masking macros.  This loop has the same general structure
        !          1489:  * as copyBitNeg_LOOP except that work must be done on the mask bitmap.
        !          1490:  * This adds complexity because for optimization purposes, there are 4 loops
        !          1491:  * instead of 2.
        !          1492:  * The general scheme is this:
        !          1493:  *     Foreach row do
        !          1494:  *             Calculate the first MASK word priming if necessary.
        !          1495:  *
        !          1496:  *             Take care of the first word priming if necessary and using
        !          1497:  *                     the mask just calculated. (Done because
        !          1498:  *                     the first word uses the RIGHT edge mask.)
        !          1499:  *
        !          1500:  *             If the source and the MASK is skewed then
        !          1501:  *                     (Means parts of 2 source words make one
        !          1502:  *                     destination word and parts of 2 mask words are used
        !          1503:  *                     to mask this one destination word.)
        !          1504:  *
        !          1505:  *                     For each word between the first and last word do
        !          1506:  *                             Calculate the MASK word.
        !          1507:  *                             Shift the source word and source word -1 and
        !          1508:  *                                     write the word to the destination using
        !          1509:  *                                     the mask just calculated.
        !          1510:  *                     endfor
        !          1511:  *
        !          1512:  *                     Calculate the MASK word.
        !          1513:  *                     Take care of the last word using the mask and left
        !          1514:  *                             edge mask. (Done here and not in 
        !          1515:  *                             the loop because the last word uses the 
        !          1516:  *                             LEFT edge mask.)
        !          1517:  * 
        !          1518:  *             else if the MASK is skewed then
        !          1519:  *                     For each word between the first and last word do
        !          1520:  *                             Calculate the MASK word.
        !          1521:  *                             Write the source word to the destination using
        !          1522:  *                                     the mask just calculated.
        !          1523:  *                     endfor
        !          1524:  *
        !          1525:  *                     Calculate the MASK word.
        !          1526:  *                     Take care of the last word using the mask and left
        !          1527:  *                             edge mask.
        !          1528:  *                     
        !          1529:  *             else if the source is skewed then
        !          1530:  *
        !          1531:  *                     For each word between the first and last word do
        !          1532:  *                             Shift the source word and source word -1 and
        !          1533:  *                                     write the word to the destination using
        !          1534:  *                                     the mask.
        !          1535:  *                     endfor
        !          1536:  *
        !          1537:  *                     Take care of the last word using the mask and left
        !          1538:  *                             edge mask.
        !          1539:  *
        !          1540:  *             else  The source and mask skew are zero meaning 1 source word,
        !          1541:  *                   one mask word are used per destination word.
        !          1542:  * 
        !          1543:  *                     For each word between the first and last word do
        !          1544:  *                             Write the source word into the destination
        !          1545:  *                                     using the mask word.
        !          1546:  *                     endfor
        !          1547:  *
        !          1548:  *                     Take care of the last word using the mask word and
        !          1549:  *                             the left edge mask.
        !          1550:  *             endif
        !          1551:  *
        !          1552:  *             DECREMENT the source,destination and mask pointers to point
        !          1553:  *                     to the next row in their respective bitmaps.
        !          1554:  *     endfor
        !          1555:  *
        !          1556:  */
        !          1557: #define maskBitNeg_LOOP(MASK_OP) {                                     \
        !          1558:        while (--s_info->height) {                                      \
        !          1559:                wordnum = s_info->nshorts;                              \
        !          1560:                if (s_info->preload_msk) {                              \
        !          1561:                        mask = (*MSK >> s_info->skew_msk) |             \
        !          1562:                               (*MINUS_MSK(msk) << inv_skew_msk);       \
        !          1563:                        DECR_MSK(msk);                                  \
        !          1564:                }                                                       \
        !          1565:                else {                                                  \
        !          1566:                        mask = (*MSK << inv_skew_msk);                  \
        !          1567:                }                                                       \
        !          1568:                if (s_info->preload_src) {                              \
        !          1569:                        MASK_OP((*SRC >> s_info->skew_src) |            \
        !          1570:                                (*(MINUS_SRC(src)) << (inv_skew_src)),  \
        !          1571:                                *DST,s_info->right_mask & mask);        \
        !          1572:                        DECR_SRC(src);                                  \
        !          1573:                }                                                       \
        !          1574:                else {                                                  \
        !          1575:                        MASK_OP((*SRC << (inv_skew_src)),*DST,          \
        !          1576:                                s_info->right_mask & mask);             \
        !          1577:                }                                                       \
        !          1578:                if (--wordnum != 0) {                                   \
        !          1579:                        DECR_DST(dst);                                  \
        !          1580:                        if (write_mode == (MSK_SKEW | SRC_SKEW)) {      \
        !          1581:                                while (wordnum-- > 1) {                 \
        !          1582:                                        mask = (*MSK >> s_info->skew_msk) |\
        !          1583:                                               (*MINUS_MSK(msk)<<inv_skew_msk);\
        !          1584:                                        MASK_OP((*SRC >> s_info->skew_src) |\
        !          1585:                                                (*(MINUS_SRC(src)) <<   \
        !          1586:                                                inv_skew_src),          \
        !          1587:                                                *DST,mask);             \
        !          1588:                                        DECR_SRC(src); DECR_MSK(msk);   \
        !          1589:                                        DECR_DST(dst);                  \
        !          1590:                                }                                       \
        !          1591:                                mask = (*MSK >> s_info->skew_msk) |     \
        !          1592:                                       (*MINUS_MSK(msk)<<inv_skew_msk); \
        !          1593:                                MASK_OP((*SRC >> s_info->skew_src) |    \
        !          1594:                                        (*(MINUS_SRC(src))<<inv_skew_src),\
        !          1595:                                        *DST,s_info->left_mask & mask);  \
        !          1596:                                DECR_SRC(src); DECR_MSK(msk);           \
        !          1597:                        }                                               \
        !          1598:                        else if (write_mode & MSK_SKEW) {               \
        !          1599:                                while (wordnum-- > 1) {                 \
        !          1600:                                        mask = (*MSK >> s_info->skew_msk) |\
        !          1601:                                               (*MINUS_MSK(msk)<<inv_skew_msk);\
        !          1602:                                        DECR_SRC(src); DECR_MSK(msk);   \
        !          1603:                                        MASK_OP(*SRC,*DST,mask);        \
        !          1604:                                        DECR_DST(dst);                  \
        !          1605:                                }                                       \
        !          1606:                                mask = (*MSK >> s_info->skew_msk) |     \
        !          1607:                                       (*MINUS_MSK(msk)<<inv_skew_msk); \
        !          1608:                                DECR_SRC(src); DECR_MSK(msk);           \
        !          1609:                                MASK_OP(*SRC,*DST,s_info->left_mask&mask);\
        !          1610:                        }                                               \
        !          1611:                        else if (write_mode & SRC_SKEW) {               \
        !          1612:                                while (wordnum-- > 1) {                 \
        !          1613:                                        DECR_MSK(msk);                  \
        !          1614:                                        MASK_OP((*SRC >> s_info->skew_src) |\
        !          1615:                                                (*(MINUS_SRC(src)) <<   \
        !          1616:                                                inv_skew_src),          \
        !          1617:                                                *DST,*MSK);             \
        !          1618:                                        DECR_SRC(src);                  \
        !          1619:                                        DECR_DST(dst);                  \
        !          1620:                                }                                       \
        !          1621:                                DECR_MSK(msk);                          \
        !          1622:                                MASK_OP((*SRC >> s_info->skew_src) |    \
        !          1623:                                        (*(MINUS_SRC(src))<<inv_skew_src),\
        !          1624:                                        *DST,s_info->left_mask & *MSK); \
        !          1625:                                DECR_SRC(src);                          \
        !          1626:                        }                                               \
        !          1627:                        else {                                          \
        !          1628:                                while (wordnum-- > 1) {                 \
        !          1629:                                        DECR_SRC(src); DECR_MSK(msk);   \
        !          1630:                                        MASK_OP(*SRC,*DST,*MSK);        \
        !          1631:                                        DECR_DST(dst);                  \
        !          1632:                                }                                       \
        !          1633:                                DECR_SRC(src); DECR_MSK(msk);           \
        !          1634:                                MASK_OP(*SRC,*DST,s_info->left_mask & *MSK);\
        !          1635:                        }                                               \
        !          1636:                }                                                       \
        !          1637:                src -= s_info->src.nextline;                            \
        !          1638:                dst -= s_info->dst.nextline;                            \
        !          1639:                msk -= s_info->msk.nextline;                            \
        !          1640:        }                                                               \
        !          1641: }
        !          1642: 
        !          1643: /*
        !          1644:  * Copies bits from bottom to top, right to left but only changes those bits
        !          1645:  * that have corrisponding ones in the mask bitmap.
        !          1646:  */
        !          1647: maskBitNeg(s_info)
        !          1648: register Blt_sysdata *s_info;
        !          1649: {
        !          1650:        register unsigned char *src; /* Register pointers are declared as  */
        !          1651:                                     /* unsigned char pointers. This is an */
        !          1652:        register unsigned char *dst; /* optimization to get around extra   */
        !          1653:                                     /* addressing in the assembler.       */
        !          1654:        register unsigned char *msk; /* register pointer to the mask */
        !          1655: #if (APA8 || APA8C)
        !          1656:        register int src_plus;
        !          1657:        register int dst_plus;
        !          1658: #endif
        !          1659:        register int wordnum;        /* number of shorts per scanline */
        !          1660:        register int inv_skew_src;   /* BPW - skew_src */
        !          1661:        register int inv_skew_msk;   /* BPW - skew_msk */
        !          1662:        register int write_mode;     /* One of 4 modes: 0. no skew.
        !          1663:                                                        1. skew just the msk.
        !          1664:                                                        2. skew just the src.
        !          1665:                                                        3. skew both. */
        !          1666:        register unsigned short mask;/* The local mask produced by shifting
        !          1667:                                        *MSK and *MINUS_MASK() */
        !          1668: 
        !          1669: #if (APA8 || APA8C)
        !          1670:        src_plus = s_info->src_plus;
        !          1671:        dst_plus = s_info->dst_plus;
        !          1672: #endif
        !          1673: 
        !          1674:        DEBUGF(blt_debug,
        !          1675:                printf("Enter maskBitNeg. rule:%d\r\n",s_info->rule));
        !          1676: 
        !          1677:        src = (unsigned char *)s_info->src.data;
        !          1678:        dst = (unsigned char *)s_info->dst.data;
        !          1679:        msk = (unsigned char *)s_info->msk.data;
        !          1680: 
        !          1681:        inv_skew_src = BPW - s_info->skew_src;
        !          1682:        inv_skew_msk = BPW - s_info->skew_msk;
        !          1683: 
        !          1684:        /*
        !          1685:         * Set the write mode so that the correct inner loop is picked.
        !          1686:         */
        !          1687:        write_mode = 0;
        !          1688:        if (s_info->skew_src & 0xf)
        !          1689:                write_mode |= SRC_SKEW;
        !          1690:        if (s_info->skew_msk & 0xf)
        !          1691:                write_mode |= MSK_SKEW;
        !          1692: 
        !          1693:        /*
        !          1694:         * Compiler optimization: a pre-decrement in a while loop saves a test
        !          1695:         * in assembly language for every iteration.
        !          1696:         */
        !          1697:        s_info->height += 1;
        !          1698:        switch (s_info->rule) {
        !          1699:                case SrcCopy:
        !          1700:                     maskBitNeg_LOOP(SrcCopy_MASK);
        !          1701:                     break;
        !          1702: 
        !          1703:                case SrcOr:
        !          1704:                     maskBitNeg_LOOP(SrcOr_MASK);
        !          1705:                     break;
        !          1706: 
        !          1707:                case SrcXor:
        !          1708:                     maskBitNeg_LOOP(SrcXor_MASK);
        !          1709:                     break;
        !          1710: 
        !          1711:                case NotSrcAnd:   
        !          1712:                     maskBitNeg_LOOP(NotSrcAnd_MASK);
        !          1713:                     break;
        !          1714: 
        !          1715:                case NotSrcCopy:
        !          1716:                     maskBitNeg_LOOP(NotSrcCopy_MASK);
        !          1717:                     break;
        !          1718: 
        !          1719:                case NotSrcOr:
        !          1720:                     maskBitNeg_LOOP(NotSrcOr_MASK);
        !          1721:                     break;
        !          1722: 
        !          1723:                case NotSrcXor:
        !          1724:                     maskBitNeg_LOOP(NotSrcXor_MASK);
        !          1725:                     break;
        !          1726: 
        !          1727:                case SrcAnd:
        !          1728:                     maskBitNeg_LOOP(SrcAnd_MASK);
        !          1729:                     break;
        !          1730: 
        !          1731:                case SrcAndNotDst:
        !          1732:                     maskBitNeg_LOOP(SrcAndNotDst_MASK);
        !          1733:                     break;
        !          1734: 
        !          1735:                case NotSrcAndNotDst:
        !          1736:                     maskBitNeg_LOOP(NotSrcAndNotDst_MASK);
        !          1737:                     break;
        !          1738: 
        !          1739:                case SrcOrNotDst:
        !          1740:                     maskBitNeg_LOOP(SrcOrNotDst_MASK);
        !          1741:                     break;
        !          1742: 
        !          1743:                case NotSrcOrNotDst:
        !          1744:                     maskBitNeg_LOOP(NotSrcOrNotDst_MASK);
        !          1745:                     break;
        !          1746: 
        !          1747:                default:
        !          1748:                     break;
        !          1749:        }
        !          1750: }
        !          1751: 
        !          1752: /*
        !          1753:  * This loop copies bits from left to right, top to bottom.  It takes as
        !          1754:  * arguments 1 of 8 masking macros.  This loop has the same general structure
        !          1755:  * as copyBitPos_LOOP except that work must be done on the mask bitmap.
        !          1756:  * This adds complexity because, for optimization purposes, there are 4 loops
        !          1757:  * instead of 2.
        !          1758:  * The general scheme is this:
        !          1759:  *     Foreach row do
        !          1760:  *             Calculate the first MASK word priming if necessary.
        !          1761:  *
        !          1762:  *             Take care of the first word priming if necessary and using
        !          1763:  *                     the mask just calculated. (Done because
        !          1764:  *                     the first word uses the RIGHT edge mask.)
        !          1765:  *
        !          1766:  *             If the source and the MASK is skewed then
        !          1767:  *                     (Means parts of 2 source words make one
        !          1768:  *                     destination word and parts of 2 mask words are used
        !          1769:  *                     to mask this one destination word.)
        !          1770:  *
        !          1771:  *                     For each word between the first and last word do
        !          1772:  *                             Calculate the MASK word.
        !          1773:  *                             Shift the source word and source word -1 and
        !          1774:  *                                     write the word to the destination using
        !          1775:  *                                     the mask just calculated.
        !          1776:  *                     endfor
        !          1777:  *
        !          1778:  *                     Calculate the MASK word.
        !          1779:  *                     Take care of the last word using the mask and left
        !          1780:  *                             edge mask. (Done here and not in 
        !          1781:  *                             the loop because the last word uses the 
        !          1782:  *                             LEFT edge mask.)
        !          1783:  * 
        !          1784:  *             else if the MASK is skewed then
        !          1785:  *                     For each word between the first and last word do
        !          1786:  *                             Calculate the MASK word.
        !          1787:  *                             Write the source word to the destination using
        !          1788:  *                                     the mask just calculated.
        !          1789:  *                     endfor
        !          1790:  *
        !          1791:  *                     Calculate the MASK word.
        !          1792:  *                     Take care of the last word using the mask and left
        !          1793:  *                             edge mask.
        !          1794:  *                     
        !          1795:  *             else if the source is skewed then
        !          1796:  *
        !          1797:  *                     For each word between the first and last word do
        !          1798:  *                             Shift the source word and source word -1 and
        !          1799:  *                                     write the word to the destination using
        !          1800:  *                                     the mask.
        !          1801:  *                     endfor
        !          1802:  *
        !          1803:  *                     Take care of the last word using the mask and left
        !          1804:  *                             edge mask.
        !          1805:  *
        !          1806:  *             else  The source and mask skew are zero meaning 1 source word,
        !          1807:  *                   one mask word are used per destination word.
        !          1808:  * 
        !          1809:  *                     For each word between the first and last word do
        !          1810:  *                             Write the source word into the destination
        !          1811:  *                                     using the mask word.
        !          1812:  *                     endfor
        !          1813:  *
        !          1814:  *                     Take care of the last word using the mask word and
        !          1815:  *                             the left edge mask.
        !          1816:  *             endif
        !          1817:  *
        !          1818:  *             INCREMENT the source,destination and mask pointers to point
        !          1819:  *                     to the next row in their respective bitmaps.
        !          1820:  *     endfor
        !          1821:  *
        !          1822:  */
        !          1823: #define maskBitPos_LOOP(MASK_OP) {                                     \
        !          1824:        while (--s_info->height) {                                      \
        !          1825:                wordnum = s_info->nshorts;                              \
        !          1826:                if (s_info->preload_msk) {                              \
        !          1827:                        mask = (*MSK << s_info->skew_msk) |             \
        !          1828:                               (*PLUS_MSK(msk) >> inv_skew_msk);        \
        !          1829:                        INCR_MSK(msk);                                  \
        !          1830:                }                                                       \
        !          1831:                else {                                                  \
        !          1832:                        mask = (*MSK >> inv_skew_msk);                  \
        !          1833:                }                                                       \
        !          1834:                if (s_info->preload_src) {                              \
        !          1835:                        MASK_OP((*SRC << s_info->skew_src) |            \
        !          1836:                                (*(PLUS_SRC(src)) >> (inv_skew_src)),*DST,\
        !          1837:                                s_info->left_mask & mask);              \
        !          1838:                        INCR_SRC(src);                                  \
        !          1839:                }                                                       \
        !          1840:                else {                                                  \
        !          1841:                         MASK_OP((*SRC >> (inv_skew_src)),*DST,         \
        !          1842:                                s_info->left_mask & mask);              \
        !          1843:                }                                                       \
        !          1844:                if (--wordnum != 0) {                                   \
        !          1845:                        INCR_DST(dst);                                  \
        !          1846:                        if (write_mode == (MSK_SKEW | SRC_SKEW)) {      \
        !          1847:                                while (wordnum-- > 1) {                 \
        !          1848:                                        mask = (*MSK << s_info->skew_msk) |\
        !          1849:                                               (*PLUS_MSK(msk)>>inv_skew_msk);\
        !          1850:                                        MASK_OP((*SRC << s_info->skew_src) |\
        !          1851:                                                (*(PLUS_SRC(src)) >>    \
        !          1852:                                                (inv_skew_src)),        \
        !          1853:                                                *DST,mask);             \
        !          1854:                                        INCR_SRC(src); INCR_MSK(msk);   \
        !          1855:                                        INCR_DST(dst);                  \
        !          1856:                                }                                       \
        !          1857:                                mask = (*MSK << s_info->skew_msk) |     \
        !          1858:                                       (*PLUS_MSK(msk) >> inv_skew_msk);\
        !          1859:                                MASK_OP((*SRC << s_info->skew_src) |    \
        !          1860:                                        (*(PLUS_SRC(src))>>(inv_skew_src)),\
        !          1861:                                        *DST, s_info->right_mask & mask);\
        !          1862:                                INCR_SRC(src); INCR_MSK(msk);           \
        !          1863:                        }                                               \
        !          1864:                        else if (write_mode & MSK_SKEW) {               \
        !          1865:                                while (wordnum-- > 1) {                 \
        !          1866:                                        mask = (*MSK << s_info->skew_msk) |\
        !          1867:                                               (*PLUS_MSK(msk) >>       \
        !          1868:                                                   inv_skew_msk);       \
        !          1869:                                        INCR_SRC(src); INCR_MSK(msk);   \
        !          1870:                                        MASK_OP(*SRC,*DST,mask);        \
        !          1871:                                        INCR_DST(dst);                  \
        !          1872:                                }                                       \
        !          1873:                                mask = (*MSK << s_info->skew_msk) |     \
        !          1874:                                          (*PLUS_MSK(msk) >> inv_skew_msk);\
        !          1875:                                INCR_SRC(src); INCR_MSK(msk);           \
        !          1876:                                MASK_OP(*SRC,*DST, s_info->right_mask & mask);\
        !          1877:                        }                                               \
        !          1878:                        else if (write_mode & SRC_SKEW) {               \
        !          1879:                                while (wordnum-- > 1) {                 \
        !          1880:                                        INCR_MSK(msk);                  \
        !          1881:                                        MASK_OP((*SRC << s_info->skew_src) |\
        !          1882:                                                (*(PLUS_SRC(src)) >>    \
        !          1883:                                                (inv_skew_src)),        \
        !          1884:                                                *DST,*MSK);             \
        !          1885:                                        INCR_SRC(src);                  \
        !          1886:                                        INCR_DST(dst);                  \
        !          1887:                                }                                       \
        !          1888:                                INCR_MSK(msk);                          \
        !          1889:                                MASK_OP((*SRC << s_info->skew_src) |    \
        !          1890:                                        (*(PLUS_SRC(src))>>(inv_skew_src)),\
        !          1891:                                        *DST, s_info->right_mask & *MSK);\
        !          1892:                                        INCR_SRC(src);                  \
        !          1893:                        }                                               \
        !          1894:                        else {                                          \
        !          1895:                                while (wordnum-- > 1) {                 \
        !          1896:                                        INCR_SRC(src); INCR_MSK(msk);   \
        !          1897:                                        MASK_OP(*SRC,*DST,*MSK);        \
        !          1898:                                        INCR_DST(dst);                  \
        !          1899:                                }                                       \
        !          1900:                                INCR_SRC(src); INCR_MSK(msk);           \
        !          1901:                                MASK_OP(*SRC,*DST,s_info->right_mask & *MSK);\
        !          1902:                        }                                               \
        !          1903:                }                                                       \
        !          1904:                src += s_info->src.nextline;                            \
        !          1905:                dst += s_info->dst.nextline;                            \
        !          1906:                msk += s_info->msk.nextline;                            \
        !          1907:        }                                                               \
        !          1908: }
        !          1909: 
        !          1910: /*
        !          1911:  * Copies bits from top to bottom , left to right but only changes those bits
        !          1912:  * that have corrisponding ones in mask bitmap given.
        !          1913:  */
        !          1914: maskBitPos(s_info)
        !          1915: register Blt_sysdata *s_info;
        !          1916: {
        !          1917:        register unsigned char *src; /* Register pointers are declared as  */
        !          1918:                                     /* unsigned char pointers. This is an */
        !          1919:        register unsigned char *dst; /* optimization to get around extra   */
        !          1920:                                     /* addressing in the assembler.       */
        !          1921:        register unsigned char *msk; /* register pointer to the mask */
        !          1922: #if (APA8 || APA8C)
        !          1923:        register int src_plus;
        !          1924:        register int dst_plus;
        !          1925: #endif
        !          1926:        register int wordnum;        /* number of shorts per scanline */
        !          1927:        register int inv_skew_src;   /* BPW - skew_src */
        !          1928:        register int inv_skew_msk;   /* BPW - skew_msk */
        !          1929:        register int write_mode;     /* One of 4 modes: 0. no skew.
        !          1930:                                                        1. skew just the msk.
        !          1931:                                                        2. skew just the src.
        !          1932:                                                        3. skew both. */
        !          1933:        register unsigned short mask;/* The local mask produced by shifting
        !          1934:                                        *MSK and *PLUS_MASK() */
        !          1935: 
        !          1936: #if (APA8 || APA8C)
        !          1937:        src_plus = s_info->src_plus;
        !          1938:        dst_plus = s_info->dst_plus;
        !          1939: #endif
        !          1940: 
        !          1941:        DEBUGF(blt_debug,printf("Enter maskBitPos. rule:%d\r\n",s_info->rule));
        !          1942: 
        !          1943:        src = (unsigned char *)s_info->src.data;
        !          1944:        dst = (unsigned char *)s_info->dst.data;
        !          1945:        msk = (unsigned char *)s_info->msk.data;
        !          1946: 
        !          1947:        inv_skew_msk = BPW - s_info->skew_msk;
        !          1948:        inv_skew_src = BPW - s_info->skew_src;
        !          1949: 
        !          1950:        /*
        !          1951:         * Set the write mode so that the correct inner loop is picked.
        !          1952:         */
        !          1953:        write_mode = 0;
        !          1954:        if (s_info->skew_src & 0xf)
        !          1955:                write_mode |=  SRC_SKEW;
        !          1956:        if (s_info->skew_msk & 0xf)
        !          1957:                write_mode |= MSK_SKEW;
        !          1958: 
        !          1959:        /*
        !          1960:         * Compiler optimization: a pre-decrement in a while loop saves a test
        !          1961:         * in assembly language for every iteration.
        !          1962:         */
        !          1963:        s_info->height += 1;
        !          1964:        switch (s_info->rule) {
        !          1965:                case SrcCopy:
        !          1966:                     maskBitPos_LOOP(SrcCopy_MASK);
        !          1967:                     break;
        !          1968: 
        !          1969:                case SrcOr:
        !          1970:                     maskBitPos_LOOP(SrcOr_MASK);
        !          1971:                     break;
        !          1972: 
        !          1973:                case SrcXor:
        !          1974:                     maskBitPos_LOOP(SrcXor_MASK);
        !          1975:                     break;
        !          1976: 
        !          1977:                case NotSrcAnd:   
        !          1978:                     maskBitPos_LOOP(NotSrcAnd_MASK);
        !          1979:                     break;
        !          1980: 
        !          1981:                case NotSrcCopy:
        !          1982:                     maskBitPos_LOOP(NotSrcCopy_MASK);
        !          1983:                     break;
        !          1984: 
        !          1985:                case NotSrcOr:
        !          1986:                     maskBitPos_LOOP(NotSrcOr_MASK);
        !          1987:                     break;
        !          1988: 
        !          1989:                case NotSrcXor:
        !          1990:                     maskBitPos_LOOP(NotSrcXor_MASK);
        !          1991:                     break;
        !          1992: 
        !          1993:                case SrcAnd:
        !          1994:                     maskBitPos_LOOP(SrcAnd_MASK);
        !          1995:                     break;
        !          1996: 
        !          1997:                case SrcAndNotDst:
        !          1998:                     maskBitPos_LOOP(SrcAndNotDst_MASK);
        !          1999:                     break;
        !          2000: 
        !          2001:                case NotSrcAndNotDst:
        !          2002:                     maskBitPos_LOOP(NotSrcAndNotDst_MASK);
        !          2003:                     break;
        !          2004: 
        !          2005:                case SrcOrNotDst:
        !          2006:                     maskBitPos_LOOP(SrcOrNotDst_MASK);
        !          2007:                     break;
        !          2008: 
        !          2009:                case NotSrcOrNotDst:
        !          2010:                     maskBitPos_LOOP(NotSrcOrNotDst_MASK);
        !          2011:                     break;
        !          2012: 
        !          2013:                default:
        !          2014:                     break;
        !          2015:        }
        !          2016: }
        !          2017: 
        !          2018: /*
        !          2019:  * This loop copies the tile to the destination only changing those bits
        !          2020:  * in the destination that have coorisponding one's in the mask bitmap.
        !          2021:  * It takes as arguments 1 of 8 masking tile macros. The general scheme
        !          2022:  * is this:
        !          2023:  *     Foreach row do
        !          2024:  *             Calculate the MASK shifting if necessary.
        !          2025:  *             Copy the tile to the first word using the left edge mask and
        !          2026:  *             MASK.
        !          2027:  *
        !          2028:  *             if the MASK is skewed then (2 mask words are needed for one
        !          2029:  *                     destination word.)
        !          2030:  *                     For each word between the first and last word do
        !          2031:  *                             Calculate the MASK.
        !          2032:  *                             Copy the tile to the destination word using
        !          2033:  *                                     the mask calculated.
        !          2034:  *                     endfor
        !          2035:  *
        !          2036:  *             Calculate the MASK.
        !          2037:  *             Copy the tile to the first word using the right edge mask and
        !          2038:  *                     the mask calculated.
        !          2039:  *
        !          2040:  *             else
        !          2041:  *                     For each word between the first and last word do
        !          2042:  *                             Copy the tile to the destination word using
        !          2043:  *                                     the mask.
        !          2044:  *                     endfor
        !          2045:  *
        !          2046:  *                     Copy the tile to the first word using the
        !          2047:  *                             right edge mask and the mask.
        !          2048:  *             endif
        !          2049:  *
        !          2050:  *             INCREMENT the tile and destination pointers to point to the
        !          2051:  *                     next row.
        !          2052:  *     endfor
        !          2053:  */
        !          2054: #define maskTile_LOOP(MASK_OP) {                                       \
        !          2055:        while (--s_info->height) {                                      \
        !          2056:                wordnum = s_info->nshorts;                              \
        !          2057:                if (s_info->preload_msk) {                              \
        !          2058:                        mask = (*MSK << s_info->skew_msk) |             \
        !          2059:                               (*PLUS_MSK(msk) >> inv_skew_msk);        \
        !          2060:                        INCR_MSK(msk);                                  \
        !          2061:                }                                                       \
        !          2062:                else {                                                  \
        !          2063:                        mask = (*MSK >> inv_skew_msk);                  \
        !          2064:                }                                                       \
        !          2065:                MASK_OP(*TILE,*DST,s_info->left_mask & mask);           \
        !          2066:                if (--wordnum != 0) {                                   \
        !          2067:                        INCR_DST(dst);                                  \
        !          2068:                        if (s_info->skew_msk & 0xf) {                   \
        !          2069:                                while (wordnum-- > 1) {                 \
        !          2070:                                        mask = (*MSK << s_info->skew_msk) |\
        !          2071:                                               (*PLUS_MSK(msk)>>inv_skew_msk);\
        !          2072:                                        MASK_OP(*TILE,*DST,mask);       \
        !          2073:                                        INCR_DST(dst); INCR_MSK(msk);   \
        !          2074:                                }                                       \
        !          2075:                                mask = (*MSK << s_info->skew_msk) |     \
        !          2076:                                       (*PLUS_MSK(msk) >> inv_skew_msk);\
        !          2077:                                MASK_OP(*TILE,*DST,                     \
        !          2078:                                        s_info->right_mask & mask);     \
        !          2079:                                INCR_MSK(msk);                          \
        !          2080:                        }                                               \
        !          2081:                        else {                                          \
        !          2082:                                while (wordnum-- > 1) {                 \
        !          2083:                                        INCR_MSK(msk);                  \
        !          2084:                                        MASK_OP(*TILE,*DST,*MSK);       \
        !          2085:                                        INCR_DST(dst);                  \
        !          2086:                                }                                       \
        !          2087:                                INCR_MSK(msk);                          \
        !          2088:                                MASK_OP(*TILE,*DST,s_info->right_mask & *MSK);\
        !          2089:                        }                                               \
        !          2090:                }                                                       \
        !          2091:                INCR_TILE_PTR(tile,last_tile);                          \
        !          2092:                dst += s_info->dst.nextline;                            \
        !          2093:                msk += s_info->msk.nextline;                            \
        !          2094:        }                                                               \
        !          2095: }
        !          2096: 
        !          2097: /*
        !          2098:  * Copies a tile to the destination but only changes those bits
        !          2099:  * that have corrisponding ones in the mask bitmap given.
        !          2100:  */
        !          2101: maskTile(s_info)
        !          2102: register Blt_sysdata *s_info;
        !          2103: {
        !          2104:        register unsigned char *dst; /* Register pointers are declared as  */
        !          2105:                                     /* unsigned char pointers. This is an */
        !          2106:        register unsigned char *msk; /* optimization to get around extra   */
        !          2107:                                     /* addressing in the assembler.       */
        !          2108:        register unsigned char *tile;/* register pointer to the tile */
        !          2109: #if (APA8 || APA8C)
        !          2110:        register int src_plus;
        !          2111:        register int dst_plus;
        !          2112: #endif
        !          2113:        register unsigned char *last_tile;/* points to the last word in a tile*/
        !          2114:        register int wordnum;        /* number of shorts per scanline */
        !          2115:        register int inv_skew_msk;   /* BPW - skew_msk */
        !          2116:        register unsigned short mask;/* The local mask produced by shifting
        !          2117:                                        *MSK and *PLUS_MASK() */
        !          2118: #if (APA8 || APA8C)
        !          2119:        src_plus = s_info->src_plus;
        !          2120:        dst_plus = s_info->dst_plus;
        !          2121: #endif
        !          2122:        dst = (unsigned char *)s_info->dst.data;
        !          2123:        msk = (unsigned char *)s_info->msk.data;
        !          2124:        tile = (unsigned char *)&s_info->tile_ptr[
        !          2125:                                            MOD_BPW(s_info->dst.rect.origin_y)];
        !          2126:        last_tile = (unsigned char *)(&s_info->tile_ptr[15]);
        !          2127: 
        !          2128: 
        !          2129:        inv_skew_msk = BPW - s_info->skew_msk;
        !          2130: 
        !          2131:        DEBUGF(blt_debug,
        !          2132:                printf("Enter maskTile%d,%d %d %s %d\r\n",s_info->skew_msk,
        !          2133:                        inv_skew_msk,s_info->preload_msk,
        !          2134:                        ((s_info->tile_ptr[0] == 0xffff &&
        !          2135:                         s_info->tile_ptr[5] == 0xffff) ?
        !          2136:                        "black" : "not black"),s_info->rule));
        !          2137: 
        !          2138:        /*
        !          2139:         * Compiler optimization: a pre-decrement in a while loop saves a test
        !          2140:         * in assembly language for every iteration.
        !          2141:         */
        !          2142:        s_info->height += 1;
        !          2143:        switch (s_info->rule) {
        !          2144:                case DstClear:
        !          2145:                case DstSet:
        !          2146:                case TileDstClear:
        !          2147:                case TileDstSet:
        !          2148:                case TileCopy:
        !          2149:                     maskTile_LOOP(TileCopy_MASK);
        !          2150:                     break;
        !          2151: 
        !          2152:                case TileOr:
        !          2153:                     maskTile_LOOP(TileOr_MASK);
        !          2154:                     break;
        !          2155: 
        !          2156:                case TileXor:
        !          2157:                     maskTile_LOOP(TileXor_MASK);
        !          2158:                     break;
        !          2159: 
        !          2160:                case NotTileAnd:
        !          2161:                     maskTile_LOOP(NotTileAnd_MASK);
        !          2162:                     break;
        !          2163: 
        !          2164:                case NotTileCopy:
        !          2165:                     maskTile_LOOP(NotTileCopy_MASK);
        !          2166:                     break;
        !          2167: 
        !          2168:                case NotTileOr:
        !          2169:                     maskTile_LOOP(NotTileOr_MASK);
        !          2170:                     break;
        !          2171: 
        !          2172:                case NotTileXor:
        !          2173:                     maskTile_LOOP(NotTileXor_MASK);
        !          2174:                     break;
        !          2175: 
        !          2176:                case TileAnd:
        !          2177:                     maskTile_LOOP(TileAnd_MASK);
        !          2178:                     break;
        !          2179: 
        !          2180:                case TileNotDstCopy:
        !          2181:                case NotDstCopy:
        !          2182:                     maskTile_LOOP(NotDstCopy_MASK);
        !          2183:                     break;
        !          2184: 
        !          2185:                case TileAndNotDst:
        !          2186:                     maskTile_LOOP(TileAndNotDst_MASK);
        !          2187:                     break;
        !          2188: 
        !          2189:                case NotTileAndNotDst:
        !          2190:                     maskTile_LOOP(NotTileAndNotDst_MASK);
        !          2191:                     break;
        !          2192: 
        !          2193:                case TileOrNotDst:
        !          2194:                     maskTile_LOOP(TileOrNotDst_MASK);
        !          2195:                     break;
        !          2196: 
        !          2197:                case NotTileOrNotDst:
        !          2198:                     maskTile_LOOP(NotTileOrNotDst_MASK);
        !          2199:                     break;
        !          2200: 
        !          2201:                default:
        !          2202:                     break;
        !          2203:        }
        !          2204: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.