From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, FAKE_REPLY_B,HTML_MESSAGE,MAILING_LIST_MULTI,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 9551 invoked from network); 3 Apr 2022 11:24:36 -0000 Received: from minnie.tuhs.org (45.79.103.53) by inbox.vuxu.org with ESMTPUTF8; 3 Apr 2022 11:24:36 -0000 Received: by minnie.tuhs.org (Postfix, from userid 112) id 44FA89D67F; Sun, 3 Apr 2022 21:24:35 +1000 (AEST) Received: from minnie.tuhs.org (localhost [127.0.0.1]) by minnie.tuhs.org (Postfix) with ESMTP id CA8FD9D666; Sun, 3 Apr 2022 21:22:41 +1000 (AEST) Authentication-Results: minnie.tuhs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=planet.nl header.i=@planet.nl header.b="Z+IOGRRF"; dkim-atps=neutral Received: by minnie.tuhs.org (Postfix, from userid 112) id 15EF59D666; Sun, 3 Apr 2022 21:22:34 +1000 (AEST) Received: from ewsoutbound.kpnmail.nl (ewsoutbound.kpnmail.nl [195.121.94.168]) by minnie.tuhs.org (Postfix) with ESMTPS id 4B5469D663 for ; Sun, 3 Apr 2022 21:22:29 +1000 (AEST) X-KPN-MessageId: 4f4fc8ac-b340-11ec-a80d-005056aba152 Received: from smtp.kpnmail.nl (unknown [10.31.155.40]) by ewsoutbound.so.kpn.org (Halon) with ESMTPS id 4f4fc8ac-b340-11ec-a80d-005056aba152; Sun, 03 Apr 2022 13:22:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=planet.nl; s=planet01; h=to:date:message-id:subject:mime-version:content-type:from; bh=OboLE7qmSVFYv5kebjwEyiG2HaBQcJ50yepOkqB8VcM=; b=Z+IOGRRFTaWSKZ5SMmGJF2IPQcYrCiwRzTilR+60pRuCQm6Up9LtwmcnTEFPdFOaqrhB9ifJqUSEX yOXNdbM2XKaGWWpLPxgG7Il7O9nCJGIcgQzeLgpQM6E3ob0LwCResyar6FRLpIL/ozMmL8d8P4TVKh dhHIGJNQJQAu0ems= X-KPN-MID: 33|4dxOBtCqaDHerwxmL5vRhRuT+42YJyY+5iyqc3aG0Rj1+8fIf9w7qz+QoPExAb2 mReL5ys2tZRNuFwzjk+l1P4HUF9pzxCfpp2f7F/ypxVc= X-KPN-VerifiedSender: Yes X-CMASSUN: 33|r3BeEDEcvcA+byhQECOOe4tLw1GswPrvT/wV0Qnu9I5X9DeB/02rxG32VhCTMrj QLIfRsiTcqhKnQ77pQ4Ue2Q== X-Originating-IP: 80.101.112.122 Received: from mba1.fritz.box (sqlite.xs4all.nl [80.101.112.122]) by smtp.kpnmail.nl (Halon) with ESMTPSA id 52386bfc-b340-11ec-b148-005056ab7584; Sun, 03 Apr 2022 13:22:18 +0200 (CEST) Content-Type: multipart/alternative; boundary="Apple-Mail=_118D36D4-5031-4A7D-B182-35A7420D80AD" Mime-Version: 1.0 (Mac OS X Mail 11.5 \(3445.9.7\)) Message-Id: <7521B7CB-E1C7-44C2-BBF4-A97F63082545@planet.nl> Date: Sun, 3 Apr 2022 13:22:17 +0200 To: TUHS main list X-Mailer: Apple Mail (2.3445.9.7) Subject: Re: [TUHS] A Reiser tour de force X-BeenThere: tuhs@minnie.tuhs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: The Unix Heritage Society mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Paul Ruizendaal via TUHS Reply-To: Paul Ruizendaal Errors-To: tuhs-bounces@minnie.tuhs.org Sender: "TUHS" --Apple-Mail=_118D36D4-5031-4A7D-B182-35A7420D80AD Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 >> A not-very-thorough search at tuhs turned up = V9/jerq/src/lib/j/bitblt.c >> It appears to be a pre-Reiser bitblt, not what was asked for. >=20 >=20 > The Reiser code is in the V8 jerq tarball that Dan Cross donated: > v8jerq.tar.bz2 = >=20 > It is in file blit/src/libj/bitblt.s (attached below for convenience). = It is 750 lines of 68K assembler. It does not appear to have been ported = to the Bellmac 32 CPU. Maybe it did not make sense in that context. >=20 > Paul There also is a file =E2=80=9Cbitblt.C=E2=80=9D in that same directory = (dated May 82, versus Aug 82 for the assembler file) that seems to have = a similar approach coded up in C, with a big switch where each case has = a lot of =E2=80=9Casm()=E2=80=9D statements. It is about 400 lines long. = No author is mentioned. I have not investigated deeply, but at first glance it is possible that = the approach was first coded up as a kind of threaded code in C (with = inline asm) and later that Summer redone as fully hand coded assembler. = Just a guess. Paul =3D=3D=3D=3D #include #define LEFTDIR 8 #define NOSHIFT 4 #define DAMMIT 4 /* you'll see why */ #undef sw bitblt(sm,r,dm,p,fc) Bitmap *sm,*dm; Rectangle r; Point p; int fc; { register Word *source,*dest,*_source,*_dest; /* %a2-%a5 */ register UWord m,mask1,mask2; /* %d2,%d3,%d4 */ register int a,b,i; /* %d5,%d6,%d7 */ int j,h,w,dx1,sw,dw; /* clip to the destination Bitmap only */ #define rp dest #define pp source rp =3D (int *) &(dm->rect); pp =3D (int *) &p; if ((a =3D *rp++ - *pp++) > 0) { *(pp-1) +=3D a; r.origin.x +=3D a; } if ((a =3D *rp++ - *pp) > 0) { *pp +=3D a; r.origin.y +=3D a; } if ((a =3D r.origin.x + *rp++ - *(pp-1)) < r.corner.x) r.corner.x =3D a; if ((a =3D r.origin.y + *rp - *pp) < r.corner.y) r.corner.y =3D a; i =3D r.corner.y - r.origin.y; /* going to be h */ a =3D r.corner.x - r.origin.x - 1; /* going to be dx1 */ if (i <=3D 0 || a < 0) return; if (a < 16) goto narrow; h =3D i;=20 dx1 =3D a; /* i and b are regs, avoid work! */ sw =3D sm->width << 1; /* sleazy hack to avoid shift */ dw =3D dm->width << 1; /* in outer, inner loops */ w =3D ((p.x+dx1) >> 4) - (p.x >> 4) - 1; /* inner loop */ mask1 =3D ~topbits[p.x & 15]; mask2 =3D topbits[((p.x+dx1) & 15) + 1]; if (sm =3D=3D dm) { /* may have to mess with loop = order */ if (r.origin.y < p.y) { /* swap top with bottom = */ r.origin.y +=3D h-1; p.y +=3D h-1; sw =3D -sw; dw =3D -dw; } if (r.origin.x < p.x) { /* swap left with right */ fc |=3D LEFTDIR; r.origin.x +=3D dx1; p.x +=3D dx1; } } _dest =3D addr(dm,p); _source =3D addr(sm,r.origin); a =3D (p.x&15) - (r.origin.x&15); if (a < 0) a +=3D 16; else /* a =3D=3D 0 means no shift, remember that */ _source--; /* else grab long and shift right */ b =3D 16 - a; if (a =3D=3D 0) fc |=3D NOSHIFT; source =3D _source; dest =3D _dest; switch (fc) { case F_STORE | NOSHIFT: b =3D w; _source++; source =3D _source; a =3D h; /* a is free =3D> use it */ do { *dest++ =3D (~mask1 & *dest) | (mask1 & = *source++); if ((i =3D b>>2) > 0) do { *((long *)dest)++ =3D *((long = *)source)++; *((long *)dest)++ =3D *((long = *)source)++; } while (--i > 0); if ((i =3D b&3) > 0) do { *dest++ =3D *source++; } while (--i > 0); *dest =3D (~mask2 & *dest) | (mask2 & *source); (char *) _source +=3D sw; source =3D _source; (char *) _dest +=3D dw; dest =3D _dest; } while (--a > 0); break; case F_STORE: do { asm(" mov.l (%a2)+,%d2 # (long) m =3D = *source++"); asm(" ror.l %d5,%d2 # rotate m right by a"); *dest++ =3D (~mask1 & *dest) | (mask1 & m); asm(" ror.l %d6,%d2 # rotate m right by b"); if ((i =3D w) > 0) do { m =3D *source++; asm(" ror.l %d5,%d2 # m >> a"); *dest++ =3D m; asm(" ror.l %d6,%d2 # m >> b"); } while (--i > 0); m =3D *source; asm(" ror.l %d5,%d2 # m >> a"); *dest =3D (~mask2 & *dest) | (mask2 & m); (char *) _source +=3D sw; source =3D _source; (char *) _dest +=3D dw; dest =3D _dest; } while (--h > 0); break; case F_STORE | NOSHIFT | LEFTDIR: b =3D w; _source++; source =3D _source; a =3D h; do { *dest =3D (~mask2 & *dest) | (mask2 & *source); if ((i =3D b>>2) > 0) do { *--((long *)dest) =3D *--((long = *)source); *--((long *)dest) =3D *--((long = *)source); } while (--i > 0); if ((i =3D b&3) > 0) do { *(--dest) =3D *(--source); } while (--i > 0); dest--; *dest =3D (~mask1 & *dest) | (mask1 & = *(--source)); (char *) _source +=3D sw; source =3D _source; (char *) _dest +=3D dw; dest =3D _dest; } while (--a > 0); break; case F_STORE | LEFTDIR: do { asm(" mov.l (%a2),%d2 # (long) m =3D = *source"); asm(" ror.l %d5,%d2 # m >> a"); *dest =3D (~mask2 & *dest) | (mask2 & m); asm(" rol.l %d5,%d2 # m << a"); if ((i =3D w) > 0) do { m =3D *(--source); asm(" rol.l %d6,%d2 # m << b"); *(--dest) =3D m; asm(" rol.l %d5,%d2 # m << a"); } while (--i > 0); m =3D *(--source); asm(" rol.l %d6,%d2 # m << b"); dest--; *dest =3D (~mask1 & *dest) | (mask1 & m); (char *) _source +=3D sw; source =3D _source; (char *) _dest +=3D dw; dest =3D _dest; } while (--h > 0); break; case F_OR: case F_OR | NOSHIFT: do { asm(" mov.l (%a2)+,%d2 # (long) m =3D = *source++"); asm(" ror.l %d5,%d2 # rotate m right by a"); *dest++ |=3D (mask1 & m); asm(" ror.l %d6,%d2 # rotate m right by b"); if ((i =3D w) > 0) do { m =3D *source++; asm(" ror.l %d5,%d2 # m >> a"); *dest++ |=3D m; asm(" ror.l %d6,%d2 # m >> b"); } while (--i > 0); m =3D *source; asm(" ror.l %d5,%d2 # m >> a"); *dest |=3D (mask2 & m); (char *) _source +=3D sw; source =3D _source; (char *) _dest +=3D dw; dest =3D _dest; } while (--h > 0); break; case F_OR | LEFTDIR: case F_OR | NOSHIFT | LEFTDIR: do { asm(" mov.l (%a2),%d2 # (long) m =3D = *source"); asm(" ror.l %d5,%d2 # m >> a"); *dest |=3D (mask2 & m); asm(" rol.l %d5,%d2 # m << a"); if ((i =3D w) > 0) do { m =3D *(--source); asm(" rol.l %d6,%d2 # m << b"); *(--dest) |=3D m; asm(" rol.l %d5,%d2 # m << a"); } while (--i > 0); m =3D *(--source); asm(" rol.l %d6,%d2 # m << b"); dest--; *dest |=3D (mask1 & m); (char *) _source +=3D sw; source =3D _source; (char *) _dest +=3D dw; dest =3D _dest; } while (--h > 0); break; case F_CLR: case F_CLR | NOSHIFT: do { asm(" mov.l (%a2)+,%d2 # (long) m =3D = *source++"); asm(" ror.l %d5,%d2 # rotate m right by a"); *dest++ &=3D ~(mask1 & m); asm(" ror.l %d6,%d2 # rotate m right by b"); if ((i =3D w) > 0) do { m =3D *source++; asm(" ror.l %d5,%d2 # m >> a"); asm(" not.w %d2 # m =3D ~m"); *dest++ &=3D m; asm(" ror.l %d6,%d2 # m >> b"); } while (--i > 0); m =3D *source; asm(" ror.l %d5,%d2 # m >> a"); *dest &=3D ~(mask2 & m); (char *) _source +=3D sw; source =3D _source; (char *) _dest +=3D dw; dest =3D _dest; } while (--h > 0); break; case F_CLR | LEFTDIR: case F_CLR | NOSHIFT | LEFTDIR: do { asm(" mov.l (%a2),%d2 # (long) m =3D = *source"); asm(" ror.l %d5,%d2 # m >> a"); *dest &=3D ~(mask2 & m); asm(" rol.l %d5,%d2 # m << a"); if ((i =3D w) > 0) do { m =3D *(--source); asm(" rol.l %d6,%d2 # m << b"); asm(" not.w %d2 # m =3D ~m"); *(--dest) &=3D m; asm(" rol.l %d5,%d2 # m << a"); } while (--i > 0); m =3D *(--source); asm(" rol.l %d6,%d2 # m << b"); dest--; *dest &=3D ~(mask1 & m); (char *) _source +=3D sw; source =3D _source; (char *) _dest +=3D dw; dest =3D _dest; } while (--h > 0); break; case F_XOR | NOSHIFT: b =3D w; _source++; source =3D _source; a =3D h; do { *dest++ ^=3D (mask1 & *source++); if ((i =3D b>>2) > 0) do { *((long *)dest)++ ^=3D *((long = *)source)++; *((long *)dest)++ ^=3D *((long = *)source)++; } while (--i > 0); if ((i =3D b&3) > 0) do { *dest++ ^=3D *source++; } while (--i > 0); *dest ^=3D (mask2 & *source); (char *) _source +=3D sw; source =3D _source; (char *) _dest +=3D dw; dest =3D _dest; } while (--a > 0); break; case F_XOR: default: do { asm(" mov.l (%a2)+,%d2 # (long) m =3D = *source++"); asm(" ror.l %d5,%d2 # rotate m right by a"); *dest++ ^=3D (mask1 & m); asm(" ror.l %d6,%d2 # rotate m right by b"); if ((i =3D w) > 0) do { m =3D *source++; asm(" ror.l %d5,%d2 # m >> a"); *dest++ ^=3D m; asm(" ror.l %d6,%d2 # m >> b"); } while (--i > 0); m =3D *source; asm(" ror.l %d5,%d2 # m >> a"); *dest ^=3D (mask2 & m); (char *) _source +=3D sw; source =3D _source; (char *) _dest +=3D dw; dest =3D _dest; } while (--h > 0); break; case F_XOR | NOSHIFT | LEFTDIR: b =3D w; _source++; source =3D _source; a =3D h; do { *dest ^=3D (mask2 & *source); if ((i =3D b>>2) > 0) do { *--((long *)dest) ^=3D *--((long = *)source); *--((long *)dest) ^=3D *--((long = *)source); } while (--i > 0); if ((i =3D b&3) > 0) do { *(--dest) ^=3D *(--source); } while (--i > 0); dest--; *dest ^=3D (mask1 & *(--source)); (char *) _source +=3D sw; source =3D _source; (char *) _dest +=3D dw; dest =3D _dest; } while (--a > 0); break; case F_XOR | LEFTDIR: do { asm(" mov.l (%a2),%d2 # (long) m =3D = *source"); asm(" ror.l %d5,%d2 # m >> a"); *dest ^=3D (mask2 & m); asm(" rol.l %d5,%d2 # m << a"); if ((i =3D w) > 0) do { m =3D *(--source); asm(" rol.l %d6,%d2 # m << b"); *(--dest) ^=3D m; asm(" rol.l %d5,%d2 # m << a"); } while (--i > 0); m =3D *(--source); asm(" rol.l %d6,%d2 # m << b"); dest--; *dest ^=3D (mask1 & m); (char *) _source +=3D sw; source =3D _source; (char *) _dest +=3D dw; dest =3D _dest; } while (--h > 0); break; } return; narrow: /* * width is 16 bits or less, so we can do it by reading and * writing 32 bits at a time */ _source =3D (Word *) sm; _dest =3D (Word *) dm; mask1 =3D ((Bitmap *) _source)->width; /* source increment */ mask1 <<=3D 1; /* hack to add to an address register */ mask2 =3D ((Bitmap *) _dest)->width; /* dest increment */ mask2 <<=3D 1; if (_source =3D=3D _dest && r.origin.y < p.y) { /* swap top with = bottom */ r.origin.y +=3D i-1; p.y +=3D i-1; mask1 =3D -mask1; mask2 =3D -mask2; } asm(" mov &0,%d6 # (long) b =3D 0"); b =3D topbits[a+1]; a =3D (16 - (p.x & 15)); /* hocus pocus to get long mask = */ asm(" rol.l %d5,%d6 # (long) b <<=3D a"); a =3D 16 - a - (r.origin.x & 15); /* shift constant */ if (a < 0) { /* guess what! -1 =3D=3D 63 to the = 68000!!! */ fc |=3D DAMMIT; /* not fatal, just slow */ } source =3D addr(_source,r.origin); dest =3D addr(_dest,p); switch (fc) { case F_STORE: case F_STORE | DAMMIT: asm(" mov.l %d6,%d1 # prepare inverse mask"); asm(" not.l %d1 "); do { asm(" mov.l (%a2),%d2 # m =3D *source"); asm(" ror.l %d5,%d2 # rotate m right by a"); asm(" and.l %d6,%d2 # m &=3D b"); asm(" mov.l (%a3),%d0 # m |=3D *dest&~b"); asm(" and.l %d1,%d0 "); asm(" or.l %d0,%d2 "); asm(" mov.l %d2,(%a3) # *dest =3D m"); (char *) source +=3D (int) mask1; (char *) dest +=3D (int) mask2; } while (--i > 0); break; case F_OR: case F_OR | DAMMIT: do { asm(" mov.l (%a2),%d2 # m =3D *source"); asm(" ror.l %d5,%d2 # rotate m right by a"); asm(" and.l %d6,%d2 # m &=3D b"); asm(" or.l %d2,(%a3) # *dest |=3D m"); (char *) source +=3D (int) mask1; (char *) dest +=3D (int) mask2; } while (--i > 0); break; case F_CLR: case F_CLR | DAMMIT: do { asm(" mov.l (%a2),%d2 # m =3D *source"); asm(" ror.l %d5,%d2 # rotate m right by a"); asm(" and.l %d6,%d2 # m &=3D b"); asm(" not.l %d2 # m =3D ^m"); asm(" and.l %d2,(%a3) # *dest &=3D m"); (char *) source +=3D (int) mask1; (char *) dest +=3D (int) mask2; } while (--i > 0); break; case F_XOR: do { asm(" mov.l (%a2),%d2 # m =3D *source"); asm(" ror.l %d5,%d2 # rotate m right by a"); asm(" and.l %d6,%d2 # m &=3D b"); asm(" eor.l %d2,(%a3) # *dest ^=3D m"); (char *) source +=3D (int) mask1; (char *) dest +=3D (int) mask2; } while (--i > 0); break; case F_XOR | DAMMIT: a =3D -a; do { asm(" mov.l (%a2),%d2 # m =3D *source"); asm(" rol.l %d5,%d2 # rotate m left by a"); asm(" and.l %d6,%d2 # m &=3D b"); asm(" eor.l %d2,(%a3) # *dest ^=3D m"); (char *) source +=3D (int) mask1; (char *) dest +=3D (int) mask2; } while (--i > 0); break; } return; } --Apple-Mail=_118D36D4-5031-4A7D-B182-35A7420D80AD Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8
A= not-very-thorough search at tuhs turned up = V9/jerq/src/lib/j/bitblt.c
It appears to be a pre-Reiser = bitblt, not what was asked for.

