2 Copyright © 1995-2018, The AROS Development Team. All rights reserved.
5 Desc: VGAGfx hardware support routines
10 NOTE: This file is mostly based on XFree86 vgaWH.c sources
13 /****************************************************************************************/
15 #include <proto/exec.h>
19 #include "vgagfx_support.h"
20 #include "vgagfx_hidd.h"
21 #include "vgagfx_bitmap.h"
23 /****************************************************************************************/
25 #define min(a,b) ((a) < (b) ? (a) : (b))
26 #define max(a,b) ((a) > (b) ? (a) : (b))
28 /****************************************************************************************/
30 /* Default ANSI (PC's) palette */
32 unsigned char vgaANSIPalette
[]=
34 0, 0, 0, 0, 0, 42, 0, 42, 0, 0, 42, 42,
35 42, 0, 0, 42, 0, 42, 42, 21, 0, 42, 42, 42,
36 21, 21, 21, 21, 21, 63, 21, 63, 21, 21, 63, 63,
37 63, 21, 21, 63, 21, 63, 63, 63, 21, 63, 63, 63,
38 0, 0, 0, 5, 5, 5, 8, 8, 8, 11, 11, 11,
39 14, 14, 14, 17, 17, 17, 20, 20, 20, 24, 24, 24,
40 28, 28, 28, 32, 32, 32, 36, 36, 36, 40, 40, 40,
41 45, 45, 45, 50, 50, 50, 56, 56, 56, 63, 63, 63,
42 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0, 63,
43 63, 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16,
44 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0,
45 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63, 0,
46 0, 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47,
47 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63,
48 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31, 63,
49 63, 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39,
50 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31,
51 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63, 31,
52 31, 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55,
53 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63,
54 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45, 63,
55 63, 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49,
56 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45,
57 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63, 45,
58 45, 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58,
59 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63,
60 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0, 28,
61 28, 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7,
62 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0,
63 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28, 0,
64 0, 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21,
65 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28,
66 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14, 28,
67 28, 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17,
68 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14,
69 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28, 14,
70 14, 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24,
71 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28,
72 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20, 28,
73 28, 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22,
74 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20,
75 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28, 20,
76 20, 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26,
77 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28,
78 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0, 16,
79 16, 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4,
80 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0,
81 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16, 0,
82 0, 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12,
83 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16,
84 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8, 16,
85 16, 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10,
86 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8,
87 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16, 8,
88 8, 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14,
89 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16,
90 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11, 16,
91 16, 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12,
92 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11,
93 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16, 11,
94 11, 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15,
95 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16,
96 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
97 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
100 /****************************************************************************************/
103 ** Load specified palette, if NULL load default
105 void vgaLoadPalette(struct vgaHWRec
*regs
, unsigned char *pal
)
110 pal
= (unsigned char *)&vgaANSIPalette
;
112 for (i
=0; i
<768; i
++)
114 regs
->DAC
[i
]=*(unsigned char*)pal
++;
118 /****************************************************************************************/
123 /****************************************************************************************/
127 ** perform a sequencer reset.
129 void vgaSaveScreen(int start
)
131 if (start
== SS_START
)
133 outw(0x3C4, 0x0100); /* synchronous reset */
137 outw(0x3C4, 0x0300); /* end reset */
141 /****************************************************************************************/
146 int vgaBlankScreen(int on
)
155 scrn
&= 0xDF; /* enable screen */
159 scrn
|= 0x20; /* blank screen */
162 vgaSaveScreen(SS_START
);
163 outw(0x3C4, (scrn
<< 8) | 0x01); /* change mode */
164 vgaSaveScreen(SS_FINISH
);
169 /****************************************************************************************/
171 #define vgaIOBase 0x3d0
173 /****************************************************************************************/
179 void vgaDACLoad(struct vgaHWRec
*restore
, unsigned char start
, int num
)
185 for (i
=0; i
<num
*3; i
++)
187 outb(0x3C9, restore
->DAC
[n
++]);
189 I beleive incrementing variables and checking cycle counter
190 provides enough delay. Uncomment this in case of problems */
196 ** restore a video mode
198 void vgaRestore(struct vgaHWRec
*restore
)
202 inb(vgaIOBase
+ 0x0A); /* Reset flip-flop */
203 outb(0x3C0, 0x00); /* Enables pallete access */
205 restore
->MiscOutReg
|= 0x01;
206 outb(0x3C2, restore
->MiscOutReg
);
208 for (i
=1; i
<5; i
++) outw(0x3C4, (restore
->Sequencer
[i
] << 8) | i
);
210 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */
212 outw(vgaIOBase
+ 4, ((restore
->CRTC
[17] & 0x7F) << 8) | 17);
214 for (i
=0; i
<25; i
++) outw(vgaIOBase
+ 4,(restore
->CRTC
[i
] << 8) | i
);
216 for (i
=0; i
<9; i
++) outw(0x3CE, (restore
->Graphics
[i
] << 8) | i
);
218 for (i
=0; i
<21; i
++) {
219 inb(vgaIOBase
+ 0x0A);
220 outb(0x3C0,i
); outb(0x3C0, restore
->Attribute
[i
]);
225 vgaDACLoad(restore
, 0, 256);
227 /* Turn on PAS bit */
228 inb(vgaIOBase
+ 0x0A);
232 /****************************************************************************************/
235 ** Init VGA registers for given displaymode
237 int vgaInitMode(struct vgaModeDesc
*mode
, struct vgaHWRec
*regs
)
246 initialize default colormap for monochrome
248 for (i
= 0; i
< 3; i
++) regs
->DAC
[i
] = 0x00;
249 for (i
= 3; i
< 768; i
++) regs
->DAC
[i
] = 0x3F;
251 /* Initialise overscan register */
252 regs
->Attribute
[17] = 0xFF;
254 regs
->NoClock
= mode
->clock
;
257 compute correct Hsync & Vsync polarity
260 int VDisplay
= mode
->Height
;
261 // if (mode->Flags & V_DBLSCAN)
264 regs
->MiscOutReg
= 0xA3; /* +hsync -vsync */
265 else if (VDisplay
< 480)
266 regs
->MiscOutReg
= 0x63; /* -hsync +vsync */
267 else if (VDisplay
< 768)
268 regs
->MiscOutReg
= 0xE3; /* -hsync -vsync 0xE3 */
270 regs
->MiscOutReg
= 0x23; /* +hsync +vsync */
273 regs
->MiscOutReg
|= (regs
->NoClock
& 0x03) << 2;
278 regs
->Sequencer
[0] = 0x02;
279 // if (mode->Flags & V_CLKDIV2) /* TODO */
280 // regs->Sequencer[1] = 0x09;
282 regs
->Sequencer
[1] = 0x01;
284 regs
->Sequencer
[2] = 0x0F;
285 regs
->Sequencer
[3] = 0x00; /* Font select */
286 regs
->Sequencer
[4] = 0x06; /* Misc */
292 hblankstart
= min(mode
->HSyncStart
, mode
->HDisplay
);
293 hblankend
= max(mode
->HSyncEnd
, mode
->HTotal
);
294 if ((hblankend
- hblankstart
) >= 63 * 8)
296 hblankstart
= hblankend
- 63 * 8;
299 vblankstart
= min(mode
->VSyncStart
, mode
->VDisplay
);
300 vblankend
= max(mode
->VSyncEnd
, mode
->VTotal
);
301 if ((vblankend
- vblankstart
) >= 127)
303 vblankstart
= vblankend
- 127;
306 regs
->CRTC
[CRTC_H_TOTAL
] = (mode
->HTotal
/ 8) - 5;
307 regs
->CRTC
[CRTC_H_DISPLAY
] = (mode
->HDisplay
/ 8) - 1;
308 regs
->CRTC
[CRTC_H_BLANK_START
] = (hblankstart
/ 8) -1;
309 regs
->CRTC
[CRTC_H_BLANK_END
] = (((hblankend
/ 8) - 1) & 0x1F) | 0x80;
311 i
= (((mode
->HSkew
<< 2) + 0x10) & ~0x1F);
314 regs
->CRTC
[CRTC_H_BLANK_END
] |= i
;
317 regs
->CRTC
[CRTC_H_SYNC_START
] = (mode
->HSyncStart
/ 8);
318 regs
->CRTC
[CRTC_H_SYNC_END
] = ((((hblankend
/ 8) - 1) & 0x20 ) << 2 ) |
319 (((mode
->HSyncEnd
/ 8)) & 0x1F);
320 regs
->CRTC
[CRTC_V_TOTAL
] = (mode
->VTotal
- 2) & 0xFF;
321 regs
->CRTC
[CRTC_OVERFLOW
] = (((mode
->VTotal
-2) & 0x100) >> 8 ) |
322 (((mode
->VDisplay
-1) & 0x100) >> 7 ) |
323 ((mode
->VSyncStart
& 0x100) >> 6 ) |
324 (((vblankstart
- 1) & 0x100) >> 5 ) |
326 (((mode
->VTotal
-2) & 0x200) >> 4 ) |
327 (((mode
->VDisplay
-1) & 0x200) >> 3 ) |
328 ((mode
->VSyncStart
& 0x200) >> 2 );
329 regs
->CRTC
[CRTC_PRESET_ROW
] = 0x00;
330 regs
->CRTC
[CRTC_MAX_SCAN
] = (((vblankstart
- 1) & 0x200) >>4) | 0x40;
331 // if (mode->Flags & V_DBLSCAN)
332 // new->CRTC[9] |= 0x80;
333 regs
->CRTC
[CRTC_CURSOR_START
] = 0x00;
334 regs
->CRTC
[CRTC_CURSOR_END
] = 0x00;
335 regs
->CRTC
[CRTC_START_HI
] = 0x00;
336 regs
->CRTC
[CRTC_START_LO
] = 0x00;
337 regs
->CRTC
[CRTC_CURSOR_HI
] = 0x00;
338 regs
->CRTC
[CRTC_CURSOR_LO
] = 0x00;
339 regs
->CRTC
[CRTC_V_SYNC_START
] = mode
->VSyncStart
& 0xFF;
340 regs
->CRTC
[CRTC_V_SYNC_END
] = (mode
->VSyncEnd
& 0x0F) | 0x20;
341 regs
->CRTC
[CRTC_V_DISP_END
] = (mode
->VDisplay
-1) & 0xFF;
342 regs
->CRTC
[CRTC_OFFSET
] = mode
->Width
>> (8 - mode
->Depth
); /* just a guess */
343 regs
->CRTC
[CRTC_UNDERLINE
] = 0x00;
344 regs
->CRTC
[CRTC_V_BLANK_START
] = (vblankstart
- 1) & 0xFF;
345 regs
->CRTC
[CRTC_V_BLANK_END
] = (vblankend
- 1) & 0xFF;
346 regs
->CRTC
[CRTC_MODE
] = 0xE3;
347 regs
->CRTC
[CRTC_LINE_COMPARE
] = 0xFF;
349 if ((hblankend
/ 8) == (mode
->HTotal
/ 8))
351 i
= (regs
->CRTC
[CRTC_H_BLANK_END
] & 0x1f) | ((regs
->CRTC
[CRTC_H_SYNC_END
] & 0x80) >> 2);
352 if ((i
-- > (regs
->CRTC
[CRTC_H_BLANK_START
] & 0x3F)) &&
353 (hblankend
== mode
->HTotal
))
358 regs
->CRTC
[CRTC_H_BLANK_END
] = (regs
->CRTC
[CRTC_H_BLANK_END
] & ~0x1F) | (i
& 0x1f);
359 regs
->CRTC
[CRTC_H_SYNC_END
] = (regs
->CRTC
[CRTC_H_SYNC_END
] & ~0x80) | ((i
<< 2) & 0x80);
362 if (vblankend
== mode
->VTotal
)
364 i
= regs
->CRTC
[CRTC_V_BLANK_END
];
365 if ((i
> regs
->CRTC
[CRTC_V_BLANK_START
]) &&
366 ((i
& 0x7F) > (regs
->CRTC
[CRTC_V_BLANK_START
] & 0x7F)) &&
367 !(regs
->CRTC
[CRTC_MAX_SCAN
] & 0x9f))
375 regs
->CRTC
[CRTC_V_BLANK_END
] = i
;
379 Graphics Display Controller
381 regs
->Graphics
[0] = 0x00;
382 regs
->Graphics
[1] = 0x00;
383 regs
->Graphics
[2] = 0x00;
384 regs
->Graphics
[3] = 0x00;
385 regs
->Graphics
[4] = 0x00;
386 regs
->Graphics
[5] = 0x00;
387 regs
->Graphics
[6] = 0x05; /* only map 64k VGA memory !!!! */
388 regs
->Graphics
[7] = 0x0F;
389 regs
->Graphics
[8] = 0xFF;
391 regs
->Attribute
[0] = 0x00; /* standard colormap translation */
392 regs
->Attribute
[1] = 0x01;
393 regs
->Attribute
[2] = 0x02;
394 regs
->Attribute
[3] = 0x03;
395 regs
->Attribute
[4] = 0x04;
396 regs
->Attribute
[5] = 0x05;
397 regs
->Attribute
[6] = 0x06;
398 regs
->Attribute
[7] = 0x07;
399 regs
->Attribute
[8] = 0x08;
400 regs
->Attribute
[9] = 0x09;
401 regs
->Attribute
[10] = 0x0A;
402 regs
->Attribute
[11] = 0x0B;
403 regs
->Attribute
[12] = 0x0C;
404 regs
->Attribute
[13] = 0x0D;
405 regs
->Attribute
[14] = 0x0E;
406 regs
->Attribute
[15] = 0x0F;
407 regs
->Attribute
[16] = 0x81; /* wrong for the ET4000 */
408 regs
->Attribute
[17] = 0x00; /* GJA -- overscan. */
410 Attribute[17] is the overscan, and is initialised above only at startup
411 time, and not when mode switching.
413 regs
->Attribute
[18] = 0x0F;
414 regs
->Attribute
[19] = 0x00;
415 regs
->Attribute
[20] = 0x00;
420 /****************************************************************************************/
422 void vgaRefreshPixel(struct VGAGfxBitMapData
*data
, unsigned int x
, unsigned int y
)
427 unsigned int srcx
= x
- data
->xoffset
;
428 unsigned int srcy
= y
- data
->yoffset
;
430 ptr
= (char *)(data
->VideoData
+ srcx
+ (srcy
* data
->bpr
));
432 ptr2
= (char *)(IPTR
)(0xa0000 + (x
+ (y
* data
->disp_width
)) / 8);
433 pix
= 0x8000 >> (x
% 8);
439 outw(0x3ce,(fg
<< 8));
442 *ptr2
|= 1; // This or'ed value isn't important
445 /****************************************************************************************/
447 void vgaRefreshArea(struct VGAGfxBitMapData
*bmap
, struct Box
*pbox
)
449 int width
, height
, FBPitch
, left
, right
, i
, j
, SRCPitch
, phase
;
451 unsigned char s1
, s2
, s3
, s4
;
453 unsigned char *dst
, *dstPtr
;
454 unsigned int srcx
, srcy
;
456 /* In 640x480x16 mode VRAM data has planar layout. All 4 bitplanes share
457 the same addresses, we use sequencer register in order to select
458 which plane to write to.
459 is very weird: we have LONGs in which first bytes contain bits 0 of
460 eight pixels, second bytes contain bits 1, third - bits 2 and fourth
461 - bits 3. Despite being planar, this is totally different to Amiga
462 native planar format.
463 Our pixelbuffer always has a simple chunky format, so we perform a
464 4-step chunky to planar conversion. In order to select VRAM bitplanes
465 we use a sequencer's plane select register */
467 /* Start and end coordinates of our box have to be on byte border */
468 left
= pbox
->x1
& ~7; /* Round down left (start) coordinate */
469 right
= (pbox
->x2
& ~7) + 7; /* Round up right (end) coordinate */
471 /* Check if refresh region is completely beyond physical display limits.
473 if ((left
>= bmap
->disp_width
) || (pbox
->y1
>= bmap
->disp_height
))
475 /* Now adjust bottom-right corner */
476 if (right
>= bmap
->disp_width
)
477 right
= bmap
->disp_width
- 1;
478 if (pbox
->y2
< bmap
->disp_height
)
479 height
= pbox
->y2
- pbox
->y1
+ 1;
481 height
= bmap
->disp_height
- pbox
->y1
;
483 /* We don't check top-left corner of the display.
484 We assume that refresh region will never have negative
485 coordinates. Also we assume that the entire screen is
486 covered with the bitmap (i.e. bitmap is not smaller than
487 physical display area and is not moved out of the view.
488 We could implement this, but we trade this off for speed */
490 FBPitch
= bmap
->disp_width
>> 3; /* UBYTEs per line for VRAM */
491 SRCPitch
= bmap
->bpr
>> 2; /* ULONGs per line for pixelbuffer */
493 /* Disable data preprocessing in graphics controller */
494 outw(0x3ce, 0x0005); /* MDR = 0 (direct write) */
495 outw(0x3ce, 0x0001); /* Disable Set/Reset operation */
496 outw(0x3ce, 0x0000); /* Set/Reset data = 0 */
497 outw(0x3ce, 0x0003); /* RFSR = 0 (no shift, no modify) */
498 outw(0x3ce, 0xff08); /* Bit mask = 0xFF (all bits from CPU) */
500 width
= (right
- left
+ 1) >> 3; /* Width of destination box in UBYTEs */
501 /* Calculate start addresses in the pixelbuffer and VRAM */
502 srcx
= left
- bmap
->xoffset
;
503 srcy
= pbox
->y1
- bmap
->yoffset
;
504 /* src is not ULONG-aligned here */
505 src
= (ULONG
*)(bmap
->VideoData
+ srcx
) + srcy
* SRCPitch
;
506 dst
= (unsigned char*)0x000a0000 + (pbox
->y1
* FBPitch
) + (left
>> 3);
508 /* In order to speedup we operate on LONGs. However since our start
509 coordinate may be not LONG-aligned, we probably have to copy
510 some BYTEs before we reach LONG border. phase is a number
512 phase
= (IPTR
)dst
& 3L;
515 if(phase
> width
) phase
= width
;
519 while(height
--) /* For each line */
521 outw(0x3c4, 0x0102); /* Enable write to plane 0 */
522 dstPtr
= dst
; /* Take start pointers */
529 /* Take bits 0 of the 8 pixels and combine them
530 (0B0B0B0B and 0A0A0A0A become BABABABA).
531 We take 8 pixels from source buffer because in one VRAM
532 plane one byte holds 8 bits for 8 different pixels.
533 After this we will get the following:
535 pixel 3 7 2 6 1 5 0 4
536 m 76543210 76543210 76543210 76543210
538 where bottom line is bitstring stored in m and top line
539 contains numbers of pixels these bits came from. Other
540 bits will be 0 (since we masked them out)
542 m
= (srcPtr
[1] & 0x01010101) | ((srcPtr
[0] & 0x01010101) << 4);
543 /* And here we recombine the data into single byte and write
544 them into VRAM. Result of these shift-or operations is:
549 again, bottom line is bit number and top one is pixel number
551 *dstPtr
++ = (m
>> 24) | (m
>> 15) | (m
>> 6) | (m
<< 3);
556 m
= (srcPtr
[1] & 0x01010101) | ((srcPtr
[0] & 0x01010101) << 4);
557 s1
= (m
>> 24) | (m
>> 15) | (m
>> 6) | (m
<< 3);
558 m
= (srcPtr
[3] & 0x01010101) | ((srcPtr
[2] & 0x01010101) << 4);
559 s2
= (m
>> 24) | (m
>> 15) | (m
>> 6) | (m
<< 3);
560 m
= (srcPtr
[5] & 0x01010101) | ((srcPtr
[4] & 0x01010101) << 4);
561 s3
= (m
>> 24) | (m
>> 15) | (m
>> 6) | (m
<< 3);
562 m
= (srcPtr
[7] & 0x01010101) | ((srcPtr
[6] & 0x01010101) << 4);
563 s4
= (m
>> 24) | (m
>> 15) | (m
>> 6) | (m
<< 3);
564 *((ULONG
*)dstPtr
) = s1
| (s2
<< 8) | (s3
<< 16) | (s4
<< 24);
571 m
= (srcPtr
[1] & 0x01010101) | ((srcPtr
[0] & 0x01010101) << 4);
572 *dstPtr
++ = (m
>> 24) | (m
>> 15) | (m
>> 6) | (m
<< 3);
576 outw(0x3c4, 0x0202); /* Enable write to plane 1 */
583 m
= (srcPtr
[1] & 0x02020202) | ((srcPtr
[0] & 0x02020202) << 4);
584 *dstPtr
++ = (m
>> 25) | (m
>> 16) | (m
>> 7) | (m
<< 2);
589 m
= (srcPtr
[1] & 0x02020202) | ((srcPtr
[0] & 0x02020202) << 4);
590 s1
= (m
>> 25) | (m
>> 16) | (m
>> 7) | (m
<< 2);
591 m
= (srcPtr
[3] & 0x02020202) | ((srcPtr
[2] & 0x02020202) << 4);
592 s2
= (m
>> 25) | (m
>> 16) | (m
>> 7) | (m
<< 2);
593 m
= (srcPtr
[5] & 0x02020202) | ((srcPtr
[4] & 0x02020202) << 4);
594 s3
= (m
>> 25) | (m
>> 16) | (m
>> 7) | (m
<< 2);
595 m
= (srcPtr
[7] & 0x02020202) | ((srcPtr
[6] & 0x02020202) << 4);
596 s4
= (m
>> 25) | (m
>> 16) | (m
>> 7) | (m
<< 2);
597 *((ULONG
*)dstPtr
) = s1
| (s2
<< 8) | (s3
<< 16) | (s4
<< 24);
604 m
= (srcPtr
[1] & 0x02020202) | ((srcPtr
[0] & 0x02020202) << 4);
605 *dstPtr
++ = (m
>> 25) | (m
>> 16) | (m
>> 7) | (m
<< 2);
609 outw(0x3c4, 0x0402); /* Enable write to plane 2 */
616 m
= (srcPtr
[1] & 0x04040404) | ((srcPtr
[0] & 0x04040404) << 4);
617 *dstPtr
++ = (m
>> 26) | (m
>> 17) | (m
>> 8) | (m
<< 1);
622 m
= (srcPtr
[1] & 0x04040404) | ((srcPtr
[0] & 0x04040404) << 4);
623 s1
= (m
>> 26) | (m
>> 17) | (m
>> 8) | (m
<< 1);
624 m
= (srcPtr
[3] & 0x04040404) | ((srcPtr
[2] & 0x04040404) << 4);
625 s2
= (m
>> 26) | (m
>> 17) | (m
>> 8) | (m
<< 1);
626 m
= (srcPtr
[5] & 0x04040404) | ((srcPtr
[4] & 0x04040404) << 4);
627 s3
= (m
>> 26) | (m
>> 17) | (m
>> 8) | (m
<< 1);
628 m
= (srcPtr
[7] & 0x04040404) | ((srcPtr
[6] & 0x04040404) << 4);
629 s4
= (m
>> 26) | (m
>> 17) | (m
>> 8) | (m
<< 1);
630 *((ULONG
*)dstPtr
) = s1
| (s2
<< 8) | (s3
<< 16) | (s4
<< 24);
637 m
= (srcPtr
[1] & 0x04040404) | ((srcPtr
[0] & 0x04040404) << 4);
638 *dstPtr
++ = (m
>> 26) | (m
>> 17) | (m
>> 8) | (m
<< 1);
642 outw(0x3c4, 0x0802); /* Enable write to plane 3 */
649 m
= (srcPtr
[1] & 0x08080808) | ((srcPtr
[0] & 0x08080808) << 4);
650 *dstPtr
++ = (m
>> 27) | (m
>> 18) | (m
>> 9) | m
;
655 m
= (srcPtr
[1] & 0x08080808) | ((srcPtr
[0] & 0x08080808) << 4);
656 s1
= (m
>> 27) | (m
>> 18) | (m
>> 9) | m
;
657 m
= (srcPtr
[3] & 0x08080808) | ((srcPtr
[2] & 0x08080808) << 4);
658 s2
= (m
>> 27) | (m
>> 18) | (m
>> 9) | m
;
659 m
= (srcPtr
[5] & 0x08080808) | ((srcPtr
[4] & 0x08080808) << 4);
660 s3
= (m
>> 27) | (m
>> 18) | (m
>> 9) | m
;
661 m
= (srcPtr
[7] & 0x08080808) | ((srcPtr
[6] & 0x08080808) << 4);
662 s4
= (m
>> 27) | (m
>> 18) | (m
>> 9) | m
;
663 *((ULONG
*)dstPtr
) = s1
| (s2
<< 8) | (s3
<< 16) | (s4
<< 24);
670 m
= (srcPtr
[1] & 0x08080808) | ((srcPtr
[0] & 0x08080808) << 4);
671 *dstPtr
++ = (m
>> 27) | (m
>> 18) | (m
>> 9) | m
;
678 } /* while(height--) */
681 /****************************************************************************************/
683 void vgaEraseArea(struct VGAGfxBitMapData
*bmap
, struct Box
*pbox
)
685 int width
, height
, FBPitch
, left
, right
;
688 FBPitch
= bmap
->disp_width
>> 3; /* UBYTEs per line for VRAM */
690 /* Disable data preprocessing in graphics controller */
691 outw(0x3ce, 0x0005); /* MDR = 0 (direct write) */
692 outw(0x3ce, 0x0001); /* Disable Set/Reset operation */
693 outw(0x3ce, 0x0000); /* Set/Reset data = 0 */
694 outw(0x3ce, 0x0003); /* RFSR = 0 (no shift, no modify) */
695 outw(0x3ce, 0xff08); /* Bit mask = 0xFF (all bits from CPU) */
697 /* Start and end coordinates of our box have to be on a byte border,
698 so get X dimensions in bytes */
699 left
= pbox
->x1
>> 3;
700 right
= pbox
->x2
>> 3;
701 width
= right
- left
+ 1;
703 height
= pbox
->y2
- pbox
->y1
+ 1;
704 dst
= (unsigned char*)0x000a0000 + (pbox
->y1
* FBPitch
) + left
;
706 outw(0x3c4, 0x0F02); /* Enable write to all planes */
708 while(height
--) /* For each line */
710 memset(dst
, 0, width
);
712 } /* while(height--) */
715 /****************************************************************************************/