Initial commit
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / xf4bpp / ppcPixFS.c
blobf24168bb0e29940eb0fdd9da45014bad95783e76
1 /*
2 * Copyright IBM Corporation 1987,1988,1989
4 * All Rights Reserved
6 * Permission to use, copy, modify, and distribute this software and its
7 * documentation for any purpose and without fee is hereby granted,
8 * provided that the above copyright notice appear in all copies and that
9 * both that copyright notice and this permission notice appear in
10 * supporting documentation, and that the name of IBM not be
11 * used in advertising or publicity pertaining to distribution of the
12 * software without specific, written prior permission.
14 * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16 * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20 * SOFTWARE.
24 /******************************************************************
25 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
27 All Rights Reserved
29 Permission to use, copy, modify, and distribute this software and its
30 documentation for any purpose and without fee is hereby granted,
31 provided that the above copyright notice appear in all copies and that
32 both that copyright notice and this permission notice appear in
33 supporting documentation, and that the name of Digital not be
34 used in advertising or publicity pertaining to distribution of the
35 software without specific, written prior permission.
37 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43 SOFTWARE.
45 ******************************************************************/
47 #ifdef HAVE_XORG_CONFIG_H
48 #include <xorg-config.h>
49 #endif
51 #include "xf4bpp.h"
52 #include "mfbmap.h"
53 #include "mfb.h"
54 #include "maskbits.h"
55 #include "mi.h"
56 #include "mispans.h"
57 #include "ppcGCstr.h"
58 #include "ppcSpMcro.h"
59 #include "vgaVideo.h"
60 #include "ibmTrace.h"
62 #define LeftMostBitInScreenLongWord SCRLEFT( 0xFFFFFFFF, 31 )
64 /* GJA -- copied this from VGA */
65 #define SCRLEFT8(lw, n) ( (unsigned char) (((unsigned char) lw) << (n)) )
66 #define SCRRIGHT8(lw, n) ( (unsigned char) (((unsigned char)lw) >> (n)) )
68 ********** ********** ********** ********** ********** ********** **********
69 these routines all clip. they assume that anything that has called
70 them has already translated the points (i.e. pGC->miTranslate is
71 non-zero, which is howit gets set in mfbCreateGC().)
73 the number of new scnalines created by clipping ==
74 MaxRectsPerBand * nSpans.
75 ********** ********** ********** ********** ********** ********** **********
77 /* A mod definition that goes smoothly into the negative.
79 static int
80 modulo
82 int n1,
83 int n2
86 int tmp;
87 if ( n1 < 0 ) {
88 tmp = (-n1) % n2;
89 if ( tmp == 0 ) {
90 return 0;
91 } else {
92 return n2 - tmp;
94 } else {
95 return n1 % n2;
99 void
100 xf4bppSolidPixmapFS( pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted )
101 DrawablePtr pDrawable ;
102 GCPtr pGC ;
103 int nInit ; /* number of spans to fill */
104 DDXPointPtr pptInit ; /* pointer to list of start points */
105 int *pwidthInit ; /* pointer to list of n widths */
106 int fSorted ;
108 register unsigned long int pm, npm ;
109 register unsigned long int fg ;
110 register int alu ;
111 /* next three parameters are post-clip */
112 int n ; /* number of spans to fill */
113 register DDXPointPtr ppt ; /* pointer to list of start points */
114 register int *pwidth ; /* pointer to list of n widths */
115 register unsigned char *addrl ; /* pointer to current longword in bitmap */
116 int i ;
117 int *pwidthFree ; /* copies of the pointers to free */
118 DDXPointPtr pptFree ;
120 TRACE(("xf4bppSolidPixmapFS(pDrawable=0x%x, pGC=0x%x, nInit=%d, pptInit=0x%x, pwidthInit=0x%x, fSorted=%d)\n", pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)) ;
122 if ( pDrawable->type != DRAWABLE_PIXMAP ) {
123 ErrorF("xf4bppSolidPixmapFS: drawable is not a pixmap\n") ;
124 return ;
127 if ( ( alu = ( (ppcPrivGC *) pGC->devPrivates[mfbGetGCPrivateIndex()].ptr )->colorRrop.alu ) == GXnoop )
128 return ;
130 n = nInit * miFindMaxBand(pGC->pCompositeClip) ;
131 if ( !( pwidthFree = (int *) ALLOCATE_LOCAL( n * sizeof( int ) ) ) )
132 return ;
133 pwidth = pwidthFree ;
135 if ( !( pptFree = (DDXPointRec *)
136 ALLOCATE_LOCAL( n * sizeof( DDXPointRec ) ) ) ) {
137 DEALLOCATE_LOCAL( pwidth ) ;
138 return ;
140 ppt = pptFree ;
142 n = miClipSpans( pGC->pCompositeClip, pptInit, pwidthInit, nInit,
143 ppt, pwidth, fSorted ) ;
145 pm = ( (ppcPrivGC *) pGC->devPrivates[mfbGetGCPrivateIndex()].ptr )->colorRrop.planemask ;
146 fg = ( (ppcPrivGC *) pGC->devPrivates[mfbGetGCPrivateIndex()].ptr )->colorRrop.fgPixel ;
147 npm = ( ~ pm ) & ( ( 1 << pDrawable->depth ) - 1 ) ;
149 for ( ; n-- ; ppt++, pwidth++ ) {
150 addrl = ( (unsigned char *) ( ( (PixmapPtr) pDrawable )->devPrivate.ptr ) )
151 + ( ppt->y * ( (int) ( ( (PixmapPtr) pDrawable )->devKind ) ) )
152 + ppt->x ;
153 for ( i = *pwidth ; i-- ; addrl++ )
155 unsigned _p;
156 DoRop( _p, alu, fg, *addrl );
157 *addrl = ( *addrl & npm ) | ( pm & _p ) ;
159 #ifdef notdef /* PURDUE */
160 *addrl = ( *addrl & npm ) | ( pm & DoRop( alu, fg, *addrl ) ) ;
161 #endif /* PURDUE */
163 DEALLOCATE_LOCAL( pptFree ) ;
164 DEALLOCATE_LOCAL( pwidthFree ) ;
165 return ;
168 /* GJA -- copied from vgaStipple.c */
169 static unsigned char
170 vgagetbits
172 register const int x,
173 register const unsigned int patternWidth,
174 register const unsigned char * const lineptr
177 register unsigned char bits ;
178 register const unsigned char *cptr ;
179 register int shift ;
180 register int wrap ;
182 cptr = lineptr + ( x >> 3 ) ;
183 bits = *cptr ;
184 if ((shift = x & 7))
185 bits = SCRLEFT8( bits, shift ) | SCRRIGHT8( cptr[1], ( 8 - shift ) ) ;
186 if ( ( wrap = x + 8 - patternWidth ) > 0 ) {
187 bits &= SCRLEFT8( 0xFF, wrap ) ;
188 bits |= SCRRIGHT8( *lineptr, ( 8 - wrap ) ) ;
191 /* GJA -- Handle extraction of 8 bits from < 8 bits wide stipple.
192 * I duplicated case 4,5,6,7 to give the compiler a chance to optimize.
194 switch (patternWidth) {
195 case 1: /* Not really useful. */
196 bits &= ~SCRRIGHT8(0xFF,1);
197 bits |= SCRRIGHT8(bits,1);
198 bits |= SCRRIGHT8(bits,2);
199 bits |= SCRRIGHT8(bits,4);
200 break;
201 case 2:
202 bits &= ~SCRRIGHT8(0xFF,2);
203 bits |= SCRRIGHT8(bits,2); bits |= SCRRIGHT8(bits,4); break;
204 case 3:
205 bits &= ~SCRRIGHT8(0xFF,3);
206 bits |= (SCRRIGHT8(bits,3) | SCRRIGHT8(bits,6)); break;
207 case 4:
208 bits = (bits & ~SCRRIGHT8(0xFF,4)) | SCRRIGHT8(bits,4); break;
209 case 5:
210 bits = (bits & ~SCRRIGHT8(0xFF,5)) | SCRRIGHT8(bits,5); break;
211 case 6:
212 bits = (bits & ~SCRRIGHT8(0xFF,6)) | SCRRIGHT8(bits,6); break;
213 case 7:
214 bits = (bits & ~SCRRIGHT8(0xFF,7)) | SCRRIGHT8(bits,7); break;
215 default:
217 /* Do nothing, of course */
220 return bits ;
223 void
224 xf4bppStipplePixmapFS( pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted )
225 register DrawablePtr pDrawable ;
226 GC *pGC ;
227 int nInit ; /* number of spans to fill */
228 DDXPointPtr pptInit ; /* pointer to list of start points */
229 int *pwidthInit ; /* pointer to list of n widths */
230 int fSorted ;
232 register unsigned char *pdst ; /* pointer to current word in bitmap */
233 register unsigned long int pm, npm ;
234 register unsigned long int fg ;
235 register int alu ;
236 /* next three parameters are post-clip */
237 int n ; /* number of spans to fill */
238 register DDXPointPtr ppt ; /* pointer to list of start points */
239 register int *pwidth ; /* pointer to list of n widths */
240 PixmapPtr pTile ; /* pointer to tile we want to fill with */
241 int width, x, xSrc, ySrc ;
242 int tlwidth, tileWidth ;
243 unsigned char *psrcT ;
244 int *pwidthFree ; /* copies of the pointers to free */
245 DDXPointPtr pptFree ;
246 int xoff, count, stip, i ;
248 TRACE(("xf4bppStipplePixmapFS(pDrawable=0x%x, pGC=0x%x, nInit=%d, pptInit=0x%x, pwidthInit=0x%x, fSorted=%d)\n",
249 pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)) ;
251 if ( pDrawable->type != DRAWABLE_PIXMAP ) {
252 ErrorF( "xf4bppStippleWindowFS: drawable is not a pixmap\n") ;
253 return ;
255 if ( pGC->stipple->drawable.depth != 1 ) {
256 ErrorF( "ppcStippleFS: bad depth\ntype = %d, depth = %d\n",
257 pDrawable->type, pGC->stipple->drawable.depth ) ;
258 return ;
261 if ( ( alu = ( (ppcPrivGC *) pGC->devPrivates[mfbGetGCPrivateIndex()].ptr )->colorRrop.alu ) == GXnoop )
262 return ;
264 SETSPANPTRS( nInit, n, pwidthInit, pwidthFree, pptInit,
265 pptFree, pwidth, ppt, fSorted ) ;
267 pm = ( (ppcPrivGC *) pGC->devPrivates[mfbGetGCPrivateIndex()].ptr )->colorRrop.planemask ;
268 fg = ( (ppcPrivGC *) pGC->devPrivates[mfbGetGCPrivateIndex()].ptr )->colorRrop.fgPixel ;
270 pTile = pGC->stipple ;
271 tlwidth = pTile->devKind ;
273 tileWidth = pTile->drawable.width ;
275 npm = ( ~ pm ) & ( ( 1 << pDrawable->depth ) - 1 ) ;
277 /* this replaces rotating the stipple. Instead, we just adjust the offset
278 * at which we start grabbing bits from the stipple */
279 xSrc = pGC->patOrg.x + pDrawable->x;
280 ySrc = pGC->patOrg.y + pDrawable->y;
282 while ( n-- ) {
283 pdst = ( (unsigned char *) ( (PixmapPtr) pDrawable )->devPrivate.ptr )
284 + ( ppt->y * ( (int) ( ( (PixmapPtr) pDrawable )->devKind ) ) )
285 + ppt->x ;
286 psrcT = (unsigned char *)pTile->devPrivate.ptr
287 + ( modulo( ppt->y - ySrc, pTile->drawable.height ) * tlwidth ) ;
288 x = ppt->x ;
290 xoff = modulo( x - xSrc, tileWidth) ;
291 for ( width = *pwidth ; width ; width -= count, xoff+=count ) {
293 if ( xoff >= tileWidth ) xoff -= tileWidth;
295 if ( width < 8 )
296 count = width;
297 else
298 count = 8;
300 stip = vgagetbits( xoff, tileWidth, psrcT ) ;
302 for ( i = count ; i-- ; ) {
303 if ( stip & 128 )
305 unsigned _p;
306 DoRop( _p, alu, fg, *pdst ) ;
307 *pdst = ( *pdst & npm ) | ( pm & _p ) ;
309 #ifdef notdef /* PURDUE */
310 *pdst = ( *pdst & npm ) | ( pm & DoRop( alu, fg, *pdst ) ) ;
311 #endif /* PURDUE */
312 pdst++ ;
313 stip = SCRLEFT( stip, 1 ) ;
316 ppt++ ;
317 pwidth++ ;
319 DEALLOCATE_LOCAL( pptFree ) ;
320 DEALLOCATE_LOCAL( pwidthFree ) ;
321 return ;
324 void
325 xf4bppOpStipplePixmapFS( pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted )
326 DrawablePtr pDrawable ;
327 GC *pGC ;
328 int nInit ; /* number of spans to fill */
329 DDXPointPtr pptInit ; /* pointer to list of start points */
330 int *pwidthInit ; /* pointer to list of n widths */
331 int fSorted ;
333 register unsigned char *pdst ; /* pointer to current word in bitmap */
334 register unsigned long int pm, npm ;
335 register unsigned long int fg, bg ;
336 register int alu ;
337 /* next three parameters are post-clip */
338 int n ; /* number of spans to fill */
339 register DDXPointPtr ppt ; /* pointer to list of start points */
340 register int *pwidth ; /* pointer to list of n widths */
341 PixmapPtr pTile ; /* pointer to tile we want to fill with */
342 int width ;
343 int xSrc, ySrc ;
344 int tlwidth, tileWidth ;
345 unsigned char *psrcT ;
346 int *pwidthFree ; /* copies of the pointers to free */
347 DDXPointPtr pptFree ;
348 int xoff, count, stip, i ;
350 TRACE( ( "xf4bppOpStipplePixmapFS(pDrawable=0x%x,pGC=0x%x,nInit=%d,pptInit=0x%x,pwidthInit=0x%x,fSorted=%d)\n",
351 pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted ) ) ;
353 if ( pGC->stipple->drawable.depth != 1 ) {
354 ErrorF( "xf4bppOpStipplePixmapFS: bad depth\ntype = %d, depth = %d\n",
355 pDrawable->type, pGC->stipple->drawable.depth ) ;
356 return ;
359 if ( ( alu = ( (ppcPrivGC *) pGC->devPrivates[mfbGetGCPrivateIndex()].ptr )->colorRrop.alu ) == GXnoop )
360 return ;
362 SETSPANPTRS( nInit, n, pwidthInit, pwidthFree, pptInit,
363 pptFree, pwidth, ppt, fSorted ) ;
365 fg = ( (ppcPrivGC *) pGC->devPrivates[mfbGetGCPrivateIndex()].ptr )->colorRrop.fgPixel ;
366 bg = ( (ppcPrivGC *) pGC->devPrivates[mfbGetGCPrivateIndex()].ptr )->colorRrop.bgPixel ;
367 pm = ( (ppcPrivGC *) pGC->devPrivates[mfbGetGCPrivateIndex()].ptr )->colorRrop.planemask ;
368 npm = ( ~ pm ) & ( ( 1 << pDrawable->depth ) - 1 ) ;
370 pTile = pGC->stipple ;
371 tlwidth = pTile->devKind ;
372 tileWidth = pTile->drawable.width ;
374 xSrc = pGC->patOrg.x + pDrawable->x;
375 ySrc = pGC->patOrg.y + pDrawable->y;
377 /* this replaces rotating the stipple. Instead, we just adjust the offset
378 * at which we start grabbing bits from the stipple */
379 for ( ; n-- ; ppt++, pwidth++ ) {
380 pdst = ( (unsigned char *) ( (PixmapPtr) pDrawable )->devPrivate.ptr )
381 + ( ppt->y * ( (int) ( (PixmapPtr) pDrawable )->devKind ) )
382 + ppt->x ;
383 psrcT = (unsigned char *)pTile->devPrivate.ptr
384 + ( modulo( ppt->y - ySrc, pTile->drawable.height ) * tlwidth ) ;
386 xoff = modulo( ppt->x - xSrc, tileWidth) ;
388 for ( width = *pwidth ; width ; width -= count, xoff+=count ) {
390 if ( xoff >= tileWidth ) xoff -= tileWidth;
392 if ( width < 8 )
393 count = width;
394 else
395 count = 8;
397 stip = vgagetbits( xoff, tileWidth, psrcT ) ;
398 for ( i = count ; i-- ; pdst++, stip = SCRLEFT( stip, 1 ) )
399 if ( stip & 128 )
401 unsigned _p;
402 DoRop( _p, alu, fg, *pdst ) ;
403 *pdst = ( *pdst & npm ) | ( pm & _p ) ;
405 #ifdef notdef /* PURDUE */
406 *pdst = ( *pdst & npm ) | ( pm & DoRop( alu, fg, *pdst ) ) ;
407 #endif /* PURDUE */
408 else
410 unsigned _p;
411 DoRop( _p, alu, bg, *pdst ) ;
412 *pdst = ( *pdst & npm ) | ( pm & _p ) ;
414 #ifdef notdef /* PURDUE */
415 *pdst = ( *pdst & npm ) | ( pm & DoRop( alu, bg, *pdst ) ) ;
416 #endif /* PURDUE */
419 DEALLOCATE_LOCAL( pptFree ) ;
420 DEALLOCATE_LOCAL( pwidthFree ) ;
421 return ;
424 void
425 xf4bppTilePixmapFS( pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted )
426 register DrawablePtr pDrawable ;
427 GC *pGC ;
428 int nInit ; /* number of spans to fill */
429 DDXPointPtr pptInit ; /* pointer to list of start points */
430 int *pwidthInit ; /* pointer to list of n widths */
431 int fSorted ;
433 register DDXPointPtr ppt ; /* pointer to list of start points */
434 register int *pwidth ; /* pointer to list of n widths */
435 register unsigned char *pdst ; /* pointer to current word in bitmap */
436 register unsigned char *psrc ; /* pointer to current word in tile */
437 register PixmapPtr pTile ; /* pointer to tile we want to fill with */
438 int i ;
439 int alu ;
440 unsigned char pm, npm ;
441 /* next three parameters are post-clip */
442 int n ; /* number of spans to fill */
443 int tileWidth ;
444 int xSrc, ySrc;
445 unsigned char *psrcT ;
446 int *pwidthFree ; /* copies of the pointers to free */
447 DDXPointPtr pptFree ;
449 TRACE( ( "ppcTileFS(pDrawable=0x%x,pGC=0x%x,nInit=%d,pptInit=0x%x,pwidthInit=0x%x,fSorted=%d)\n",
450 pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted ) ) ;
452 if ( ( pDrawable->depth == 1 ) && ( pDrawable->type == DRAWABLE_PIXMAP ) ) {
453 mfbTileFS( pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted ) ;
454 return ;
456 if ( !xf4bppDepthOK( pDrawable, pGC->tile.pixmap->drawable.depth ) ) {
457 ErrorF( "ppcTileFS: bad depth\ntype = %d, depth = %d\n",
458 pDrawable->type, pDrawable->depth) ;
459 return ;
462 if ( ( alu = ( (ppcPrivGC *) pGC->devPrivates[mfbGetGCPrivateIndex()].ptr )->colorRrop.alu ) == GXnoop )
463 return ;
465 SETSPANPTRS( nInit, n, pwidthInit, pwidthFree, pptInit,
466 pptFree, pwidth, ppt, fSorted ) ;
468 /* the following code is for 8 bits per pixel addressable memory only */
469 pm = ( (ppcPrivGC *) pGC->devPrivates[mfbGetGCPrivateIndex()].ptr )->colorRrop.planemask ;
470 npm = ( ~ pm ) & ( ( 1 << pDrawable->depth ) - 1 ) ;
471 pTile = pGC->tile.pixmap ;
472 tileWidth = pTile->drawable.width ;
474 xSrc = pGC->patOrg.x + pDrawable->x;
475 ySrc = pGC->patOrg.y + pDrawable->y;
476 /* this replaces rotating the tile. Instead we just adjust the offset
477 * at which we start grabbing bits from the tile */
478 for ( ; n-- ; ppt++, pwidth++ ) {
479 pdst = ( (unsigned char *) ( (PixmapPtr) pDrawable )->devPrivate.ptr )
480 + ( ppt->y * ( (int) ( (PixmapPtr) pDrawable )->devKind ) )
481 + ppt->x ;
482 psrcT = (unsigned char *) pTile->devPrivate.ptr
483 + ( modulo( ppt->y - ySrc, pTile->drawable.height) * pTile->devKind ) ;
485 psrc = psrcT + modulo( ppt->x - xSrc, tileWidth ) ;
486 for ( i = *pwidth ; i-- ; pdst++, psrc++ ) {
487 if ( psrc >= ( psrcT + tileWidth ) )
488 psrc = psrcT ;
490 unsigned _p;
491 DoRop( _p, alu, *psrc, *pdst ) ;
492 *pdst = ( *pdst & npm ) | ( pm & _p ) ;
494 #ifdef notdef /* PURDUE */
495 *pdst = ( *pdst & npm ) | ( pm & DoRop( alu, *psrc, *pdst ) ) ;
496 #endif /* PURDUE */
499 DEALLOCATE_LOCAL( pptFree ) ;
500 DEALLOCATE_LOCAL( pwidthFree ) ;
501 return ;