xref: /original-bsd/sys/news3400/fb/fb_mfbs.c (revision 36940495)
1 /*
2  * Copyright (c) 1992, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7  *
8  * %sccs.include.redist.c%
9  *
10  * from: $Hdr: fb_mfbs.c,v 4.300 91/06/27 20:42:43 root Rel41 $ SONY
11  *
12  *	@(#)fb_mfbs.c	8.1 (Berkeley) 06/11/93
13  */
14 
15 #include <sys/param.h>
16 #include <news3400/iop/framebuf.h>
17 #include <news3400/iop/fbreg.h>
18 #include <news3400/fb/fbdefs.h>
19 
20 u_short mfbstarttab16[16] =
21     {
22 	 ( 0x0000 ), ( 0x7FFF ), ( 0x3FFF ), ( 0x1FFF ),
23 	 ( 0x0FFF ), ( 0x07FF ), ( 0x03FF ), ( 0x01FF ),
24 	 ( 0x00FF ), ( 0x007F ), ( 0x003F ), ( 0x001F ),
25 	 ( 0x000F ), ( 0x0007 ), ( 0x0003 ), ( 0x0001 ),
26     };
27 u_short mfbendtab16[16] =
28     {
29 	 ( 0x0000 ), ( 0x8000 ), ( 0xC000 ), ( 0xE000 ),
30 	 ( 0xF000 ), ( 0xF800 ), ( 0xFC00 ), ( 0xFE00 ),
31 	 ( 0xFF00 ), ( 0xFF80 ), ( 0xFFC0 ), ( 0xFFE0 ),
32 	 ( 0xFFF0 ), ( 0xFFF8 ), ( 0xFFFC ), ( 0xFFFE ),
33     };
34 
35 u_short mfbpartmasks16[16][16] = {
36      { ( 0xFFFF ),  ( 0x8000 ),  ( 0xC000 ),  ( 0xE000 ),
37        ( 0xF000 ),  ( 0xF800 ),  ( 0xFC00 ),  ( 0xFE00 ),
38        ( 0xFF00 ),  ( 0xFF80 ),  ( 0xFFC0 ),  ( 0xFFE0 ),
39        ( 0xFFF0 ),  ( 0xFFF8 ),  ( 0xFFFC ),  ( 0xFFFE )},
40      { ( 0x0000 ),  ( 0x4000 ),  ( 0x6000 ),  ( 0x7000 ),
41        ( 0x7800 ),  ( 0x7C00 ),  ( 0x7E00 ),  ( 0x7F00 ),
42        ( 0x7F80 ),  ( 0x7FC0 ),  ( 0x7FE0 ),  ( 0x7FF0 ),
43        ( 0x7FF8 ),  ( 0x7FFC ),  ( 0x7FFE ),  ( 0x7FFF )},
44      { ( 0x0000 ),  ( 0x2000 ),  ( 0x3000 ),  ( 0x3800 ),
45        ( 0x3C00 ),  ( 0x3E00 ),  ( 0x3F00 ),  ( 0x3F80 ),
46        ( 0x3FC0 ),  ( 0x3FE0 ),  ( 0x3FF0 ),  ( 0x3FF8 ),
47        ( 0x3FFC ),  ( 0x3FFE ),  ( 0x3FFF ),  ( 0x0000 )},
48      { ( 0x0000 ),  ( 0x1000 ),  ( 0x1800 ),  ( 0x1C00 ),
49        ( 0x1E00 ),  ( 0x1F00 ),  ( 0x1F80 ),  ( 0x1FC0 ),
50        ( 0x1FE0 ),  ( 0x1FF0 ),  ( 0x1FF8 ),  ( 0x1FFC ),
51        ( 0x1FFE ),  ( 0x1FFF ),  ( 0x0000 ),  ( 0x0000 )},
52      { ( 0x0000 ),  ( 0x0800 ),  ( 0x0C00 ),  ( 0x0E00 ),
53        ( 0x0F00 ),  ( 0x0F80 ),  ( 0x0FC0 ),  ( 0x0FE0 ),
54        ( 0x0FF0 ),  ( 0x0FF8 ),  ( 0x0FFC ),  ( 0x0FFE ),
55        ( 0x0FFF ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 )},
56      { ( 0x0000 ),  ( 0x0400 ),  ( 0x0600 ),  ( 0x0700 ),
57        ( 0x0780 ),  ( 0x07C0 ),  ( 0x07E0 ),  ( 0x07F0 ),
58        ( 0x07F8 ),  ( 0x07FC ),  ( 0x07FE ),  ( 0x07FF ),
59        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 )},
60      { ( 0x0000 ),  ( 0x0200 ),  ( 0x0300 ),  ( 0x0380 ),
61        ( 0x03C0 ),  ( 0x03E0 ),  ( 0x03F0 ),  ( 0x03F8 ),
62        ( 0x03FC ),  ( 0x03FE ),  ( 0x03FF ),  ( 0x0000 ),
63        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 )},
64      { ( 0x0000 ),  ( 0x0100 ),  ( 0x0180 ),  ( 0x01C0 ),
65        ( 0x01E0 ),  ( 0x01F0 ),  ( 0x01F8 ),  ( 0x01FC ),
66        ( 0x01FE ),  ( 0x01FF ),  ( 0x0000 ),  ( 0x0000 ),
67        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 )},
68      { ( 0x0000 ),  ( 0x0080 ),  ( 0x00C0 ),  ( 0x00E0 ),
69        ( 0x00F0 ),  ( 0x00F8 ),  ( 0x00FC ),  ( 0x00FE ),
70        ( 0x00FF ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),
71        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 )},
72      { ( 0x0000 ),  ( 0x0040 ),  ( 0x0060 ),  ( 0x0070 ),
73        ( 0x0078 ),  ( 0x007C ),  ( 0x007E ),  ( 0x007F ),
74        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),
75        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 )},
76      { ( 0x0000 ),  ( 0x0020 ),  ( 0x0030 ),  ( 0x0038 ),
77        ( 0x003C ),  ( 0x003E ),  ( 0x003F ),  ( 0x0000 ),
78        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),
79        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 )},
80      { ( 0x0000 ),  ( 0x0010 ),  ( 0x0018 ),  ( 0x001C ),
81        ( 0x001E ),  ( 0x001F ),  ( 0x0000 ),  ( 0x0000 ),
82        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),
83        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 )},
84      { ( 0x0000 ),  ( 0x0008 ),  ( 0x000C ),  ( 0x000E ),
85        ( 0x000F ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),
86        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),
87        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 )},
88      { ( 0x0000 ),  ( 0x0004 ),  ( 0x0006 ),  ( 0x0007 ),
89        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),
90        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),
91        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 )},
92      { ( 0x0000 ),  ( 0x0002 ),  ( 0x0003 ),  ( 0x0000 ),
93        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),
94        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),
95        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 )},
96      { ( 0x0000 ),  ( 0x0001 ),  ( 0x0000 ),  ( 0x0000 ),
97        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),
98        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),
99        ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 ),  ( 0x0000 )},
100 };
101 
102 u_short mfbmask16[16] =
103     {
104      ( 1<<15 ),  ( 1<<14 ), ( 1<<13 ),
105      ( 1<<12 ),  ( 1<<11 ), ( 1<<10 ),
106      ( 1<<9 ),  ( 1<<8 ),  ( 1<<7 ),
107      ( 1<<6 ),  ( 1<<5 ),  ( 1<<4 ),
108      ( 1<<3 ),  ( 1<<2 ),  ( 1<<1 ),
109      ( 1<<0 )
110     };
111 u_short mfbrmask16[16] =
112     {
113     0xffffffff ^  ( 1<<15 ), 0xffffffff ^  ( 1<<14),
114     0xffffffff ^  ( 1<<13 ), 0xffffffff ^  ( 1<<12 ),
115     0xffffffff ^  ( 1<<11 ), 0xffffffff ^  ( 1<<10),
116     0xffffffff ^  ( 1<<9 ),  0xffffffff ^  ( 1<<8),
117     0xffffffff ^  ( 1<<7 ),  0xffffffff ^  ( 1<<6),
118     0xffffffff ^  ( 1<<5 ),  0xffffffff ^  ( 1<<4),
119     0xffffffff ^  ( 1<<3 ),  0xffffffff ^  ( 1<<2),
120     0xffffffff ^  ( 1<<1 ),  0xffffffff ^  ( 1<<0)
121     };
122 
123 u_int mfbstarttab32[32] =
124     {
125 	 ( 0x00000000 ), ( 0x7FFFFFFF ), ( 0x3FFFFFFF ), ( 0x1FFFFFFF ),
126 	 ( 0x0FFFFFFF ), ( 0x07FFFFFF ), ( 0x03FFFFFF ), ( 0x01FFFFFF ),
127 	 ( 0x00FFFFFF ), ( 0x007FFFFF ), ( 0x003FFFFF ), ( 0x001FFFFF ),
128 	 ( 0x000FFFFF ), ( 0x0007FFFF ), ( 0x0003FFFF ), ( 0x0001FFFF ),
129 	 ( 0x0000FFFF ), ( 0x00007FFF ), ( 0x00003FFF ), ( 0x00001FFF ),
130 	 ( 0x00000FFF ), ( 0x000007FF ), ( 0x000003FF ), ( 0x000001FF ),
131 	 ( 0x000000FF ), ( 0x0000007F ), ( 0x0000003F ), ( 0x0000001F ),
132 	 ( 0x0000000F ), ( 0x00000007 ), ( 0x00000003 ), ( 0x00000001 )
133     };
134 u_int mfbendtab32[32] =
135     {
136 	 ( 0x00000000 ), ( 0x80000000 ), ( 0xC0000000 ), ( 0xE0000000 ),
137 	 ( 0xF0000000 ), ( 0xF8000000 ), ( 0xFC000000 ), ( 0xFE000000 ),
138 	 ( 0xFF000000 ), ( 0xFF800000 ), ( 0xFFC00000 ), ( 0xFFE00000 ),
139 	 ( 0xFFF00000 ), ( 0xFFF80000 ), ( 0xFFFC0000 ), ( 0xFFFE0000 ),
140 	 ( 0xFFFF0000 ), ( 0xFFFF8000 ), ( 0xFFFFC000 ), ( 0xFFFFE000 ),
141 	 ( 0xFFFFF000 ), ( 0xFFFFF800 ), ( 0xFFFFFC00 ), ( 0xFFFFFE00 ),
142 	 ( 0xFFFFFF00 ), ( 0xFFFFFF80 ), ( 0xFFFFFFC0 ), ( 0xFFFFFFE0 ),
143 	 ( 0xFFFFFFF0 ), ( 0xFFFFFFF8 ), ( 0xFFFFFFFC ), ( 0xFFFFFFFE )
144     };
145 
146 u_int mfbpartmasks32[32][32] = {
147      { ( 0xFFFFFFFF ),  ( 0x80000000 ),  ( 0xC0000000 ),  ( 0xE0000000 ),
148        ( 0xF0000000 ),  ( 0xF8000000 ),  ( 0xFC000000 ),  ( 0xFE000000 ),
149        ( 0xFF000000 ),  ( 0xFF800000 ),  ( 0xFFC00000 ),  ( 0xFFE00000 ),
150        ( 0xFFF00000 ),  ( 0xFFF80000 ),  ( 0xFFFC0000 ),  ( 0xFFFE0000 ),
151        ( 0xFFFF0000 ),  ( 0xFFFF8000 ),  ( 0xFFFFC000 ),  ( 0xFFFFE000 ),
152        ( 0xFFFFF000 ),  ( 0xFFFFF800 ),  ( 0xFFFFFC00 ),  ( 0xFFFFFE00 ),
153        ( 0xFFFFFF00 ),  ( 0xFFFFFF80 ),  ( 0xFFFFFFC0 ),  ( 0xFFFFFFE0 ),
154        ( 0xFFFFFFF0 ),  ( 0xFFFFFFF8 ),  ( 0xFFFFFFFC ),  ( 0xFFFFFFFE )},
155      { ( 0x00000000 ),  ( 0x40000000 ),  ( 0x60000000 ),  ( 0x70000000 ),
156        ( 0x78000000 ),  ( 0x7C000000 ),  ( 0x7E000000 ),  ( 0x7F000000 ),
157        ( 0x7F800000 ),  ( 0x7FC00000 ),  ( 0x7FE00000 ),  ( 0x7FF00000 ),
158        ( 0x7FF80000 ),  ( 0x7FFC0000 ),  ( 0x7FFE0000 ),  ( 0x7FFF0000 ),
159        ( 0x7FFF8000 ),  ( 0x7FFFC000 ),  ( 0x7FFFE000 ),  ( 0x7FFFF000 ),
160        ( 0x7FFFF800 ),  ( 0x7FFFFC00 ),  ( 0x7FFFFE00 ),  ( 0x7FFFFF00 ),
161        ( 0x7FFFFF80 ),  ( 0x7FFFFFC0 ),  ( 0x7FFFFFE0 ),  ( 0x7FFFFFF0 ),
162        ( 0x7FFFFFF8 ),  ( 0x7FFFFFFC ),  ( 0x7FFFFFFE ),  ( 0x7FFFFFFF )},
163      { ( 0x00000000 ),  ( 0x20000000 ),  ( 0x30000000 ),  ( 0x38000000 ),
164        ( 0x3C000000 ),  ( 0x3E000000 ),  ( 0x3F000000 ),  ( 0x3F800000 ),
165        ( 0x3FC00000 ),  ( 0x3FE00000 ),  ( 0x3FF00000 ),  ( 0x3FF80000 ),
166        ( 0x3FFC0000 ),  ( 0x3FFE0000 ),  ( 0x3FFF0000 ),  ( 0x3FFF8000 ),
167        ( 0x3FFFC000 ),  ( 0x3FFFE000 ),  ( 0x3FFFF000 ),  ( 0x3FFFF800 ),
168        ( 0x3FFFFC00 ),  ( 0x3FFFFE00 ),  ( 0x3FFFFF00 ),  ( 0x3FFFFF80 ),
169        ( 0x3FFFFFC0 ),  ( 0x3FFFFFE0 ),  ( 0x3FFFFFF0 ),  ( 0x3FFFFFF8 ),
170        ( 0x3FFFFFFC ),  ( 0x3FFFFFFE ),  ( 0x3FFFFFFF ),  ( 0x00000000 )},
171      { ( 0x00000000 ),  ( 0x10000000 ),  ( 0x18000000 ),  ( 0x1C000000 ),
172        ( 0x1E000000 ),  ( 0x1F000000 ),  ( 0x1F800000 ),  ( 0x1FC00000 ),
173        ( 0x1FE00000 ),  ( 0x1FF00000 ),  ( 0x1FF80000 ),  ( 0x1FFC0000 ),
174        ( 0x1FFE0000 ),  ( 0x1FFF0000 ),  ( 0x1FFF8000 ),  ( 0x1FFFC000 ),
175        ( 0x1FFFE000 ),  ( 0x1FFFF000 ),  ( 0x1FFFF800 ),  ( 0x1FFFFC00 ),
176        ( 0x1FFFFE00 ),  ( 0x1FFFFF00 ),  ( 0x1FFFFF80 ),  ( 0x1FFFFFC0 ),
177        ( 0x1FFFFFE0 ),  ( 0x1FFFFFF0 ),  ( 0x1FFFFFF8 ),  ( 0x1FFFFFFC ),
178        ( 0x1FFFFFFE ),  ( 0x1FFFFFFF ),  ( 0x00000000 ),  ( 0x00000000 )},
179      { ( 0x00000000 ),  ( 0x08000000 ),  ( 0x0C000000 ),  ( 0x0E000000 ),
180        ( 0x0F000000 ),  ( 0x0F800000 ),  ( 0x0FC00000 ),  ( 0x0FE00000 ),
181        ( 0x0FF00000 ),  ( 0x0FF80000 ),  ( 0x0FFC0000 ),  ( 0x0FFE0000 ),
182        ( 0x0FFF0000 ),  ( 0x0FFF8000 ),  ( 0x0FFFC000 ),  ( 0x0FFFE000 ),
183        ( 0x0FFFF000 ),  ( 0x0FFFF800 ),  ( 0x0FFFFC00 ),  ( 0x0FFFFE00 ),
184        ( 0x0FFFFF00 ),  ( 0x0FFFFF80 ),  ( 0x0FFFFFC0 ),  ( 0x0FFFFFE0 ),
185        ( 0x0FFFFFF0 ),  ( 0x0FFFFFF8 ),  ( 0x0FFFFFFC ),  ( 0x0FFFFFFE ),
186        ( 0x0FFFFFFF ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
187      { ( 0x00000000 ),  ( 0x04000000 ),  ( 0x06000000 ),  ( 0x07000000 ),
188        ( 0x07800000 ),  ( 0x07C00000 ),  ( 0x07E00000 ),  ( 0x07F00000 ),
189        ( 0x07F80000 ),  ( 0x07FC0000 ),  ( 0x07FE0000 ),  ( 0x07FF0000 ),
190        ( 0x07FF8000 ),  ( 0x07FFC000 ),  ( 0x07FFE000 ),  ( 0x07FFF000 ),
191        ( 0x07FFF800 ),  ( 0x07FFFC00 ),  ( 0x07FFFE00 ),  ( 0x07FFFF00 ),
192        ( 0x07FFFF80 ),  ( 0x07FFFFC0 ),  ( 0x07FFFFE0 ),  ( 0x07FFFFF0 ),
193        ( 0x07FFFFF8 ),  ( 0x07FFFFFC ),  ( 0x07FFFFFE ),  ( 0x07FFFFFF ),
194        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
195      { ( 0x00000000 ),  ( 0x02000000 ),  ( 0x03000000 ),  ( 0x03800000 ),
196        ( 0x03C00000 ),  ( 0x03E00000 ),  ( 0x03F00000 ),  ( 0x03F80000 ),
197        ( 0x03FC0000 ),  ( 0x03FE0000 ),  ( 0x03FF0000 ),  ( 0x03FF8000 ),
198        ( 0x03FFC000 ),  ( 0x03FFE000 ),  ( 0x03FFF000 ),  ( 0x03FFF800 ),
199        ( 0x03FFFC00 ),  ( 0x03FFFE00 ),  ( 0x03FFFF00 ),  ( 0x03FFFF80 ),
200        ( 0x03FFFFC0 ),  ( 0x03FFFFE0 ),  ( 0x03FFFFF0 ),  ( 0x03FFFFF8 ),
201        ( 0x03FFFFFC ),  ( 0x03FFFFFE ),  ( 0x03FFFFFF ),  ( 0x00000000 ),
202        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
203      { ( 0x00000000 ),  ( 0x01000000 ),  ( 0x01800000 ),  ( 0x01C00000 ),
204        ( 0x01E00000 ),  ( 0x01F00000 ),  ( 0x01F80000 ),  ( 0x01FC0000 ),
205        ( 0x01FE0000 ),  ( 0x01FF0000 ),  ( 0x01FF8000 ),  ( 0x01FFC000 ),
206        ( 0x01FFE000 ),  ( 0x01FFF000 ),  ( 0x01FFF800 ),  ( 0x01FFFC00 ),
207        ( 0x01FFFE00 ),  ( 0x01FFFF00 ),  ( 0x01FFFF80 ),  ( 0x01FFFFC0 ),
208        ( 0x01FFFFE0 ),  ( 0x01FFFFF0 ),  ( 0x01FFFFF8 ),  ( 0x01FFFFFC ),
209        ( 0x01FFFFFE ),  ( 0x01FFFFFF ),  ( 0x00000000 ),  ( 0x00000000 ),
210        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
211      { ( 0x00000000 ),  ( 0x00800000 ),  ( 0x00C00000 ),  ( 0x00E00000 ),
212        ( 0x00F00000 ),  ( 0x00F80000 ),  ( 0x00FC0000 ),  ( 0x00FE0000 ),
213        ( 0x00FF0000 ),  ( 0x00FF8000 ),  ( 0x00FFC000 ),  ( 0x00FFE000 ),
214        ( 0x00FFF000 ),  ( 0x00FFF800 ),  ( 0x00FFFC00 ),  ( 0x00FFFE00 ),
215        ( 0x00FFFF00 ),  ( 0x00FFFF80 ),  ( 0x00FFFFC0 ),  ( 0x00FFFFE0 ),
216        ( 0x00FFFFF0 ),  ( 0x00FFFFF8 ),  ( 0x00FFFFFC ),  ( 0x00FFFFFE ),
217        ( 0x00FFFFFF ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
218        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
219      { ( 0x00000000 ),  ( 0x00400000 ),  ( 0x00600000 ),  ( 0x00700000 ),
220        ( 0x00780000 ),  ( 0x007C0000 ),  ( 0x007E0000 ),  ( 0x007F0000 ),
221        ( 0x007F8000 ),  ( 0x007FC000 ),  ( 0x007FE000 ),  ( 0x007FF000 ),
222        ( 0x007FF800 ),  ( 0x007FFC00 ),  ( 0x007FFE00 ),  ( 0x007FFF00 ),
223        ( 0x007FFF80 ),  ( 0x007FFFC0 ),  ( 0x007FFFE0 ),  ( 0x007FFFF0 ),
224        ( 0x007FFFF8 ),  ( 0x007FFFFC ),  ( 0x007FFFFE ),  ( 0x007FFFFF ),
225        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
226        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
227      { ( 0x00000000 ),  ( 0x00200000 ),  ( 0x00300000 ),  ( 0x00380000 ),
228        ( 0x003C0000 ),  ( 0x003E0000 ),  ( 0x003F0000 ),  ( 0x003F8000 ),
229        ( 0x003FC000 ),  ( 0x003FE000 ),  ( 0x003FF000 ),  ( 0x003FF800 ),
230        ( 0x003FFC00 ),  ( 0x003FFE00 ),  ( 0x003FFF00 ),  ( 0x003FFF80 ),
231        ( 0x003FFFC0 ),  ( 0x003FFFE0 ),  ( 0x003FFFF0 ),  ( 0x003FFFF8 ),
232        ( 0x003FFFFC ),  ( 0x003FFFFE ),  ( 0x003FFFFF ),  ( 0x00000000 ),
233        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
234        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
235      { ( 0x00000000 ),  ( 0x00100000 ),  ( 0x00180000 ),  ( 0x001C0000 ),
236        ( 0x001E0000 ),  ( 0x001F0000 ),  ( 0x001F8000 ),  ( 0x001FC000 ),
237        ( 0x001FE000 ),  ( 0x001FF000 ),  ( 0x001FF800 ),  ( 0x001FFC00 ),
238        ( 0x001FFE00 ),  ( 0x001FFF00 ),  ( 0x001FFF80 ),  ( 0x001FFFC0 ),
239        ( 0x001FFFE0 ),  ( 0x001FFFF0 ),  ( 0x001FFFF8 ),  ( 0x001FFFFC ),
240        ( 0x001FFFFE ),  ( 0x001FFFFF ),  ( 0x00000000 ),  ( 0x00000000 ),
241        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
242        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
243      { ( 0x00000000 ),  ( 0x00080000 ),  ( 0x000C0000 ),  ( 0x000E0000 ),
244        ( 0x000F0000 ),  ( 0x000F8000 ),  ( 0x000FC000 ),  ( 0x000FE000 ),
245        ( 0x000FF000 ),  ( 0x000FF800 ),  ( 0x000FFC00 ),  ( 0x000FFE00 ),
246        ( 0x000FFF00 ),  ( 0x000FFF80 ),  ( 0x000FFFC0 ),  ( 0x000FFFE0 ),
247        ( 0x000FFFF0 ),  ( 0x000FFFF8 ),  ( 0x000FFFFC ),  ( 0x000FFFFE ),
248        ( 0x000FFFFF ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
249        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
250        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
251      { ( 0x00000000 ),  ( 0x00040000 ),  ( 0x00060000 ),  ( 0x00070000 ),
252        ( 0x00078000 ),  ( 0x0007C000 ),  ( 0x0007E000 ),  ( 0x0007F000 ),
253        ( 0x0007F800 ),  ( 0x0007FC00 ),  ( 0x0007FE00 ),  ( 0x0007FF00 ),
254        ( 0x0007FF80 ),  ( 0x0007FFC0 ),  ( 0x0007FFE0 ),  ( 0x0007FFF0 ),
255        ( 0x0007FFF8 ),  ( 0x0007FFFC ),  ( 0x0007FFFE ),  ( 0x0007FFFF ),
256        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
257        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
258        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
259      { ( 0x00000000 ),  ( 0x00020000 ),  ( 0x00030000 ),  ( 0x00038000 ),
260        ( 0x0003C000 ),  ( 0x0003E000 ),  ( 0x0003F000 ),  ( 0x0003F800 ),
261        ( 0x0003FC00 ),  ( 0x0003FE00 ),  ( 0x0003FF00 ),  ( 0x0003FF80 ),
262        ( 0x0003FFC0 ),  ( 0x0003FFE0 ),  ( 0x0003FFF0 ),  ( 0x0003FFF8 ),
263        ( 0x0003FFFC ),  ( 0x0003FFFE ),  ( 0x0003FFFF ),  ( 0x00000000 ),
264        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
265        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
266        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
267      { ( 0x00000000 ),  ( 0x00010000 ),  ( 0x00018000 ),  ( 0x0001C000 ),
268        ( 0x0001E000 ),  ( 0x0001F000 ),  ( 0x0001F800 ),  ( 0x0001FC00 ),
269        ( 0x0001FE00 ),  ( 0x0001FF00 ),  ( 0x0001FF80 ),  ( 0x0001FFC0 ),
270        ( 0x0001FFE0 ),  ( 0x0001FFF0 ),  ( 0x0001FFF8 ),  ( 0x0001FFFC ),
271        ( 0x0001FFFE ),  ( 0x0001FFFF ),  ( 0x00000000 ),  ( 0x00000000 ),
272        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
273        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
274        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
275      { ( 0x00000000 ),  ( 0x00008000 ),  ( 0x0000C000 ),  ( 0x0000E000 ),
276        ( 0x0000F000 ),  ( 0x0000F800 ),  ( 0x0000FC00 ),  ( 0x0000FE00 ),
277        ( 0x0000FF00 ),  ( 0x0000FF80 ),  ( 0x0000FFC0 ),  ( 0x0000FFE0 ),
278        ( 0x0000FFF0 ),  ( 0x0000FFF8 ),  ( 0x0000FFFC ),  ( 0x0000FFFE ),
279        ( 0x0000FFFF ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
280        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
281        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
282        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
283      { ( 0x00000000 ),  ( 0x00004000 ),  ( 0x00006000 ),  ( 0x00007000 ),
284        ( 0x00007800 ),  ( 0x00007C00 ),  ( 0x00007E00 ),  ( 0x00007F00 ),
285        ( 0x00007F80 ),  ( 0x00007FC0 ),  ( 0x00007FE0 ),  ( 0x00007FF0 ),
286        ( 0x00007FF8 ),  ( 0x00007FFC ),  ( 0x00007FFE ),  ( 0x00007FFF ),
287        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
288        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
289        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
290        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
291      { ( 0x00000000 ),  ( 0x00002000 ),  ( 0x00003000 ),  ( 0x00003800 ),
292        ( 0x00003C00 ),  ( 0x00003E00 ),  ( 0x00003F00 ),  ( 0x00003F80 ),
293        ( 0x00003FC0 ),  ( 0x00003FE0 ),  ( 0x00003FF0 ),  ( 0x00003FF8 ),
294        ( 0x00003FFC ),  ( 0x00003FFE ),  ( 0x00003FFF ),  ( 0x00000000 ),
295        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
296        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
297        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
298        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
299      { ( 0x00000000 ),  ( 0x00001000 ),  ( 0x00001800 ),  ( 0x00001C00 ),
300        ( 0x00001E00 ),  ( 0x00001F00 ),  ( 0x00001F80 ),  ( 0x00001FC0 ),
301        ( 0x00001FE0 ),  ( 0x00001FF0 ),  ( 0x00001FF8 ),  ( 0x00001FFC ),
302        ( 0x00001FFE ),  ( 0x00001FFF ),  ( 0x00000000 ),  ( 0x00000000 ),
303        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
304        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
305        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
306        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
307      { ( 0x00000000 ),  ( 0x00000800 ),  ( 0x00000C00 ),  ( 0x00000E00 ),
308        ( 0x00000F00 ),  ( 0x00000F80 ),  ( 0x00000FC0 ),  ( 0x00000FE0 ),
309        ( 0x00000FF0 ),  ( 0x00000FF8 ),  ( 0x00000FFC ),  ( 0x00000FFE ),
310        ( 0x00000FFF ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
311        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
312        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
313        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
314        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
315      { ( 0x00000000 ),  ( 0x00000400 ),  ( 0x00000600 ),  ( 0x00000700 ),
316        ( 0x00000780 ),  ( 0x000007C0 ),  ( 0x000007E0 ),  ( 0x000007F0 ),
317        ( 0x000007F8 ),  ( 0x000007FC ),  ( 0x000007FE ),  ( 0x000007FF ),
318        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
319        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
320        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
321        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
322        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
323      { ( 0x00000000 ),  ( 0x00000200 ),  ( 0x00000300 ),  ( 0x00000380 ),
324        ( 0x000003C0 ),  ( 0x000003E0 ),  ( 0x000003F0 ),  ( 0x000003F8 ),
325        ( 0x000003FC ),  ( 0x000003FE ),  ( 0x000003FF ),  ( 0x00000000 ),
326        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
327        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
328        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
329        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
330        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
331      { ( 0x00000000 ),  ( 0x00000100 ),  ( 0x00000180 ),  ( 0x000001C0 ),
332        ( 0x000001E0 ),  ( 0x000001F0 ),  ( 0x000001F8 ),  ( 0x000001FC ),
333        ( 0x000001FE ),  ( 0x000001FF ),  ( 0x00000000 ),  ( 0x00000000 ),
334        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
335        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
336        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
337        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
338        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
339      { ( 0x00000000 ),  ( 0x00000080 ),  ( 0x000000C0 ),  ( 0x000000E0 ),
340        ( 0x000000F0 ),  ( 0x000000F8 ),  ( 0x000000FC ),  ( 0x000000FE ),
341        ( 0x000000FF ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
342        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
343        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
344        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
345        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
346        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
347      { ( 0x00000000 ),  ( 0x00000040 ),  ( 0x00000060 ),  ( 0x00000070 ),
348        ( 0x00000078 ),  ( 0x0000007C ),  ( 0x0000007E ),  ( 0x0000007F ),
349        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
350        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
351        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
352        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
353        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
354        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
355      { ( 0x00000000 ),  ( 0x00000020 ),  ( 0x00000030 ),  ( 0x00000038 ),
356        ( 0x0000003C ),  ( 0x0000003E ),  ( 0x0000003F ),  ( 0x00000000 ),
357        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
358        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
359        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
360        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
361        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
362        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
363      { ( 0x00000000 ),  ( 0x00000010 ),  ( 0x00000018 ),  ( 0x0000001C ),
364        ( 0x0000001E ),  ( 0x0000001F ),  ( 0x00000000 ),  ( 0x00000000 ),
365        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
366        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
367        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
368        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
369        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
370        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
371      { ( 0x00000000 ),  ( 0x00000008 ),  ( 0x0000000C ),  ( 0x0000000E ),
372        ( 0x0000000F ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
373        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
374        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
375        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
376        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
377        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
378        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
379      { ( 0x00000000 ),  ( 0x00000004 ),  ( 0x00000006 ),  ( 0x00000007 ),
380        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
381        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
382        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
383        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
384        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
385        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
386        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
387      { ( 0x00000000 ),  ( 0x00000002 ),  ( 0x00000003 ),  ( 0x00000000 ),
388        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
389        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
390        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
391        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
392        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
393        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
394        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
395      { ( 0x00000000 ),  ( 0x00000001 ),  ( 0x00000000 ),  ( 0x00000000 ),
396        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
397        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
398        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
399        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
400        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
401        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),
402        ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 ),  ( 0x00000000 )},
403 };
404 
405 u_int mfbmask32[32] =
406     {
407      ( 1<<31 ),  ( 1<<30 ),  ( 1<<29 ),
408      ( 1<<28 ),  ( 1<<27 ),  ( 1<<26 ),
409      ( 1<<25 ),  ( 1<<24 ),  ( 1<<23 ),
410      ( 1<<22 ),  ( 1<<21 ),  ( 1<<20 ),
411      ( 1<<19 ),  ( 1<<18 ),  ( 1<<17 ),
412      ( 1<<16 ),  ( 1<<15 ),  ( 1<<14 ),
413      ( 1<<13 ),  ( 1<<12 ),  ( 1<<11 ),
414      ( 1<<10 ),  ( 1<<9 ),  ( 1<<8 ),
415      ( 1<<7 ),  ( 1<<6 ),  ( 1<<5 ),
416      ( 1<<4 ),  ( 1<<3 ),  ( 1<<2 ),
417      ( 1<<1 ),  ( 1<<0 )
418     };
419 
420 u_int mfbrmask32[32] =
421     {
422     0xffffffff ^  ( 1<<31 ), 0xffffffff ^  ( 1<<30 ),
423     0xffffffff ^  ( 1<<29 ), 0xffffffff ^  ( 1<<28),
424     0xffffffff ^  ( 1<<27 ), 0xffffffff ^  ( 1<<26),
425     0xffffffff ^  ( 1<<25 ), 0xffffffff ^  ( 1<<24 ),
426     0xffffffff ^  ( 1<<23 ), 0xffffffff ^  ( 1<<22),
427     0xffffffff ^  ( 1<<21 ), 0xffffffff ^  ( 1<<20),
428     0xffffffff ^  ( 1<<19 ), 0xffffffff ^  ( 1<<18 ),
429     0xffffffff ^  ( 1<<17 ), 0xffffffff ^  ( 1<<16),
430     0xffffffff ^  ( 1<<15 ), 0xffffffff ^  ( 1<<14),
431     0xffffffff ^  ( 1<<13 ), 0xffffffff ^  ( 1<<12 ),
432     0xffffffff ^  ( 1<<11 ), 0xffffffff ^  ( 1<<10),
433     0xffffffff ^  ( 1<<9 ),  0xffffffff ^  ( 1<<8),
434     0xffffffff ^  ( 1<<7 ),  0xffffffff ^  ( 1<<6),
435     0xffffffff ^  ( 1<<5 ),  0xffffffff ^  ( 1<<4),
436     0xffffffff ^  ( 1<<3 ),  0xffffffff ^  ( 1<<2),
437     0xffffffff ^  ( 1<<1 ),  0xffffffff ^  ( 1<<0)
438     };
439 
440 mergeRopRec mergeRopBits[16] = {
441 	 0, 0, 0, 0,		/* BF_0		0 */
442 	~0, 0, 0, 0,		/* BF_SDA	src & dst */
443 	~0, 0,~0, 0,		/* BF_SDIA	src & ~dst */
444 	 0, 0,~0, 0,		/* BF_S		src */
445 	~0,~0, 0, 0,		/* BF_SIDA	~src & dst */
446 	 0,~0, 0, 0,		/* BF_D		dst */
447 	 0,~0,~0, 0,		/* BF_SDX	src ^ dst */
448 	~0,~0,~0, 0,		/* BF_SDO	src | dst */
449 	~0,~0,~0,~0,		/* BF_SDOI	~(src | dst) */
450 	 0,~0,~0,~0,		/* BF_SDXI	~(src ^ dst) */
451 	 0,~0, 0,~0,		/* BF_DI	~dst */
452 	~0,~0, 0,~0,		/* BF_SDIO	src | ~dst */
453 	 0, 0,~0,~0,		/* BF_SI	~src */
454 	~0, 0,~0,~0,		/* BF_SIDO	~src | dst */
455 	~0, 0, 0,~0,		/* BF_SDAI	~(src & dst) */
456 	 0, 0, 0,~0,		/* BF_1		1 */
457 };
458 
459 #define Duff(counter, block) { \
460 	switch (counter & 7) { \
461 	case 7: { block; } \
462 	case 6: { block; } \
463 	case 5: { block; } \
464 	case 4: { block; } \
465 	case 3: { block; } \
466 	case 2: { block; } \
467 	case 1: { block; } \
468 	case 0:; \
469 	} \
470 	while ((counter -= 8) >= 0) { \
471 		{ block; } \
472 		{ block; } \
473 		{ block; } \
474 		{ block; } \
475 		{ block; } \
476 		{ block; } \
477 		{ block; } \
478 		{ block; } \
479 	} \
480 }
481 
482 #ifdef mc68020
483 #define	Duff_plus(n, dst, src, op) { \
484 	switch ((n) & 7) { \
485 	case 7: \
486 		*(dst)++ op *(src)++; \
487 	case 6: \
488 		*(dst)++ op *(src)++; \
489 	case 5: \
490 		*(dst)++ op *(src)++; \
491 	case 4: \
492 		*(dst)++ op *(src)++; \
493 	case 3: \
494 		*(dst)++ op *(src)++; \
495 	case 2: \
496 		*(dst)++ op *(src)++; \
497 	case 1: \
498 		*(dst)++ op *(src)++; \
499 	} \
500 	while (((n) -= 8) >= 0) { \
501 		*(dst)++ op *(src)++; \
502 		*(dst)++ op *(src)++; \
503 		*(dst)++ op *(src)++; \
504 		*(dst)++ op *(src)++; \
505 		*(dst)++ op *(src)++; \
506 		*(dst)++ op *(src)++; \
507 		*(dst)++ op *(src)++; \
508 		*(dst)++ op *(src)++; \
509 	} \
510 } \
511 
512 #define Duff_minus(n, dst, src, op) { \
513 	switch ((n) & 7) { \
514 	case 7: \
515 		*--(dst) op *--(src); \
516 	case 6: \
517 		*--(dst) op *--(src); \
518 	case 5: \
519 		*--(dst) op *--(src); \
520 	case 4: \
521 		*--(dst) op *--(src); \
522 	case 3: \
523 		*--(dst) op *--(src); \
524 	case 2: \
525 		*--(dst) op *--(src); \
526 	case 1: \
527 		*--(dst) op *--(src); \
528 	} \
529 	while (((n) -= 8) >= 0) { \
530 		*--(dst) op *--(src); \
531 		*--(dst) op *--(src); \
532 		*--(dst) op *--(src); \
533 		*--(dst) op *--(src); \
534 		*--(dst) op *--(src); \
535 		*--(dst) op *--(src); \
536 		*--(dst) op *--(src); \
537 		*--(dst) op *--(src); \
538 	} \
539 }
540 
541 #define	Duff_shift_plus(n, dst, src, op) { \
542 	switch ((n) & 3) { \
543 	case 3: \
544 		bits = *(src)++; \
545 		*(dst)++ op (bits1 << leftShift) | (bits >> rightShift); \
546 	case 2: \
547 		bits1 = *(src)++; \
548 		*(dst)++ op (bits << leftShift) | (bits1 >> rightShift); \
549 	case 1: \
550 		bits = *(src)++; \
551 		*(dst)++ op (bits1 << leftShift) | (bits >> rightShift); \
552 	} \
553 	while (((n) -= 4) >= 0) { \
554 		bits1 = *(src)++; \
555 		*(dst)++ op (bits << leftShift) | (bits1 >> rightShift); \
556 		bits = *(src)++; \
557 		*(dst)++ op (bits1 << leftShift) | (bits >> rightShift); \
558 		bits1 = *(src)++; \
559 		*(dst)++ op (bits << leftShift) | (bits1 >> rightShift); \
560 		bits = *(src)++; \
561 		*(dst)++ op (bits1 << leftShift) | (bits >> rightShift); \
562 	} \
563 }
564 
565 #define	Duff_shift_minus(n, dst, src, op) { \
566 	switch ((n) & 3) { \
567 	case 3: \
568 		bits = *--(src); \
569 		*--(dst) op ((bits1 >> rightShift) | (bits << leftShift)); \
570 	case 2: \
571 		bits1 = *--(src); \
572 		*--(dst) op ((bits >> rightShift) | (bits1 << leftShift)); \
573 	case 1: \
574 		bits = *--(src); \
575 		*--(dst) op ((bits1 >> rightShift) | (bits << leftShift)); \
576 	} \
577 	while (((n) -= 4) >= 0) { \
578 		bits1 = *--(src); \
579 		*--(dst) op ((bits >> rightShift) | (bits1 << leftShift)); \
580 		bits = *--(src); \
581 		*--(dst) op ((bits1 >> rightShift) | (bits << leftShift)); \
582 		bits1 = *--(src); \
583 		*--(dst) op ((bits >> rightShift) | (bits1 << leftShift)); \
584 		bits = *--(src); \
585 		*--(dst) op ((bits1 >> rightShift) | (bits << leftShift)); \
586 	} \
587 }
588 
589 #define	Duff_single(nlw, addr, op) { \
590 	switch ((nlw) & 7) { \
591 	case 7: \
592 		*(addr)++ op ; \
593 	case 6: \
594 		*(addr)++ op ; \
595 	case 5: \
596 		*(addr)++ op ; \
597 	case 4: \
598 		*(addr)++ op ; \
599 	case 3: \
600 		*(addr)++ op ; \
601 	case 2: \
602 		*(addr)++ op ; \
603 	case 1: \
604 		*(addr)++ op ; \
605 	} \
606 	while (((nlw) -= 8) >= 0) { \
607 		*(addr)++ op ; \
608 		*(addr)++ op ; \
609 		*(addr)++ op ; \
610 		*(addr)++ op ; \
611 		*(addr)++ op ; \
612 		*(addr)++ op ; \
613 		*(addr)++ op ; \
614 		*(addr)++ op ; \
615 	} \
616 }
617 #else /* mc68020 */
618 #define	Duff_plus(n, dst, src, op) { \
619 	(src) += (n) & 7; \
620 	(dst) += (n) & 7; \
621 	switch ((n) & 7) { \
622 	case 7: \
623 		(dst)[-7] op (src)[-7]; \
624 	case 6: \
625 		(dst)[-6] op (src)[-6]; \
626 	case 5: \
627 		(dst)[-5] op (src)[-5]; \
628 	case 4: \
629 		(dst)[-4] op (src)[-4]; \
630 	case 3: \
631 		(dst)[-3] op (src)[-3]; \
632 	case 2: \
633 		(dst)[-2] op (src)[-2]; \
634 	case 1: \
635 		(dst)[-1] op (src)[-1]; \
636 	} \
637 	while (((n) -= 8) >= 0) { \
638 		(dst) += 8; \
639 		(src) += 8; \
640 		(dst)[-8] op (src)[-8]; \
641 		(dst)[-7] op (src)[-7]; \
642 		(dst)[-6] op (src)[-6]; \
643 		(dst)[-5] op (src)[-5]; \
644 		(dst)[-4] op (src)[-4]; \
645 		(dst)[-3] op (src)[-3]; \
646 		(dst)[-2] op (src)[-2]; \
647 		(dst)[-1] op (src)[-1]; \
648 	} \
649 } \
650 
651 #define Duff_minus(n, dst, src, op) { \
652 	(src) -= (n) & 7; \
653 	(dst) -= (n) & 7; \
654 	switch ((n) & 7) { \
655 	case 7: \
656 		(dst)[7-1] op (src)[7-1]; \
657 	case 6: \
658 		(dst)[6-1] op (src)[6-1]; \
659 	case 5: \
660 		(dst)[5-1] op (src)[5-1]; \
661 	case 4: \
662 		(dst)[4-1] op (src)[4-1]; \
663 	case 3: \
664 		(dst)[3-1] op (src)[3-1]; \
665 	case 2: \
666 		(dst)[2-1] op (src)[2-1]; \
667 	case 1: \
668 		(dst)[1-1] op (src)[1-1]; \
669 	} \
670 	while (((n) -= 8) >= 0) { \
671 		(dst) -= 8; \
672 		(src) -= 8; \
673 		(dst)[8-1] op (src)[8-1]; \
674 		(dst)[7-1] op (src)[7-1]; \
675 		(dst)[6-1] op (src)[6-1]; \
676 		(dst)[5-1] op (src)[5-1]; \
677 		(dst)[4-1] op (src)[4-1]; \
678 		(dst)[3-1] op (src)[3-1]; \
679 		(dst)[2-1] op (src)[2-1]; \
680 		(dst)[1-1] op (src)[1-1]; \
681 	} \
682 }
683 
684 #define	Duff_shift_plus(n, dst, src, op) { \
685 	(src) += (n) & 7; \
686 	(dst) += (n) & 7; \
687 	switch ((n) & 7) { \
688 	case 7: \
689 		bits = (src)[-7]; \
690 		(dst)[-7] op (bits1 << leftShift) | (bits >> rightShift); \
691 	case 6: \
692 		bits1 = (src)[-6]; \
693 		(dst)[-6] op (bits << leftShift) | (bits1 >> rightShift); \
694 	case 5: \
695 		bits = (src)[-5]; \
696 		(dst)[-5] op (bits1 << leftShift) | (bits >> rightShift); \
697 	case 4: \
698 		bits1 = (src)[-4]; \
699 		(dst)[-4] op (bits << leftShift) | (bits1 >> rightShift); \
700 	case 3: \
701 		bits = (src)[-3]; \
702 		(dst)[-3] op (bits1 << leftShift) | (bits >> rightShift); \
703 	case 2: \
704 		bits1 = (src)[-2]; \
705 		(dst)[-2] op (bits << leftShift) | (bits1 >> rightShift); \
706 	case 1: \
707 		bits = (src)[-1]; \
708 		(dst)[-1] op (bits1 << leftShift) | (bits >> rightShift); \
709 	} \
710 	while (((n) -= 8) >= 0) { \
711 		(dst) += 8; \
712 		(src) += 8; \
713 		bits1 = (src)[-8]; \
714 		(dst)[-8] op (bits << leftShift) | (bits1 >> rightShift); \
715 		bits = (src)[-7]; \
716 		(dst)[-7] op (bits1 << leftShift) | (bits >> rightShift); \
717 		bits1 = (src)[-6]; \
718 		(dst)[-6] op (bits << leftShift) | (bits1 >> rightShift); \
719 		bits = (src)[-5]; \
720 		(dst)[-5] op (bits1 << leftShift) | (bits >> rightShift); \
721 		bits1 = (src)[-4]; \
722 		(dst)[-4] op (bits << leftShift) | (bits1 >> rightShift); \
723 		bits = (src)[-3]; \
724 		(dst)[-3] op (bits1 << leftShift) | (bits >> rightShift); \
725 		bits1 = (src)[-2]; \
726 		(dst)[-2] op (bits << leftShift) | (bits1 >> rightShift); \
727 		bits = (src)[-1]; \
728 		(dst)[-1] op (bits1 << leftShift) | (bits >> rightShift); \
729 	} \
730 }
731 
732 #define	Duff_shift_minus(n, dst, src, op) { \
733 	(src) -= (n) & 7; \
734 	(dst) -= (n) & 7; \
735 	switch ((n) & 7) { \
736 	case 7: \
737 		bits = (src)[7-1]; \
738 		(dst)[7-1] op ((bits1 >> rightShift) | (bits << leftShift)); \
739 	case 6: \
740 		bits1 = (src)[6-1]; \
741 		(dst)[6-1] op ((bits >> rightShift) | (bits1 << leftShift)); \
742 	case 5: \
743 		bits = (src)[5-1]; \
744 		(dst)[5-1] op ((bits1 >> rightShift) | (bits << leftShift)); \
745 	case 4: \
746 		bits1 = (src)[4-1]; \
747 		(dst)[4-1] op ((bits >> rightShift) | (bits1 << leftShift)); \
748 	case 3: \
749 		bits = (src)[3-1]; \
750 		(dst)[3-1] op ((bits1 >> rightShift) | (bits << leftShift)); \
751 	case 2: \
752 		bits1 = (src)[2-1]; \
753 		(dst)[2-1] op ((bits >> rightShift) | (bits1 << leftShift)); \
754 	case 1: \
755 		bits = (src)[1-1]; \
756 		(dst)[1-1] op ((bits1 >> rightShift) | (bits << leftShift)); \
757 	} \
758 	while (((n) -= 8) >= 0) { \
759 		(dst) -= 8; \
760 		(src) -= 8; \
761 		bits1 = (src)[8-1]; \
762 		(dst)[8-1] op ((bits >> rightShift) | (bits1 << leftShift)); \
763 		bits = (src)[7-1]; \
764 		(dst)[7-1] op ((bits1 >> rightShift) | (bits << leftShift)); \
765 		bits1 = (src)[6-1]; \
766 		(dst)[6-1] op ((bits >> rightShift) | (bits1 << leftShift)); \
767 		bits = (src)[5-1]; \
768 		(dst)[5-1] op ((bits1 >> rightShift) | (bits << leftShift)); \
769 		bits1 = (src)[4-1]; \
770 		(dst)[4-1] op ((bits >> rightShift) | (bits1 << leftShift)); \
771 		bits = (src)[3-1]; \
772 		(dst)[3-1] op ((bits1 >> rightShift) | (bits << leftShift)); \
773 		bits1 = (src)[2-1]; \
774 		(dst)[2-1] op ((bits >> rightShift) | (bits1 << leftShift)); \
775 		bits = (src)[1-1]; \
776 		(dst)[1-1] op ((bits1 >> rightShift) | (bits << leftShift)); \
777 	} \
778 }
779 
780 #define	Duff_single(nlw, addr, op) { \
781 	(addr) += (nlw) & 7; \
782 	switch ((nlw) & 7) { \
783 	case 7: \
784 		(addr)[-7] op; \
785 	case 6: \
786 		(addr)[-6] op; \
787 	case 5: \
788 		(addr)[-5] op; \
789 	case 4: \
790 		(addr)[-4] op; \
791 	case 3: \
792 		(addr)[-3] op; \
793 	case 2: \
794 		(addr)[-2] op; \
795 	case 1: \
796 		(addr)[-1] op; \
797 	} \
798 	while (((nlw) -= 8) >= 0) { \
799 		(addr) += 8; \
800 		(addr)[-8] op; \
801 		(addr)[-7] op; \
802 		(addr)[-6] op; \
803 		(addr)[-5] op; \
804 		(addr)[-4] op; \
805 		(addr)[-3] op; \
806 		(addr)[-2] op; \
807 		(addr)[-1] op; \
808 	} \
809 }
810 #endif /* mc68020 */
811 
812 void
813 mfb_copy_area32(addrSrc, addrDst, widthSrc, widthDst, sr, dp)
814 u_int	*addrSrc;
815 u_int	*addrDst;
816 u_int	widthSrc;
817 u_int	widthDst;
818 lRectangle	*sr;	/* source rectangle */
819 lPoint		*dp;	/* destination point */
820 {
821 	register u_int *psrcLine, *psrc;
822 	register u_int *pdstLine, *pdst;
823 	int w, h;
824 	int xdir, ydir;
825 	u_int startmask, endmask;
826 	register int nlMiddle;
827 	int xoffSrc, xoffDst;
828 	register int leftShift, rightShift;
829 	u_int bits;
830 	u_int bits1;
831 	register int nl;
832 
833 	if (sr->origin.y < dp->y) {
834 		ydir = -1;
835 		widthSrc = -widthSrc;
836 		widthDst = -widthDst;
837 	} else {
838 		ydir = 1;
839 	}
840 
841 	if (sr->origin.x < dp->x) {
842 		xdir = -1;
843 	} else {
844 		xdir = 1;
845 	}
846 
847 	w = sr->extent.x;
848 	h = sr->extent.y;
849 
850 	if (ydir == -1) {
851 		psrcLine = addrSrc + ((sr->origin.y + h - 1) * -widthSrc);
852 		pdstLine = addrDst + ((dp->y + h - 1) * -widthDst);
853 	} else {
854 		psrcLine = addrSrc + (sr->origin.y * widthSrc);
855 		pdstLine = addrDst + (dp->y * widthDst);
856 	}
857 	if ((dp->x & 0x1f) +w <= 32) {
858 		startmask = mfbpartmasks32[dp->x & 0x1f][w & 0x1f];
859 		endmask = 0;
860 		nlMiddle = 0;
861 	} else {
862 		startmask = mfbstarttab32[dp->x & 0x1f];
863 		endmask = mfbendtab32[(dp->x + w) & 0x1f];
864 		if (startmask) {
865 			nlMiddle = (w - (32 - (dp->x & 0x1f))) >> 5;
866 		} else {
867 			nlMiddle = w >> 5;
868 		}
869 	}
870 
871 	if (xdir == 1) {
872 		xoffSrc = sr->origin.x & 0x1f;
873 		xoffDst = dp->x & 0x1f;
874 		pdstLine += (dp->x >> 5);
875 		psrcLine += (sr->origin.x >> 5);
876 		if (xoffSrc == xoffDst) {
877 			while (h--) {
878 				psrc = psrcLine;
879 				pdst = pdstLine;
880 				pdstLine += widthDst;
881 				psrcLine += widthSrc;
882 				if (startmask) {
883 					*pdst = (*pdst & ~startmask |
884 						 *psrc & startmask);
885 					psrc++;
886 					pdst++;
887 				}
888 				nl = nlMiddle;
889 				Duff_plus(nl, pdst, psrc, =);
890 				if (endmask) {
891 					*pdst = (*pdst & ~endmask |
892 						 *psrc & endmask);
893 				}
894 			}
895 		} else {
896 			if (xoffSrc > xoffDst) {
897 				leftShift = xoffSrc - xoffDst;
898 				rightShift = 32 - leftShift;
899 			} else {
900 				rightShift = xoffDst - xoffSrc;
901 				leftShift = 32 - rightShift;
902 			}
903 			while (h--) {
904 				psrc = psrcLine;
905 				pdst = pdstLine;
906 				pdstLine += widthDst;
907 				psrcLine += widthSrc;
908 				bits = 0;
909 				if (xoffSrc > xoffDst)
910 					bits = *psrc++;
911 				if (startmask) {
912 					bits1 = bits << leftShift;
913 					bits = *psrc++;
914 					bits1 |= bits >> rightShift;
915 					*pdst = (*pdst & ~startmask |
916 						 bits1 & startmask);
917 					pdst++;
918 				}
919 				nl = nlMiddle;
920 				bits1 = bits;
921 				Duff_shift_plus(nl, pdst, psrc, =);
922 				if (endmask) {
923 					bits1 = bits << leftShift;
924 					if (endmask << rightShift) {
925 						bits1 |= *psrc >> rightShift;
926 					}
927 					*pdst = (*pdst & ~endmask |
928 						 bits1 & endmask);
929 				}
930 			}
931 		}
932 	} else {
933 		xoffSrc = (sr->origin.x + w - 1) & 0x1f;
934 		xoffDst = (dp->x + w - 1) & 0x1f;
935 		pdstLine += ((dp->x + w - 1) >> 5) + 1;
936 		psrcLine += ((sr->origin.x + w - 1) >> 5) + 1;
937 		if (xoffSrc == xoffDst) {
938 			while (h--) {
939 				psrc = psrcLine;
940 				pdst = pdstLine;
941 				pdstLine += widthDst;
942 				psrcLine += widthSrc;
943 				if (endmask) {
944 					pdst--;
945 					psrc--;
946 					*pdst = (*pdst & ~endmask |
947 						 *psrc & endmask);
948 				}
949 				nl = nlMiddle;
950 				Duff_minus(nl, pdst, psrc, =);
951 				if (startmask) {
952 					--pdst;
953 					--psrc;
954 					*pdst = (*pdst & ~startmask |
955 						 *psrc & startmask);
956 				}
957 			}
958 		} else {
959 			if (xoffDst > xoffSrc) {
960 				rightShift = xoffDst - xoffSrc;
961 				leftShift = 32 - rightShift;
962 			} else {
963 				leftShift = xoffSrc - xoffDst;
964 				rightShift = 32 - leftShift;
965 			}
966 			while (h--) {
967 				psrc = psrcLine;
968 				pdst = pdstLine;
969 				pdstLine += widthDst;
970 				psrcLine += widthSrc;
971 				bits = 0;
972 				if (xoffDst > xoffSrc)
973 					bits = *--psrc;
974 				if (endmask) {
975 					bits1 = bits >> rightShift;
976 					bits = *--psrc;
977 					bits1 |= (bits << leftShift);
978 					pdst--;
979 					*pdst = (*pdst & ~endmask |
980 						 bits1 & endmask);
981 				}
982 				nl = nlMiddle;
983 				bits1 = bits;
984 				Duff_shift_minus(nl, pdst, psrc, =);
985 				if (startmask) {
986 					bits1 = (bits >> rightShift);
987 					if (startmask >> leftShift) {
988 						bits1 |= *--psrc << leftShift;
989 					}
990 					--pdst;
991 					*pdst = (*pdst & ~startmask |
992 						 bits1 & startmask);
993 				}
994 			}
995 		}
996 	}
997 }
998 
999 void
1000 mfb_copyinv_area32(addrSrc, addrDst, widthSrc, widthDst, sr, dp)
1001 u_int	*addrSrc;
1002 u_int	*addrDst;
1003 int	widthSrc;
1004 int	widthDst;
1005 lRectangle	*sr;	/* source rectangle */
1006 lPoint		*dp;	/* destination point */
1007 {
1008 	register u_int *psrcLine, *psrc;
1009 	register u_int *pdstLine, *pdst;
1010 	int w, h;
1011 	int xdir, ydir;
1012 	u_int startmask, endmask;
1013 	register int nlMiddle;
1014 	int xoffSrc, xoffDst;
1015 	register int leftShift, rightShift;
1016 	u_int bits;
1017 	u_int bits1;
1018 	register int nl;
1019 
1020 	if (sr->origin.y < dp->y) {
1021 		ydir = -1;
1022 		widthSrc = -widthSrc;
1023 		widthDst = -widthDst;
1024 	} else {
1025 		ydir = 1;
1026 	}
1027 
1028 	if (sr->origin.x < dp->x) {
1029 		xdir = -1;
1030 	} else {
1031 		xdir = 1;
1032 	}
1033 
1034 	w = sr->extent.x;
1035 	h = sr->extent.y;
1036 
1037 	if (ydir == -1) {
1038 		psrcLine = addrSrc + ((sr->origin.y + h - 1) * -widthSrc);
1039 		pdstLine = addrDst + ((dp->y + h - 1) * -widthDst);
1040 	} else {
1041 		psrcLine = addrSrc + (sr->origin.y * widthSrc);
1042 		pdstLine = addrDst + (dp->y * widthDst);
1043 	}
1044 	if ((dp->x & 0x1f) +w <= 32) {
1045 		startmask = mfbpartmasks32[dp->x & 0x1f][w & 0x1f];
1046 		endmask = 0;
1047 		nlMiddle = 0;
1048 	} else {
1049 		startmask = mfbstarttab32[dp->x & 0x1f];
1050 		endmask = mfbendtab32[(dp->x + w) & 0x1f];
1051 		if (startmask) {
1052 			nlMiddle = (w - (32 - (dp->x & 0x1f))) >> 5;
1053 		} else {
1054 			nlMiddle = w >> 5;
1055 		}
1056 	}
1057 
1058 	if (xdir == 1) {
1059 		xoffSrc = sr->origin.x & 0x1f;
1060 		xoffDst = dp->x & 0x1f;
1061 		pdstLine += (dp->x >> 5);
1062 		psrcLine += (sr->origin.x >> 5);
1063 		if (xoffSrc == xoffDst) {
1064 			while (h--) {
1065 				psrc = psrcLine;
1066 				pdst = pdstLine;
1067 				pdstLine += widthDst;
1068 				psrcLine += widthSrc;
1069 				if (startmask) {
1070 					*pdst = (*pdst & ~startmask |
1071 						 ~*psrc & startmask);
1072 					psrc++;
1073 					pdst++;
1074 				}
1075 				nl = nlMiddle;
1076 				Duff_plus(nl, pdst, psrc, = ~);
1077 				if (endmask) {
1078 					*pdst = (*pdst & ~endmask |
1079 						 ~*psrc & endmask);
1080 				}
1081 			}
1082 		} else {
1083 			if (xoffSrc > xoffDst) {
1084 				leftShift = xoffSrc - xoffDst;
1085 				rightShift = 32 - leftShift;
1086 			} else {
1087 				rightShift = xoffDst - xoffSrc;
1088 				leftShift = 32 - rightShift;
1089 			}
1090 			while (h--) {
1091 				psrc = psrcLine;
1092 				pdst = pdstLine;
1093 				psrcLine += widthSrc;
1094 				pdstLine += widthDst;
1095 				bits = 0;
1096 				if (xoffSrc > xoffDst)
1097 					bits = *psrc++;
1098 				if (startmask) {
1099 					bits1 = bits << leftShift;
1100 					bits = *psrc++;
1101 					bits1 |= bits >> rightShift;
1102 					*pdst = (*pdst & ~startmask |
1103 						 ~bits1 & startmask);
1104 					pdst++;
1105 				}
1106 				nl = nlMiddle;
1107 				bits1 = bits;
1108 				Duff_shift_plus(nl, pdst, psrc, = ~);
1109 				if (endmask) {
1110 					bits1 = bits << leftShift;
1111 					if (endmask << rightShift) {
1112 						bits1 |= *psrc >> rightShift;
1113 					}
1114 					*pdst = (*pdst & ~endmask |
1115 						 ~bits1 & endmask);
1116 				}
1117 			}
1118 		}
1119 	} else {
1120 		xoffSrc = (sr->origin.x + w - 1) & 0x1f;
1121 		xoffDst = (dp->x + w - 1) & 0x1f;
1122 		pdstLine += ((dp->x + w - 1) >> 5) + 1;
1123 		psrcLine += ((sr->origin.x + w - 1) >> 5) + 1;
1124 		if (xoffSrc == xoffDst) {
1125 			while (h--) {
1126 				psrc = psrcLine;
1127 				pdst = pdstLine;
1128 				pdstLine += widthDst;
1129 				psrcLine += widthSrc;
1130 				if (endmask) {
1131 					pdst--;
1132 					psrc--;
1133 					*pdst = (*pdst & ~endmask |
1134 						 ~*psrc & endmask);
1135 				}
1136 				nl = nlMiddle;
1137 				Duff_minus(nl, pdst, psrc, = ~);
1138 				if (startmask) {
1139 					--pdst;
1140 					--psrc;
1141 					*pdst = (*pdst & ~startmask |
1142 						 ~*psrc & startmask);
1143 				}
1144 			}
1145 		} else {
1146 			if (xoffDst > xoffSrc) {
1147 				rightShift = xoffDst - xoffSrc;
1148 				leftShift = 32 - rightShift;
1149 			} else {
1150 				leftShift = xoffSrc - xoffDst;
1151 				rightShift = 32 - leftShift;
1152 			}
1153 			while (h--) {
1154 				psrc = psrcLine;
1155 				pdst = pdstLine;
1156 				pdstLine += widthDst;
1157 				psrcLine += widthSrc;
1158 				bits = 0;
1159 				if (xoffDst > xoffSrc)
1160 					bits = *--psrc;
1161 				if (endmask) {
1162 					bits1 = bits >> rightShift;
1163 					bits = *--psrc;
1164 					bits1 |= (bits << leftShift);
1165 					pdst--;
1166 					*pdst = (*pdst & ~endmask |
1167 						 ~bits1 & endmask);
1168 				}
1169 				nl = nlMiddle;
1170 				bits1 = bits;
1171 				Duff_shift_minus(nl, pdst, psrc, = ~);
1172 				if (startmask) {
1173 					bits1 = (bits >> rightShift);
1174 					if (startmask >> leftShift) {
1175 						bits1 |= *--psrc << leftShift;
1176 					}
1177 					--pdst;
1178 					*pdst = (*pdst & ~startmask |
1179 						 ~bits1 & startmask);
1180 				}
1181 			}
1182 		}
1183 	}
1184 }
1185 
1186 void
1187 mfb_or_area32(addrSrc, addrDst, widthSrc, widthDst, sr, dp)
1188 u_int	*addrSrc;
1189 u_int	*addrDst;
1190 int	widthSrc;
1191 int	widthDst;
1192 lRectangle	*sr;	/* source rectangle */
1193 lPoint		*dp;	/* destination point */
1194 {
1195 	register u_int *psrcLine, *psrc;
1196 	register u_int *pdstLine, *pdst;
1197 	int w, h;
1198 	int xdir, ydir;
1199 	u_int startmask, endmask;
1200 	register int nlMiddle;
1201 	int xoffSrc, xoffDst;
1202 	register int leftShift, rightShift;
1203 	u_int bits;
1204 	u_int bits1;
1205 	register int nl;
1206 
1207 	if (sr->origin.y < dp->y) {
1208 		ydir = -1;
1209 		widthSrc = -widthSrc;
1210 		widthDst = -widthDst;
1211 	} else {
1212 		ydir = 1;
1213 	}
1214 
1215 	if (sr->origin.x < dp->x) {
1216 		xdir = -1;
1217 	} else {
1218 		xdir = 1;
1219 	}
1220 
1221 	w = sr->extent.x;
1222 	h = sr->extent.y;
1223 
1224 	if (ydir == -1) {
1225 		psrcLine = addrSrc + ((sr->origin.y + h - 1) * -widthSrc);
1226 		pdstLine = addrDst + ((dp->y + h - 1) * -widthDst);
1227 	} else {
1228 		psrcLine = addrSrc + (sr->origin.y * widthSrc);
1229 		pdstLine = addrDst + (dp->y * widthDst);
1230 	}
1231 	if ((dp->x & 0x1f) +w <= 32) {
1232 		startmask = mfbpartmasks32[dp->x & 0x1f][w & 0x1f];
1233 		endmask = 0;
1234 		nlMiddle = 0;
1235 	} else {
1236 		startmask = mfbstarttab32[dp->x & 0x1f];
1237 		endmask = mfbendtab32[(dp->x + w) & 0x1f];
1238 		if (startmask) {
1239 			nlMiddle = (w - (32 - (dp->x & 0x1f))) >> 5;
1240 		} else {
1241 			nlMiddle = w >> 5;
1242 		}
1243 	}
1244 
1245 	if (xdir == 1) {
1246 		xoffSrc = sr->origin.x & 0x1f;
1247 		xoffDst = dp->x & 0x1f;
1248 		pdstLine += (dp->x >> 5);
1249 		psrcLine += (sr->origin.x >> 5);
1250 		if (xoffSrc == xoffDst) {
1251 			while (h--) {
1252 				psrc = psrcLine;
1253 				pdst = pdstLine;
1254 				pdstLine += widthDst;
1255 				psrcLine += widthSrc;
1256 				if (startmask) {
1257 					*pdst++ |= *psrc++ & startmask;
1258 				}
1259 				nl = nlMiddle;
1260 				Duff_plus(nl, pdst, psrc, |=);
1261 				if (endmask) {
1262 					*pdst |= *psrc & endmask;
1263 				}
1264 			}
1265 		} else {
1266 			if (xoffSrc > xoffDst) {
1267 				leftShift = xoffSrc - xoffDst;
1268 				rightShift = 32 - leftShift;
1269 			} else {
1270 				rightShift = xoffDst - xoffSrc;
1271 				leftShift = 32 - rightShift;
1272 			}
1273 			while (h--) {
1274 				psrc = psrcLine;
1275 				pdst = pdstLine;
1276 				pdstLine += widthDst;
1277 				psrcLine += widthSrc;
1278 				bits = 0;
1279 				if (xoffSrc > xoffDst)
1280 					bits = *psrc++;
1281 				if (startmask) {
1282 					bits1 = bits << leftShift;
1283 					bits = *psrc++;
1284 					bits1 |= bits >> rightShift;
1285 					*pdst++ |= bits1 & startmask;
1286 				}
1287 				nl = nlMiddle;
1288 				bits1 = bits;
1289 				Duff_shift_plus(nl, pdst, psrc, |=);
1290 				if (endmask) {
1291 					bits1 = bits << leftShift;
1292 					if (endmask << rightShift) {
1293 						bits1 |= *psrc >> rightShift;
1294 					}
1295 					*pdst |= bits1 & endmask;
1296 				}
1297 			}
1298 		}
1299 	} else {
1300 		xoffSrc = (sr->origin.x + w - 1) & 0x1f;
1301 		xoffDst = (dp->x + w - 1) & 0x1f;
1302 		pdstLine += ((dp->x + w - 1) >> 5) + 1;
1303 		psrcLine += ((sr->origin.x + w - 1) >> 5) + 1;
1304 		if (xoffSrc == xoffDst) {
1305 			while (h--) {
1306 				psrc = psrcLine;
1307 				pdst = pdstLine;
1308 				pdstLine += widthDst;
1309 				psrcLine += widthSrc;
1310 				if (endmask) {
1311 					*--pdst |= *--psrc & endmask;
1312 				}
1313 				nl = nlMiddle;
1314 				Duff_minus(nl, pdst, psrc, |=);
1315 				if (startmask) {
1316 					*--pdst |= *--psrc & startmask;
1317 				}
1318 			}
1319 		} else {
1320 			if (xoffDst > xoffSrc) {
1321 				rightShift = xoffDst - xoffSrc;
1322 				leftShift = 32 - rightShift;
1323 			} else {
1324 				leftShift = xoffSrc - xoffDst;
1325 				rightShift = 32 - leftShift;
1326 			}
1327 			while (h--) {
1328 				psrc = psrcLine;
1329 				pdst = pdstLine;
1330 				pdstLine += widthDst;
1331 				psrcLine += widthSrc;
1332 				bits = 0;
1333 				if (xoffDst > xoffSrc)
1334 					bits = *--psrc;
1335 				if (endmask) {
1336 					bits1 = bits >> rightShift;
1337 					bits = *--psrc;
1338 					bits1 |= (bits << leftShift);
1339 					*--pdst |= bits1 & endmask;
1340 				}
1341 				nl = nlMiddle;
1342 				bits1 = bits;
1343 				Duff_shift_minus(nl, pdst, psrc, |=);
1344 				if (startmask) {
1345 					bits1 = (bits >> rightShift);
1346 					if (startmask >> leftShift) {
1347 						bits1 |= *--psrc << leftShift;
1348 					}
1349 					*--pdst |= bits1 & startmask;
1350 				}
1351 			}
1352 		}
1353 	}
1354 }
1355 
1356 void
1357 mfb_xor_area32(addrSrc, addrDst, widthSrc, widthDst, sr, dp)
1358 u_int	*addrSrc;
1359 u_int	*addrDst;
1360 int	widthSrc;
1361 int	widthDst;
1362 lRectangle	*sr;	/* source rectangle */
1363 lPoint		*dp;	/* destination point */
1364 {
1365 	register u_int *psrcLine, *psrc;
1366 	register u_int *pdstLine, *pdst;
1367 	int w, h;
1368 	int xdir, ydir;
1369 	u_int startmask, endmask;
1370 	register int nlMiddle;
1371 	int xoffSrc, xoffDst;
1372 	register int leftShift, rightShift;
1373 	u_int bits;
1374 	u_int bits1;
1375 	register int nl;
1376 
1377 	if (sr->origin.y < dp->y) {
1378 		ydir = -1;
1379 		widthSrc = -widthSrc;
1380 		widthDst = -widthDst;
1381 	} else {
1382 		ydir = 1;
1383 	}
1384 
1385 	if (sr->origin.x < dp->x) {
1386 		xdir = -1;
1387 	} else {
1388 		xdir = 1;
1389 	}
1390 
1391 	w = sr->extent.x;
1392 	h = sr->extent.y;
1393 
1394 	if (ydir == -1) {
1395 		psrcLine = addrSrc + ((sr->origin.y + h - 1) * -widthSrc);
1396 		pdstLine = addrDst + ((dp->y + h - 1) * -widthDst);
1397 	} else {
1398 		psrcLine = addrSrc + (sr->origin.y * widthSrc);
1399 		pdstLine = addrDst + (dp->y * widthDst);
1400 	}
1401 	if ((dp->x & 0x1f) +w <= 32) {
1402 		startmask = mfbpartmasks32[dp->x & 0x1f][w & 0x1f];
1403 		endmask = 0;
1404 		nlMiddle = 0;
1405 	} else {
1406 		startmask = mfbstarttab32[dp->x & 0x1f];
1407 		endmask = mfbendtab32[(dp->x + w) & 0x1f];
1408 		if (startmask) {
1409 			nlMiddle = (w - (32 - (dp->x & 0x1f))) >> 5;
1410 		} else {
1411 			nlMiddle = w >> 5;
1412 		}
1413 	}
1414 
1415 	if (xdir == 1) {
1416 		xoffSrc = sr->origin.x & 0x1f;
1417 		xoffDst = dp->x & 0x1f;
1418 		pdstLine += (dp->x >> 5);
1419 		psrcLine += (sr->origin.x >> 5);
1420 		if (xoffSrc == xoffDst) {
1421 			while (h--) {
1422 				psrc = psrcLine;
1423 				pdst = pdstLine;
1424 				pdstLine += widthDst;
1425 				psrcLine += widthSrc;
1426 				if (startmask) {
1427 					*pdst++ ^= *psrc++ & startmask;
1428 				}
1429 				nl = nlMiddle;
1430 				Duff_plus(nl, pdst, psrc, ^=);
1431 				if (endmask) {
1432 					*pdst ^= *psrc & endmask;
1433 				}
1434 			}
1435 		} else {
1436 			if (xoffSrc > xoffDst) {
1437 				leftShift = xoffSrc - xoffDst;
1438 				rightShift = 32 - leftShift;
1439 			} else {
1440 				rightShift = xoffDst - xoffSrc;
1441 				leftShift = 32 - rightShift;
1442 			}
1443 			while (h--) {
1444 				psrc = psrcLine;
1445 				pdst = pdstLine;
1446 				pdstLine += widthDst;
1447 				psrcLine += widthSrc;
1448 				bits = 0;
1449 				if (xoffSrc > xoffDst)
1450 					bits = *psrc++;
1451 				if (startmask) {
1452 					bits1 = bits << leftShift;
1453 					bits = *psrc++;
1454 					bits1 |= bits >> rightShift;
1455 					*pdst++ ^= bits1 & startmask;
1456 				}
1457 				nl = nlMiddle;
1458 				bits1 = bits;
1459 				Duff_shift_plus(nl, pdst, psrc, ^=);
1460 				if (endmask) {
1461 					bits1 = bits << leftShift;
1462 					if (endmask << rightShift) {
1463 						bits1 |= *psrc >> rightShift;
1464 					}
1465 					*pdst ^= bits1 & endmask;
1466 				}
1467 			}
1468 		}
1469 	} else {
1470 		xoffSrc = (sr->origin.x + w - 1) & 0x1f;
1471 		xoffDst = (dp->x + w - 1) & 0x1f;
1472 		pdstLine += ((dp->x + w - 1) >> 5) + 1;
1473 		psrcLine += ((sr->origin.x + w - 1) >> 5) + 1;
1474 		if (xoffSrc == xoffDst) {
1475 			while (h--) {
1476 				psrc = psrcLine;
1477 				pdst = pdstLine;
1478 				pdstLine += widthDst;
1479 				psrcLine += widthSrc;
1480 				if (endmask) {
1481 					*--pdst ^= *--psrc & endmask;
1482 				}
1483 				nl = nlMiddle;
1484 				Duff_minus(nl, pdst, psrc, ^=);
1485 				if (startmask) {
1486 					*--pdst ^= *--psrc & startmask;
1487 				}
1488 			}
1489 		} else {
1490 			if (xoffDst > xoffSrc) {
1491 				rightShift = xoffDst - xoffSrc;
1492 				leftShift = 32 - rightShift;
1493 			} else {
1494 				leftShift = xoffSrc - xoffDst;
1495 				rightShift = 32 - leftShift;
1496 			}
1497 			while (h--) {
1498 				psrc = psrcLine;
1499 				pdst = pdstLine;
1500 				pdstLine += widthDst;
1501 				psrcLine += widthSrc;
1502 				bits = 0;
1503 				if (xoffDst > xoffSrc)
1504 					bits = *--psrc;
1505 				if (endmask) {
1506 					bits1 = bits >> rightShift;
1507 					bits = *--psrc;
1508 					bits1 |= (bits << leftShift);
1509 					*--pdst ^= bits1 & endmask;
1510 				}
1511 				nl = nlMiddle;
1512 				bits1 = bits;
1513 				Duff_shift_minus(nl, pdst, psrc, ^=);
1514 				if (startmask) {
1515 					bits1 = (bits >> rightShift);
1516 					if (startmask >> leftShift) {
1517 						bits1 |= *--psrc << leftShift;
1518 					}
1519 					*--pdst ^= bits1 & startmask;
1520 				}
1521 			}
1522 		}
1523 	}
1524 }
1525 
1526 void
1527 mfb_general_area32(func, addrSrc, addrDst, widthSrc, widthDst, sr, dp)
1528 int		func;
1529 u_int	*addrSrc;
1530 u_int	*addrDst;
1531 int	widthSrc;
1532 int	widthDst;
1533 lRectangle	*sr;	/* source rectangle */
1534 lPoint		*dp;	/* destination point */
1535 {
1536 	register u_int *psrcLine, *psrc;
1537 	register u_int *pdstLine, *pdst;
1538 	register int leftShift, rightShift;
1539 	u_int bits;
1540 	u_int bits1;
1541 	register int nl;
1542 	u_int _ca1, _cx1, _ca2, _cx2;
1543 	u_int startmask, endmask;
1544 	int w, h;
1545 	int xdir, ydir;
1546 	register int nlMiddle;
1547 	int xoffSrc, xoffDst;
1548 
1549 	_ca1 = mergeRopBits[func].ca1;
1550 	_cx1 = mergeRopBits[func].cx1;
1551 	_ca2 = mergeRopBits[func].ca2;
1552 	_cx2 = mergeRopBits[func].cx2;
1553 
1554 	if (sr->origin.y < dp->y) {
1555 		ydir = -1;
1556 		widthSrc = -widthSrc;
1557 		widthDst = -widthDst;
1558 	} else {
1559 		ydir = 1;
1560 	}
1561 
1562 	if (sr->origin.x < dp->x) {
1563 		xdir = -1;
1564 	} else {
1565 		xdir = 1;
1566 	}
1567 
1568 	w = sr->extent.x;
1569 	h = sr->extent.y;
1570 
1571 	if (ydir == -1) {
1572 		psrcLine = addrSrc + ((sr->origin.y + h - 1) * -widthSrc);
1573 		pdstLine = addrDst + ((dp->y + h - 1) * -widthDst);
1574 	} else {
1575 		psrcLine = addrSrc + (sr->origin.y * widthSrc);
1576 		pdstLine = addrDst + (dp->y * widthDst);
1577 	}
1578 	if ((dp->x & 0x1f) +w <= 32) {
1579 		startmask = mfbpartmasks32[dp->x & 0x1f][w & 0x1f];
1580 		endmask = 0;
1581 		nlMiddle = 0;
1582 	} else {
1583 		startmask = mfbstarttab32[dp->x & 0x1f];
1584 		endmask = mfbendtab32[(dp->x + w) & 0x1f];
1585 		if (startmask) {
1586 			nlMiddle = (w - (32 - (dp->x & 0x1f))) >> 5;
1587 		} else {
1588 			nlMiddle = w >> 5;
1589 		}
1590 	}
1591 
1592 	if (xdir == 1) {
1593 		xoffSrc = sr->origin.x & 0x1f;
1594 		xoffDst = dp->x & 0x1f;
1595 		pdstLine += (dp->x >> 5);
1596 		psrcLine += (sr->origin.x >> 5);
1597 		if (xoffSrc == xoffDst) {
1598 			while (h--) {
1599 				psrc = psrcLine;
1600 				pdst = pdstLine;
1601 				pdstLine += widthDst;
1602 				psrcLine += widthSrc;
1603 				if (startmask) {
1604 					*pdst = DoMergeRopMask(*psrc, *pdst,
1605 							       startmask);
1606 					psrc++;
1607 					pdst++;
1608 				}
1609 				nl = nlMiddle;
1610 #ifdef mc68020
1611 				Duff(nl, *pdst = DoMergeRop(*psrc, *pdst);
1612 					  psrc++; pdst++);
1613 #else /* mc68020 */
1614 				psrc += nl & 7;
1615 				pdst += nl & 7;
1616 				switch (nl & 7) {
1617 				case 7:
1618 					pdst[-7] = DoMergeRop(psrc[-7], pdst[-7]);
1619 				case 6:
1620 					pdst[-6] = DoMergeRop(psrc[-6], pdst[-6]);
1621 				case 5:
1622 					pdst[-5] = DoMergeRop(psrc[-5], pdst[-5]);
1623 				case 4:
1624 					pdst[-4] = DoMergeRop(psrc[-4], pdst[-4]);
1625 				case 3:
1626 					pdst[-3] = DoMergeRop(psrc[-3], pdst[-3]);
1627 				case 2:
1628 					pdst[-2] = DoMergeRop(psrc[-2], pdst[-2]);
1629 				case 1:
1630 					pdst[-1] = DoMergeRop(psrc[-1], pdst[-1]);
1631 				}
1632 				while ((nl -= 8) >= 0) {
1633 					pdst += 8;
1634 					psrc += 8;
1635 					pdst[-8] = DoMergeRop(psrc[-8], pdst[-8]);
1636 					pdst[-7] = DoMergeRop(psrc[-7], pdst[-7]);
1637 					pdst[-6] = DoMergeRop(psrc[-6], pdst[-6]);
1638 					pdst[-5] = DoMergeRop(psrc[-5], pdst[-5]);
1639 					pdst[-4] = DoMergeRop(psrc[-4], pdst[-4]);
1640 					pdst[-3] = DoMergeRop(psrc[-3], pdst[-3]);
1641 					pdst[-2] = DoMergeRop(psrc[-2], pdst[-2]);
1642 					pdst[-1] = DoMergeRop(psrc[-1], pdst[-1]);
1643 				}
1644 #endif /* mc68020 */
1645 				if (endmask) {
1646 					*pdst = DoMergeRopMask(*psrc, *pdst,
1647 							       endmask);
1648 				}
1649 			}
1650 		} else {
1651 			if (xoffSrc > xoffDst) {
1652 				leftShift = xoffSrc - xoffDst;
1653 				rightShift = 32 - leftShift;
1654 			} else {
1655 				rightShift = xoffDst - xoffSrc;
1656 				leftShift = 32 - rightShift;
1657 			}
1658 			while (h--) {
1659 				psrc = psrcLine;
1660 				pdst = pdstLine;
1661 				pdstLine += widthDst;
1662 				psrcLine += widthSrc;
1663 				bits = 0;
1664 				if (xoffSrc > xoffDst)
1665 					bits = *psrc++;
1666 				if (startmask) {
1667 					bits1 = bits << leftShift;
1668 					bits = *psrc++;
1669 					bits1 |= bits >> rightShift;
1670 					*pdst = DoMergeRopMask(bits1, *pdst,
1671 							       startmask);
1672 					pdst++;
1673 				}
1674 				nl = nlMiddle;
1675 				bits1 = bits;
1676 				psrc += nl & 7;
1677 				pdst += nl & 7;
1678 				switch (nl & 7) {
1679 				case 7:
1680 					bits = psrc[-7];
1681 					pdst[-7] = DoMergeRop(((bits1 << leftShift) | (bits >> rightShift)), pdst[-7]);
1682 				case 6:
1683 					bits1 = psrc[-6];
1684 					pdst[-6] = DoMergeRop(((bits << leftShift) | (bits1 >> rightShift)), pdst[-6]);
1685 				case 5:
1686 					bits = psrc[-5];
1687 					pdst[-5] = DoMergeRop(((bits1 << leftShift) | (bits >> rightShift)), pdst[-5]);
1688 				case 4:
1689 					bits1 = psrc[-4];
1690 					pdst[-4] = DoMergeRop(((bits << leftShift) | (bits1 >> rightShift)), pdst[-4]);
1691 				case 3:
1692 					bits = psrc[-3];
1693 					pdst[-3] = DoMergeRop(((bits1 << leftShift) | (bits >> rightShift)), pdst[-3]);
1694 				case 2:
1695 					bits1 = psrc[-2];
1696 					pdst[-2] = DoMergeRop(((bits << leftShift) | (bits1 >> rightShift)), pdst[-2]);
1697 				case 1:
1698 					bits = psrc[-1];
1699 					pdst[-1] = DoMergeRop(((bits1 << leftShift) | (bits >> rightShift)), pdst[-1]);
1700 				}
1701 				while ((nl -= 8) >= 0) {
1702 					pdst += 8;
1703 					psrc += 8;
1704 					bits1 = psrc[-8];
1705 					pdst[-8] = DoMergeRop(((bits << leftShift) | (bits1 >> rightShift)), pdst[-8]);
1706 					bits = psrc[-7];
1707 					pdst[-7] = DoMergeRop(((bits1 << leftShift) | (bits >> rightShift)), pdst[-7]);
1708 					bits1 = psrc[-6];
1709 					pdst[-6] = DoMergeRop(((bits << leftShift) | (bits1 >> rightShift)), pdst[-6]);
1710 					bits = psrc[-5];
1711 					pdst[-5] = DoMergeRop(((bits1 << leftShift) | (bits >> rightShift)), pdst[-5]);
1712 					bits1 = psrc[-4];
1713 					pdst[-4] = DoMergeRop(((bits << leftShift) | (bits1 >> rightShift)), pdst[-4]);
1714 					bits = psrc[-3];
1715 					pdst[-3] = DoMergeRop(((bits1 << leftShift) | (bits >> rightShift)), pdst[-3]);
1716 					bits1 = psrc[-2];
1717 					pdst[-2] = DoMergeRop(((bits << leftShift) | (bits1 >> rightShift)), pdst[-2]);
1718 					bits = psrc[-1];
1719 					pdst[-1] = DoMergeRop(((bits1 << leftShift) | (bits >> rightShift)), pdst[-1]);
1720 				}
1721 				if (endmask) {
1722 					bits1 = bits << leftShift;
1723 					if (endmask << rightShift) {
1724 						bits = *psrc;
1725 						bits1 |= (bits >> rightShift);
1726 					}
1727 					*pdst = DoMergeRopMask(bits1, *pdst,
1728 							       endmask);
1729 				}
1730 			}
1731 		}
1732 	} else {
1733 		xoffSrc = (sr->origin.x + w - 1) & 0x1f;
1734 		xoffDst = (dp->x + w - 1) & 0x1f;
1735 		pdstLine += ((dp->x + w - 1) >> 5) + 1;
1736 		psrcLine += ((sr->origin.x + w - 1) >> 5) + 1;
1737 		if (xoffSrc == xoffDst) {
1738 			while (h--) {
1739 				psrc = psrcLine;
1740 				pdst = pdstLine;
1741 				pdstLine += widthDst;
1742 				psrcLine += widthSrc;
1743 				if (endmask) {
1744 					pdst--;
1745 					psrc--;
1746 					*pdst = DoMergeRopMask(*psrc, *pdst,
1747 							       endmask);
1748 				}
1749 				nl = nlMiddle;
1750 #ifdef mc68020
1751 				Duff(nl, pdst--; psrc--;
1752 					  *pdst = DoMergeRop(*psrc, *pdst));
1753 #else /* mc68020 */
1754 				psrc -= nl & 7;
1755 				pdst -= nl & 7;
1756 				switch (nl & 7) {
1757 				case 7:
1758 					pdst[7-1] = DoMergeRop(psrc[7-1], pdst[7-1]);
1759 				case 6:
1760 					pdst[6-1] = DoMergeRop(psrc[6-1], pdst[6-1]);
1761 				case 5:
1762 					pdst[5-1] = DoMergeRop(psrc[5-1], pdst[5-1]);
1763 				case 4:
1764 					pdst[4-1] = DoMergeRop(psrc[4-1], pdst[4-1]);
1765 				case 3:
1766 					pdst[3-1] = DoMergeRop(psrc[3-1], pdst[3-1]);
1767 				case 2:
1768 					pdst[2-1] = DoMergeRop(psrc[2-1], pdst[2-1]);
1769 				case 1:
1770 					pdst[1-1] = DoMergeRop(psrc[1-1], pdst[1-1]);
1771 				}
1772 				while ((nl -= 8) >= 0) {
1773 					pdst -= 8;
1774 					psrc -= 8;
1775 					pdst[8-1] = DoMergeRop(psrc[8-1], pdst[8-1]);
1776 					pdst[7-1] = DoMergeRop(psrc[7-1], pdst[7-1]);
1777 					pdst[6-1] = DoMergeRop(psrc[6-1], pdst[6-1]);
1778 					pdst[5-1] = DoMergeRop(psrc[5-1], pdst[5-1]);
1779 					pdst[4-1] = DoMergeRop(psrc[4-1], pdst[4-1]);
1780 					pdst[3-1] = DoMergeRop(psrc[3-1], pdst[3-1]);
1781 					pdst[2-1] = DoMergeRop(psrc[2-1], pdst[2-1]);
1782 					pdst[1-1] = DoMergeRop(psrc[1-1], pdst[1-1]);
1783 				}
1784 #endif /* mc68020 */
1785 				if (startmask) {
1786 					--pdst;
1787 					--psrc;
1788 					*pdst = DoMergeRopMask(*psrc, *pdst,
1789 							       startmask);
1790 				}
1791 			}
1792 		} else {
1793 			if (xoffDst > xoffSrc) {
1794 				rightShift = xoffDst - xoffSrc;
1795 				leftShift = 32 - rightShift;
1796 			} else {
1797 				leftShift = xoffSrc - xoffDst;
1798 				rightShift = 32 - leftShift;
1799 			}
1800 			while (h--) {
1801 				psrc = psrcLine;
1802 				pdst = pdstLine;
1803 				pdstLine += widthDst;
1804 				psrcLine += widthSrc;
1805 				bits = 0;
1806 				if (xoffDst > xoffSrc)
1807 					bits = *--psrc;
1808 				if (endmask) {
1809 					bits1 = bits >> rightShift;
1810 					bits = *--psrc;
1811 					bits1 |= (bits << leftShift);
1812 					pdst--;
1813 					*pdst = DoMergeRopMask(bits1, *pdst,
1814 							       endmask);
1815 				}
1816 				nl = nlMiddle;
1817 				bits1 = bits;
1818 				psrc -= nl & 7;
1819 				pdst -= nl & 7;
1820 				switch (nl & 7) {
1821 				case 7:
1822 					bits = psrc[7-1];
1823 					pdst[7-1] = DoMergeRop(((bits1 >> rightShift) | (bits << leftShift)), pdst[7-1]);
1824 				case 6:
1825 					bits1 = psrc[6-1];
1826 					pdst[6-1] = DoMergeRop(((bits >> rightShift) | (bits1 << leftShift)), pdst[6-1]);
1827 				case 5:
1828 					bits = psrc[5-1];
1829 					pdst[5-1] = DoMergeRop(((bits1 >> rightShift) | (bits << leftShift)), pdst[5-1]);
1830 				case 4:
1831 					bits1 = psrc[4-1];
1832 					pdst[4-1] = DoMergeRop(((bits >> rightShift) | (bits1 << leftShift)), pdst[4-1]);
1833 				case 3:
1834 					bits = psrc[3-1];
1835 					pdst[3-1] = DoMergeRop(((bits1 >> rightShift) | (bits << leftShift)), pdst[3-1]);
1836 				case 2:
1837 					bits1 = psrc[2-1];
1838 					pdst[2-1] = DoMergeRop(((bits >> rightShift) | (bits1 << leftShift)), pdst[2-1]);
1839 				case 1:
1840 					bits = psrc[1-1];
1841 					pdst[1-1] = DoMergeRop(((bits1 >> rightShift) | (bits << leftShift)), pdst[1-1]);
1842 				}
1843 				while ((nl -= 8) >= 0) {
1844 					pdst -= 8;
1845 					psrc -= 8;
1846 					bits1 = psrc[8-1];
1847 					pdst[8-1] = DoMergeRop(((bits >> rightShift) | (bits1 << leftShift)), pdst[8-1]);
1848 					bits = psrc[7-1];
1849 					pdst[7-1] = DoMergeRop(((bits1 >> rightShift) | (bits << leftShift)), pdst[7-1]);
1850 					bits1 = psrc[6-1];
1851 					pdst[6-1] = DoMergeRop(((bits >> rightShift) | (bits1 << leftShift)), pdst[6-1]);
1852 					bits = psrc[5-1];
1853 					pdst[5-1] = DoMergeRop(((bits1 >> rightShift) | (bits << leftShift)), pdst[5-1]);
1854 					bits1 = psrc[4-1];
1855 					pdst[4-1] = DoMergeRop(((bits >> rightShift) | (bits1 << leftShift)), pdst[4-1]);
1856 					bits = psrc[3-1];
1857 					pdst[3-1] = DoMergeRop(((bits1 >> rightShift) | (bits << leftShift)), pdst[3-1]);
1858 					bits1 = psrc[2-1];
1859 					pdst[2-1] = DoMergeRop(((bits >> rightShift) | (bits1 << leftShift)), pdst[2-1]);
1860 					bits = psrc[1-1];
1861 					pdst[1-1] = DoMergeRop(((bits1 >> rightShift) | (bits << leftShift)), pdst[1-1]);
1862 				}
1863 				if (startmask) {
1864 					bits1 = (bits >> rightShift);
1865 					if (startmask >> leftShift) {
1866 						bits = *--psrc;
1867 						bits1 |= (bits << leftShift);
1868 					}
1869 					--pdst;
1870 					*pdst = DoMergeRopMask(bits1, *pdst,
1871 							       startmask);
1872 				}
1873 			}
1874 		}
1875 	}
1876 }
1877 
1878 void
1879 mfb_clr_area32(x, y, w, h, addr, nlwidth)
1880 int x;
1881 int y;
1882 int w;
1883 register int h;
1884 register u_int *addr;
1885 int nlwidth;
1886 {
1887 	register u_int startmask;
1888 	u_int endmask;
1889 	register int nlw, nlwExtra;
1890 	int nlwMiddle;
1891 	int startoff, endoff;
1892 
1893 	addr += (y * nlwidth + (x >> 5));
1894 
1895 	startoff = x & 0x1f;
1896 	if (((startoff) + w) < 32) {
1897 		startmask = ~mfbpartmasks32[startoff][w & 0x1f];
1898 		nlwExtra = nlwidth;
1899 #ifdef mc68020
1900 		asm("	lsl.l	#2,d4");
1901 		Duff(h, asm("	and.l	d6,(a5)");
1902 			asm("	adda.l	d4,a5"))
1903 #else /* mc68020 */
1904 		Duff(h, *addr &= startmask; addr += nlwExtra)
1905 #endif /* mc68020 */
1906 		return;
1907 	}
1908 	endoff = (x + w) & 0x1f;
1909 	if (startoff) {
1910 		startmask = ~mfbstarttab32[startoff];
1911 		nlwMiddle = (w - (32 - (startoff))) >> 5;
1912 		nlwExtra = nlwidth - nlwMiddle - 1;
1913 		if (endoff) {
1914 			endmask = ~mfbendtab32[endoff];
1915 			while (h--) {
1916 				nlw = nlwMiddle;
1917 				*addr++ &= startmask;
1918 				Duff_single(nlw, addr, = 0);
1919 				*addr &= endmask;
1920 				addr += nlwExtra;
1921 			}
1922 		} else {
1923 			while (h--) {
1924 				nlw = nlwMiddle;
1925 				*addr++ &= startmask;
1926 				Duff_single(nlw, addr, = 0);
1927 				addr += nlwExtra;
1928 			}
1929 		}
1930 	} else {
1931 		nlwMiddle = w >> 5;
1932 		nlwExtra = nlwidth - nlwMiddle;
1933 		if (endoff) {
1934 			endmask = ~mfbendtab32[endoff];
1935 			while (h--) {
1936 				nlw = nlwMiddle;
1937 				Duff_single(nlw, addr, = 0);
1938 				*addr &= endmask;
1939 				addr += nlwExtra;
1940 			}
1941 		} else {
1942 			while (h--) {
1943 				nlw = nlwMiddle;
1944 				Duff_single(nlw, addr, = 0);
1945 				addr += nlwExtra;
1946 			}
1947 		}
1948 	}
1949 }
1950 
1951 void
1952 mfb_inv_area32(x, y, w, h, addr, nlwidth)
1953 int x;
1954 int y;
1955 int w;
1956 register int h;
1957 register u_int *addr;
1958 int nlwidth;
1959 {
1960 	register u_int startmask;
1961 	u_int endmask;
1962 	register int nlw, nlwExtra;
1963 	int nlwMiddle;
1964 	int startoff, endoff;
1965 
1966 	addr += (y * nlwidth + (x >> 5));
1967 
1968 	startoff = x & 0x1f;
1969 	if (((startoff) + w) < 32) {
1970 		startmask = mfbpartmasks32[startoff][w & 0x1f];
1971 		nlwExtra = nlwidth;
1972 #ifdef mc68020
1973 		asm("	lsl.l	#2,d4");
1974 		Duff(h, asm("	eor.l	d6,(a5)");
1975 			asm("	adda.l	d4,a5"))
1976 #else /* mc68020 */
1977 		Duff(h, *addr ^= startmask; addr += nlwExtra)
1978 #endif /* mc68020 */
1979 		return;
1980 	}
1981 	endoff = (x + w) & 0x1f;
1982 	if (startoff) {
1983 		startmask = mfbstarttab32[startoff];
1984 		nlwMiddle = (w - (32 - (startoff))) >> 5;
1985 		nlwExtra = nlwidth - nlwMiddle - 1;
1986 		if (endoff) {
1987 			endmask = mfbendtab32[endoff];
1988 			while (h--) {
1989 				nlw = nlwMiddle;
1990 				*addr++ ^= startmask;
1991 				Duff_single(nlw, addr, ^= ~0);
1992 				*addr ^= endmask;
1993 				addr += nlwExtra;
1994 			}
1995 		} else {
1996 			while (h--) {
1997 				nlw = nlwMiddle;
1998 				*addr++ ^= startmask;
1999 				Duff_single(nlw, addr, ^= ~0);
2000 				addr += nlwExtra;
2001 			}
2002 		}
2003 	} else {
2004 		nlwMiddle = w >> 5;
2005 		nlwExtra = nlwidth - nlwMiddle;
2006 		if (endoff) {
2007 			endmask = mfbendtab32[endoff];
2008 			while (h--) {
2009 				nlw = nlwMiddle;
2010 				Duff_single(nlw, addr, ^= ~0);
2011 				*addr ^= endmask;
2012 				addr += nlwExtra;
2013 			}
2014 		} else {
2015 			while (h--) {
2016 				nlw = nlwMiddle;
2017 				Duff_single(nlw, addr, ^= ~0);
2018 				addr += nlwExtra;
2019 			}
2020 		}
2021 	}
2022 }
2023 
2024 void
2025 mfb_set_area32(x, y, w, h, addr, nlwidth)
2026 int x;
2027 int y;
2028 int w;
2029 register int h;
2030 register u_int *addr;
2031 int nlwidth;
2032 {
2033 	register u_int startmask;
2034 	u_int endmask;
2035 	register int nlw, nlwExtra;
2036 	int nlwMiddle;
2037 	int startoff, endoff;
2038 
2039 	addr += (y * nlwidth + (x >> 5));
2040 
2041 	startoff = x & 0x1f;
2042 	if (((startoff) + w) < 32) {
2043 		startmask = mfbpartmasks32[startoff][w & 0x1f];
2044 		nlwExtra = nlwidth;
2045 #ifdef mc68020
2046 		asm("	lsl.l	#2,d4");
2047 		Duff(h, asm("	or.l	d6,(a5)");
2048 			asm("	adda.l	d4,a5"))
2049 #else /* mc68020 */
2050 		Duff(h, *addr |= startmask; addr += nlwExtra)
2051 #endif /* mc68020 */
2052 		return;
2053 	}
2054 	endoff = (x + w) & 0x1f;
2055 	if (startoff) {
2056 		startmask = mfbstarttab32[startoff];
2057 		nlwMiddle = (w - (32 - (startoff))) >> 5;
2058 		nlwExtra = nlwidth - nlwMiddle - 1;
2059 		if (endoff) {
2060 			endmask = mfbendtab32[endoff];
2061 			while (h--) {
2062 				nlw = nlwMiddle;
2063 				*addr++ |= startmask;
2064 				Duff_single(nlw, addr, = ~0);
2065 				*addr |= endmask;
2066 				addr += nlwExtra;
2067 			}
2068 		} else {
2069 			while (h--) {
2070 				nlw = nlwMiddle;
2071 				*addr++ |= startmask;
2072 				Duff_single(nlw, addr, = ~0);
2073 				addr += nlwExtra;
2074 			}
2075 		}
2076 	} else {
2077 		nlwMiddle = w >> 5;
2078 		nlwExtra = nlwidth - nlwMiddle;
2079 		if (endoff) {
2080 			endmask = mfbendtab32[endoff];
2081 			while (h--) {
2082 				nlw = nlwMiddle;
2083 				Duff_single(nlw, addr, = ~0);
2084 				*addr |= endmask;
2085 				addr += nlwExtra;
2086 			}
2087 		} else {
2088 			while (h--) {
2089 				nlw = nlwMiddle;
2090 				Duff_single(nlw, addr, = ~0);
2091 				addr += nlwExtra;
2092 			}
2093 		}
2094 	}
2095 }
2096 
2097 void
2098 mfb_copy_area16(addrSrc, addrDst, widthSrc, widthDst, sr, dp)
2099 u_short	*addrSrc;
2100 u_short	*addrDst;
2101 u_int	widthSrc;
2102 u_int	widthDst;
2103 lRectangle	*sr;	/* source rectangle */
2104 lPoint		*dp;	/* destination point */
2105 {
2106 	register u_short *psrcLine, *psrc;
2107 	register u_short *pdstLine, *pdst;
2108 	int w, h;
2109 	int xdir, ydir;
2110 	u_short startmask, endmask;
2111 	register int nlMiddle;
2112 	int xoffSrc, xoffDst;
2113 	register int leftShift, rightShift;
2114 	u_short bits;
2115 	u_short bits1;
2116 	register int nl;
2117 
2118 	if (sr->origin.y < dp->y) {
2119 		ydir = -1;
2120 		widthSrc = -widthSrc;
2121 		widthDst = -widthDst;
2122 	} else {
2123 		ydir = 1;
2124 	}
2125 
2126 	if (sr->origin.x < dp->x) {
2127 		xdir = -1;
2128 	} else {
2129 		xdir = 1;
2130 	}
2131 
2132 	w = sr->extent.x;
2133 	h = sr->extent.y;
2134 
2135 	if (ydir == -1) {
2136 		psrcLine = addrSrc + ((sr->origin.y + h - 1) * -widthSrc);
2137 		pdstLine = addrDst + ((dp->y + h - 1) * -widthDst);
2138 	} else {
2139 		psrcLine = addrSrc + (sr->origin.y * widthSrc);
2140 		pdstLine = addrDst + (dp->y * widthDst);
2141 	}
2142 	if ((dp->x & 0xf) +w <= 16) {
2143 		startmask = mfbpartmasks16[dp->x & 0xf][w & 0xf];
2144 		endmask = 0;
2145 		nlMiddle = 0;
2146 	} else {
2147 		startmask = mfbstarttab16[dp->x & 0xf];
2148 		endmask = mfbendtab16[(dp->x + w) & 0xf];
2149 		if (startmask) {
2150 			nlMiddle = (w - (16 - (dp->x & 0xf))) >> 4;
2151 		} else {
2152 			nlMiddle = w >> 4;
2153 		}
2154 	}
2155 
2156 	if (xdir == 1) {
2157 		xoffSrc = sr->origin.x & 0xf;
2158 		xoffDst = dp->x & 0xf;
2159 		pdstLine += (dp->x >> 4);
2160 		psrcLine += (sr->origin.x >> 4);
2161 		if (xoffSrc == xoffDst) {
2162 			while (h--) {
2163 				psrc = psrcLine;
2164 				pdst = pdstLine;
2165 				psrcLine += widthSrc;
2166 				pdstLine += widthDst;
2167 				if (startmask) {
2168 					*pdst = (*pdst & ~startmask |
2169 						 *psrc & startmask);
2170 					psrc++;
2171 					pdst++;
2172 				}
2173 				nl = nlMiddle;
2174 				Duff_plus(nl, pdst, psrc, =);
2175 				if (endmask) {
2176 					*pdst = (*pdst & ~endmask |
2177 						 *psrc & endmask);
2178 				}
2179 			}
2180 		} else {
2181 			if (xoffSrc > xoffDst) {
2182 				leftShift = xoffSrc - xoffDst;
2183 				rightShift = 16 - leftShift;
2184 			} else {
2185 				rightShift = xoffDst - xoffSrc;
2186 				leftShift = 16 - rightShift;
2187 			}
2188 			while (h--) {
2189 				psrc = psrcLine;
2190 				pdst = pdstLine;
2191 				psrcLine += widthSrc;
2192 				pdstLine += widthDst;
2193 				bits = 0;
2194 				if (xoffSrc > xoffDst)
2195 					bits = *psrc++;
2196 				if (startmask) {
2197 					bits1 = bits << leftShift;
2198 					bits = *psrc++;
2199 					bits1 |= bits >> rightShift;
2200 					*pdst = (*pdst & ~startmask |
2201 						 bits1 & startmask);
2202 					pdst++;
2203 				}
2204 				nl = nlMiddle;
2205 				bits1 = bits;
2206 				Duff_shift_plus(nl, pdst, psrc, =);
2207 				if (endmask) {
2208 					bits1 = bits << leftShift;
2209 					if ((endmask << rightShift) & 0xffff) {
2210 						bits1 |= *psrc >> rightShift;
2211 					}
2212 					*pdst = (*pdst & ~endmask |
2213 						 bits1 & endmask);
2214 				}
2215 			}
2216 		}
2217 	} else {
2218 		xoffSrc = (sr->origin.x + w - 1) & 0xf;
2219 		xoffDst = (dp->x + w - 1) & 0xf;
2220 		pdstLine += ((dp->x + w - 1) >> 4) + 1;
2221 		psrcLine += ((sr->origin.x + w - 1) >> 4) + 1;
2222 		if (xoffSrc == xoffDst) {
2223 			while (h--) {
2224 				psrc = psrcLine;
2225 				pdst = pdstLine;
2226 				psrcLine += widthSrc;
2227 				pdstLine += widthDst;
2228 				if (endmask) {
2229 					pdst--;
2230 					psrc--;
2231 					*pdst = (*pdst & ~endmask |
2232 						 *psrc & endmask);
2233 				}
2234 				nl = nlMiddle;
2235 				Duff_minus(nl, pdst, psrc, =);
2236 				if (startmask) {
2237 					--pdst;
2238 					--psrc;
2239 					*pdst = (*pdst & ~startmask |
2240 						 *psrc & startmask);
2241 				}
2242 			}
2243 		} else {
2244 			if (xoffDst > xoffSrc) {
2245 				rightShift = xoffDst - xoffSrc;
2246 				leftShift = 16 - rightShift;
2247 			} else {
2248 				leftShift = xoffSrc - xoffDst;
2249 				rightShift = 16 - leftShift;
2250 			}
2251 			while (h--) {
2252 				psrc = psrcLine;
2253 				pdst = pdstLine;
2254 				psrcLine += widthSrc;
2255 				pdstLine += widthDst;
2256 				bits = 0;
2257 				if (xoffDst > xoffSrc)
2258 					bits = *--psrc;
2259 				if (endmask) {
2260 					bits1 = bits >> rightShift;
2261 					bits = *--psrc;
2262 					bits1 |= (bits << leftShift);
2263 					pdst--;
2264 					*pdst = (*pdst & ~endmask |
2265 						 bits1 & endmask);
2266 				}
2267 				nl = nlMiddle;
2268 				bits1 = bits;
2269 				Duff_shift_minus(nl, pdst, psrc, =);
2270 				if (startmask) {
2271 					bits1 = (bits >> rightShift);
2272 					if (startmask >> leftShift) {
2273 						bits1 |= *--psrc << leftShift;
2274 					}
2275 					--pdst;
2276 					*pdst = (*pdst & ~startmask |
2277 						 bits1 & startmask);
2278 				}
2279 			}
2280 		}
2281 	}
2282 }
2283 
2284 void
2285 mfb_copyinv_area16(addrSrc, addrDst, widthSrc, widthDst, sr, dp)
2286 u_short	*addrSrc;
2287 u_short	*addrDst;
2288 register int	widthSrc;
2289 register int	widthDst;
2290 lRectangle	*sr;	/* source rectangle */
2291 lPoint		*dp;	/* destination point */
2292 {
2293 	register u_short *psrcLine, *psrc;
2294 	register u_short *pdstLine, *pdst;
2295 	int w, h;
2296 	int xdir, ydir;
2297 	u_short startmask, endmask;
2298 	register int nlMiddle;
2299 	int xoffSrc, xoffDst;
2300 	register int leftShift, rightShift;
2301 	u_short bits;
2302 	u_short bits1;
2303 	register int nl;
2304 
2305 	if (sr->origin.y < dp->y) {
2306 		ydir = -1;
2307 		widthSrc = -widthSrc;
2308 		widthDst = -widthDst;
2309 	} else {
2310 		ydir = 1;
2311 	}
2312 
2313 	if (sr->origin.x < dp->x) {
2314 		xdir = -1;
2315 	} else {
2316 		xdir = 1;
2317 	}
2318 
2319 	w = sr->extent.x;
2320 	h = sr->extent.y;
2321 
2322 	if (ydir == -1) {
2323 		psrcLine = addrSrc + ((sr->origin.y + h - 1) * -widthSrc);
2324 		pdstLine = addrDst + ((dp->y + h - 1) * -widthDst);
2325 	} else {
2326 		psrcLine = addrSrc + (sr->origin.y * widthSrc);
2327 		pdstLine = addrDst + (dp->y * widthDst);
2328 	}
2329 	if ((dp->x & 0xf) +w <= 16) {
2330 		startmask = mfbpartmasks16[dp->x & 0xf][w & 0xf];
2331 		endmask = 0;
2332 		nlMiddle = 0;
2333 	} else {
2334 		startmask = mfbstarttab16[dp->x & 0xf];
2335 		endmask = mfbendtab16[(dp->x + w) & 0xf];
2336 		if (startmask) {
2337 			nlMiddle = (w - (16 - (dp->x & 0xf))) >> 4;
2338 		} else {
2339 			nlMiddle = w >> 4;
2340 		}
2341 	}
2342 
2343 	if (xdir == 1) {
2344 		xoffSrc = sr->origin.x & 0xf;
2345 		xoffDst = dp->x & 0xf;
2346 		psrcLine += (sr->origin.x >> 4);
2347 		pdstLine += (dp->x >> 4);
2348 		if (xoffSrc == xoffDst) {
2349 			while (h--) {
2350 				psrc = psrcLine;
2351 				pdst = pdstLine;
2352 				psrcLine += widthSrc;
2353 				pdstLine += widthDst;
2354 				if (startmask) {
2355 					*pdst = (*pdst & ~startmask |
2356 						 ~*psrc & startmask);
2357 					psrc++;
2358 					pdst++;
2359 				}
2360 				nl = nlMiddle;
2361 				Duff_plus(nl, pdst, psrc, = ~);
2362 				if (endmask) {
2363 					*pdst = (*pdst & ~endmask |
2364 						 ~*psrc & endmask);
2365 				}
2366 			}
2367 		} else {
2368 			if (xoffSrc > xoffDst) {
2369 				leftShift = xoffSrc - xoffDst;
2370 				rightShift = 16 - leftShift;
2371 			} else {
2372 				rightShift = xoffDst - xoffSrc;
2373 				leftShift = 16 - rightShift;
2374 			}
2375 			while (h--) {
2376 				psrc = psrcLine;
2377 				pdst = pdstLine;
2378 				psrcLine += widthSrc;
2379 				pdstLine += widthDst;
2380 				bits = 0;
2381 				if (xoffSrc > xoffDst)
2382 					bits = *psrc++;
2383 				if (startmask) {
2384 					bits1 = bits << leftShift;
2385 					bits = *psrc++;
2386 					bits1 |= bits >> rightShift;
2387 					*pdst = (*pdst & ~startmask |
2388 						 ~bits1 & startmask);
2389 					pdst++;
2390 				}
2391 				nl = nlMiddle;
2392 				bits1 = bits;
2393 				Duff_shift_plus(nl, pdst, psrc, = ~);
2394 				if (endmask) {
2395 					bits1 = bits << leftShift;
2396 					if ((endmask << rightShift) & 0xffff) {
2397 						bits1 |= *psrc >> rightShift;
2398 					}
2399 					*pdst = (*pdst & ~endmask |
2400 						 ~bits1 & endmask);
2401 				}
2402 			}
2403 		}
2404 	} else {
2405 		xoffSrc = (sr->origin.x + w - 1) & 0xf;
2406 		xoffDst = (dp->x + w - 1) & 0xf;
2407 		pdstLine += ((dp->x + w - 1) >> 4) + 1;
2408 		psrcLine += ((sr->origin.x + w - 1) >> 4) + 1;
2409 		if (xoffSrc == xoffDst) {
2410 			while (h--) {
2411 				psrc = psrcLine;
2412 				pdst = pdstLine;
2413 				psrcLine += widthSrc;
2414 				pdstLine += widthDst;
2415 				if (endmask) {
2416 					pdst--;
2417 					psrc--;
2418 					*pdst = (*pdst & ~endmask |
2419 						 ~*psrc & endmask);
2420 				}
2421 				nl = nlMiddle;
2422 				Duff_minus(nl, pdst, psrc, = ~);
2423 				if (startmask) {
2424 					--pdst;
2425 					--psrc;
2426 					*pdst = (*pdst & ~startmask |
2427 						 ~*psrc & startmask);
2428 				}
2429 			}
2430 		} else {
2431 			if (xoffDst > xoffSrc) {
2432 				rightShift = xoffDst - xoffSrc;
2433 				leftShift = 16 - rightShift;
2434 			} else {
2435 				leftShift = xoffSrc - xoffDst;
2436 				rightShift = 16 - leftShift;
2437 			}
2438 			while (h--) {
2439 				psrc = psrcLine;
2440 				pdst = pdstLine;
2441 				psrcLine += widthSrc;
2442 				pdstLine += widthDst;
2443 				bits = 0;
2444 				if (xoffDst > xoffSrc)
2445 					bits = *--psrc;
2446 				if (endmask) {
2447 					bits1 = bits >> rightShift;
2448 					bits = *--psrc;
2449 					bits1 |= (bits << leftShift);
2450 					pdst--;
2451 					*pdst = (*pdst & ~endmask |
2452 						 ~bits1 & endmask);
2453 				}
2454 				nl = nlMiddle;
2455 				bits1 = bits;
2456 				Duff_shift_minus(nl, pdst, psrc, = ~);
2457 				if (startmask) {
2458 					bits1 = (bits >> rightShift);
2459 					if (startmask >> leftShift) {
2460 						bits1 |= *--psrc << leftShift;
2461 					}
2462 					--pdst;
2463 					*pdst = (*pdst & ~startmask |
2464 						 ~bits1 & startmask);
2465 				}
2466 			}
2467 		}
2468 	}
2469 }
2470 
2471 void
2472 mfb_or_area16(addrSrc, addrDst, widthSrc, widthDst, sr, dp)
2473 u_short	*addrSrc;
2474 u_short	*addrDst;
2475 register int	widthSrc;
2476 register int	widthDst;
2477 lRectangle	*sr;	/* source rectangle */
2478 lPoint		*dp;	/* destination point */
2479 {
2480 	register u_short *psrcLine, *psrc;
2481 	register u_short *pdstLine, *pdst;
2482 	int w, h;
2483 	int xdir, ydir;
2484 	u_short startmask, endmask;
2485 	register int nlMiddle;
2486 	int xoffSrc, xoffDst;
2487 	register int leftShift, rightShift;
2488 	u_short bits;
2489 	u_short bits1;
2490 	register int nl;
2491 
2492 	if (sr->origin.y < dp->y) {
2493 		ydir = -1;
2494 		widthSrc = -widthSrc;
2495 		widthDst = -widthDst;
2496 	} else {
2497 		ydir = 1;
2498 	}
2499 
2500 	if (sr->origin.x < dp->x) {
2501 		xdir = -1;
2502 	} else {
2503 		xdir = 1;
2504 	}
2505 
2506 	w = sr->extent.x;
2507 	h = sr->extent.y;
2508 
2509 	if (ydir == -1) {
2510 		psrcLine = addrSrc + ((sr->origin.y + h - 1) * -widthSrc);
2511 		pdstLine = addrDst + ((dp->y + h - 1) * -widthDst);
2512 	} else {
2513 		psrcLine = addrSrc + (sr->origin.y * widthSrc);
2514 		pdstLine = addrDst + (dp->y * widthDst);
2515 	}
2516 	if ((dp->x & 0xf) +w <= 16) {
2517 		startmask = mfbpartmasks16[dp->x & 0xf][w & 0xf];
2518 		endmask = 0;
2519 		nlMiddle = 0;
2520 	} else {
2521 		startmask = mfbstarttab16[dp->x & 0xf];
2522 		endmask = mfbendtab16[(dp->x + w) & 0xf];
2523 		if (startmask) {
2524 			nlMiddle = (w - (16 - (dp->x & 0xf))) >> 4;
2525 		} else {
2526 			nlMiddle = w >> 4;
2527 		}
2528 	}
2529 
2530 	if (xdir == 1) {
2531 		xoffSrc = sr->origin.x & 0xf;
2532 		xoffDst = dp->x & 0xf;
2533 		pdstLine += (dp->x >> 4);
2534 		psrcLine += (sr->origin.x >> 4);
2535 		if (xoffSrc == xoffDst) {
2536 			while (h--) {
2537 				psrc = psrcLine;
2538 				pdst = pdstLine;
2539 				psrcLine += widthSrc;
2540 				pdstLine += widthDst;
2541 				if (startmask) {
2542 					*pdst++ |= *psrc++ & startmask;
2543 				}
2544 				nl = nlMiddle;
2545 				Duff_plus(nl, pdst, psrc, |=);
2546 				if (endmask) {
2547 					*pdst |= *psrc & endmask;
2548 				}
2549 			}
2550 		} else {
2551 			if (xoffSrc > xoffDst) {
2552 				leftShift = xoffSrc - xoffDst;
2553 				rightShift = 16 - leftShift;
2554 			} else {
2555 				rightShift = xoffDst - xoffSrc;
2556 				leftShift = 16 - rightShift;
2557 			}
2558 			while (h--) {
2559 				psrc = psrcLine;
2560 				pdst = pdstLine;
2561 				psrcLine += widthSrc;
2562 				pdstLine += widthDst;
2563 				bits = 0;
2564 				if (xoffSrc > xoffDst)
2565 					bits = *psrc++;
2566 				if (startmask) {
2567 					bits1 = bits << leftShift;
2568 					bits = *psrc++;
2569 					bits1 |= bits >> rightShift;
2570 					*pdst++ |= bits1 & startmask;
2571 				}
2572 				nl = nlMiddle;
2573 				bits1 = bits;
2574 				Duff_shift_plus(nl, pdst, psrc, |=);
2575 				if (endmask) {
2576 					bits1 = bits << leftShift;
2577 					if ((endmask << rightShift) & 0xffff) {
2578 						bits1 |= *psrc >> rightShift;
2579 					}
2580 					*pdst |= bits1 & endmask;
2581 				}
2582 			}
2583 		}
2584 	} else {
2585 		xoffSrc = (sr->origin.x + w - 1) & 0xf;
2586 		xoffDst = (dp->x + w - 1) & 0xf;
2587 		pdstLine += ((dp->x + w - 1) >> 4) + 1;
2588 		psrcLine += ((sr->origin.x + w - 1) >> 4) + 1;
2589 		if (xoffSrc == xoffDst) {
2590 			while (h--) {
2591 				psrc = psrcLine;
2592 				pdst = pdstLine;
2593 				psrcLine += widthSrc;
2594 				pdstLine += widthDst;
2595 				if (endmask) {
2596 					*--pdst |= *--psrc & endmask;
2597 				}
2598 				nl = nlMiddle;
2599 				Duff_minus(nl, pdst, psrc, |=);
2600 				if (startmask) {
2601 					*--pdst |= *--psrc & startmask;
2602 				}
2603 			}
2604 		} else {
2605 			if (xoffDst > xoffSrc) {
2606 				rightShift = xoffDst - xoffSrc;
2607 				leftShift = 16 - rightShift;
2608 			} else {
2609 				leftShift = xoffSrc - xoffDst;
2610 				rightShift = 16 - leftShift;
2611 			}
2612 			while (h--) {
2613 				psrc = psrcLine;
2614 				pdst = pdstLine;
2615 				psrcLine += widthSrc;
2616 				pdstLine += widthDst;
2617 				bits = 0;
2618 				if (xoffDst > xoffSrc)
2619 					bits = *--psrc;
2620 				if (endmask) {
2621 					bits1 = bits >> rightShift;
2622 					bits = *--psrc;
2623 					bits1 |= (bits << leftShift);
2624 					*--pdst |= bits1 & endmask;
2625 				}
2626 				nl = nlMiddle;
2627 				bits1 = bits;
2628 				Duff_shift_minus(nl, pdst, psrc, |=);
2629 				if (startmask) {
2630 					bits1 = (bits >> rightShift);
2631 					if (startmask >> leftShift) {
2632 						bits1 |= *--psrc << leftShift;
2633 					}
2634 					*--pdst |= bits1 & startmask;
2635 				}
2636 			}
2637 		}
2638 	}
2639 }
2640 
2641 void
2642 mfb_xor_area16(addrSrc, addrDst, widthSrc, widthDst, sr, dp)
2643 u_short	*addrSrc;
2644 u_short	*addrDst;
2645 int	widthSrc;
2646 int	widthDst;
2647 lRectangle	*sr;	/* source rectangle */
2648 lPoint		*dp;	/* destination point */
2649 {
2650 	register u_short *psrcLine, *psrc;
2651 	register u_short *pdstLine, *pdst;
2652 	int w, h;
2653 	int xdir, ydir;
2654 	u_short startmask, endmask;
2655 	register int nlMiddle;
2656 	int xoffSrc, xoffDst;
2657 	register int leftShift, rightShift;
2658 	u_short bits;
2659 	u_short bits1;
2660 	register int nl;
2661 
2662 	if (sr->origin.y < dp->y) {
2663 		ydir = -1;
2664 		widthSrc = -widthSrc;
2665 		widthDst = -widthDst;
2666 	} else {
2667 		ydir = 1;
2668 	}
2669 
2670 	if (sr->origin.x < dp->x) {
2671 		xdir = -1;
2672 	} else {
2673 		xdir = 1;
2674 	}
2675 
2676 	w = sr->extent.x;
2677 	h = sr->extent.y;
2678 
2679 	if (ydir == -1) {
2680 		psrcLine = addrSrc + ((sr->origin.y + h - 1) * -widthSrc);
2681 		pdstLine = addrDst + ((dp->y + h - 1) * -widthDst);
2682 	} else {
2683 		psrcLine = addrSrc + (sr->origin.y * widthSrc);
2684 		pdstLine = addrDst + (dp->y * widthDst);
2685 	}
2686 	if ((dp->x & 0xf) +w <= 16) {
2687 		startmask = mfbpartmasks16[dp->x & 0xf][w & 0xf];
2688 		endmask = 0;
2689 		nlMiddle = 0;
2690 	} else {
2691 		startmask = mfbstarttab16[dp->x & 0xf];
2692 		endmask = mfbendtab16[(dp->x + w) & 0xf];
2693 		if (startmask) {
2694 			nlMiddle = (w - (16 - (dp->x & 0xf))) >> 4;
2695 		} else {
2696 			nlMiddle = w >> 4;
2697 		}
2698 	}
2699 
2700 	if (xdir == 1) {
2701 		xoffSrc = sr->origin.x & 0xf;
2702 		xoffDst = dp->x & 0xf;
2703 		pdstLine += (dp->x >> 4);
2704 		psrcLine += (sr->origin.x >> 4);
2705 		if (xoffSrc == xoffDst) {
2706 			while (h--) {
2707 				psrc = psrcLine;
2708 				pdst = pdstLine;
2709 				psrcLine += widthSrc;
2710 				pdstLine += widthDst;
2711 				if (startmask) {
2712 					*pdst++ ^= *psrc++ & startmask;
2713 				}
2714 				nl = nlMiddle;
2715 				Duff_plus(nl, pdst, psrc, ^=);
2716 				if (endmask) {
2717 					*pdst ^= *psrc & endmask;
2718 				}
2719 			}
2720 		} else {
2721 			if (xoffSrc > xoffDst) {
2722 				leftShift = xoffSrc - xoffDst;
2723 				rightShift = 16 - leftShift;
2724 			} else {
2725 				rightShift = xoffDst - xoffSrc;
2726 				leftShift = 16 - rightShift;
2727 			}
2728 			while (h--) {
2729 				psrc = psrcLine;
2730 				pdst = pdstLine;
2731 				psrcLine += widthSrc;
2732 				pdstLine += widthDst;
2733 				bits = 0;
2734 				if (xoffSrc > xoffDst)
2735 					bits = *psrc++;
2736 				if (startmask) {
2737 					bits1 = bits << leftShift;
2738 					bits = *psrc++;
2739 					bits1 |= bits >> rightShift;
2740 					*pdst++ ^= bits1 & startmask;
2741 				}
2742 				nl = nlMiddle;
2743 				bits1 = bits;
2744 				Duff_shift_plus(nl, pdst, psrc, ^=);
2745 				if (endmask) {
2746 					bits1 = bits << leftShift;
2747 					if ((endmask << rightShift) & 0xffff) {
2748 						bits1 |= (*psrc >> rightShift);
2749 					}
2750 					*pdst ^= bits1 & endmask;
2751 				}
2752 			}
2753 		}
2754 	} else {
2755 		xoffSrc = (sr->origin.x + w - 1) & 0xf;
2756 		xoffDst = (dp->x + w - 1) & 0xf;
2757 		pdstLine += ((dp->x + w - 1) >> 4) + 1;
2758 		psrcLine += ((sr->origin.x + w - 1) >> 4) + 1;
2759 		if (xoffSrc == xoffDst) {
2760 			while (h--) {
2761 				psrc = psrcLine;
2762 				pdst = pdstLine;
2763 				psrcLine += widthSrc;
2764 				pdstLine += widthDst;
2765 				if (endmask) {
2766 					*--pdst ^= *--psrc & endmask;
2767 				}
2768 				nl = nlMiddle;
2769 				Duff_minus(nl, pdst, psrc, ^=);
2770 				if (startmask) {
2771 					*--pdst ^= *--psrc & startmask;
2772 				}
2773 			}
2774 		} else {
2775 			if (xoffDst > xoffSrc) {
2776 				rightShift = xoffDst - xoffSrc;
2777 				leftShift = 16 - rightShift;
2778 			} else {
2779 				leftShift = xoffSrc - xoffDst;
2780 				rightShift = 16 - leftShift;
2781 			}
2782 			while (h--) {
2783 				psrc = psrcLine;
2784 				pdst = pdstLine;
2785 				psrcLine += widthSrc;
2786 				pdstLine += widthDst;
2787 				bits = 0;
2788 				if (xoffDst > xoffSrc)
2789 					bits = *--psrc;
2790 				if (endmask) {
2791 					bits1 = bits >> rightShift;
2792 					bits = *--psrc;
2793 					bits1 |= (bits << leftShift);
2794 					*--pdst ^= bits1 & endmask;
2795 				}
2796 				nl = nlMiddle;
2797 				bits1 = bits;
2798 				Duff_shift_minus(nl, pdst, psrc, ^=);
2799 				if (startmask) {
2800 					bits1 = (bits >> rightShift);
2801 					if (startmask >> leftShift) {
2802 						bits1 |= (*--psrc << leftShift);
2803 					}
2804 					*--pdst ^= bits1 & startmask;
2805 				}
2806 			}
2807 		}
2808 	}
2809 }
2810 
2811 void
2812 mfb_general_area16(func, addrSrc, addrDst, widthSrc, widthDst, sr, dp)
2813 int		func;
2814 u_short	*addrSrc;
2815 u_short	*addrDst;
2816 int	widthSrc;
2817 int	widthDst;
2818 lRectangle	*sr;	/* source rectangle */
2819 lPoint		*dp;	/* destination point */
2820 {
2821 	register u_short *psrcLine, *psrc;
2822 	register u_short *pdstLine, *pdst;
2823 	register int leftShift, rightShift;
2824 	u_short bits;
2825 	u_short bits1;
2826 	register int nl;
2827 	u_short _ca1, _cx1, _ca2, _cx2;
2828 	u_short startmask, endmask;
2829 	int w, h;
2830 	int xdir, ydir;
2831 	register int nlMiddle;
2832 	int xoffSrc, xoffDst;
2833 
2834 	_ca1 = mergeRopBits[func].ca1;
2835 	_cx1 = mergeRopBits[func].cx1;
2836 	_ca2 = mergeRopBits[func].ca2;
2837 	_cx2 = mergeRopBits[func].cx2;
2838 
2839 	if (sr->origin.y < dp->y) {
2840 		ydir = -1;
2841 		widthSrc = -widthSrc;
2842 		widthDst = -widthDst;
2843 	} else {
2844 		ydir = 1;
2845 	}
2846 
2847 	if (sr->origin.x < dp->x) {
2848 		xdir = -1;
2849 	} else {
2850 		xdir = 1;
2851 	}
2852 
2853 	w = sr->extent.x;
2854 	h = sr->extent.y;
2855 
2856 	if (ydir == -1) {
2857 		psrcLine = addrSrc + ((sr->origin.y + h - 1) * -widthSrc);
2858 		pdstLine = addrDst + ((dp->y + h - 1) * -widthDst);
2859 	} else {
2860 		psrcLine = addrSrc + (sr->origin.y * widthSrc);
2861 		pdstLine = addrDst + (dp->y * widthDst);
2862 	}
2863 	if ((dp->x & 0xf) +w <= 16) {
2864 		startmask = mfbpartmasks16[dp->x & 0xf][w & 0xf];
2865 		endmask = 0;
2866 		nlMiddle = 0;
2867 	} else {
2868 		startmask = mfbstarttab16[dp->x & 0xf];
2869 		endmask = mfbendtab16[(dp->x + w) & 0xf];
2870 		if (startmask) {
2871 			nlMiddle = (w - (16 - (dp->x & 0xf))) >> 4;
2872 		} else {
2873 			nlMiddle = w >> 4;
2874 		}
2875 	}
2876 
2877 	if (xdir == 1) {
2878 		xoffSrc = sr->origin.x & 0xf;
2879 		xoffDst = dp->x & 0xf;
2880 		pdstLine += (dp->x >> 4);
2881 		psrcLine += (sr->origin.x >> 4);
2882 		if (xoffSrc == xoffDst) {
2883 			while (h--) {
2884 				psrc = psrcLine;
2885 				pdst = pdstLine;
2886 				psrcLine += widthSrc;
2887 				pdstLine += widthDst;
2888 				if (startmask) {
2889 					*pdst = DoMergeRopMask(*psrc, *pdst,
2890 							       startmask);
2891 					psrc++;
2892 					pdst++;
2893 				}
2894 				nl = nlMiddle;
2895 				psrc += nl & 7;
2896 				pdst += nl & 7;
2897 				switch (nl & 7) {
2898 				case 7:
2899 					pdst[-7] = DoMergeRop(psrc[-7], pdst[-7]);
2900 				case 6:
2901 					pdst[-6] = DoMergeRop(psrc[-6], pdst[-6]);
2902 				case 5:
2903 					pdst[-5] = DoMergeRop(psrc[-5], pdst[-5]);
2904 				case 4:
2905 					pdst[-4] = DoMergeRop(psrc[-4], pdst[-4]);
2906 				case 3:
2907 					pdst[-3] = DoMergeRop(psrc[-3], pdst[-3]);
2908 				case 2:
2909 					pdst[-2] = DoMergeRop(psrc[-2], pdst[-2]);
2910 				case 1:
2911 					pdst[-1] = DoMergeRop(psrc[-1], pdst[-1]);
2912 				}
2913 				while ((nl -= 8) >= 0) {
2914 					pdst += 8;
2915 					psrc += 8;
2916 					pdst[-8] = DoMergeRop(psrc[-8], pdst[-8]);
2917 					pdst[-7] = DoMergeRop(psrc[-7], pdst[-7]);
2918 					pdst[-6] = DoMergeRop(psrc[-6], pdst[-6]);
2919 					pdst[-5] = DoMergeRop(psrc[-5], pdst[-5]);
2920 					pdst[-4] = DoMergeRop(psrc[-4], pdst[-4]);
2921 					pdst[-3] = DoMergeRop(psrc[-3], pdst[-3]);
2922 					pdst[-2] = DoMergeRop(psrc[-2], pdst[-2]);
2923 					pdst[-1] = DoMergeRop(psrc[-1], pdst[-1]);
2924 				}
2925 				if (endmask) {
2926 					*pdst = DoMergeRopMask(*psrc, *pdst,
2927 							       endmask);
2928 				}
2929 			}
2930 		} else {
2931 			if (xoffSrc > xoffDst) {
2932 				leftShift = xoffSrc - xoffDst;
2933 				rightShift = 16 - leftShift;
2934 			} else {
2935 				rightShift = xoffDst - xoffSrc;
2936 				leftShift = 16 - rightShift;
2937 			}
2938 			while (h--) {
2939 				psrc = psrcLine;
2940 				pdst = pdstLine;
2941 				psrcLine += widthSrc;
2942 				pdstLine += widthDst;
2943 				bits = 0;
2944 				if (xoffSrc > xoffDst)
2945 					bits = *psrc++;
2946 				if (startmask) {
2947 					bits1 = bits << leftShift;
2948 					bits = *psrc++;
2949 					bits1 |= bits >> rightShift;
2950 					*pdst = DoMergeRopMask(bits1, *pdst,
2951 							       startmask);
2952 					pdst++;
2953 				}
2954 				nl = nlMiddle;
2955 				bits1 = bits;
2956 				psrc += nl & 7;
2957 				pdst += nl & 7;
2958 				switch (nl & 7) {
2959 				case 7:
2960 					bits = psrc[-7];
2961 					pdst[-7] = DoMergeRop(((bits1 << leftShift) | (bits >> rightShift)), pdst[-7]);
2962 				case 6:
2963 					bits1 = psrc[-6];
2964 					pdst[-6] = DoMergeRop(((bits << leftShift) | (bits1 >> rightShift)), pdst[-6]);
2965 				case 5:
2966 					bits = psrc[-5];
2967 					pdst[-5] = DoMergeRop(((bits1 << leftShift) | (bits >> rightShift)), pdst[-5]);
2968 				case 4:
2969 					bits1 = psrc[-4];
2970 					pdst[-4] = DoMergeRop(((bits << leftShift) | (bits1 >> rightShift)), pdst[-4]);
2971 				case 3:
2972 					bits = psrc[-3];
2973 					pdst[-3] = DoMergeRop(((bits1 << leftShift) | (bits >> rightShift)), pdst[-3]);
2974 				case 2:
2975 					bits1 = psrc[-2];
2976 					pdst[-2] = DoMergeRop(((bits << leftShift) | (bits1 >> rightShift)), pdst[-2]);
2977 				case 1:
2978 					bits = psrc[-1];
2979 					pdst[-1] = DoMergeRop(((bits1 << leftShift) | (bits >> rightShift)), pdst[-1]);
2980 				}
2981 				while ((nl -= 8) >= 0) {
2982 					pdst += 8;
2983 					psrc += 8;
2984 					bits1 = psrc[-8];
2985 					pdst[-8] = DoMergeRop(((bits << leftShift) | (bits1 >> rightShift)), pdst[-8]);
2986 					bits = psrc[-7];
2987 					pdst[-7] = DoMergeRop(((bits1 << leftShift) | (bits >> rightShift)), pdst[-7]);
2988 					bits1 = psrc[-6];
2989 					pdst[-6] = DoMergeRop(((bits << leftShift) | (bits1 >> rightShift)), pdst[-6]);
2990 					bits = psrc[-5];
2991 					pdst[-5] = DoMergeRop(((bits1 << leftShift) | (bits >> rightShift)), pdst[-5]);
2992 					bits1 = psrc[-4];
2993 					pdst[-4] = DoMergeRop(((bits << leftShift) | (bits1 >> rightShift)), pdst[-4]);
2994 					bits = psrc[-3];
2995 					pdst[-3] = DoMergeRop(((bits1 << leftShift) | (bits >> rightShift)), pdst[-3]);
2996 					bits1 = psrc[-2];
2997 					pdst[-2] = DoMergeRop(((bits << leftShift) | (bits1 >> rightShift)), pdst[-2]);
2998 					bits = psrc[-1];
2999 					pdst[-1] = DoMergeRop(((bits1 << leftShift) | (bits >> rightShift)), pdst[-1]);
3000 				}
3001 				if (endmask) {
3002 					bits1 = bits << leftShift;
3003 					if ((endmask << rightShift) & 0xffff) {
3004 						bits = *psrc;
3005 						bits1 |= (bits >> rightShift);
3006 					}
3007 					*pdst = DoMergeRopMask(bits1, *pdst,
3008 							       endmask);
3009 				}
3010 			}
3011 		}
3012 	} else {
3013 		xoffSrc = (sr->origin.x + w - 1) & 0xf;
3014 		xoffDst = (dp->x + w - 1) & 0xf;
3015 		pdstLine += ((dp->x + w - 1) >> 4) + 1;
3016 		psrcLine += ((sr->origin.x + w - 1) >> 4) + 1;
3017 		if (xoffSrc == xoffDst) {
3018 			while (h--) {
3019 				psrc = psrcLine;
3020 				pdst = pdstLine;
3021 				psrcLine += widthSrc;
3022 				pdstLine += widthDst;
3023 				if (endmask) {
3024 					pdst--;
3025 					psrc--;
3026 					*pdst = DoMergeRopMask(*psrc, *pdst,
3027 							       endmask);
3028 				}
3029 				nl = nlMiddle;
3030 				psrc -= nl & 7;
3031 				pdst -= nl & 7;
3032 				switch (nl & 7) {
3033 				case 7:
3034 					pdst[7-1] = DoMergeRop(psrc[7-1], pdst[7-1]);
3035 				case 6:
3036 					pdst[6-1] = DoMergeRop(psrc[6-1], pdst[6-1]);
3037 				case 5:
3038 					pdst[5-1] = DoMergeRop(psrc[5-1], pdst[5-1]);
3039 				case 4:
3040 					pdst[4-1] = DoMergeRop(psrc[4-1], pdst[4-1]);
3041 				case 3:
3042 					pdst[3-1] = DoMergeRop(psrc[3-1], pdst[3-1]);
3043 				case 2:
3044 					pdst[2-1] = DoMergeRop(psrc[2-1], pdst[2-1]);
3045 				case 1:
3046 					pdst[1-1] = DoMergeRop(psrc[1-1], pdst[1-1]);
3047 				}
3048 				while ((nl -= 8) >= 0) {
3049 					pdst -= 8;
3050 					psrc -= 8;
3051 					pdst[8-1] = DoMergeRop(psrc[8-1], pdst[8-1]);
3052 					pdst[7-1] = DoMergeRop(psrc[7-1], pdst[7-1]);
3053 					pdst[6-1] = DoMergeRop(psrc[6-1], pdst[6-1]);
3054 					pdst[5-1] = DoMergeRop(psrc[5-1], pdst[5-1]);
3055 					pdst[4-1] = DoMergeRop(psrc[4-1], pdst[4-1]);
3056 					pdst[3-1] = DoMergeRop(psrc[3-1], pdst[3-1]);
3057 					pdst[2-1] = DoMergeRop(psrc[2-1], pdst[2-1]);
3058 					pdst[1-1] = DoMergeRop(psrc[1-1], pdst[1-1]);
3059 				}
3060 				if (startmask) {
3061 					--pdst;
3062 					--psrc;
3063 					*pdst = DoMergeRopMask(*psrc, *pdst,
3064 							       startmask);
3065 				}
3066 			}
3067 		} else {
3068 			if (xoffDst > xoffSrc) {
3069 				rightShift = xoffDst - xoffSrc;
3070 				leftShift = 16 - rightShift;
3071 			} else {
3072 				leftShift = xoffSrc - xoffDst;
3073 				rightShift = 16 - leftShift;
3074 			}
3075 			while (h--) {
3076 				psrc = psrcLine;
3077 				pdst = pdstLine;
3078 				psrcLine += widthSrc;
3079 				pdstLine += widthDst;
3080 				bits = 0;
3081 				if (xoffDst > xoffSrc)
3082 					bits = *--psrc;
3083 				if (endmask) {
3084 					bits1 = bits >> rightShift;
3085 					bits = *--psrc;
3086 					bits1 |= (bits << leftShift);
3087 					pdst--;
3088 					*pdst = DoMergeRopMask(bits1, *pdst,
3089 							       endmask);
3090 				}
3091 				nl = nlMiddle;
3092 				bits1 = bits;
3093 				psrc -= nl & 7;
3094 				pdst -= nl & 7;
3095 				switch (nl & 7) {
3096 				case 7:
3097 					bits = psrc[7-1];
3098 					pdst[7-1] = DoMergeRop(((bits1 >> rightShift) | (bits << leftShift)), pdst[7-1]);
3099 				case 6:
3100 					bits1 = psrc[6-1];
3101 					pdst[6-1] = DoMergeRop(((bits >> rightShift) | (bits1 << leftShift)), pdst[6-1]);
3102 				case 5:
3103 					bits = psrc[5-1];
3104 					pdst[5-1] = DoMergeRop(((bits1 >> rightShift) | (bits << leftShift)), pdst[5-1]);
3105 				case 4:
3106 					bits1 = psrc[4-1];
3107 					pdst[4-1] = DoMergeRop(((bits >> rightShift) | (bits1 << leftShift)), pdst[4-1]);
3108 				case 3:
3109 					bits = psrc[3-1];
3110 					pdst[3-1] = DoMergeRop(((bits1 >> rightShift) | (bits << leftShift)), pdst[3-1]);
3111 				case 2:
3112 					bits1 = psrc[2-1];
3113 					pdst[2-1] = DoMergeRop(((bits >> rightShift) | (bits1 << leftShift)), pdst[2-1]);
3114 				case 1:
3115 					bits = psrc[1-1];
3116 					pdst[1-1] = DoMergeRop(((bits1 >> rightShift) | (bits << leftShift)), pdst[1-1]);
3117 				}
3118 				while ((nl -= 8) >= 0) {
3119 					pdst -= 8;
3120 					psrc -= 8;
3121 					bits1 = psrc[8-1];
3122 					pdst[8-1] = DoMergeRop(((bits >> rightShift) | (bits1 << leftShift)), pdst[8-1]);
3123 					bits = psrc[7-1];
3124 					pdst[7-1] = DoMergeRop(((bits1 >> rightShift) | (bits << leftShift)), pdst[7-1]);
3125 					bits1 = psrc[6-1];
3126 					pdst[6-1] = DoMergeRop(((bits >> rightShift) | (bits1 << leftShift)), pdst[6-1]);
3127 					bits = psrc[5-1];
3128 					pdst[5-1] = DoMergeRop(((bits1 >> rightShift) | (bits << leftShift)), pdst[5-1]);
3129 					bits1 = psrc[4-1];
3130 					pdst[4-1] = DoMergeRop(((bits >> rightShift) | (bits1 << leftShift)), pdst[4-1]);
3131 					bits = psrc[3-1];
3132 					pdst[3-1] = DoMergeRop(((bits1 >> rightShift) | (bits << leftShift)), pdst[3-1]);
3133 					bits1 = psrc[2-1];
3134 					pdst[2-1] = DoMergeRop(((bits >> rightShift) | (bits1 << leftShift)), pdst[2-1]);
3135 					bits = psrc[1-1];
3136 					pdst[1-1] = DoMergeRop(((bits1 >> rightShift) | (bits << leftShift)), pdst[1-1]);
3137 				}
3138 				if (startmask) {
3139 					bits1 = (bits >> rightShift);
3140 					if (startmask >> leftShift) {
3141 						bits = *--psrc;
3142 						bits1 |= (bits << leftShift);
3143 					}
3144 					--pdst;
3145 					*pdst = DoMergeRopMask(bits1, *pdst,
3146 							       startmask);
3147 				}
3148 			}
3149 		}
3150 	}
3151 }
3152 
3153 void
3154 mfb_clr_area16(x, y, w, h, addr, nlwidth)
3155 int x;
3156 int y;
3157 int w;
3158 register int h;
3159 register u_short *addr;
3160 int nlwidth;
3161 {
3162 	register u_short startmask;
3163 	u_short endmask;
3164 	register int nlw, nlwExtra;
3165 	int nlwMiddle;
3166 
3167 	addr += (y * nlwidth + (x >> 4));
3168 
3169 	if (((x & 0xf) + w) < 16) {
3170 		startmask = mfbpartmasks16[x & 0xf][w & 0xf];
3171 		nlwExtra = nlwidth;
3172 		Duff(h, *addr &= ~startmask; addr += nlwExtra)
3173 	} else {
3174 		startmask = mfbstarttab16[x & 0xf];
3175 		endmask = mfbendtab16[(x + w) & 0xf];
3176 		if (startmask) {
3177 			nlwMiddle = (w - (16 - (x & 0xf))) >> 4;
3178 		} else {
3179 			nlwMiddle = w >> 4;
3180 		}
3181 		nlwExtra = nlwidth - nlwMiddle;
3182 		if (startmask && endmask) {
3183 			startmask ^= ~0;
3184 			endmask ^= ~0;
3185 			nlwExtra -= 1;
3186 			while (h--) {
3187 				nlw = nlwMiddle;
3188 				*addr++ &= startmask;
3189 				Duff_single(nlw, addr, = 0)
3190 				*addr &= endmask;
3191 				addr += nlwExtra;
3192 			}
3193 		} else if (startmask && !endmask) {
3194 			startmask ^= ~0;
3195 			nlwExtra -= 1;
3196 			while (h--) {
3197 				nlw = nlwMiddle;
3198 				*addr++ &= startmask;
3199 				Duff_single(nlw, addr, = 0)
3200 				addr += nlwExtra;
3201 			}
3202 		} else if (!startmask && endmask) {
3203 			endmask ^= ~0;
3204 			while (h--) {
3205 				nlw = nlwMiddle;
3206 				Duff_single(nlw, addr, = 0)
3207 				*addr &= endmask;
3208 				addr += nlwExtra;
3209 			}
3210 		} else {
3211 			while (h--) {
3212 				nlw = nlwMiddle;
3213 				Duff_single(nlw, addr, = 0)
3214 				addr += nlwExtra;
3215 			}
3216 		}
3217 	}
3218 }
3219 
3220 void
3221 mfb_inv_area16(x, y, w, h, addr, nlwidth)
3222 int x;
3223 int y;
3224 int w;
3225 register int h;
3226 register u_short *addr;
3227 int nlwidth;
3228 {
3229 	register u_short startmask;
3230 	u_short endmask;
3231 	register int nlw, nlwExtra;
3232 	int nlwMiddle;
3233 
3234 	addr += (y * nlwidth + (x >> 4));
3235 
3236 	if (((x & 0xf) + w) < 16) {
3237 		startmask = mfbpartmasks16[x & 0xf][w & 0xf];
3238 		nlwExtra = nlwidth;
3239 		Duff(h, *addr ^= startmask; addr += nlwExtra)
3240 	} else {
3241 		startmask = mfbstarttab16[x & 0xf];
3242 		endmask = mfbendtab16[(x + w) & 0xf];
3243 		if (startmask) {
3244 			nlwMiddle = (w - (16 - (x & 0xf))) >> 4;
3245 		} else {
3246 			nlwMiddle = w >> 4;
3247 		}
3248 		nlwExtra = nlwidth - nlwMiddle;
3249 		if (startmask && endmask) {
3250 			nlwExtra -= 1;
3251 			while (h--) {
3252 				nlw = nlwMiddle;
3253 				*addr++ ^= startmask;
3254 				Duff_single(nlw, addr, ^= ~0)
3255 				*addr ^= endmask;
3256 				addr += nlwExtra;
3257 			}
3258 		} else if (startmask && !endmask) {
3259 			nlwExtra -= 1;
3260 			while (h--) {
3261 				nlw = nlwMiddle;
3262 				*addr++ ^= startmask;
3263 				Duff_single(nlw, addr, ^= ~0)
3264 				addr += nlwExtra;
3265 			}
3266 		} else if (!startmask && endmask) {
3267 			while (h--) {
3268 				nlw = nlwMiddle;
3269 				Duff_single(nlw, addr, ^= ~0)
3270 				*addr ^= endmask;
3271 				addr += nlwExtra;
3272 			}
3273 		} else {
3274 			while (h--) {
3275 				nlw = nlwMiddle;
3276 				Duff_single(nlw, addr, ^= ~0)
3277 				addr += nlwExtra;
3278 			}
3279 		}
3280 	}
3281 }
3282 
3283 void
3284 mfb_set_area16(x, y, w, h, addr, nlwidth)
3285 int x;
3286 int y;
3287 int w;
3288 register int h;
3289 register u_short *addr;
3290 int nlwidth;
3291 {
3292 	register u_short startmask;
3293 	u_short endmask;
3294 	register int nlw, nlwExtra;
3295 	int nlwMiddle;
3296 
3297 	addr += (y * nlwidth + (x >> 4));
3298 
3299 	if (((x & 0xf) + w) < 16) {
3300 		startmask = mfbpartmasks16[x & 0xf][w & 0xf];
3301 		nlwExtra = nlwidth;
3302 		Duff(h, *addr |= startmask; addr += nlwExtra)
3303 	} else {
3304 		startmask = mfbstarttab16[x & 0xf];
3305 		endmask = mfbendtab16[(x + w) & 0xf];
3306 		if (startmask) {
3307 			nlwMiddle = (w - (16 - (x & 0xf))) >> 4;
3308 		} else {
3309 			nlwMiddle = w >> 4;
3310 		}
3311 		nlwExtra = nlwidth - nlwMiddle;
3312 		if (startmask && endmask) {
3313 			nlwExtra -= 1;
3314 			while (h--) {
3315 				nlw = nlwMiddle;
3316 				*addr++ |= startmask;
3317 #ifdef mc68020
3318 				asm(" move.w #-1,d3");
3319 				Duff(nlw, asm(" move.w d3,(a5)+"))
3320 #else /* mc68020 */
3321 				Duff_single(nlw, addr, = ~0)
3322 #endif /* mc68020 */
3323 				*addr |= endmask;
3324 				addr += nlwExtra;
3325 			}
3326 		} else if (startmask && !endmask) {
3327 			nlwExtra -= 1;
3328 			while (h--) {
3329 				nlw = nlwMiddle;
3330 				*addr++ |= startmask;
3331 #ifdef mc68020
3332 				asm(" move.w #-1,d3");
3333 				Duff(nlw, asm(" move.w d3,(a5)+"));
3334 #else /* mc68020 */
3335 				Duff_single(nlw, addr, = ~0)
3336 #endif /* mc68020 */
3337 				addr += nlwExtra;
3338 			}
3339 		} else if (!startmask && endmask) {
3340 			while (h--) {
3341 				nlw = nlwMiddle;
3342 #ifdef mc68020
3343 				asm(" move.w #-1,d3");
3344 				Duff(nlw, asm(" move.w d3,(a5)+"));
3345 #else /* mc68020 */
3346 				Duff_single(nlw, addr, = ~0)
3347 #endif /* mc68020 */
3348 				*addr |= endmask;
3349 				addr += nlwExtra;
3350 			}
3351 		} else {
3352 			while (h--) {
3353 				nlw = nlwMiddle;
3354 #ifdef mc68020
3355 				asm(" move.w #-1,d3");
3356 				Duff(nlw, asm(" move.w d3,(a5)+"));
3357 #else /* mc68020 */
3358 				Duff_single(nlw, addr, = ~0)
3359 #endif /* mc68020 */
3360 				addr += nlwExtra;
3361 			}
3362 		}
3363 	}
3364 }
3365 
3366 void
3367 mfb_clrvvector32(addr, nlwidth, x, len, lpf)
3368 register u_int *addr;
3369 register int nlwidth;
3370 register int x;
3371 register int len;
3372 {
3373 	register u_int bitmask;
3374 
3375 	if (len < 0) {
3376 		nlwidth = -nlwidth;
3377 		len = -len;
3378 	}
3379 	if (lpf)
3380 		len++;
3381 	addr += (x >> 5);
3382 
3383 	bitmask = mfbrmask32[x & 0x1f];
3384 
3385 	Duff(len, *addr &= bitmask; addr += nlwidth)
3386 }
3387 
3388 void
3389 mfb_clrhvector32(addr, x, len, lpf)
3390 register u_int *addr;
3391 int x;
3392 int len;
3393 int lpf;
3394 {
3395 	register u_int	startmask;
3396 	register u_int 	endmask;
3397 	register int	nl, off;
3398 
3399 	if (len < 0) {
3400 		x += len;
3401 		len = -len;
3402 		if (lpf) {
3403 			len++;
3404 		} else {
3405 			x++;
3406 		}
3407 	} else {
3408 		if (lpf) {
3409 			len++;
3410 		}
3411 	}
3412 	addr += (x >> 5);
3413 
3414 	off = x & 0x1f;
3415 	if (off + len < 32) {
3416 		*addr &= ~mfbpartmasks32[off][len & 0x1f];
3417 	} else {
3418 		startmask = mfbstarttab32[off];
3419 		endmask = mfbendtab32[(x + len) & 0x1f];
3420 		if (startmask) {
3421 			nl = (len - (32 - off)) >> 5;
3422 			*addr++ &= ~startmask;
3423 		} else
3424 			nl = len >> 5;
3425 		Duff_single(nl, addr, = 0);
3426 		if (endmask)
3427 			*addr &= ~endmask;
3428 	}
3429 }
3430 
3431 void
3432 mfb_clrvector32(fb, addr, ddy, p0, p1, lpf)
3433 struct fbdev	*fb;
3434 register u_int *addr;
3435 register int ddy;
3436 register lPoint *p0, *p1;
3437 int lpf;		/* if 0, don't draw last point */
3438 {
3439 	register int i;
3440 	register int lim;
3441 #ifdef mc68020
3442 	register int x = p0->x;
3443 #else /* mc68020 */
3444 	register u_int bit, leftbit, rightbit;
3445 #endif /* mc68020 */
3446 	int ddx;
3447 	int dx = p1->x - p0->x;
3448 	int dy = p1->y - p0->y;
3449 	int s, d, c;
3450 
3451 	addr += (p0->y * ddy);
3452 
3453 	if (dx == 0) {
3454 		mfb_clrvvector32(addr, ddy, p0->x, dy, lpf);
3455 		return;
3456 	}
3457 	if (dy == 0) {
3458 		mfb_clrhvector32(addr, p0->x, dx, lpf);
3459 		return;
3460 	}
3461 
3462 	if (dx < 0) {
3463 		ddx = -1;
3464 		dx = -dx;
3465 	} else {
3466 		ddx = 1;
3467 	}
3468 	if (dy < 0) {
3469 		dy = -dy;
3470 		ddy = -ddy;
3471 	}
3472 
3473 #ifndef mc68020
3474 	bit = mfbmask32[p0->x & 0x1f];
3475 	leftbit = mfbmask32[0];
3476 	rightbit = mfbmask32[31];
3477 	addr += (p0->x >> 5);
3478 #endif /* mc68020 */
3479 	if (dx > dy) {	/* case x */
3480 		lim = dx;
3481 		if (lpf)
3482 			lim++;
3483 
3484 		s = -dx;
3485 		d = dx << 1;
3486 		c = dy << 1;
3487 
3488 		if (ddx > 0) {
3489 			for (i = lim; i > 0; i--) {
3490 #ifdef mc68020
3491 				asm("	bfclr	(a5){d4:1}");
3492 				x++;
3493 #else /* mc68020 */
3494 				*addr &= ~bit;
3495 				bit >>= 1;
3496 				if (!bit) {
3497 					bit = leftbit;
3498 					addr++;
3499 				}
3500 #endif /* mc68020 */
3501 				if ((s += c) >= 0) {
3502 					s -= d;
3503 					addr += ddy;
3504 				}
3505 			}
3506 		} else {
3507 			for (i = lim; i > 0; i--) {
3508 #ifdef mc68020
3509 				asm("	bfclr	(a5){d4:1}");
3510 				x--;
3511 #else /* mc68020 */
3512 				*addr &= ~bit;
3513 				bit <<= 1;
3514 				if (!bit) {
3515 					bit = rightbit;
3516 					addr--;
3517 				}
3518 #endif /* mc68020 */
3519 				if ((s += c) >= 0) {
3520 					s -= d;
3521 					addr += ddy;
3522 				}
3523 			}
3524 		}
3525 	} else {			/* case y */
3526 		lim = dy;
3527 		if (lpf)
3528 			lim++;
3529 		s = -dy;
3530 		d = dy << 1;
3531 		c = dx << 1;
3532 
3533 		if (ddx > 0) {
3534 			for (i = lim; i > 0; i--) {
3535 #ifdef mc68020
3536 				asm("	bfclr	(a5){d4:1}");
3537 				if ((s += c) >= 0) {
3538 					s -= d;
3539 					x++;
3540 				}
3541 #else /* mc68020 */
3542 				*addr &= ~bit;
3543 				if ((s += c) >= 0) {
3544 					s -= d;
3545 					bit >>= 1;
3546 					if (!bit) {
3547 						bit = leftbit;
3548 						addr++;
3549 					}
3550 				}
3551 #endif /* mc68020 */
3552 				addr += ddy;
3553 			}
3554 		} else {
3555 			for (i = lim; i > 0; i--) {
3556 #ifdef mc68020
3557 				asm("	bfclr	(a5){d4:1}");
3558 				if ((s += c) >= 0) {
3559 					s -= d;
3560 					x--;
3561 				}
3562 #else /* mc68020 */
3563 				*addr &= ~bit;
3564 				if ((s += c) >= 0) {
3565 					s -= d;
3566 					bit <<= 1;
3567 					if (!bit) {
3568 						bit = rightbit;
3569 						addr--;
3570 					}
3571 				}
3572 #endif /* mc68020 */
3573 				addr += ddy;
3574 			}
3575 		}
3576 	}
3577 }
3578 
3579 void
3580 mfb_invvvector32(addr, nlwidth, x, len, lpf)
3581 register u_int *addr;
3582 register int nlwidth;
3583 register int x;
3584 register int len;
3585 {
3586 	register u_int bitmask;
3587 
3588 	if (len < 0) {
3589 		nlwidth = -nlwidth;
3590 		len = -len;
3591 	}
3592 	if (lpf)
3593 		len++;
3594 	addr += (x >> 5);
3595 
3596 	bitmask = mfbmask32[x & 0x1f];
3597 
3598 	Duff(len, *addr ^= bitmask; addr += nlwidth)
3599 }
3600 
3601 void
3602 mfb_invhvector32(addr, x, len, lpf)
3603 register u_int *addr;
3604 int x;
3605 int len;
3606 int lpf;
3607 {
3608 	register u_int	startmask;
3609 	register u_int 	endmask;
3610 	register int nl, off;
3611 
3612 	if (len < 0) {
3613 		x += len;
3614 		len = -len;
3615 		if (lpf) {
3616 			len++;
3617 		} else {
3618 			x++;
3619 		}
3620 	} else {
3621 		if (lpf) {
3622 			len++;
3623 		}
3624 	}
3625 	addr += (x >> 5);
3626 
3627 	off = x & 0x1f;
3628 	if (off + len < 32) {
3629 		*addr ^= mfbpartmasks32[off][len & 0x1f];
3630 	} else {
3631 		startmask = mfbstarttab32[off];
3632 		endmask = mfbendtab32[(x + len) & 0x1f];
3633 		if (startmask) {
3634 			nl = (len - (32 - off)) >> 5;
3635 			*addr++ ^= startmask;
3636 		} else
3637 			nl = len >> 5;
3638 		Duff_single(nl, addr, ^= ~0);
3639 		if (endmask)
3640 			*addr ^= endmask;
3641 	}
3642 }
3643 
3644 void
3645 mfb_invvector32(fb, addr, ddy, p0, p1, lpf)
3646 struct fbdev	*fb;
3647 register u_int *addr;
3648 register int	ddy;
3649 register lPoint *p0, *p1;
3650 int lpf;		/* if 0, don't draw last point */
3651 {
3652 	register int i;
3653 	register int lim;
3654 #ifdef mc68020
3655 	register int x = p0->x;
3656 #else /* mc68020 */
3657 	register u_int bit, leftbit, rightbit;
3658 #endif /* mc68020 */
3659 	int ddx;
3660 	int dx = p1->x - p0->x;
3661 	int dy = p1->y - p0->y;
3662 	int s, d, c;
3663 
3664 	addr += (p0->y * ddy);
3665 
3666 	if (dx == 0) {
3667 		mfb_invvvector32(addr, ddy, p0->x, dy, lpf);
3668 		return;
3669 	}
3670 	if (dy == 0) {
3671 		mfb_invhvector32(addr, p0->x, dx, lpf);
3672 		return;
3673 	}
3674 
3675 	if (dx < 0) {
3676 		dx = -dx;
3677 		ddx = -1;
3678 	} else {
3679 		ddx = 1;
3680 	}
3681 	if (dy < 0) {
3682 		dy = -dy;
3683 		ddy = -ddy;
3684 	}
3685 
3686 #ifndef mc68020
3687 	bit = mfbmask32[p0->x & 0x1f];
3688 	leftbit = mfbmask32[0];
3689 	rightbit = mfbmask32[31];
3690 	addr += (p0->x >> 5);
3691 #endif /* mc68020 */
3692 	if (dx > dy) {	/* case x */
3693 		lim = dx;
3694 		if (lpf)
3695 			lim++;
3696 
3697 		s = -dx;
3698 		d = dx << 1;
3699 		c = dy << 1;
3700 
3701 		if (ddx > 0) {
3702 			for (i = lim; i > 0; i--) {
3703 #ifdef mc68020
3704 				asm("	bfchg	(a5){d4:1}");
3705 				x++;
3706 #else /* mc68020 */
3707 				*addr ^= bit;
3708 				bit >>= 1;
3709 				if (!bit) {
3710 					bit = leftbit;
3711 					addr++;
3712 				}
3713 #endif /* mc68020 */
3714 				if ((s += c) >= 0) {
3715 					s -= d;
3716 					addr += ddy;
3717 				}
3718 			}
3719 		} else {
3720 			for (i = lim; i > 0; i--) {
3721 #ifdef mc68020
3722 				asm("	bfchg	(a5){d4:1}");
3723 				x--;
3724 #else /* mc68020 */
3725 				*addr ^= bit;
3726 				bit <<= 1;
3727 				if (!bit) {
3728 					bit = rightbit;
3729 					addr--;
3730 				}
3731 #endif /* mc68020 */
3732 				if ((s += c) >= 0) {
3733 					s -= d;
3734 					addr += ddy;
3735 				}
3736 			}
3737 		}
3738 	} else {			/* case y */
3739 		lim = dy;
3740 		if (lpf)
3741 			lim++;
3742 		s = -dy;
3743 		d = dy << 1;
3744 		c = dx << 1;
3745 
3746 		if (ddx > 0) {
3747 			for (i = lim; i > 0; i--) {
3748 #ifdef mc68020
3749 				asm("	bfchg	(a5){d4:1}");
3750 				if ((s += c) >= 0) {
3751 					s -= d;
3752 					x++;
3753 				}
3754 #else /* mc68020 */
3755 				*addr ^= bit;
3756 				if ((s += c) >= 0) {
3757 					s -= d;
3758 					bit >>= 1;
3759 					if (!bit) {
3760 						bit = leftbit;
3761 						addr++;
3762 					}
3763 				}
3764 #endif /* mc68020 */
3765 				addr += ddy;
3766 			}
3767 		} else {
3768 			for (i = lim; i > 0; i--) {
3769 #ifdef mc68020
3770 				asm("	bfchg	(a5){d4:1}");
3771 				if ((s += c) >= 0) {
3772 					s -= d;
3773 					x--;
3774 				}
3775 #else /* mc68020 */
3776 				*addr ^= bit;
3777 				if ((s += c) >= 0) {
3778 					s -= d;
3779 					bit <<= 1;
3780 					if (!bit) {
3781 						bit = rightbit;
3782 						addr--;
3783 					}
3784 				}
3785 #endif /* mc68020 */
3786 				addr += ddy;
3787 			}
3788 		}
3789 	}
3790 }
3791 
3792 void
3793 mfb_setvvector32(addr, nlwidth, x, len, lpf)
3794 register u_int *addr;
3795 register int nlwidth;
3796 register int x;
3797 register int len;
3798 {
3799 	register u_int bitmask;
3800 
3801 	if (len < 0) {
3802 		nlwidth = -nlwidth;
3803 		len = -len;
3804 	}
3805 	if (lpf)
3806 		len++;
3807 	addr += (x >> 5);
3808 
3809 	bitmask = mfbmask32[x & 0x1f];
3810 
3811 	Duff(len, *addr |= bitmask; addr += nlwidth)
3812 }
3813 
3814 void
3815 mfb_sethvector32(addr, x, len, lpf)
3816 register u_int *addr;
3817 int x;
3818 int len;
3819 int lpf;
3820 {
3821 	register u_int startmask;
3822 	register u_int endmask;
3823 	register int nl, off;
3824 
3825 	if (len < 0) {
3826 		x += len;
3827 		len = -len;
3828 		if (lpf) {
3829 			len++;
3830 		} else {
3831 			x++;
3832 		}
3833 	} else {
3834 		if (lpf) {
3835 			len++;
3836 		}
3837 	}
3838 	addr += (x >> 5);
3839 
3840 	off = x & 0x1f;
3841 	if (off + len < 32) {
3842 		*addr |= mfbpartmasks32[off][len & 0x1f];
3843 	} else {
3844 		startmask = mfbstarttab32[off];
3845 		endmask = mfbendtab32[(x + len) & 0x1f];
3846 		if (startmask) {
3847 			nl = (len - (32 - off)) >> 5;
3848 			*addr++ |= startmask;
3849 		} else
3850 			nl = len >> 5;
3851 #ifdef mc68020
3852 		;
3853 		asm(" move.l #-1,d3");
3854 		Duff(nl, asm(" move.l d3,(a5)+"))
3855 #else /* mc68020 */
3856 		Duff_single(nl, addr, = ~0);
3857 #endif /* mc68020 */
3858 		if (endmask)
3859 			*addr |= endmask;
3860 	}
3861 }
3862 
3863 void
3864 mfb_setvector32(fb, addr, ddy, p0, p1, lpf)
3865 struct fbdev	*fb;
3866 register u_int *addr;
3867 register int ddy;
3868 register lPoint *p0, *p1;
3869 int lpf;		/* if 0, don't draw last point */
3870 {
3871 	register int i;
3872 	register int lim;
3873 #ifdef mc68020
3874 	register int x = p0->x;
3875 #else /* mc68020 */
3876 	register u_int bit, leftbit, rightbit;
3877 #endif /* mc68020 */
3878 	int ddx;
3879 	int dx = p1->x - p0->x;
3880 	int dy = p1->y - p0->y;
3881 	int s, d, c;
3882 
3883 	ddx = 1;
3884 	addr += (p0->y * ddy);
3885 
3886 	if (dx == 0) {
3887 		mfb_setvvector32(addr, ddy, p0->x, dy, lpf);
3888 		return;
3889 	}
3890 	if (dy == 0) {
3891 		mfb_sethvector32(addr, p0->x, dx, lpf);
3892 		return;
3893 	}
3894 
3895 	if (dx < 0) {
3896 		dx = -dx;
3897 		ddx = -ddx;
3898 	}
3899 	if (dy < 0) {
3900 		dy = -dy;
3901 		ddy = -ddy;
3902 	}
3903 
3904 #ifndef mc68020
3905 	bit = mfbmask32[p0->x & 0x1f];
3906 	leftbit = mfbmask32[0];
3907 	rightbit = mfbmask32[31];
3908 	addr += (p0->x >> 5);
3909 #endif /* mc68020 */
3910 	if (dx > dy) {	/* case x */
3911 		lim = dx;
3912 		if (lpf)
3913 			lim++;
3914 
3915 		s = -dx;
3916 		d = dx << 1;
3917 		c = dy << 1;
3918 
3919 		if (ddx > 0) {
3920 			for (i = lim; i > 0; i--) {
3921 #ifdef mc68020
3922 				asm("	bfset	(a5){d4:1}");
3923 				x++;
3924 #else /* mc68020 */
3925 				*addr |= bit;
3926 				bit >>= 1;
3927 				if (!bit) {
3928 					bit = leftbit;
3929 					addr++;
3930 				}
3931 #endif /* mc68020 */
3932 				if ((s += c) >= 0) {
3933 					s -= d;
3934 					addr += ddy;
3935 				}
3936 			}
3937 		} else {
3938 			for (i = lim; i > 0; i--) {
3939 #ifdef mc68020
3940 				asm("	bfset	(a5){d4:1}");
3941 				x--;
3942 #else /* mc68020 */
3943 				*addr |= bit;
3944 				bit <<= 1;
3945 				if (!bit) {
3946 					bit = rightbit;
3947 					addr--;
3948 				}
3949 #endif /* mc68020 */
3950 				if ((s += c) >= 0) {
3951 					s -= d;
3952 					addr += ddy;
3953 				}
3954 			}
3955 		}
3956 	} else {			/* case y */
3957 		lim = dy;
3958 		if (lpf)
3959 			lim++;
3960 		s = -dy;
3961 		d = dy << 1;
3962 		c = dx << 1;
3963 
3964 		if (ddx > 0) {
3965 			for (i = lim; i > 0; i--) {
3966 #ifdef mc68020
3967 				asm("	bfset	(a5){d4:1}");
3968 				if ((s += c) >= 0) {
3969 					s -= d;
3970 					x++;
3971 				}
3972 #else /* mc68020 */
3973 				*addr |= bit;
3974 				if ((s += c) >= 0) {
3975 					s -= d;
3976 					bit >>= 1;
3977 					if (!bit) {
3978 						bit = leftbit;
3979 						addr++;
3980 					}
3981 				}
3982 #endif /* mc68020 */
3983 				addr += ddy;
3984 			}
3985 		} else {
3986 			for (i = lim; i > 0; i--) {
3987 #ifdef mc68020
3988 				asm("	bfset	(a5){d4:1}");
3989 				if ((s += c) >= 0) {
3990 					s -= d;
3991 					x--;
3992 				}
3993 #else /* mc68020 */
3994 				*addr |= bit;
3995 				if ((s += c) >= 0) {
3996 					s -= d;
3997 					bit <<= 1;
3998 					if (!bit) {
3999 						bit = rightbit;
4000 						addr--;
4001 					}
4002 				}
4003 #endif /* mc68020 */
4004 				addr += ddy;
4005 			}
4006 		}
4007 	}
4008 }
4009 
4010 void
4011 mfb_point(p, x, s, f)
4012 register u_int *p;
4013 register int x;
4014 register u_int s;
4015 register char *f;
4016 {
4017 #ifdef mc68020
4018 	asm("	andi.l	#31, d7");
4019 	asm("	move.l	d7,d0");
4020 	asm("	neg.l	d7");
4021 	asm("	addi.l	#31, d7");
4022 
4023 	asm("	move.l	(a5), d1");
4024 	asm("	lsr.l	d7, d1");
4025 	asm("	andi.l	#1, d1");
4026 
4027 	asm("	andi.l	#1, d6");
4028 	asm("	lsl.l	#1, d6");
4029 	asm("	or.l	d6, d1");
4030 	asm("	neg.l	d1");
4031 	asm("	addq.l	#3, d1");
4032 
4033 	asm("	btst.b	d1, (a4)");
4034 	asm("	beq	bcl");
4035 	asm("	bfset	(a5){d0:1}");
4036 	asm("	bra	bend");
4037 	asm("bcl:	bfclr	(a5){d0:1}");
4038 	asm("bend:	");
4039 #else /* mc68020 */
4040 	x = 31 - (x & 31);
4041 	if ((1 << (3 - (((s & 1) << 1) | ((*p >> x) & 1)))) & *f)
4042 		*p |= (1 << x);
4043 	else
4044 		*p &= ~(1 << x);
4045 #endif /* mc68020 */
4046 }
4047 
4048 void
4049 mfb_vector32(fb, addr, ddy, p0, p1, lpf)
4050 struct fbdev	*fb;
4051 register u_int *addr;
4052 int	ddy;
4053 register lPoint *p0, *p1;
4054 int lpf;		/* if 0, don't draw last point */
4055 {
4056 	register char *fp = fb->funcvec;
4057 	register int x = p0->x;
4058 	register u_int pat = fb->pat;
4059 	int lim;
4060 	register int i;
4061 	register int ddx;
4062 	int s, d, c;
4063 	int dx = p1->x - x;
4064 	int dy = p1->y - p0->y;
4065 
4066 	ddx = 1;
4067 	addr += (p0->y * ddy);
4068 
4069 	if (dx == 0) {
4070 		ddx = 0;
4071 	} else if (dx < 0) {
4072 		dx = -dx;
4073 		ddx = -ddx;
4074 	}
4075 
4076 	if (dy == 0)
4077 		ddy = 0;
4078 	else if (dy < 0) {
4079 		dy = -dy;
4080 		ddy = -ddy;
4081 	}
4082 
4083 	if (dx > dy) {			/* case x */
4084 		lim = dx;
4085 		if (lpf)
4086 			lim++;
4087 
4088 		s = -dx;
4089 		d = dx << 1;
4090 		c = dy << 1;
4091 
4092 		for (i = lim; i > 0; i--) {
4093 #ifdef mc68020
4094 			asm(" rol.l	#1, d6 ");
4095 #else /* mc68020 */
4096 			pat = (pat << 1) | ((pat & 0x80000000) ? 1: 0);
4097 #endif /* mc68020 */
4098 			mfb_point(addr + (x >> 5), x, pat, fp);
4099 
4100 			if ((s += c) >= 0) {
4101 				s -= d;
4102 				addr += ddy;
4103 			}
4104 
4105 			x += ddx;
4106 		}
4107 	} else {			/* case y */
4108 		lim = dy;
4109 		if (lpf)
4110 			lim++;
4111 		s = -dy;
4112 		d = dy << 1;
4113 		c = dx << 1;
4114 
4115 		for (i = lim; i > 0; i--) {
4116 #ifdef mc68020
4117 			asm(" rol.l	#1, d6 ");
4118 #else /* mc68020 */
4119 			pat = (pat << 1) | ((pat & 0x80000000) ? 1: 0);
4120 #endif /* mc68020 */
4121 			mfb_point(addr + (x >> 5), x, pat, fp);
4122 
4123 			if ((s += c) >= 0) {
4124 				s -= d;
4125 				x += ddx;
4126 			}
4127 
4128 			addr += ddy;
4129 		}
4130 	}
4131 
4132 	/* rotate pattern */
4133 	pat = fb->pat;
4134 
4135 #ifdef mc68020
4136 	asm("	move.l	(-8, fp), d0");
4137 	asm("	andi.l	#31, d0");
4138 	asm("	rol.l	d0, d6");
4139 #else /* mc68020 */
4140 	{
4141 		register int tmp;
4142 
4143 		tmp = lim & 31;
4144 		pat = (pat << tmp) | (pat >> (32 - tmp));
4145 	}
4146 #endif /* mc68020 */
4147 
4148 	fb->pat = pat;
4149 }
4150 
4151 void
4152 mem_to_mem(func, mapSrc, offSrc, widthSrc, mapDst, offDst, widthDst, sr, dp)
4153 int		func;
4154 struct fb_map	*mapSrc;
4155 int		offSrc;
4156 u_int		widthSrc;
4157 struct fb_map	*mapDst;
4158 int		offDst;
4159 u_int		widthDst;
4160 register lRectangle *sr;	/* source rectangle */
4161 register lPoint	 *dp;	/* destination point */
4162 {
4163 	register u_short *addrSrc;
4164 	register u_short *addrDst;
4165 
4166 	addrSrc = (u_short *)TypeAt(mapSrc, offSrc);
4167 	addrDst = (u_short *)TypeAt(mapDst, offDst);
4168 
4169 	if ((!((u_int)addrSrc & 3) && !(widthSrc & 1)) &&
4170 	    (!((u_int)addrDst & 3) && !(widthDst & 1))) {
4171 		switch (func) {
4172 
4173 		case BF_0:
4174 			mfb_clr_area32(dp->x, dp->y,
4175 			    sr->extent.x, sr->extent.y, addrDst, widthDst / 2);
4176 			break;
4177 		case BF_S:
4178 			mfb_copy_area32(addrSrc, addrDst,
4179 			    widthSrc / 2, widthDst / 2, sr, dp);
4180 			break;
4181 		case BF_D:
4182 			break;
4183 		case BF_SDX:
4184 			mfb_xor_area32(addrSrc, addrDst,
4185 			    widthSrc / 2, widthDst / 2, sr, dp);
4186 			break;
4187 		case BF_SDO:
4188 			mfb_or_area32(addrSrc, addrDst,
4189 			    widthSrc / 2, widthDst / 2, sr, dp);
4190 			break;
4191 		case BF_DI:
4192 			mfb_inv_area32(dp->x, dp->y,
4193 			    sr->extent.x, sr->extent.y, addrDst, widthDst / 2);
4194 			break;
4195 		case BF_SI:
4196 			mfb_copyinv_area32(addrSrc, addrDst,
4197 			    widthSrc / 2, widthDst / 2, sr, dp);
4198 			break;
4199 		case BF_1:
4200 			mfb_set_area32(dp->x, dp->y,
4201 			    sr->extent.x, sr->extent.y, addrDst, widthDst / 2);
4202 			break;
4203 		default:
4204 			mfb_general_area32(func, addrSrc, addrDst,
4205 			    widthSrc / 2, widthDst / 2, sr, dp);
4206 			break;
4207 		}
4208 	} else {
4209 		switch (func) {
4210 
4211 		case BF_0:
4212 			mfb_clr_area16(dp->x, dp->y,
4213 			    sr->extent.x, sr->extent.y, addrDst, widthDst);
4214 			break;
4215 		case BF_S:
4216 			mfb_copy_area16(addrSrc, addrDst,
4217 			    widthSrc, widthDst, sr, dp);
4218 			break;
4219 		case BF_D:
4220 			break;
4221 		case BF_SDX:
4222 			mfb_xor_area16(addrSrc, addrDst,
4223 			    widthSrc, widthDst, sr, dp);
4224 			break;
4225 		case BF_SDO:
4226 			mfb_or_area16(addrSrc, addrDst,
4227 			    widthSrc, widthDst, sr, dp);
4228 			break;
4229 		case BF_DI:
4230 			mfb_inv_area16(dp->x, dp->y,
4231 			    sr->extent.x, sr->extent.y, addrDst, widthDst);
4232 			break;
4233 		case BF_SI:
4234 			mfb_copyinv_area16(addrSrc, addrDst,
4235 			    widthSrc, widthDst, sr, dp);
4236 			break;
4237 		case BF_1:
4238 			mfb_set_area16(dp->x, dp->y,
4239 			    sr->extent.x, sr->extent.y, addrDst, widthDst);
4240 			break;
4241 		default:
4242 			mfb_general_area16(func, addrSrc, addrDst,
4243 			    widthSrc, widthDst, sr, dp);
4244 			break;
4245 		}
4246 	}
4247 }
4248 
4249 void
4250 mem_clear(func, map, offset, width, dr, mode)
4251 register int	func;
4252 struct fb_map	*map;
4253 int		offset;
4254 u_int		width;
4255 register lRectangle *dr;
4256 int		mode;
4257 {
4258 	u_short *addr;
4259 
4260 	if (!mode)
4261 		func >>= 2;
4262 	func &= 0x3;
4263 
4264 	addr = (u_short *)TypeAt(map, offset);
4265 
4266 	if (!((u_int)addr & 3) && !(width & 1)) {
4267 		switch (func) {
4268 
4269 		case 0:
4270 			mfb_clr_area32(dr->origin.x, dr->origin.y,
4271 			    dr->extent.x, dr->extent.y, addr, width / 2);
4272 			break;
4273 		case 2:
4274 			mfb_inv_area32(dr->origin.x, dr->origin.y,
4275 			    dr->extent.x, dr->extent.y, addr, width / 2);
4276 			break;
4277 		case 3:
4278 			mfb_set_area32(dr->origin.x, dr->origin.y,
4279 			    dr->extent.x, dr->extent.y, addr, width / 2);
4280 			break;
4281 		}
4282 	} else {
4283 		switch (func) {
4284 
4285 		case 0:
4286 			mfb_clr_area16(dr->origin.x, dr->origin.y,
4287 			    dr->extent.x, dr->extent.y, addr, width);
4288 			break;
4289 		case 2:
4290 			mfb_inv_area16(dr->origin.x, dr->origin.y,
4291 			    dr->extent.x, dr->extent.y, addr, width);
4292 			break;
4293 		case 3:
4294 			mfb_set_area16(dr->origin.x, dr->origin.y,
4295 			    dr->extent.x, dr->extent.y, addr, width);
4296 			break;
4297 		}
4298 	}
4299 }
4300 
4301 #ifdef CPU_SINGLE
4302 #define	VRAM_START(fb)		(((struct mfbdev *)(fb)->private)->vram_start)
4303 #define	VRAM_WIDTH(fb)		(((struct mfbdev *)(fb)->private)->vram_width)
4304 
4305 fbmem_rop_init(fb, func)
4306 struct fbdev	*fb;
4307 char	*func;
4308 {
4309 	fb->func = *func;
4310 }
4311 
4312 void
4313 fbmem_rop_winit(fb)
4314 struct fbdev	*fb;
4315 {
4316 }
4317 
4318 void
4319 fbmem_rop_copy(fb, sr, dp, mode, wmask)
4320 register struct fbdev	*fb;
4321 register lRectangle	*sr;	/* source rectangle */
4322 register lPoint		*dp;	/* destination point */
4323 {
4324 	if (!(wmask & 1)) {
4325 		return;
4326 	}
4327 
4328 	switch (fb->func) {
4329 	case BF_0:
4330 		mfb_clr_area32(dp->x, dp->y,
4331 		    sr->extent.x, sr->extent.y, VRAM_START(fb), VRAM_WIDTH(fb));
4332 		break;
4333 	case BF_S:
4334 		mfb_copy_area32(VRAM_START(fb), VRAM_START(fb),
4335 		    VRAM_WIDTH(fb), VRAM_WIDTH(fb), sr, dp);
4336 		break;
4337 	case BF_D:
4338 		break;
4339 	case BF_SDX:
4340 		mfb_xor_area32(VRAM_START(fb), VRAM_START(fb),
4341 		    VRAM_WIDTH(fb), VRAM_WIDTH(fb), sr, dp);
4342 		break;
4343 	case BF_SDO:
4344 		mfb_or_area32(VRAM_START(fb), VRAM_START(fb),
4345 		    VRAM_WIDTH(fb), VRAM_WIDTH(fb), sr, dp);
4346 		break;
4347 	case BF_DI:
4348 		mfb_inv_area32(dp->x, dp->y,
4349 		    sr->extent.x, sr->extent.y, VRAM_START(fb), VRAM_WIDTH(fb));
4350 		break;
4351 	case BF_SI:
4352 		mfb_copyinv_area32(VRAM_START(fb), VRAM_START(fb),
4353 		    VRAM_WIDTH(fb), VRAM_WIDTH(fb), sr, dp);
4354 		break;
4355 	case BF_1:
4356 		mfb_set_area32(dp->x, dp->y,
4357 		    sr->extent.x, sr->extent.y, VRAM_START(fb), VRAM_WIDTH(fb));
4358 		break;
4359 	default:
4360 		mfb_general_area32(fb->func, VRAM_START(fb), VRAM_START(fb),
4361 		    VRAM_WIDTH(fb), VRAM_WIDTH(fb), sr, dp);
4362 		break;
4363 	}
4364 }
4365 
4366 void
4367 fbmem_rop_read(fb, map, offset, width, sr, dp, rplane, wplane)
4368 register struct fbdev	*fb;
4369 struct fb_map	*map;
4370 u_int		offset;
4371 u_int		width;
4372 register lRectangle *sr;	/* source rectangle */
4373 register lPoint	*dp;	/* destination point */
4374 int		rplane;
4375 int		wplane;
4376 {
4377 	register u_short *addrDst;
4378 
4379 	addrDst = (u_short *)TypeAt(map, offset);
4380 
4381 	if (!((u_int)addrDst & 3) && !(width & 1)) {
4382 		switch (fb->funcvec[wplane]) {
4383 		case BF_0:
4384 			mfb_clr_area32(dp->x, dp->y,
4385 			    sr->extent.x, sr->extent.y, addrDst, width / 2);
4386 			break;
4387 		case BF_S:
4388 			mfb_copy_area32(VRAM_START(fb), addrDst,
4389 			    VRAM_WIDTH(fb), width / 2, sr, dp);
4390 			break;
4391 		case BF_D:
4392 			break;
4393 		case BF_SDX:
4394 			mfb_xor_area32(VRAM_START(fb), addrDst,
4395 			    VRAM_WIDTH(fb), width / 2, sr, dp);
4396 			break;
4397 		case BF_SDO:
4398 			mfb_or_area32(VRAM_START(fb), addrDst,
4399 			    VRAM_WIDTH(fb), width / 2, sr, dp);
4400 			break;
4401 		case BF_DI:
4402 			mfb_inv_area32(dp->x, dp->y,
4403 			    sr->extent.x, sr->extent.y, addrDst, width / 2);
4404 			break;
4405 		case BF_SI:
4406 			mfb_copyinv_area32(VRAM_START(fb), addrDst,
4407 			    VRAM_WIDTH(fb), width / 2, sr, dp);
4408 			break;
4409 		case BF_1:
4410 			mfb_set_area32(dp->x, dp->y,
4411 			    sr->extent.x, sr->extent.y, addrDst, width / 2);
4412 			break;
4413 		default:
4414 			mfb_general_area32(fb->funcvec[wplane], VRAM_START(fb),
4415 			    addrDst, VRAM_WIDTH(fb), width/2, sr, dp);
4416 			break;
4417 		}
4418 	} else {
4419 		switch (fb->funcvec[wplane]) {
4420 		case BF_0:
4421 			mfb_clr_area16(dp->x, dp->y,
4422 			    sr->extent.x, sr->extent.y, addrDst, width);
4423 			break;
4424 		case BF_S:
4425 			mfb_copy_area16(VRAM_START(fb), addrDst,
4426 			    VRAM_WIDTH(fb) * 2, width, sr, dp);
4427 			break;
4428 		case BF_D:
4429 			break;
4430 		case BF_SDX:
4431 			mfb_xor_area16(VRAM_START(fb), addrDst,
4432 			    VRAM_WIDTH(fb) * 2, width, sr, dp);
4433 			break;
4434 		case BF_SDO:
4435 			mfb_or_area16(VRAM_START(fb), addrDst,
4436 			    VRAM_WIDTH(fb) * 2, width, sr, dp);
4437 			break;
4438 		case BF_DI:
4439 			mfb_inv_area16(dp->x, dp->y,
4440 			    sr->extent.x, sr->extent.y, addrDst, width);
4441 			break;
4442 		case BF_SI:
4443 			mfb_copyinv_area16(VRAM_START(fb), addrDst,
4444 			    VRAM_WIDTH(fb) * 2, width, sr, dp);
4445 			break;
4446 		case BF_1:
4447 			mfb_set_area16(dp->x, dp->y,
4448 			    sr->extent.x, sr->extent.y, addrDst, width);
4449 			break;
4450 		default:
4451 			mfb_general_area16(fb->funcvec[wplane], VRAM_START(fb),
4452 			    addrDst, VRAM_WIDTH(fb)*2, width, sr, dp);
4453 			break;
4454 		}
4455 	}
4456 }
4457 
4458 void
4459 fbmem_rop_write(fb, map, offset, width, sr, dp, wmask)
4460 register struct fbdev *fb;
4461 struct fb_map	*map;
4462 int		offset;
4463 u_int		width;
4464 register lRectangle *sr;	/* source rectangle */
4465 register lPoint	*dp;	/* destination point */
4466 int		wmask;
4467 {
4468 	register u_short *addrSrc;
4469 
4470 	addrSrc = (u_short *)TypeAt(map, offset);
4471 
4472 	if (!(wmask & 1)) {
4473 		return;
4474 	}
4475 
4476 	if (!((u_int)addrSrc & 3) && !(width & 1)) {
4477 		switch (fb->funcvec[0]) {
4478 
4479 		case BF_0:
4480 			mfb_clr_area32(dp->x, dp->y,
4481 			    sr->extent.x, sr->extent.y,
4482 			    VRAM_START(fb), VRAM_WIDTH(fb));
4483 			break;
4484 		case BF_S:
4485 			mfb_copy_area32(addrSrc, VRAM_START(fb),
4486 			    width / 2, VRAM_WIDTH(fb), sr, dp);
4487 			break;
4488 		case BF_D:
4489 			break;
4490 		case BF_SDX:
4491 			mfb_xor_area32(addrSrc, VRAM_START(fb),
4492 			    width / 2, VRAM_WIDTH(fb), sr, dp);
4493 			break;
4494 		case BF_SDO:
4495 			mfb_or_area32(addrSrc, VRAM_START(fb),
4496 			    width / 2, VRAM_WIDTH(fb), sr, dp);
4497 			break;
4498 		case BF_DI:
4499 			mfb_inv_area32(dp->x, dp->y,
4500 			    sr->extent.x, sr->extent.y,
4501 			    VRAM_START(fb), VRAM_WIDTH(fb));
4502 			break;
4503 		case BF_SI:
4504 			mfb_copyinv_area32(addrSrc, VRAM_START(fb),
4505 			    width / 2, VRAM_WIDTH(fb), sr, dp);
4506 			break;
4507 		case BF_1:
4508 			mfb_set_area32(dp->x, dp->y,
4509 			    sr->extent.x, sr->extent.y,
4510 			    VRAM_START(fb), VRAM_WIDTH(fb));
4511 			break;
4512 		default:
4513 			mfb_general_area32(fb->funcvec[0], addrSrc,
4514 			    VRAM_START(fb), width / 2, VRAM_WIDTH(fb), sr, dp);
4515 			break;
4516 		}
4517 	} else {
4518 		switch (fb->funcvec[0]) {
4519 		case BF_0:
4520 			mfb_clr_area32(dp->x, dp->y,
4521 			    sr->extent.x, sr->extent.y,
4522 			    VRAM_START(fb), VRAM_WIDTH(fb));
4523 			break;
4524 		case BF_S:
4525 			mfb_copy_area16(addrSrc, VRAM_START(fb),
4526 			    width, VRAM_WIDTH(fb) * 2, sr, dp);
4527 			break;
4528 		case BF_D:
4529 			break;
4530 		case BF_SDX:
4531 			mfb_xor_area16(addrSrc, VRAM_START(fb),
4532 			    width, VRAM_WIDTH(fb) * 2, sr, dp);
4533 			break;
4534 		case BF_SDO:
4535 			mfb_or_area16(addrSrc, VRAM_START(fb),
4536 			    width, VRAM_WIDTH(fb) * 2, sr, dp);
4537 			break;
4538 		case BF_DI:
4539 			mfb_inv_area32(dp->x, dp->y,
4540 			    sr->extent.x, sr->extent.y,
4541 			    VRAM_START(fb), VRAM_WIDTH(fb));
4542 			break;
4543 		case BF_SI:
4544 			mfb_copyinv_area16(addrSrc, VRAM_START(fb),
4545 			    width, VRAM_WIDTH(fb) * 2, sr, dp);
4546 			break;
4547 		case BF_1:
4548 			mfb_set_area32(dp->x, dp->y,
4549 			    sr->extent.x, sr->extent.y,
4550 			    VRAM_START(fb), VRAM_WIDTH(fb));
4551 			break;
4552 		default:
4553 			mfb_general_area16(fb->funcvec[0], addrSrc,
4554 			    VRAM_START(fb), width, VRAM_WIDTH(fb) * 2, sr, dp);
4555 			break;
4556 		}
4557 	}
4558 }
4559 
4560 void
4561 fbmem_rop_cinit(fb, wplane, sw)
4562 struct fbdev	*fb;
4563 {
4564 	fb->Pmask = wplane;
4565 	fb->Mode = sw;
4566 }
4567 
4568 void
4569 fbmem_rop_clear(fb, dr)
4570 register struct fbdev *fb;
4571 register lRectangle *dr;
4572 {
4573 	register int func;
4574 
4575 	if (!(fb->Pmask & 1)) {
4576 		return;
4577 	}
4578 	func = fb->funcvec[0];
4579 	if (!fb->Mode)
4580 		func >>= 2;
4581 	func &= 3;
4582 
4583 	switch (func) {
4584 	case 0:
4585 		mfb_clr_area32(dr->origin.x, dr->origin.y,
4586 		    dr->extent.x, dr->extent.y, VRAM_START(fb), VRAM_WIDTH(fb));
4587 		break;
4588 	case 2:
4589 		mfb_inv_area32(dr->origin.x, dr->origin.y,
4590 		    dr->extent.x, dr->extent.y, VRAM_START(fb), VRAM_WIDTH(fb));
4591 		break;
4592 	case 3:
4593 		mfb_set_area32(dr->origin.x, dr->origin.y,
4594 		    dr->extent.x, dr->extent.y, VRAM_START(fb), VRAM_WIDTH(fb));
4595 		break;
4596 	}
4597 }
4598 
4599 void
4600 fbmem_rop_vect(fb, clip, ropf, forc, auxc, transp, wplane,
4601 						np, ps, lptn, lpf, joint)
4602 register struct fbdev *fb;
4603 register lRectangle *clip;
4604 int ropf, forc, auxc, transp;
4605 register int np;
4606 register lPoint *ps;
4607 register u_int lptn;
4608 {
4609 	lPoint p0, p1;
4610 	register void (*line_func)();
4611 	register int func;
4612 
4613 	if (!(wplane & 1))
4614 		return;
4615 	linerop(fb, ropf, forc, auxc, transp);
4616 	func = fb->funcvec[0];
4617 	if (lptn == 0xffffffff || lptn == 0) {
4618 		if (!lptn)
4619 			func >>= 2;
4620 		switch (func & 3) {
4621 		case 0:
4622 			line_func = mfb_clrvector32;
4623 			break;
4624 		case 1:
4625 			return;
4626 		case 2:
4627 			line_func = mfb_invvector32;
4628 			break;
4629 		default:
4630 			line_func = mfb_setvector32;
4631 			break;
4632 		}
4633 	} else
4634 		line_func = mfb_vector32;
4635 	if (joint) {
4636 		fb->pat = lptn;
4637 		p0 = *ps++;
4638 		np--;
4639 		if (clip) {
4640 			while (--np > 0) {
4641 				p1 = *ps;
4642 				if (lineclip(&p0, &p1, clip)) {
4643 					(*line_func)(fb,
4644 						VRAM_START(fb), VRAM_WIDTH(fb),
4645 						&p0, &p1,
4646 						ps->x != p1.x || ps->y != p1.y);
4647 				}
4648 				p0 = *ps++;
4649 			}
4650 			p1 = *ps;
4651 			if (lineclip(&p0, &p1, clip)) {
4652 				(*line_func)(fb, VRAM_START(fb), VRAM_WIDTH(fb),
4653 					&p0, &p1,
4654 					ps->x != p1.x || ps->y != p1.y || lpf);
4655 			}
4656 		} else {
4657 			while (--np > 0) {
4658 				p1 = *ps;
4659 				(*line_func)(fb, VRAM_START(fb), VRAM_WIDTH(fb),
4660 					&p0, &p1, 0);
4661 				p0 = *ps++;
4662 			}
4663 			p1 = *ps;
4664 			(*line_func)(fb, VRAM_START(fb), VRAM_WIDTH(fb),
4665 				&p0, &p1, lpf);
4666 		}
4667 	} else {
4668 		np >>= 1;
4669 		if (lpf) {
4670 			if (clip) {
4671 				while (--np >= 0) {
4672 					p0 = *ps++;
4673 					p1 = *ps++;
4674 					fb->pat = lptn;
4675 					if (lineclip(&p0, &p1, clip)) {
4676 						(*line_func)(fb,
4677 							VRAM_START(fb),
4678 							VRAM_WIDTH(fb),
4679 							&p0, &p1, 1);
4680 					}
4681 				}
4682 			} else {
4683 				while (--np >= 0) {
4684 					p0 = *ps++;
4685 					p1 = *ps++;
4686 					fb->pat = lptn;
4687 					(*line_func)(fb,
4688 						VRAM_START(fb), VRAM_WIDTH(fb),
4689 						&p0, &p1, 1);
4690 				}
4691 			}
4692 		} else {
4693 			if (clip) {
4694 				while (--np >= 0) {
4695 					p0 = *ps++;
4696 					p1 = *ps;
4697 					fb->pat = lptn;
4698 					if (lineclip(&p0, &p1, clip)) {
4699 						(*line_func)(fb,
4700 							VRAM_START(fb),
4701 							VRAM_WIDTH(fb),
4702 							&p0, &p1,
4703 							ps->x != p1.x ||
4704 							ps->y != p1.y);
4705 					}
4706 					ps++;
4707 				}
4708 			} else {
4709 				while (--np >= 0) {
4710 					p0 = *ps++;
4711 					p1 = *ps++;
4712 					fb->pat = lptn;
4713 					(*line_func)(fb,
4714 						VRAM_START(fb), VRAM_WIDTH(fb),
4715 						&p0, &p1, 0);
4716 				}
4717 			}
4718 		}
4719 	}
4720 }
4721 
4722 #define	mfb_clrdot32(fb, addr, ddy, p) \
4723 { *((u_int *)addr + (p->y * ddy) + (p->x >> 5)) &= mfbrmask32[p->x & 0x1f]; }
4724 
4725 #define	mfb_invdot32(fb, addr, ddy, p) \
4726 { *((u_int *)addr + (p->y * ddy) + (p->x >> 5)) ^= mfbmask32[p->x & 0x1f]; }
4727 
4728 #define	mfb_setdot32(fb, addr, ddy, p) \
4729 { *((u_int *)addr + (p->y * ddy) + (p->x >> 5)) |= mfbmask32[p->x & 0x1f]; }
4730 
4731 void
4732 fbmem_rop_dot_BF_clr(fb, clip, np, ps)
4733 register struct fbdev *fb;
4734 lRectangle *clip;
4735 register int np;
4736 register lPoint *ps;
4737 {
4738 	register int x0, y0, x1, y1;
4739 
4740 	if (clip) {
4741 		x0 = clip->origin.x;
4742 		y0 = clip->origin.y;
4743 		x1 = x0 + clip->extent.x - 1;
4744 		y1 = y0 + clip->extent.y - 1;
4745 		if (x1 <= 0 || y1 <= 0) return;
4746 
4747 		while (np-- > 0) {
4748 			if ((ps->x >= x0) && (ps->y >= y0)
4749 			 && (ps->x <= x1) && (ps->y <= y1))
4750 				mfb_clrdot32(fb, VRAM_START(fb), VRAM_WIDTH(fb), ps);
4751 			ps++;
4752 		}
4753 	} else {
4754 		while (np-- > 0) {
4755 			mfb_clrdot32(fb, VRAM_START(fb), VRAM_WIDTH(fb), ps);
4756 			ps++;
4757 		}
4758 	}
4759 }
4760 
4761 void
4762 fbmem_rop_dot_BF_inv(fb, clip, np, ps)
4763 register struct fbdev *fb;
4764 lRectangle *clip;
4765 register int np;
4766 register lPoint *ps;
4767 {
4768 	register int x0, y0, x1, y1;
4769 
4770 	if (clip) {
4771 		x0 = clip->origin.x;
4772 		y0 = clip->origin.y;
4773 		x1 = x0 + clip->extent.x - 1;
4774 		y1 = y0 + clip->extent.y - 1;
4775 		if (x1 <= 0 || y1 <= 0) return;
4776 
4777 		while (np-- > 0) {
4778 			if ((ps->x >= x0) && (ps->y >= y0)
4779 			 && (ps->x <= x1) && (ps->y <= y1))
4780 				mfb_invdot32(fb, VRAM_START(fb), VRAM_WIDTH(fb), ps);
4781 			ps++;
4782 		}
4783 	} else {
4784 		while (np-- > 0) {
4785 			mfb_invdot32(fb, VRAM_START(fb), VRAM_WIDTH(fb), ps);
4786 			ps++;
4787 		}
4788 	}
4789 }
4790 
4791 void
4792 fbmem_rop_dot(fb, clip, ropf, forc, auxc, transp, wplane, np, ps)
4793 register struct fbdev *fb;
4794 lRectangle *clip;
4795 int ropf, forc, auxc, transp;
4796 register int np;
4797 register lPoint *ps;
4798 {
4799 	register int x0, y0, x1, y1;
4800 
4801 	if (!(wplane & 1))
4802 		return;
4803 
4804 	linerop(fb, ropf, forc, auxc, transp);
4805 
4806 	switch (fb->funcvec[0] & 3) {
4807 	case 1:
4808 		break;
4809 
4810 	case 0:
4811 		fbmem_rop_dot_BF_clr(fb, clip, np, ps);
4812 		break;
4813 	case 2:
4814 		fbmem_rop_dot_BF_inv(fb, clip, np, ps);
4815 		break;
4816 
4817 	default:
4818 		if (clip) {
4819 			x0 = clip->origin.x;
4820 			y0 = clip->origin.y;
4821 			x1 = x0 + clip->extent.x - 1;
4822 			y1 = y0 + clip->extent.y - 1;
4823 			if (x1 <= 0 || y1 <= 0) return;
4824 
4825 			while (np-- > 0) {
4826 				if ((ps->x >= x0) && (ps->y >= y0)
4827 				 && (ps->x <= x1) && (ps->y <= y1))
4828 					mfb_setdot32(fb,
4829 					    VRAM_START(fb), VRAM_WIDTH(fb), ps);
4830 				ps++;
4831 			}
4832 		} else {
4833 			while (np-- > 0) {
4834 				mfb_setdot32(fb,
4835 				    VRAM_START(fb), VRAM_WIDTH(fb), ps);
4836 				ps++;
4837 			}
4838 		}
4839 	}
4840 }
4841 
4842 #ifdef notdef
4843 
4844 #ifndef mfb_clrdot32
4845 void
4846 mfb_clrdot32(fb, addr, ddy, p)
4847 struct fbdev	*fb;
4848 register unsigned int *addr;
4849 register int ddy;
4850 register lPoint *p;
4851 {
4852 	addr += (p->y * ddy) + (p->x >> 5);
4853 	*addr &= mfbrmask32[p->x & 0x1f];
4854 }
4855 #endif /* ! mfb_clrdot32 */
4856 
4857 #ifndef mfb_invdot32
4858 void
4859 mfb_invdot32(fb, addr, ddy, p)
4860 struct fbdev	*fb;
4861 register unsigned int *addr;
4862 register int	ddy;
4863 register lPoint *p;
4864 {
4865 	addr += (p->y * ddy) + (p->x >> 5);
4866 	*addr ^= mfbmask32[p->x & 0x1f];
4867 }
4868 #endif /* ! mfb_invdot32 */
4869 
4870 #ifndef mfb_setdot32
4871 void
4872 mfb_setdot32(fb, addr, ddy, p)
4873 struct fbdev	*fb;
4874 register unsigned int *addr;
4875 register int ddy;
4876 register lPoint *p;
4877 {
4878 	addr += (p->y * ddy) + (p->x >> 5);
4879 	*addr |= mfbmask32[p->x & 0x1f];
4880 }
4881 #endif /* ! mfb_setdot32 */
4882 #endif
4883 
4884 #endif /* CPU_SINGLE */
4885