revert between 56095 -> 55830 in arch
[AROS.git] / arch / all-native / hidd / vgagfx / vgagfx_support.c
blobb96e9853968c620d1fa6e9f9a0c701d01a59f40a
1 /*
2 Copyright © 1995-2018, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: VGAGfx hardware support routines
6 Lang: English.
7 */
9 /*
10 NOTE: This file is mostly based on XFree86 vgaWH.c sources
13 /****************************************************************************************/
15 #include <proto/exec.h>
16 #include <oop/oop.h>
17 #include <string.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)
107 int i;
109 if (!pal)
110 pal = (unsigned char *)&vgaANSIPalette;
112 for (i=0; i<768; i++)
114 regs->DAC[i]=*(unsigned char*)pal++;
118 /****************************************************************************************/
120 #define SS_START 1
121 #define SS_FINISH 0
123 /****************************************************************************************/
126 ** vgaHWSaveScreen
127 ** perform a sequencer reset.
129 void vgaSaveScreen(int start)
131 if (start == SS_START)
133 outw(0x3C4, 0x0100); /* synchronous reset */
135 else
137 outw(0x3C4, 0x0300); /* end reset */
141 /****************************************************************************************/
144 ** Blank the screen.
146 int vgaBlankScreen(int on)
148 unsigned char scrn;
150 outb(0x3C4,1);
151 scrn = inb(0x3C5);
153 if(on)
155 scrn &= 0xDF; /* enable screen */
157 else
159 scrn |= 0x20; /* blank screen */
162 vgaSaveScreen(SS_START);
163 outw(0x3C4, (scrn << 8) | 0x01); /* change mode */
164 vgaSaveScreen(SS_FINISH);
166 return TRUE;
169 /****************************************************************************************/
171 #define vgaIOBase 0x3d0
173 /****************************************************************************************/
176 ** vgaDACLoad --
177 ** load the DAC
179 void vgaDACLoad(struct vgaHWRec *restore, unsigned char start, int num)
181 int i, n;
183 n = start * 3;
184 outb(0x3C8,start);
185 for (i=0; i<num*3; i++)
187 outb(0x3C9, restore->DAC[n++]);
188 /* DACDelay;
189 I beleive incrementing variables and checking cycle counter
190 provides enough delay. Uncomment this in case of problems */
195 ** vgaRestore --
196 ** restore a video mode
198 void vgaRestore(struct vgaHWRec *restore)
200 int i;
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]);
223 outb(0x3C6,0xFF);
225 vgaDACLoad(restore, 0, 256);
227 /* Turn on PAS bit */
228 inb(vgaIOBase + 0x0A);
229 outb(0x3C0, 0x20);
232 /****************************************************************************************/
235 ** Init VGA registers for given displaymode
237 int vgaInitMode(struct vgaModeDesc *mode, struct vgaHWRec *regs)
239 unsigned int i;
240 int hblankstart;
241 int hblankend;
242 int vblankstart;
243 int vblankend;
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)
262 // VDisplay *= 2;
263 if (VDisplay < 400)
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 */
269 else
270 regs->MiscOutReg = 0x23; /* +hsync +vsync */
273 regs->MiscOutReg |= (regs->NoClock & 0x03) << 2;
276 Time Sequencer
278 regs->Sequencer[0] = 0x02;
279 // if (mode->Flags & V_CLKDIV2) /* TODO */
280 // regs->Sequencer[1] = 0x09;
281 // else
282 regs->Sequencer[1] = 0x01;
284 regs->Sequencer[2] = 0x0F;
285 regs->Sequencer[3] = 0x00; /* Font select */
286 regs->Sequencer[4] = 0x06; /* Misc */
289 CRTC Controller
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);
312 if (i < 0x80)
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 ) |
325 0x10 |
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))
355 i = 0;
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))
369 i = 0;
371 else
373 i = (UBYTE)(i - 1);
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;
417 return TRUE;
420 /****************************************************************************************/
422 void vgaRefreshPixel(struct VGAGfxBitMapData *data, unsigned int x, unsigned int y)
424 int pix;
425 char *ptr, *ptr2;
426 UWORD fg;
427 unsigned int srcx = x - data->xoffset;
428 unsigned int srcy = y - data->yoffset;
430 ptr = (char *)(data->VideoData + srcx + (srcy * data->bpr));
431 fg = *ptr;
432 ptr2 = (char *)(IPTR)(0xa0000 + (x + (y * data->disp_width)) / 8);
433 pix = 0x8000 >> (x % 8);
435 outw(0x3c4,0x0f02);
436 outw(0x3ce,pix | 8);
437 outw(0x3ce,0x0005);
438 outw(0x3ce,0x0003);
439 outw(0x3ce,(fg << 8));
440 outw(0x3ce,0x0f01);
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;
450 register ULONG m;
451 unsigned char s1, s2, s3, s4;
452 ULONG *src, *srcPtr;
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.
472 If so, do nothing */
473 if ((left >= bmap->disp_width) || (pbox->y1 >= bmap->disp_height))
474 return;
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;
480 else
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
511 of these bytes */
512 phase = (IPTR)dst & 3L;
513 if (phase) {
514 phase = 4 - phase;
515 if(phase > width) phase = width;
516 width -= phase;
519 while(height--) /* For each line */
521 outw(0x3c4, 0x0102); /* Enable write to plane 0 */
522 dstPtr = dst; /* Take start pointers */
523 srcPtr = src;
524 i = width;
525 j = phase;
527 while(j--)
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:
546 pixel 01234567
547 value 76543210
549 again, bottom line is bit number and top one is pixel number
551 *dstPtr++ = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
552 srcPtr += 2;
555 while(i >= 4) {
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);
565 srcPtr += 8;
566 dstPtr += 4;
567 i -= 4;
570 while(i--) {
571 m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4);
572 *dstPtr++ = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
573 srcPtr += 2;
576 outw(0x3c4, 0x0202); /* Enable write to plane 1 */
577 dstPtr = dst;
578 srcPtr = src;
579 i = width;
580 j = phase;
582 while(j--) {
583 m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4);
584 *dstPtr++ = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
585 srcPtr += 2;
588 while(i >= 4) {
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);
598 srcPtr += 8;
599 dstPtr += 4;
600 i -= 4;
603 while(i--) {
604 m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4);
605 *dstPtr++ = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
606 srcPtr += 2;
609 outw(0x3c4, 0x0402); /* Enable write to plane 2 */
610 dstPtr = dst;
611 srcPtr = src;
612 i = width;
613 j = phase;
615 while(j--) {
616 m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4);
617 *dstPtr++ = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
618 srcPtr += 2;
621 while(i >= 4) {
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);
631 srcPtr += 8;
632 dstPtr += 4;
633 i -= 4;
636 while(i--) {
637 m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4);
638 *dstPtr++ = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
639 srcPtr += 2;
642 outw(0x3c4, 0x0802); /* Enable write to plane 3 */
643 dstPtr = dst;
644 srcPtr = src;
645 i = width;
646 j = phase;
648 while(j--) {
649 m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4);
650 *dstPtr++ = (m >> 27) | (m >> 18) | (m >> 9) | m;
651 srcPtr += 2;
654 while(i >= 4) {
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);
664 srcPtr += 8;
665 dstPtr += 4;
666 i -= 4;
669 while(i--) {
670 m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4);
671 *dstPtr++ = (m >> 27) | (m >> 18) | (m >> 9) | m;
672 srcPtr += 2;
675 dst += FBPitch;
676 src += SRCPitch;
678 } /* while(height--) */
681 /****************************************************************************************/
683 void vgaEraseArea(struct VGAGfxBitMapData *bmap, struct Box *pbox)
685 int width, height, FBPitch, left, right;
686 unsigned char *dst;
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);
711 dst += FBPitch;
712 } /* while(height--) */
715 /****************************************************************************************/