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