The Reiser code is in the V8 jerq tarball that Dan = Cross donated:

It is in file blit/src/libj/bitblt.s = (attached below for convenience). It is 750 lines of 68K assembler. It = does not appear to have been ported to the Bellmac 32 CPU. Maybe it did = not make sense in that context.

Paul

There also is a file =E2=80=9Cbitblt.C=E2= =80=9D in that same directory (dated May 82, versus Aug 82 for the = assembler file) that seems to have a similar approach coded up in C, = with a big switch where each case has a lot of =E2=80=9Casm()=E2=80=9D = statements. It is about 400 lines long. No author is = mentioned.

I = have not investigated deeply, but at first glance it is possible that = the approach was first coded up as a kind of threaded code in C (with = inline asm) and later that Summer redone as fully hand coded assembler. = Just a guess.

Paul

=3D=3D=3D=3D

#include <jerq.h>
#define LEFTDIR 8
#define = NOSHIFT 4
#define DAMMIT 4 = /* you'll see why */
#undef = sw

bitblt(sm,r,dm,p,fc)
Bitmap = *sm,*dm;
Rectangle r;
Point = p;
int fc;
{
= register Word *source,*dest,*_source,*_dest; /* = %a2-%a5 */
register UWord = m,mask1,mask2; = /* %d2,%d3,%d4 */
register = int a,b,i; = /* %d5,%d6,%d7 */

int j,h,w,dx1,sw,dw;

/* clip = to the destination Bitmap only */
#define rp = dest
#define pp source
rp =3D = (int *) &(dm->rect);
pp =3D = (int *) &p;
if ((a =3D *rp++ - *pp++) > 0) = {
*(pp-1) +=3D a;
= r.origin.x +=3D a;
= }
if ((a =3D *rp++ - *pp) > 0) = {
*pp +=3D a;
= r.origin.y +=3D a;
= }
if ((a =3D r.origin.x + *rp++ - = *(pp-1)) < r.corner.x)
= r.corner.x =3D a;
if ((a =3D = r.origin.y + *rp - *pp) < r.corner.y)
= r.corner.y =3D a;
i =3D = r.corner.y - r.origin.y; /* going to be h */
= a =3D r.corner.x - r.origin.x - 1; /* going to be dx1 */
= if (i <=3D 0 || a < 0)
= return;
if (a < 16)
= goto narrow;
h =3D i; 
= dx1 =3D a;= /* i and b are regs, avoid work! */
= sw =3D sm->width << 1; /* sleazy hack to avoid shift = */
dw =3D dm->width << = 1; = /* in outer, inner loops */
w =3D = ((p.x+dx1) >> 4) - (p.x >> 4) - 1; /* inner = loop */
mask1 =3D ~topbits[p.x & = 15];
mask2 =3D topbits[((p.x+dx1) = & 15) + 1];
if (sm =3D=3D dm) { = /* may have to mess with loop order */
= if (r.origin.y < p.y) { /* swap top with bottom = */
r.origin.y +=3D = h-1;
p.y +=3D = h-1;
sw =3D = -sw;
dw =3D = -dw;
}
= if (r.origin.x < p.x) { /* swap left with right = */
fc |=3D = LEFTDIR;
r.origin.x +=3D = dx1;
p.x +=3D = dx1;
}
= }
_dest =3D addr(dm,p);
= _source =3D addr(sm,r.origin);
a =3D = (p.x&15) - (r.origin.x&15);
if (a = < 0)
a +=3D 16;
= else = /* a =3D=3D 0 means no shift, remember that */
= _source--;= /* else grab long and shift right */
= b =3D 16 - a;
if (a =3D=3D 0)
= fc |=3D NOSHIFT;
source =3D = _source;
dest =3D _dest;
= switch (fc) {
case F_STORE | NOSHIFT:
= b =3D w;
_source++;
= source =3D _source;
a = =3D h; = /* a is free =3D> use it */
= do {
*dest++ =3D = (~mask1 & *dest) | (mask1 & *source++);
= if ((i =3D b>>2) > 0) do {
= *((long *)dest)++ =3D *((long *)source)++;
= *((long *)dest)++ =3D *((long = *)source)++;
} while (--i > = 0);
if ((i =3D = b&3) > 0) do {
*dest++ =3D= *source++;
} while (--i > = 0);
*dest =3D (~mask2 = & *dest) | (mask2 & *source);
= (char *) _source +=3D sw;
= source =3D _source;
= (char *) _dest +=3D dw;
= dest =3D _dest;
} while (--a > = 0);
break;
= case F_STORE:
do {
asm(" = mov.l (%a2)+,%d2 # (long) = m =3D *source++");
asm(" = ror.l = %d5,%d2 = # rotate m right by a");
= *dest++ =3D (~mask1 & *dest) | (mask1 & m);
asm(" = ror.l %d6,%d2 # = rotate m right by b");
if ((i =3D w) = > 0) do {
m =3D = *source++;
asm(" = ror.l = %d5,%d2 = # m >> a");
= *dest++ =3D m;
asm(" = ror.l = %d6,%d2 = # m >> b");
= } while (--i > 0);
= m =3D *source;
asm(" = ror.l = %d5,%d2 = # m >> a");
= *dest =3D (~mask2 & *dest) | (mask2 & m);
= (char *) _source +=3D sw;
= source =3D _source;
= (char *) _dest +=3D dw;
= dest =3D _dest;
} while (--h > = 0);
break;
= case F_STORE | NOSHIFT | LEFTDIR:
b = =3D w;
_source++;
= source =3D _source;
a = =3D h;
do {
= *dest =3D (~mask2 & *dest) | (mask2 & = *source);
if ((i =3D = b>>2) > 0) do {
= *--((long *)dest) =3D *--((long *)source);
= *--((long *)dest) =3D *--((long = *)source);
} while (--i > = 0);
if ((i =3D = b&3) > 0) do {
*(--dest) = =3D *(--source);
} while (--i > = 0);
dest--;
= *dest =3D (~mask1 & *dest) | (mask1 & = *(--source));
(char *) _source = +=3D sw;
source =3D = _source;
(char *) _dest +=3D= dw;
dest =3D = _dest;
} while (--a > = 0);
break;
= case F_STORE | LEFTDIR:
= do {
asm(" mov.l = (%a2),%d2 = # (long) m =3D *source");
asm(" = ror.l = %d5,%d2 = # m >> a");
= *dest =3D (~mask2 & *dest) | (mask2 & m);
asm(" = rol.l %d5,%d2 # = m << a");
if ((i =3D w) = > 0) do {
m =3D = *(--source);
asm(" = rol.l = %d6,%d2 = # m << b");
= *(--dest) =3D m;
asm(" = rol.l = %d5,%d2 = # m << a");
= } while (--i > 0);
= m =3D *(--source);
asm(" = rol.l = %d6,%d2 = # m << b");
= dest--;
*dest =3D (~mask1 = & *dest) | (mask1 & m);
= (char *) _source +=3D sw;
= source =3D _source;
= (char *) _dest +=3D dw;
= dest =3D _dest;
} while (--h > = 0);
break;
= case F_OR:
case F_OR | NOSHIFT:
= do {
asm(" mov.l = (%a2)+,%d2= # (long) m =3D *source++");
asm(" = ror.l = %d5,%d2 = # rotate m right by a");
= *dest++ |=3D (mask1 & m);
asm(" = ror.l = %d6,%d2 = # rotate m right by b");
= if ((i =3D w) > 0) do {
= m =3D *source++;
asm(" = ror.l = %d5,%d2 = # m >> a");
= *dest++ |=3D m;
asm(" = ror.l = %d6,%d2 = # m >> b");
= } while (--i > 0);
= m =3D *source;
asm(" = ror.l = %d5,%d2 = # m >> a");
= *dest |=3D (mask2 & m);
= (char *) _source +=3D sw;
= source =3D _source;
= (char *) _dest +=3D dw;
= dest =3D _dest;
} while (--h > = 0);
break;
= case F_OR | LEFTDIR:
case F_OR = | NOSHIFT | LEFTDIR:
do {
asm(" = mov.l (%a2),%d2 # (long) = m =3D *source");
asm(" ror.l = %d5,%d2 = # m >> a");
= *dest |=3D (mask2 & m);
asm(" = rol.l = %d5,%d2 = # m << a");
= if ((i =3D w) > 0) do {
= m =3D *(--source);
asm(" = rol.l = %d6,%d2 = # m << b");
= *(--dest) |=3D m;
asm(" = rol.l = %d5,%d2 = # m << a");
= } while (--i > 0);
= m =3D *(--source);
asm(" = rol.l = %d6,%d2 = # m << b");
= dest--;
*dest |=3D (mask1 = & m);
(char *) _source = +=3D sw;
source =3D = _source;
(char *) _dest +=3D= dw;
dest =3D = _dest;
} while (--h > = 0);
break;
= case F_CLR:
case F_CLR | NOSHIFT:
= do {
asm(" mov.l = (%a2)+,%d2= # (long) m =3D *source++");
asm(" = ror.l = %d5,%d2 = # rotate m right by a");
= *dest++ &=3D ~(mask1 & m);
asm(" = ror.l = %d6,%d2 = # rotate m right by b");
= if ((i =3D w) > 0) do {
= m =3D *source++;
asm(" = ror.l = %d5,%d2 = # m >> a");
asm(" = not.w = %d2 = # m =3D ~m");
*dest++ = &=3D m;
asm(" = ror.l = %d6,%d2 = # m >> b");
= } while (--i > 0);
= m =3D *source;
asm(" = ror.l = %d5,%d2 = # m >> a");
= *dest &=3D ~(mask2 & m);
= (char *) _source +=3D sw;
= source =3D _source;
= (char *) _dest +=3D dw;
= dest =3D _dest;
} while (--h > = 0);
break;
= case F_CLR | LEFTDIR:
case = F_CLR | NOSHIFT | LEFTDIR:
= do {
asm(" mov.l = (%a2),%d2 = # (long) m =3D *source");
asm(" = ror.l = %d5,%d2 = # m >> a");
= *dest &=3D ~(mask2 & m);
asm(" = rol.l = %d5,%d2 = # m << a");
= if ((i =3D w) > 0) do {
= m =3D *(--source);
asm(" = rol.l = %d6,%d2 = # m << b");
asm(" = not.w = %d2 = # m =3D ~m");
*(--dest) = &=3D m;
asm(" = rol.l = %d5,%d2 = # m << a");
= } while (--i > 0);
= m =3D *(--source);
asm(" = rol.l = %d6,%d2 = # m << b");
= dest--;
*dest &=3D = ~(mask1 & m);
(char *) _source = +=3D sw;
source =3D = _source;
(char *) _dest +=3D= dw;
dest =3D = _dest;
} while (--h > = 0);
break;
= case F_XOR | NOSHIFT:
b = =3D w;
_source++;
= source =3D _source;
a = =3D h;
do {
= *dest++ ^=3D (mask1 & *source++);
= if ((i =3D b>>2) > 0) do {
= *((long *)dest)++ ^=3D *((long = *)source)++;
*((long = *)dest)++ ^=3D *((long *)source)++;
= } while (--i > 0);
= if ((i =3D b&3) > 0) do {
= *dest++ ^=3D *source++;
= } while (--i > 0);
= *dest ^=3D (mask2 & *source);
= (char *) _source +=3D sw;
= source =3D _source;
= (char *) _dest +=3D dw;
= dest =3D _dest;
} while (--a > = 0);
break;
= case F_XOR:
default:
= do {
asm(" mov.l = (%a2)+,%d2= # (long) m =3D *source++");
asm(" = ror.l = %d5,%d2 = # rotate m right by a");
= *dest++ ^=3D (mask1 & m);
asm(" = ror.l = %d6,%d2 = # rotate m right by b");
= if ((i =3D w) > 0) do {
= m =3D *source++;
asm(" = ror.l = %d5,%d2 = # m >> a");
= *dest++ ^=3D m;
asm(" = ror.l = %d6,%d2 = # m >> b");
= } while (--i > 0);
= m =3D *source;
asm(" = ror.l = %d5,%d2 = # m >> a");
= *dest ^=3D (mask2 & m);
= (char *) _source +=3D sw;
= source =3D _source;
= (char *) _dest +=3D dw;
= dest =3D _dest;
} while (--h > = 0);
break;
= case F_XOR | NOSHIFT | LEFTDIR:
b = =3D w;
_source++;
= source =3D _source;
a = =3D h;
do {
= *dest ^=3D (mask2 & *source);
= if ((i =3D b>>2) > 0) do {
= *--((long *)dest) ^=3D *--((long = *)source);
*--((long = *)dest) ^=3D *--((long *)source);
= } while (--i > 0);
= if ((i =3D b&3) > 0) do {
= *(--dest) ^=3D *(--source);
= } while (--i > 0);
= dest--;
*dest ^=3D (mask1 = & *(--source));
(char *) _source = +=3D sw;
source =3D = _source;
(char *) _dest +=3D= dw;
dest =3D = _dest;
} while (--a > = 0);
break;
= case F_XOR | LEFTDIR:
= do {
asm(" mov.l = (%a2),%d2 = # (long) m =3D *source");
asm(" = ror.l = %d5,%d2 = # m >> a");
= *dest ^=3D (mask2 & m);
asm(" = rol.l = %d5,%d2 = # m << a");
= if ((i =3D w) > 0) do {
= m =3D *(--source);
asm(" = rol.l = %d6,%d2 = # m << b");
= *(--dest) ^=3D m;
asm(" = rol.l = %d5,%d2 = # m << a");
= } while (--i > 0);
= m =3D *(--source);
asm(" = rol.l = %d6,%d2 = # m << b");
= dest--;
*dest ^=3D (mask1 = & m);
(char *) _source = +=3D sw;
source =3D = _source;
(char *) _dest +=3D= dw;
dest =3D = _dest;
} while (--h > = 0);
break;
= }
return;
narrow:
/*
* width = is 16 bits or less, so we can do it by reading and
= * writing 32 bits at a time
= */
_source =3D (Word *) = sm;
_dest =3D (Word *) dm;
= mask1 =3D ((Bitmap *) _source)->width; /* source = increment */
mask1 <<=3D 1; = /* hack to add to an address register */
mask2 =3D = ((Bitmap *) _dest)->width; /* dest increment */
= mask2 <<=3D 1;
if = (_source =3D=3D _dest && r.origin.y < p.y) { /* swap = top with bottom */
r.origin.y +=3D = i-1;
p.y +=3D i-1;
= mask1 =3D -mask1;
= mask2 =3D -mask2;
= }
asm(" mov &0,%d6 # = (long) b =3D 0");
b =3D topbits[a+1];
= a =3D (16 - (p.x & 15)); /* hocus pocus to get long mask = */
asm(" rol.l %d5,%d6 # = (long) b <<=3D a");
a =3D 16 = - a - (r.origin.x & 15); /* shift constant */
= if (a < 0) { /* guess what! -1 =3D=3D = 63 to the 68000!!! */
fc |=3D DAMMIT; /* not = fatal, just slow */
}
source =3D = addr(_source,r.origin);
dest =3D = addr(_dest,p);
switch (fc) {
= case F_STORE:
case F_STORE | DAMMIT:
asm(" = mov.l %d6,%d1 # = prepare inverse mask");
asm(" = not.l = %d1 = ");
do {
asm(" = mov.l (%a2),%d2 # m =3D = *source");
asm(" ror.l = %d5,%d2 = # rotate m right by a");
asm(" = and.l = %d6,%d2 = # m &=3D b");
asm(" = mov.l = (%a3),%d0 = # m |=3D *dest&~b");
asm(" = and.l = %d1,%d0 = ");
asm(" or.l = %d0,%d2 = ");
asm(" mov.l = %d2,(%a3) = # *dest =3D m");
= (char *) source +=3D (int) mask1;
= (char *) dest +=3D (int) mask2;
} = while (--i > 0);
break;
= case F_OR:
case F_OR | DAMMIT:
= do {
asm(" mov.l = (%a2),%d2 = # m =3D *source");
asm(" = ror.l = %d5,%d2 = # rotate m right by a");
asm(" = and.l = %d6,%d2 = # m &=3D b");
asm(" = or.l = %d2,(%a3) = # *dest |=3D m");
= (char *) source +=3D (int) mask1;
= (char *) dest +=3D (int) mask2;
} = while (--i > 0);
break;
= case F_CLR:
case F_CLR | DAMMIT:
= do {
asm(" mov.l = (%a2),%d2 = # m =3D *source");
asm(" = ror.l = %d5,%d2 = # rotate m right by a");
asm(" = and.l = %d6,%d2 = # m &=3D b");
asm(" = not.l = %d2 = # m =3D ^m");
asm(" = and.l = %d2,(%a3) = # *dest &=3D m");
= (char *) source +=3D (int) mask1;
= (char *) dest +=3D (int) mask2;
} = while (--i > 0);
break;
= case F_XOR:
do {
asm(" = mov.l (%a2),%d2 # m =3D = *source");
asm(" ror.l = %d5,%d2 = # rotate m right by a");
asm(" = and.l = %d6,%d2 = # m &=3D b");
asm(" = eor.l = %d2,(%a3) = # *dest ^=3D m");
= (char *) source +=3D (int) mask1;
= (char *) dest +=3D (int) mask2;
} = while (--i > 0);
break;
= case F_XOR | DAMMIT:
a = =3D -a;
do {
asm(" = mov.l (%a2),%d2 # m =3D = *source");
asm(" rol.l = %d5,%d2 = # rotate m left by a");
asm(" = and.l = %d6,%d2 = # m &=3D b");
asm(" = eor.l = %d2,(%a3) = # *dest ^=3D m");
= (char *) source +=3D (int) mask1;
= (char *) dest +=3D (int) mask2;
} = while (--i > 0);
break;
= }
return;
}

= --Apple-Mail=_118D36D4-5031-4A7D-B182-35A7420D80AD--