1
/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/vgaSolid.c,v 1.5tsi 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 $ */
27
#ifdef HAVE_XORG_CONFIG_H
28
#include <xorg-config.h>
32
#include "OScompiler.h"
36
#include "xf86str.h" /* for pScrn->vtSema */
37
extern ScrnInfoPtr *xf86Screens;
46
extern void fastFill();
47
extern void fastFillRMW();
52
register volatile unsigned char *destination,
53
register const unsigned int bytes_per_line,
54
register const unsigned int bytewidth, /* MUST BE > 0 !! */
55
register unsigned int height /* MUST BE > 0 !! */
58
int stop_count = bytewidth ;
59
register int row_jump = bytes_per_line - bytewidth ;
60
#if !defined(OLDHC) && defined(BSDrt) && !defined(i386)
61
register const unsigned int notZero = ((unsigned char)(~0x0));
63
#define notZero ((unsigned char)(~0))
66
#define SINGLE_STORE \
67
( *( (VgaMemoryPtr) destination ) = notZero ); \
68
destination++; stop_count--;
70
/* TOP OF FIRST LOOP */
73
switch ( bytewidth & 0xF ) { /* Jump into loop at mod 16 remainder */
75
case 0x0 : SINGLE_STORE ;
76
case 0xF : SINGLE_STORE ;
77
case 0xE : SINGLE_STORE ;
78
case 0xD : SINGLE_STORE ;
79
case 0xC : SINGLE_STORE ;
80
case 0xB : SINGLE_STORE ;
81
case 0xA : SINGLE_STORE ;
82
case 0x9 : SINGLE_STORE ;
83
case 0x8 : SINGLE_STORE ;
84
case 0x7 : SINGLE_STORE ;
85
case 0x6 : SINGLE_STORE ;
86
case 0x5 : SINGLE_STORE ;
87
case 0x4 : SINGLE_STORE ;
88
case 0x3 : SINGLE_STORE ;
89
case 0x2 : SINGLE_STORE ;
90
case 0x1 : SINGLE_STORE ;
96
destination += row_jump ;
97
stop_count = bytewidth ;
107
/* For Read-Modify-Write Case */
108
static void fastFillRMW
110
register volatile unsigned char *destination,
111
register const unsigned int bytes_per_line,
112
register const unsigned int bytewidth, /* MUST BE > 0 !! */
113
register unsigned int height /* MUST BE > 0 !! */
116
int stop_count = bytewidth ;
117
register int row_jump = bytes_per_line - bytewidth ;
118
#if !defined(OLDHC) && defined(BSDrt) && !defined(i386)
119
register const unsigned int notZero = ((unsigned char)(~0x0));
123
#define SINGLE_STORE \
124
tmp = *( (VgaMemoryPtr) destination ) ; (void)tmp; \
125
( *( (VgaMemoryPtr) destination ) = notZero ) ; \
126
destination++; stop_count-- ;
128
/* TOP OF FIRST LOOP */
131
switch ( bytewidth & 0xF ) { /* Jump into loop at mod 16 remainder */
133
case 0x0 : SINGLE_STORE ;
134
case 0xF : SINGLE_STORE ;
135
case 0xE : SINGLE_STORE ;
136
case 0xD : SINGLE_STORE ;
137
case 0xC : SINGLE_STORE ;
138
case 0xB : SINGLE_STORE ;
139
case 0xA : SINGLE_STORE ;
140
case 0x9 : SINGLE_STORE ;
141
case 0x8 : SINGLE_STORE ;
142
case 0x7 : SINGLE_STORE ;
143
case 0x6 : SINGLE_STORE ;
144
case 0x5 : SINGLE_STORE ;
145
case 0x4 : SINGLE_STORE ;
146
case 0x3 : SINGLE_STORE ;
147
case 0x2 : SINGLE_STORE ;
148
case 0x1 : SINGLE_STORE ;
154
destination += row_jump ;
155
stop_count = bytewidth ;
167
void xf4bppFillSolid( pWin, color, alu, planes, x0, y0, lx, ly )
168
WindowPtr pWin; /* GJA */
169
unsigned long int color ;
171
unsigned long int planes ;
173
register const int y0 ;
175
register const int ly ; /* MUST BE > 0 !! */
178
register volatile unsigned char *dst ;
182
unsigned int data_rotate_value = VGA_COPY_MODE ;
183
unsigned int read_write_modify = FALSE ;
184
unsigned int invert_existing_data = FALSE ;
187
if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) {
188
xf4bppOffFillSolid( pWin, color, alu, planes, x0, y0, lx, ly );
193
if ( ( lx == 0 ) || ( ly == 0 ) )
197
case GXclear: /* 0x0 Zero 0 */
200
case GXnor: /* 0x8 NOT src AND NOT dst */
201
invert_existing_data = TRUE ;
202
case GXandInverted: /* 0x4 NOT src AND dst */
204
case GXand: /* 0x1 src AND dst */
205
data_rotate_value = VGA_AND_MODE ;
206
read_write_modify = TRUE ;
207
case GXcopy: /* 0x3 src */
209
case GXnoop: /* 0x5 dst */
211
case GXequiv: /* 0x9 NOT src XOR dst */
213
case GXxor: /* 0x6 src XOR dst */
214
data_rotate_value = VGA_XOR_MODE ;
215
read_write_modify = TRUE ;
218
case GXandReverse: /* 0x2 src AND NOT dst */
219
invert_existing_data = TRUE ;
220
data_rotate_value = VGA_AND_MODE ;
221
read_write_modify = TRUE ;
223
case GXorReverse: /* 0xb src OR NOT dst */
224
invert_existing_data = TRUE ;
225
data_rotate_value = VGA_OR_MODE ;
226
read_write_modify = TRUE ;
228
case GXnand: /* 0xe NOT src OR NOT dst */
229
invert_existing_data = TRUE ;
230
case GXorInverted: /* 0xd NOT src OR dst */
232
case GXor: /* 0x7 src OR dst */
233
data_rotate_value = VGA_OR_MODE ;
234
read_write_modify = TRUE ;
236
case GXcopyInverted: /* 0xc NOT src */
239
case GXinvert: /* 0xa NOT dst */
240
data_rotate_value = VGA_XOR_MODE ;
241
read_write_modify = TRUE ;
242
case GXset: /* 0xf 1 */
243
color = VGA_ALLPLANES ;
248
if ( !( planes &= VGA_ALLPLANES ) )
252
xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->domainIOBase + 0x300;
255
* Set The Plane-Enable
257
SetVideoSequencer( Mask_MapIndex, planes ) ;
258
SetVideoGraphics( Enb_Set_ResetIndex, planes ) ;
260
* Put Display Into SET/RESET Write Mode
262
SetVideoGraphics( Graphics_ModeIndex, VGA_WRITE_MODE_3 ) ;
264
* Set The Color in The Set/Reset Register
266
SetVideoGraphics( Set_ResetIndex, color & VGA_ALLPLANES ) ;
268
* Set The Function-Select In The Data Rotate Register
270
SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ;
273
if ((tmp = x0 & 07)) {
274
tmp2 = SCRRIGHT8( ( (unsigned) 0xFF ), tmp ) ;
275
/* Catch The Cases Where The Entire Region Is Within One Byte */
276
if ( ( lx -= 8 - tmp ) < 0 ) {
277
tmp2 &= SCRLEFT8( 0xFF, -lx ) ;
280
/* Set The Bit Mask Reg */
281
SetVideoGraphics(Bit_MaskIndex, tmp2 ) ;
282
if ( invert_existing_data == TRUE ) {
283
SetVideoGraphics( Set_ResetIndex, VGA_ALLPLANES ) ;
284
SetVideoGraphics( Data_RotateIndex, VGA_XOR_MODE ) ;
285
dst = SCREENADDRESS( pWin, x0, y0 );
288
tmp3 = *( (VgaMemoryPtr) dst ) ;
290
*( (VgaMemoryPtr) dst ) = tmp2 ;
291
dst += BYTES_PER_LINE(pWin);
293
SetVideoGraphics( Set_ResetIndex, color & VGA_ALLPLANES ) ;
294
SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ;
297
dst = SCREENADDRESS( pWin, x0, y0 );
300
tmp3 = *( (VgaMemoryPtr) dst ) ;
302
*( (VgaMemoryPtr) dst ) = tmp2 ;
303
dst += BYTES_PER_LINE(pWin);
305
if ( !lx ) { /* All Handled In This Byte */
308
x0 = ( x0 + 8 ) & ~07 ;
311
/* Fill The Center Of The Box */
312
if ( ROW_OFFSET( lx ) ) {
313
SetVideoGraphics(Bit_MaskIndex, 0xFF ) ;
314
if ( invert_existing_data == TRUE ) {
315
SetVideoGraphics( Set_ResetIndex, VGA_ALLPLANES ) ;
316
SetVideoGraphics( Data_RotateIndex, VGA_XOR_MODE ) ;
317
fastFillRMW( SCREENADDRESS( pWin, x0, y0 ),
318
BYTES_PER_LINE(pWin),
319
ROW_OFFSET( lx ), ly ) ;
320
SetVideoGraphics( Set_ResetIndex, color & VGA_ALLPLANES ) ;
321
SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ;
323
/* Point At The Bit Mask Reg */
325
(* ( ( read_write_modify == FALSE ) ? fastFill : fastFillRMW ) )
326
( SCREENADDRESS( pWin, x0, y0 ), BYTES_PER_LINE(pWin),
327
ROW_OFFSET( lx ), ly ) ;
331
if ((tmp = BIT_OFFSET(lx))) { /* x0 Now Is Byte Aligned */
332
/* Set The Bit Mask */
333
SetVideoGraphics( Bit_MaskIndex,
334
(tmp2 = SCRLEFT8( 0xFF, ( 8 - tmp ) ) ) ) ;
335
if ( invert_existing_data == TRUE ) {
336
SetVideoGraphics( Set_ResetIndex, VGA_ALLPLANES ) ;
337
SetVideoGraphics( Data_RotateIndex, VGA_XOR_MODE ) ;
338
dst = SCREENADDRESS( pWin, ( x0 + lx ), y0 );
341
tmp3 = *( (VgaMemoryPtr) dst ) ;
343
*( (VgaMemoryPtr) dst ) = tmp2 ;
344
dst += BYTES_PER_LINE(pWin);
346
SetVideoGraphics( Set_ResetIndex, color & VGA_ALLPLANES ) ;
347
SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ;
350
dst = SCREENADDRESS( pWin, ( x0 + lx ), y0 );
353
tmp3 = *( (VgaMemoryPtr) dst ) ;
355
*( (VgaMemoryPtr) dst ) = tmp2 ;
356
dst += BYTES_PER_LINE(pWin) ;
359
/* Disable Set/Reset Register */
360
SetVideoGraphics( Enb_Set_ResetIndex, 0 ) ;
366
#else /* for PC98 EGC */
367
static void WordfastFill( destination, bytes_per_line, wordwidth, height )
368
register volatile unsigned char *destination ;
369
register const unsigned int bytes_per_line ;
370
register const unsigned int wordwidth ; /* MUST BE > 0 !! */
371
register unsigned int height ; /* MUST BE > 0 !! */
373
int stop_count = wordwidth ;
374
register int row_jump = bytes_per_line - wordwidth*2 ;
375
#if !defined(OLDHC) && defined(BSDrt) && !defined(i386) && 0
376
register const int notZero = ~0x0 ;
378
#define notZero ( ~0 )
381
#define SINGLE_STORE \
382
( *( (unsigned short *) destination++ ) = notZero ); \
383
destination++; stop_count--;
385
/* TOP OF FIRST LOOP */
388
switch ( wordwidth & 0xF ) { /* Jump into loop at mod 16 remainder */
390
case 0x0 : SINGLE_STORE ;
391
case 0xF : SINGLE_STORE ;
392
case 0xE : SINGLE_STORE ;
393
case 0xD : SINGLE_STORE ;
394
case 0xC : SINGLE_STORE ;
395
case 0xB : SINGLE_STORE ;
396
case 0xA : SINGLE_STORE ;
397
case 0x9 : SINGLE_STORE ;
398
case 0x8 : SINGLE_STORE ;
399
case 0x7 : SINGLE_STORE ;
400
case 0x6 : SINGLE_STORE ;
401
case 0x5 : SINGLE_STORE ;
402
case 0x4 : SINGLE_STORE ;
403
case 0x3 : SINGLE_STORE ;
404
case 0x2 : SINGLE_STORE ;
405
case 0x1 : SINGLE_STORE ;
411
destination += row_jump ;
412
stop_count = wordwidth ;
422
void xf4bppFillSolid( pWin, color, alu, planes, x0, y0, lx, ly )
423
WindowPtr pWin; /* GJA */
424
unsigned long int color ;
426
unsigned long int planes ;
428
register const int y0 ;
430
register const int ly ; /* MUST BE > 0 !! */
432
register volatile unsigned char *dst ;
435
register unsigned short tmp3 ;
436
unsigned short ROP_value;
437
unsigned int data_rotate_value = VGA_COPY_MODE ;
438
unsigned int read_write_modify = FALSE ;
439
unsigned int invert_existing_data = FALSE ;
442
if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) {
443
xf4bppOffFillSolid( pWin, color, alu, planes, x0, y0, lx, ly );
448
if ( ( lx == 0 ) || ( ly == 0 ) )
452
case GXclear: /* 0x0 Zero 0 */
455
case GXnor: /* 0x8 NOT src AND NOT dst */
456
invert_existing_data = TRUE ;
457
case GXandInverted: /* 0x4 NOT src AND dst */
459
case GXand: /* 0x1 src AND dst */
460
data_rotate_value = VGA_AND_MODE ;
461
read_write_modify = TRUE ;
462
case GXcopy: /* 0x3 src */
464
case GXnoop: /* 0x5 dst */
466
case GXequiv: /* 0x9 NOT src XOR dst */
468
case GXxor: /* 0x6 src XOR dst */
469
data_rotate_value = VGA_XOR_MODE ;
470
read_write_modify = TRUE ;
473
case GXandReverse: /* 0x2 src AND NOT dst */
474
invert_existing_data = TRUE ;
475
data_rotate_value = VGA_AND_MODE ;
476
read_write_modify = TRUE ;
478
case GXorReverse: /* 0xb src OR NOT dst */
479
invert_existing_data = TRUE ;
480
data_rotate_value = VGA_OR_MODE ;
481
read_write_modify = TRUE ;
483
case GXnand: /* 0xe NOT src OR NOT dst */
484
invert_existing_data = TRUE ;
485
case GXorInverted: /* 0xd NOT src OR dst */
487
case GXor: /* 0x7 src OR dst */
488
data_rotate_value = VGA_OR_MODE ;
489
read_write_modify = TRUE ;
491
case GXcopyInverted: /* 0xc NOT src */
494
case GXinvert: /* 0xa NOT dst */
495
data_rotate_value = VGA_XOR_MODE ;
496
read_write_modify = TRUE ;
497
case GXset: /* 0xf 1 */
498
color = VGA_ALLPLANES ;
503
if ( !( planes &= VGA_ALLPLANES ) )
506
/* Set Access Planes */
507
outw(EGC_PLANE, ~planes);
508
switch(data_rotate_value) {
509
/* EGC MODE.. Cmp Read: Flase, WriteSource=ROP, ReadSource=CPU */
511
if (invert_existing_data)
512
ROP_value = EGC_AND_INV_MODE;
514
ROP_value = EGC_AND_MODE;
517
if (invert_existing_data)
518
ROP_value = EGC_OR_INV_MODE;
520
ROP_value = EGC_OR_MODE;
523
if (invert_existing_data)
524
ROP_value = EGC_XOR_INV_MODE;
526
ROP_value = EGC_XOR_MODE;
530
ROP_value = EGC_COPY_MODE;
533
outw(EGC_MODE, ROP_value);
534
outw(EGC_FGC, color & VGA_ALLPLANES);
536
if ( tmp = x0 & 0x0f ) {
537
dst = (unsigned char *)((int)(SCREENADDRESS(pWin,x0,y0)) & ~0x01);
538
tmp3 = (unsigned)0xffff >>tmp;
539
/* Catch The Cases Where The Entire Region Is Within One Word */
540
if ( ( lx -= 16 - tmp ) < 0 ) {
541
tmp3 &= (unsigned)0xffff << -lx;
544
tmp3 = (unsigned short)(tmp3 >> 8 | tmp3 << 8);
547
*((unsigned short *) dst ) = tmp3 ;
548
dst += BYTES_PER_LINE(pWin);
550
if ( !lx ) { /* All Handled In This Word */
553
x0 = ( x0 + 0x0f ) & ~0x0f ;
556
/* Fill The Center Of The Box */
558
WordfastFill( SCREENADDRESS( pWin, x0, y0 ), BYTES_PER_LINE(pWin),
563
if ( tmp = lx & 0x0f ) { /* x0 Now Is Word Aligned */
564
/* Set The Bit Mask */
565
tmp3 = (unsigned)0xffff << ( 16 - tmp );
566
dst = (unsigned char*)((int)SCREENADDRESS(pWin,(x0+lx),y0) & ~0x01);
567
tmp3 = (unsigned short)(tmp3 >> 8 | tmp3 << 8);
570
*( (unsigned short *) dst ) = tmp3 ;
571
dst += BYTES_PER_LINE(pWin);