1
/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/vgaSolid.c,v 1.5 2002/01/25 21:56:22 tsi Exp $ */
3
* Copyright IBM Corporation 1987,1988,1989
7
* Permission to use, copy, modify, and distribute this software and its
8
* documentation for any purpose and without fee is hereby granted,
9
* provided that the above copyright notice appear in all copies and that
10
* both that copyright notice and this permission notice appear in
11
* supporting documentation, and that the name of IBM not be
12
* used in advertising or publicity pertaining to distribution of the
13
* software without specific, written prior permission.
15
* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17
* IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
25
/* $XConsortium: vgaSolid.c /main/5 1996/02/21 17:59:06 kaleb $ */
28
#include "OScompiler.h"
32
#include "xf86str.h" /* for pScrn->vtSema */
33
extern ScrnInfoPtr *xf86Screens;
42
extern void fastFill();
43
extern void fastFillRMW();
48
register volatile unsigned char *destination,
49
register const unsigned int bytes_per_line,
50
register const unsigned int bytewidth, /* MUST BE > 0 !! */
51
register unsigned int height /* MUST BE > 0 !! */
54
int stop_count = bytewidth ;
55
register int row_jump = bytes_per_line - bytewidth ;
56
#if !defined(OLDHC) && defined(BSDrt) && !defined(i386)
57
register const unsigned int notZero = ((unsigned char)(~0x0));
59
#define notZero ((unsigned char)(~0))
62
#define SINGLE_STORE \
63
( *( (VgaMemoryPtr) destination ) = notZero ); \
64
destination++; stop_count--;
66
/* TOP OF FIRST LOOP */
69
switch ( bytewidth & 0xF ) { /* Jump into loop at mod 16 remainder */
71
case 0x0 : SINGLE_STORE ;
72
case 0xF : SINGLE_STORE ;
73
case 0xE : SINGLE_STORE ;
74
case 0xD : SINGLE_STORE ;
75
case 0xC : SINGLE_STORE ;
76
case 0xB : SINGLE_STORE ;
77
case 0xA : SINGLE_STORE ;
78
case 0x9 : SINGLE_STORE ;
79
case 0x8 : SINGLE_STORE ;
80
case 0x7 : SINGLE_STORE ;
81
case 0x6 : SINGLE_STORE ;
82
case 0x5 : SINGLE_STORE ;
83
case 0x4 : SINGLE_STORE ;
84
case 0x3 : SINGLE_STORE ;
85
case 0x2 : SINGLE_STORE ;
86
case 0x1 : SINGLE_STORE ;
92
destination += row_jump ;
93
stop_count = bytewidth ;
103
/* For Read-Modify-Write Case */
104
static void fastFillRMW
106
register volatile unsigned char *destination,
107
register const unsigned int bytes_per_line,
108
register const unsigned int bytewidth, /* MUST BE > 0 !! */
109
register unsigned int height /* MUST BE > 0 !! */
112
int stop_count = bytewidth ;
113
register int row_jump = bytes_per_line - bytewidth ;
114
#if !defined(OLDHC) && defined(BSDrt) && !defined(i386)
115
register const unsigned int notZero = ((unsigned char)(~0x0));
119
#define SINGLE_STORE \
120
tmp = *( (VgaMemoryPtr) destination ) ; \
121
( *( (VgaMemoryPtr) destination ) = notZero ) ; \
122
destination++; stop_count-- ;
124
/* TOP OF FIRST LOOP */
127
switch ( bytewidth & 0xF ) { /* Jump into loop at mod 16 remainder */
129
case 0x0 : SINGLE_STORE ;
130
case 0xF : SINGLE_STORE ;
131
case 0xE : SINGLE_STORE ;
132
case 0xD : SINGLE_STORE ;
133
case 0xC : SINGLE_STORE ;
134
case 0xB : SINGLE_STORE ;
135
case 0xA : SINGLE_STORE ;
136
case 0x9 : SINGLE_STORE ;
137
case 0x8 : SINGLE_STORE ;
138
case 0x7 : SINGLE_STORE ;
139
case 0x6 : SINGLE_STORE ;
140
case 0x5 : SINGLE_STORE ;
141
case 0x4 : SINGLE_STORE ;
142
case 0x3 : SINGLE_STORE ;
143
case 0x2 : SINGLE_STORE ;
144
case 0x1 : SINGLE_STORE ;
150
destination += row_jump ;
151
stop_count = bytewidth ;
163
void xf4bppFillSolid( pWin, color, alu, planes, x0, y0, lx, ly )
164
WindowPtr pWin; /* GJA */
165
unsigned long int color ;
167
unsigned long int planes ;
169
register const int y0 ;
171
register const int ly ; /* MUST BE > 0 !! */
174
register volatile unsigned char *dst ;
178
unsigned int data_rotate_value = VGA_COPY_MODE ;
179
unsigned int read_write_modify = FALSE ;
180
unsigned int invert_existing_data = FALSE ;
183
if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) {
184
xf4bppOffFillSolid( pWin, color, alu, planes, x0, y0, lx, ly );
189
if ( ( lx == 0 ) || ( ly == 0 ) )
193
case GXclear: /* 0x0 Zero 0 */
196
case GXnor: /* 0x8 NOT src AND NOT dst */
197
invert_existing_data = TRUE ;
198
case GXandInverted: /* 0x4 NOT src AND dst */
200
case GXand: /* 0x1 src AND dst */
201
data_rotate_value = VGA_AND_MODE ;
202
read_write_modify = TRUE ;
203
case GXcopy: /* 0x3 src */
205
case GXnoop: /* 0x5 dst */
207
case GXequiv: /* 0x9 NOT src XOR dst */
209
case GXxor: /* 0x6 src XOR dst */
210
data_rotate_value = VGA_XOR_MODE ;
211
read_write_modify = TRUE ;
214
case GXandReverse: /* 0x2 src AND NOT dst */
215
invert_existing_data = TRUE ;
216
data_rotate_value = VGA_AND_MODE ;
217
read_write_modify = TRUE ;
219
case GXorReverse: /* 0xb src OR NOT dst */
220
invert_existing_data = TRUE ;
221
data_rotate_value = VGA_OR_MODE ;
222
read_write_modify = TRUE ;
224
case GXnand: /* 0xe NOT src OR NOT dst */
225
invert_existing_data = TRUE ;
226
case GXorInverted: /* 0xd NOT src OR dst */
228
case GXor: /* 0x7 src OR dst */
229
data_rotate_value = VGA_OR_MODE ;
230
read_write_modify = TRUE ;
232
case GXcopyInverted: /* 0xc NOT src */
235
case GXinvert: /* 0xa NOT dst */
236
data_rotate_value = VGA_XOR_MODE ;
237
read_write_modify = TRUE ;
238
case GXset: /* 0xf 1 */
239
color = VGA_ALLPLANES ;
244
if ( !( planes &= VGA_ALLPLANES ) )
248
xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->domainIOBase + 0x300;
251
* Set The Plane-Enable
253
SetVideoSequencer( Mask_MapIndex, planes ) ;
254
SetVideoGraphics( Enb_Set_ResetIndex, planes ) ;
256
* Put Display Into SET/RESET Write Mode
258
SetVideoGraphics( Graphics_ModeIndex, VGA_WRITE_MODE_3 ) ;
260
* Set The Color in The Set/Reset Register
262
SetVideoGraphics( Set_ResetIndex, color & VGA_ALLPLANES ) ;
264
* Set The Function-Select In The Data Rotate Register
266
SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ;
269
if ((tmp = x0 & 07)) {
270
tmp2 = SCRRIGHT8( ( (unsigned) 0xFF ), tmp ) ;
271
/* Catch The Cases Where The Entire Region Is Within One Byte */
272
if ( ( lx -= 8 - tmp ) < 0 ) {
273
tmp2 &= SCRLEFT8( 0xFF, -lx ) ;
276
/* Set The Bit Mask Reg */
277
SetVideoGraphics(Bit_MaskIndex, tmp2 ) ;
278
if ( invert_existing_data == TRUE ) {
279
SetVideoGraphics( Set_ResetIndex, VGA_ALLPLANES ) ;
280
SetVideoGraphics( Data_RotateIndex, VGA_XOR_MODE ) ;
281
dst = SCREENADDRESS( pWin, x0, y0 );
284
tmp3 = *( (VgaMemoryPtr) dst ) ;
285
*( (VgaMemoryPtr) dst ) = tmp2 ;
286
dst += BYTES_PER_LINE(pWin);
288
SetVideoGraphics( Set_ResetIndex, color & VGA_ALLPLANES ) ;
289
SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ;
292
dst = SCREENADDRESS( pWin, x0, y0 );
295
tmp3 = *( (VgaMemoryPtr) dst ) ;
296
*( (VgaMemoryPtr) dst ) = tmp2 ;
297
dst += BYTES_PER_LINE(pWin);
299
if ( !lx ) { /* All Handled In This Byte */
302
x0 = ( x0 + 8 ) & ~07 ;
305
/* Fill The Center Of The Box */
306
if ( ROW_OFFSET( lx ) ) {
307
SetVideoGraphics(Bit_MaskIndex, 0xFF ) ;
308
if ( invert_existing_data == TRUE ) {
309
SetVideoGraphics( Set_ResetIndex, VGA_ALLPLANES ) ;
310
SetVideoGraphics( Data_RotateIndex, VGA_XOR_MODE ) ;
311
fastFillRMW( SCREENADDRESS( pWin, x0, y0 ),
312
BYTES_PER_LINE(pWin),
313
ROW_OFFSET( lx ), ly ) ;
314
SetVideoGraphics( Set_ResetIndex, color & VGA_ALLPLANES ) ;
315
SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ;
317
/* Point At The Bit Mask Reg */
319
(* ( ( read_write_modify == FALSE ) ? fastFill : fastFillRMW ) )
320
( SCREENADDRESS( pWin, x0, y0 ), BYTES_PER_LINE(pWin),
321
ROW_OFFSET( lx ), ly ) ;
325
if ((tmp = BIT_OFFSET(lx))) { /* x0 Now Is Byte Aligned */
326
/* Set The Bit Mask */
327
SetVideoGraphics( Bit_MaskIndex,
328
(tmp2 = SCRLEFT8( 0xFF, ( 8 - tmp ) ) ) ) ;
329
if ( invert_existing_data == TRUE ) {
330
SetVideoGraphics( Set_ResetIndex, VGA_ALLPLANES ) ;
331
SetVideoGraphics( Data_RotateIndex, VGA_XOR_MODE ) ;
332
dst = SCREENADDRESS( pWin, ( x0 + lx ), y0 );
335
tmp3 = *( (VgaMemoryPtr) dst ) ;
336
*( (VgaMemoryPtr) dst ) = tmp2 ;
337
dst += BYTES_PER_LINE(pWin);
339
SetVideoGraphics( Set_ResetIndex, color & VGA_ALLPLANES ) ;
340
SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ;
343
dst = SCREENADDRESS( pWin, ( x0 + lx ), y0 );
346
tmp3 = *( (VgaMemoryPtr) dst ) ;
347
*( (VgaMemoryPtr) dst ) = tmp2 ;
348
dst += BYTES_PER_LINE(pWin) ;
351
/* Disable Set/Reset Register */
352
SetVideoGraphics( Enb_Set_ResetIndex, 0 ) ;
358
#else /* for PC98 EGC */
359
static void WordfastFill( destination, bytes_per_line, wordwidth, height )
360
register volatile unsigned char *destination ;
361
register const unsigned int bytes_per_line ;
362
register const unsigned int wordwidth ; /* MUST BE > 0 !! */
363
register unsigned int height ; /* MUST BE > 0 !! */
365
int stop_count = wordwidth ;
366
register int row_jump = bytes_per_line - wordwidth*2 ;
367
#if !defined(OLDHC) && defined(BSDrt) && !defined(i386) && 0
368
register const int notZero = ~0x0 ;
370
#define notZero ( ~0 )
373
#define SINGLE_STORE \
374
( *( (unsigned short *) destination++ ) = notZero ); \
375
destination++; stop_count--;
377
/* TOP OF FIRST LOOP */
380
switch ( wordwidth & 0xF ) { /* Jump into loop at mod 16 remainder */
382
case 0x0 : SINGLE_STORE ;
383
case 0xF : SINGLE_STORE ;
384
case 0xE : SINGLE_STORE ;
385
case 0xD : SINGLE_STORE ;
386
case 0xC : SINGLE_STORE ;
387
case 0xB : SINGLE_STORE ;
388
case 0xA : SINGLE_STORE ;
389
case 0x9 : SINGLE_STORE ;
390
case 0x8 : SINGLE_STORE ;
391
case 0x7 : SINGLE_STORE ;
392
case 0x6 : SINGLE_STORE ;
393
case 0x5 : SINGLE_STORE ;
394
case 0x4 : SINGLE_STORE ;
395
case 0x3 : SINGLE_STORE ;
396
case 0x2 : SINGLE_STORE ;
397
case 0x1 : SINGLE_STORE ;
403
destination += row_jump ;
404
stop_count = wordwidth ;
414
void xf4bppFillSolid( pWin, color, alu, planes, x0, y0, lx, ly )
415
WindowPtr pWin; /* GJA */
416
unsigned long int color ;
418
unsigned long int planes ;
420
register const int y0 ;
422
register const int ly ; /* MUST BE > 0 !! */
424
register volatile unsigned char *dst ;
427
register unsigned short tmp3 ;
428
unsigned short ROP_value;
429
unsigned int data_rotate_value = VGA_COPY_MODE ;
430
unsigned int read_write_modify = FALSE ;
431
unsigned int invert_existing_data = FALSE ;
434
if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) {
435
xf4bppOffFillSolid( pWin, color, alu, planes, x0, y0, lx, ly );
440
if ( ( lx == 0 ) || ( ly == 0 ) )
444
case GXclear: /* 0x0 Zero 0 */
447
case GXnor: /* 0x8 NOT src AND NOT dst */
448
invert_existing_data = TRUE ;
449
case GXandInverted: /* 0x4 NOT src AND dst */
451
case GXand: /* 0x1 src AND dst */
452
data_rotate_value = VGA_AND_MODE ;
453
read_write_modify = TRUE ;
454
case GXcopy: /* 0x3 src */
456
case GXnoop: /* 0x5 dst */
458
case GXequiv: /* 0x9 NOT src XOR dst */
460
case GXxor: /* 0x6 src XOR dst */
461
data_rotate_value = VGA_XOR_MODE ;
462
read_write_modify = TRUE ;
465
case GXandReverse: /* 0x2 src AND NOT dst */
466
invert_existing_data = TRUE ;
467
data_rotate_value = VGA_AND_MODE ;
468
read_write_modify = TRUE ;
470
case GXorReverse: /* 0xb src OR NOT dst */
471
invert_existing_data = TRUE ;
472
data_rotate_value = VGA_OR_MODE ;
473
read_write_modify = TRUE ;
475
case GXnand: /* 0xe NOT src OR NOT dst */
476
invert_existing_data = TRUE ;
477
case GXorInverted: /* 0xd NOT src OR dst */
479
case GXor: /* 0x7 src OR dst */
480
data_rotate_value = VGA_OR_MODE ;
481
read_write_modify = TRUE ;
483
case GXcopyInverted: /* 0xc NOT src */
486
case GXinvert: /* 0xa NOT dst */
487
data_rotate_value = VGA_XOR_MODE ;
488
read_write_modify = TRUE ;
489
case GXset: /* 0xf 1 */
490
color = VGA_ALLPLANES ;
495
if ( !( planes &= VGA_ALLPLANES ) )
498
/* Set Access Planes */
499
outw(EGC_PLANE, ~planes);
500
switch(data_rotate_value) {
501
/* EGC MODE.. Cmp Read: Flase, WriteSource=ROP, ReadSource=CPU */
503
if (invert_existing_data)
504
ROP_value = EGC_AND_INV_MODE;
506
ROP_value = EGC_AND_MODE;
509
if (invert_existing_data)
510
ROP_value = EGC_OR_INV_MODE;
512
ROP_value = EGC_OR_MODE;
515
if (invert_existing_data)
516
ROP_value = EGC_XOR_INV_MODE;
518
ROP_value = EGC_XOR_MODE;
522
ROP_value = EGC_COPY_MODE;
525
outw(EGC_MODE, ROP_value);
526
outw(EGC_FGC, color & VGA_ALLPLANES);
528
if ( tmp = x0 & 0x0f ) {
529
dst = (unsigned char *)((int)(SCREENADDRESS(pWin,x0,y0)) & ~0x01);
530
tmp3 = (unsigned)0xffff >>tmp;
531
/* Catch The Cases Where The Entire Region Is Within One Word */
532
if ( ( lx -= 16 - tmp ) < 0 ) {
533
tmp3 &= (unsigned)0xffff << -lx;
536
tmp3 = (unsigned short)(tmp3 >> 8 | tmp3 << 8);
539
*((unsigned short *) dst ) = tmp3 ;
540
dst += BYTES_PER_LINE(pWin);
542
if ( !lx ) { /* All Handled In This Word */
545
x0 = ( x0 + 0x0f ) & ~0x0f ;
548
/* Fill The Center Of The Box */
550
WordfastFill( SCREENADDRESS( pWin, x0, y0 ), BYTES_PER_LINE(pWin),
555
if ( tmp = lx & 0x0f ) { /* x0 Now Is Word Aligned */
556
/* Set The Bit Mask */
557
tmp3 = (unsigned)0xffff << ( 16 - tmp );
558
dst = (unsigned char*)((int)SCREENADDRESS(pWin,(x0+lx),y0) & ~0x01);
559
tmp3 = (unsigned short)(tmp3 >> 8 | tmp3 << 8);
562
*( (unsigned short *) dst ) = tmp3 ;
563
dst += BYTES_PER_LINE(pWin);