2 * Copyright IBM Corporation 1987,1988,1989
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
24 #ifdef HAVE_XORG_CONFIG_H
25 #include <xorg-config.h>
29 #include "OScompiler.h"
33 #include "xf86str.h" /* for pScrn->vtSema */
34 extern ScrnInfoPtr
*xf86Screens
;
41 register const unsigned int patternWidth
,
42 register const unsigned char * const lineptr
45 register unsigned char bits
;
46 register const unsigned char *cptr
;
50 cptr
= lineptr
+ ( x
>> 3 ) ;
53 bits
= SCRLEFT8( bits
, shift
) | SCRRIGHT8( cptr
[1], ( 8 - shift
) ) ;
54 if ( ( wrap
= x
+ 8 - patternWidth
) > 0 ) {
55 bits
&= SCRLEFT8( 0xFF, wrap
) ;
56 bits
|= SCRRIGHT8( *lineptr
, ( 8 - wrap
) ) ;
59 /* GJA -- Handle extraction of 8 bits from < 8 bits wide stipple.
60 * I duplicated case 4,5,6,7 to give the compiler a chance to optimize.
62 switch (patternWidth
) {
63 case 1: /* Not really useful. */
64 bits
&= ~SCRRIGHT8(0xFF,1);
65 bits
|= SCRRIGHT8(bits
,1);
66 bits
|= SCRRIGHT8(bits
,2);
67 bits
|= SCRRIGHT8(bits
,4);
70 bits
&= ~SCRRIGHT8(0xFF,2);
71 bits
|= SCRRIGHT8(bits
,2); bits
|= SCRRIGHT8(bits
,4); break;
73 bits
&= ~SCRRIGHT8(0xFF,3);
74 bits
|= (SCRRIGHT8(bits
,3) | SCRRIGHT8(bits
,6)); break;
76 bits
= (bits
& ~SCRRIGHT8(0xFF,4)) | SCRRIGHT8(bits
,4); break;
78 bits
= (bits
& ~SCRRIGHT8(0xFF,5)) | SCRRIGHT8(bits
,5); break;
80 bits
= (bits
& ~SCRRIGHT8(0xFF,6)) | SCRRIGHT8(bits
,6); break;
82 bits
= (bits
& ~SCRRIGHT8(0xFF,7)) | SCRRIGHT8(bits
,7); break;
85 /* Do nothing, of course */
92 * Basically, in the code below, we will draw a stipple in the usual
93 * three parts: left edge, center and right edge.
94 * For efficiency reasons, the center will be drawn byte aligned, so that
95 * we will have to shuffle the bits in the left and right edges.
96 * The hard cases will be stipples with width < 8: In order to get 8
97 * bits from those, we will need a loop. One single 'if' will never do.
98 * This is taken care of above.
103 WindowPtr pWin
, /* GJA */
107 register const unsigned char *mastersrc
,
109 register unsigned int width
,
110 register unsigned int paddedByteWidth
,
117 xf86Screens
[((DrawablePtr
)pWin
)->pScreen
->myNum
]->domainIOBase
+ 0x300;
118 register volatile unsigned char *xDst
;
119 register VideoAdapterObject tmp2
;
120 register int NeedValX
;
121 register int counter
;
123 unsigned int rowCounter
;
126 unsigned char bitmask
;
130 if ((tmp1
= x
& 07)) {
131 tmp2
= SCRRIGHT8( ( (unsigned) 0xFF ), tmp1
) ;
132 /* Catch The Cases Where The Entire Region Is Within One Byte */
133 if ( ( w
-= 8 - tmp1
) < 0 ) {
134 tmp2
&= SCRLEFT8( (unsigned) 0xFF, -w
) ;
138 SetVideoGraphics( Bit_MaskIndex
, tmp2
) ; /* Set The Bit Mask */
140 bitmask
= tmp2
; /* Set The Bit Mask */
143 * For Each Line In The Source Pixmap
145 xDst
= SCREENADDRESS( pWin
, x
, y
);
146 for ( tmp1
= yshift
, rowCounter
= h
;
148 rowCounter
-- , tmp1
++ ) {
150 if ( tmp1
>= (int)height
)
154 tmp2
= *( (VgaMemoryPtr
) xDst
) ;
157 *( (VgaMemoryPtr
) xDst
) =
159 getbits( xshift
/* GJA */, width
,
161 + ( tmp1
* paddedByteWidth
) ) >> (x
& 07) ;
164 (getbits( xshift
/* GJA */, width
,
166 + ( tmp1
* paddedByteWidth
) ) >> (x
& 07)
169 (getbits_x( xshift
/* GJA */, width
,
171 + ( tmp1
* paddedByteWidth
), (x
& 07))
175 xDst
+= BYTES_PER_LINE(pWin
);
177 NeedValX
= (xshift
+ 8 - (x
& 07)) % width
;
178 x
= ( x
+ 7 ) & ~07 ;
184 if ((byte_cnt
= ROW_OFFSET(w
))) { /* Fill The Center Of The Box */
185 int SavNeedX
= NeedValX
;
188 SetVideoGraphics( Bit_MaskIndex
, 0xFF ) ; /* Set The Bit Mask */
191 * For Each Line In The Source Pixmap
193 xDst
= SCREENADDRESS( pWin
, x
, y
);
194 for ( tmp1
= yshift
, rowCounter
= h
;
196 rowCounter
-- , tmp1
++ ) {
197 register const unsigned char *l_ptr
;
198 if ( tmp1
>= (int)height
)
200 l_ptr
= mastersrc
+ ( tmp1
* paddedByteWidth
) ;
202 * For Each Byte Across The Pattern In X
204 for ( counter
= byte_cnt
, NeedValX
= SavNeedX
;
208 tmp2
= *( (VgaMemoryPtr
) xDst
) ;
211 *( (VgaMemoryPtr
) xDst
) =
213 getbits( NeedValX
, width
, l_ptr
) ;
216 getbits( NeedValX
, width
, l_ptr
) ;
218 getbits_x ( NeedValX
, width
, l_ptr
, 0 ) ;
221 /* GJA -- The '%' is there since width could be < 8 */
222 NeedValX
= (NeedValX
+ 8) % width
;
225 xDst
+= BYTES_PER_LINE(pWin
) - byte_cnt
;
230 if ((tmp1
= BIT_OFFSET(w
))) { /* x Now Is Byte Aligned */
231 /* Set The Bit Mask */
233 SetVideoGraphics( Bit_MaskIndex
, SCRLEFT8( 0xFF, ( 8 - tmp1
) ) ) ;
235 bitmask
= SCRLEFT8( 0xFF, ( 8 - tmp1
));
238 * For Each Line In The Source Pixmap
240 xDst
= SCREENADDRESS( pWin
, ( x
+ w
), y
);
241 for ( tmp1
= yshift
, rowCounter
= h
;
243 rowCounter
-- , tmp1
++ ) {
244 if ( tmp1
>= (int)height
)
248 tmp2
= *( (VgaMemoryPtr
) xDst
) ;
251 *( (VgaMemoryPtr
) xDst
) =
253 getbits( NeedValX
, width
,
255 + ( tmp1
* paddedByteWidth
) ) ;
258 (getbits( NeedValX
, width
,
260 + ( tmp1
* paddedByteWidth
) ) & bitmask
);
262 (getbits_x( NeedValX
, width
,
264 + ( tmp1
* paddedByteWidth
), 0 ) & bitmask
);
267 xDst
+= BYTES_PER_LINE(pWin
) ;
277 WindowPtr pWin
, /* GJA */
281 register const unsigned char *mastersrc
,
283 register unsigned int width
,
284 register unsigned int paddedByteWidth
,
291 xf86Screens
[((DrawablePtr
)pWin
)->pScreen
->myNum
]->domainIOBase
+ 0x300;
292 register volatile unsigned char *xDst
;
293 register VideoAdapterObject tmp2
;
294 register int NeedValX
;
295 register int byte_cnt
;
297 unsigned DestinationRow
;
298 unsigned int SourceRow
;
299 volatile unsigned char *dst
;
300 int scr_incr
= ( height
* BYTES_PER_LINE(pWin
) ) ;
302 unsigned char bitmask
;
306 if ((tmp1
= x
& 07)) {
307 tmp2
= SCRRIGHT8( ( (unsigned) 0xFF ), tmp1
) ;
308 /* Catch The Cases Where The Entire Region Is Within One Byte */
309 if ( ( w
-= 8 - tmp1
) < 0 ) {
310 tmp2
&= SCRLEFT8( (unsigned) 0xFF, -w
) ;
314 SetVideoGraphics( Bit_MaskIndex
, tmp2
) ; /* Set The Bit Mask */
316 bitmask
= tmp2
; /* Set The Bit Mask */
319 * For Each Line In The Source Pixmap
321 for ( tmp1
= yshift
, SourceRow
= 0, dst
= SCREENADDRESS( pWin
, x
, y
) ;
323 tmp1
++, SourceRow
++, dst
+= BYTES_PER_LINE(pWin
) ) {
324 register unsigned bitPattern
;
326 if ( tmp1
>= (int)height
)
329 * For Each Time Pattern Repeats In The Y Dimension
332 for ( DestinationRow
= SourceRow
,
334 bitPattern
= getbits( xshift
, width
,
336 + ( tmp1
* paddedByteWidth
) ) ;
339 bitPattern
= getbits( xshift
, width
,
341 + ( tmp1
* paddedByteWidth
) ) ;
343 bitPattern
= getbits_x( xshift
, width
,
345 + ( tmp1
* paddedByteWidth
), 0 ) ;
348 (int)DestinationRow
< h
;
349 DestinationRow
+= height
) {
352 tmp2
= *( (VgaMemoryPtr
) xDst
) ;
356 *( (VgaMemoryPtr
) xDst
) = bitPattern
>> (x
& 07);
358 *( (VgaMemoryPtr
) xDst
) = (bitPattern
>> (x
& 07)) & bitmask
;
363 NeedValX
= (xshift
+ 8 - (x
& 07)) % width
;
364 x
= ( x
+ 7 ) & ~07 ;
370 if ((byte_cnt
= ROW_OFFSET(w
))) { /* Fill The Center Of The Box */
371 int SavNeedX
= NeedValX
;
374 SetVideoGraphics( Bit_MaskIndex
, 0xFF ) ; /* Set The Bit Mask */
377 * For Each Line In The Source Pixmap
379 for ( tmp1
= yshift
, SourceRow
= 0, dst
= SCREENADDRESS( pWin
, x
, y
) ;
381 tmp1
++, SourceRow
++, dst
+= BYTES_PER_LINE(pWin
) - byte_cnt
) {
382 register const unsigned char *l_ptr
;
383 if ( tmp1
>= (int)height
)
385 l_ptr
= mastersrc
+ ( tmp1
* paddedByteWidth
) ;
387 * For Each Byte Across The Pattern In X
389 for ( tmp2
= byte_cnt
, NeedValX
= SavNeedX
;
392 register unsigned bitPattern
;
394 register VideoAdapterObject tmp3
;
397 * For Each Time Pattern Repeats In Y
400 for ( DestinationRow
= SourceRow
,
402 bitPattern
= getbits( NeedValX
, width
, l_ptr
) ;
405 bitPattern
= getbits( NeedValX
, width
, l_ptr
) ;
407 bitPattern
= getbits_x( NeedValX
, width
, l_ptr
, 0 ) ;
410 (int)DestinationRow
< h
;
411 DestinationRow
+= height
) {
414 tmp3
= *( (VgaMemoryPtr
) xDst
) ;
418 *( (VgaMemoryPtr
) xDst
) = bitPattern
;
421 NeedValX
= (NeedValX
+ 8) % width
;
427 if ((tmp1
= BIT_OFFSET(w
))) { /* x Now Is Byte Aligned */
428 /* Set The Bit Mask */
430 SetVideoGraphics( Bit_MaskIndex
, SCRLEFT8( 0xFF, ( 8 - tmp1
) ) ) ;
432 bitmask
= SCRLEFT8( 0xFF, ( 8 - tmp1
) );
435 * For Each Line In The Source Pixmap
437 for ( tmp1
= yshift
, SourceRow
= 0,
438 dst
= SCREENADDRESS( pWin
, ( x
+ w
), y
) ;
440 tmp1
++, SourceRow
++, dst
+= BYTES_PER_LINE(pWin
) ) {
441 register unsigned bitPattern
;
442 if ( tmp1
>= (int)height
)
445 * For Each Time Pattern Repeats In The Y Dimension
448 for ( DestinationRow
= SourceRow
,
450 bitPattern
= getbits( NeedValX
, width
,
452 + ( tmp1
* paddedByteWidth
) ) ;
455 bitPattern
= getbits( NeedValX
, width
,
457 + ( tmp1
* paddedByteWidth
) ) ;
459 bitPattern
= getbits_x( NeedValX
, width
,
461 + ( tmp1
* paddedByteWidth
), 0 ) ;
464 (int)DestinationRow
< h
;
465 DestinationRow
+= height
) {
468 tmp2
= *( (VgaMemoryPtr
) xDst
) ;
472 *( (VgaMemoryPtr
) xDst
) = bitPattern
;
474 *( (VgaMemoryPtr
) xDst
) = bitPattern
& bitmask
;
484 #define DO_RECURSE 0x10000
489 DrawablePtr pDrawable
,
490 register unsigned long int plane_mask
,
491 register unsigned long int desiredState
495 xf86Screens
[pDrawable
->pScreen
->myNum
]->domainIOBase
+ 0x300;
497 /* Setup VGA Registers */
499 * Set The Plane-Enable
501 SetVideoSequencer( Mask_MapIndex
, plane_mask
) ;
502 SetVideoGraphics( Enb_Set_ResetIndex
, plane_mask
) ;
504 * Put Display Into SET-AND (i.e. Write Mode 3 )
506 SetVideoGraphics( Graphics_ModeIndex
, VGA_WRITE_MODE_3
) ;
508 * Set The Color in The Set/Reset Register
510 SetVideoGraphics( Set_ResetIndex
, desiredState
& VGA_ALLPLANES
) ;
512 * Set The Vga's Alu Function
514 SetVideoGraphics( Data_RotateIndex
, desiredState
>> 8 ) ;
516 unsigned short ROP_value
;
517 /* Setup VGA Registers */
519 * Set The Plane-Enable
521 outw(EGC_PLANE
, ~plane_mask
);
522 switch((desiredState
>> 8)&0x18) {
523 /* EGC MODE.. Cmp Read: Flase, WriteSource=ROP, ReadSource=CPU */
525 if (desiredState
& DO_RECURSE
)
526 ROP_value
= EGC_AND_INV_MODE
;
528 ROP_value
= EGC_AND_MODE
;
531 if (desiredState
& DO_RECURSE
)
532 ROP_value
= EGC_OR_INV_MODE
;
534 ROP_value
= EGC_OR_MODE
;
537 if (desiredState
& DO_RECURSE
)
538 ROP_value
= EGC_XOR_INV_MODE
;
540 ROP_value
= EGC_XOR_MODE
;
544 ROP_value
= EGC_COPY_MODE
;
547 outw(EGC_MODE
, ROP_value
);
548 outw(EGC_FGC
, desiredState
& VGA_ALLPLANES
);
558 register unsigned long int color
561 register unsigned int data_rotate_value
= VGA_COPY_MODE
<< 8 ;
562 register unsigned int invert_existing_data
= 0 ;
564 /* Test The Raster-Op */
565 switch ( rasterOp
) {
566 case GXclear
: /* 0x0 Zero 0 */
569 case GXinvert
: /* 0xa NOT dst */
570 data_rotate_value
= VGA_XOR_MODE
<< 8 ;
571 case GXset
: /* 0xf 1 */
572 color
= VGA_ALLPLANES
;
574 case GXnor
: /* 0x8 NOT src AND NOT dst */
575 invert_existing_data
= DO_RECURSE
;
576 case GXandInverted
: /* 0x4 NOT src AND dst */
578 case GXand
: /* 0x1 src AND dst */
579 data_rotate_value
= VGA_AND_MODE
<< 8 ;
580 case GXcopy
: /* 0x3 src */
582 case GXequiv
: /* 0x9 NOT src XOR dst */
584 case GXxor
: /* 0x6 src XOR dst */
585 data_rotate_value
= VGA_XOR_MODE
<< 8 ;
587 case GXandReverse
: /* 0x2 src AND NOT dst */
588 invert_existing_data
= DO_RECURSE
;
589 data_rotate_value
= VGA_AND_MODE
<< 8 ;
591 case GXorReverse
: /* 0xb src OR NOT dst */
592 invert_existing_data
= DO_RECURSE
;
593 data_rotate_value
= VGA_OR_MODE
<< 8 ;
595 case GXnand
: /* 0xe NOT src OR NOT dst */
596 invert_existing_data
= DO_RECURSE
;
597 case GXorInverted
: /* 0xd NOT src OR dst */
599 case GXor
: /* 0x7 src OR dst */
600 data_rotate_value
= VGA_OR_MODE
<< 8 ;
602 case GXcopyInverted
: /* 0xc NOT src */
605 case GXnoop
: /* 0x5 dst */
606 ; /* Shouldn't Get Here !! */
609 return ( color
& VGA_ALLPLANES
) | data_rotate_value
| invert_existing_data
;
615 WindowPtr pWin
, /* GJA */
621 unsigned long int fg
,
623 unsigned long int planes
626 unsigned long regState
;
628 if ( !xf86Screens
[((DrawablePtr
)pWin
)->pScreen
->myNum
]->vtSema
) {
629 xf4bppOffDrawMonoImage( pWin
, data
, x
, y
, w
, h
, fg
, alu
, planes
);
633 if ( ( alu
== GXnoop
) || !( planes
&= VGA_ALLPLANES
) )
637 if ( ( regState
= vgaCalcMonoMode( alu
, fg
) ) & DO_RECURSE
) {
638 vgaDrawMonoImage( pWin
, data
, x
, y
, w
, h
,
639 VGA_ALLPLANES
, GXinvert
, planes
) ;
640 regState
&= ~DO_RECURSE
;
643 regState
= vgaCalcMonoMode(alu
, (char)fg
);
647 vgaSetMonoRegisters( (DrawablePtr
)pWin
, planes
, regState
) ;
649 DoMonoSingle( pWin
, w
, x
, y
, (const unsigned char *) data
, h
,
650 w
, ( ( w
+ 31 ) & ~31 ) >> 3, h
, 0, 0 ) ;
657 xf4bppFillStipple( pWin
, pStipple
, fg
, alu
, planes
, x
, y
, w
, h
, xSrc
, ySrc
)
658 WindowPtr pWin
; /* GJA */
659 register PixmapPtr
const pStipple
;
660 unsigned long int fg
;
662 unsigned long int planes
;
664 const int xSrc
, ySrc
;
667 unsigned int height
;
670 unsigned long regState
;
672 if ( !xf86Screens
[((DrawablePtr
)pWin
)->pScreen
->myNum
]->vtSema
) {
673 xf4bppOffFillStipple( pWin
, pStipple
, fg
, alu
, planes
,
674 x
, y
, w
, h
, xSrc
, ySrc
);
678 if ( ( alu
== GXnoop
) || !( planes
&= VGA_ALLPLANES
) )
682 if ( ( regState
= vgaCalcMonoMode( alu
, fg
) ) & DO_RECURSE
) {
683 xf4bppFillStipple( pWin
, pStipple
, VGA_ALLPLANES
, GXinvert
, planes
,
684 x
, y
, w
, h
, xSrc
, ySrc
) ;
685 regState
&= ~DO_RECURSE
;
688 regState
= vgaCalcMonoMode(alu
, (char)fg
);
692 vgaSetMonoRegisters( (DrawablePtr
)pWin
, planes
, regState
) ;
694 /* Figure Bit Offsets & Source Address */
695 width
= pStipple
->drawable
.width
;
696 if ( ( xshift
= ( x
- xSrc
) ) < 0 )
697 xshift
= width
- ( ( - xshift
) % width
) ;
700 if ( xshift
== (int)width
) xshift
= 0;
702 height
= pStipple
->drawable
.height
;
703 if ( ( yshift
= ( y
- ySrc
) ) < 0 )
704 yshift
= height
- ( ( - yshift
) % height
) ;
707 if ( yshift
== (int)height
) yshift
= 0;
709 (* ( (h
> (int)height
) ? DoMonoMany
: DoMonoSingle
) ) (
711 (const unsigned char *) pStipple
->devPrivate
.ptr
,
714 ( ( width
+ 31 ) & ((unsigned)(~31)) ) >> 3,