move Drivers -> drivers
[AROS.git] / arch / i386-pc / drivers / vga.hidd / vgahw.c
blobc0cd24eeac52d22df534e8b98574f6b83705e8c4
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: VGA Inside...
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 "vgahw.h"
18 #include "vgaclass.h"
19 #include "bitmap.h"
21 /****************************************************************************************/
23 #undef SysBase
24 #define SysBase (*(struct ExecBase **)4UL)
26 /****************************************************************************************/
28 #define min(a,b) ((a) < (b) ? (a) : (b))
29 #define max(a,b) ((a) > (b) ? (a) : (b))
31 /****************************************************************************************/
33 /* Default ANSI (PC's) palette */
35 unsigned char vgaANSIPalette[]=
37 0, 0, 0, 0, 0, 42, 0, 42, 0, 0, 42, 42,
38 42, 0, 0, 42, 0, 42, 42, 21, 0, 42, 42, 42,
39 /* 21, 21, 21, 21, 21, 63, 21, 63, 21, 21, 63, 63,
40 A temporary measure which prevents annoying effect of
41 a pointer appearing in strange colors before the first
42 screen opens.
43 In fact the pointer should appear only upon opening of
44 the first screen. */
45 21, 21, 21, 224, 64, 64, 0, 0, 0, 224,224,192,
46 63, 21, 21, 63, 21, 63, 63, 63, 21, 63, 63, 63,
47 0, 0, 0, 5, 5, 5, 8, 8, 8, 11, 11, 11,
48 14, 14, 14, 17, 17, 17, 20, 20, 20, 24, 24, 24,
49 28, 28, 28, 32, 32, 32, 36, 36, 36, 40, 40, 40,
50 45, 45, 45, 50, 50, 50, 56, 56, 56, 63, 63, 63,
51 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0, 63,
52 63, 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16,
53 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0,
54 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63, 0,
55 0, 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47,
56 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63,
57 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31, 63,
58 63, 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39,
59 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31,
60 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63, 31,
61 31, 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55,
62 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63,
63 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45, 63,
64 63, 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49,
65 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45,
66 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63, 45,
67 45, 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58,
68 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63,
69 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0, 28,
70 28, 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7,
71 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0,
72 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28, 0,
73 0, 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21,
74 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28,
75 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14, 28,
76 28, 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17,
77 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14,
78 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28, 14,
79 14, 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24,
80 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28,
81 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20, 28,
82 28, 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22,
83 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20,
84 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28, 20,
85 20, 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26,
86 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28,
87 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0, 16,
88 16, 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4,
89 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0,
90 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16, 0,
91 0, 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12,
92 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16,
93 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8, 16,
94 16, 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10,
95 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8,
96 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16, 8,
97 8, 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14,
98 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16,
99 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11, 16,
100 16, 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12,
101 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11,
102 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16, 11,
103 11, 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15,
104 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16,
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
109 /****************************************************************************************/
112 ** Load specified palette, if NULL load default
114 void vgaLoadPalette(struct vgaHWRec *regs, unsigned char *pal)
116 int i;
118 if (!pal)
119 pal = (unsigned char *)&vgaANSIPalette;
121 for (i=0; i<768; i++)
123 regs->DAC[i]=*(unsigned char*)pal++;
127 /****************************************************************************************/
129 #define SS_START 1
130 #define SS_FINISH 0
132 /****************************************************************************************/
135 ** vgaHWSaveScreen
136 ** perform a sequencer reset.
138 void vgaSaveScreen(int start)
140 if (start == SS_START)
142 outw(0x3C4, 0x0100); /* synchronous reset */
144 else
146 outw(0x3C4, 0x0300); /* end reset */
150 /****************************************************************************************/
153 ** Blank the screen.
155 int vgaBlankScreen(int on)
157 unsigned char scrn;
159 outb(0x3C4,1);
160 scrn = inb(0x3C5);
162 if(on)
164 scrn &= 0xDF; /* enable screen */
166 else
168 scrn |= 0x20; /* blank screen */
171 vgaSaveScreen(SS_START);
172 outw(0x3C4, (scrn << 8) | 0x01); /* change mode */
173 vgaSaveScreen(SS_FINISH);
175 return TRUE;
178 /****************************************************************************************/
180 #define vgaIOBase 0x3d0
182 /****************************************************************************************/
185 ** vgaDACLoad --
186 ** load the DAC
188 void vgaDACLoad(struct vgaHWRec *restore, unsigned char start, int num)
190 int i, n;
192 n = start * 3;
193 outb(0x3C8,start);
194 for (i=0; i<num*3; i++)
196 outb(0x3C9, restore->DAC[n++]);
197 /* DACDelay;
198 I beleive incrementing variables and checking cycle counter
199 provides enough delay. Uncomment this in case of problems */
204 ** vgaRestore --
205 ** restore a video mode
207 void vgaRestore(struct vgaHWRec *restore, BOOL onlyDac)
209 int i,tmp;
211 if (!onlyDac)
213 tmp = inb(vgaIOBase + 0x0A); /* Reset flip-flop */
214 outb(0x3C0, 0x00); /* Enables pallete access */
216 restore->MiscOutReg |= 0x01;
217 outb(0x3C2, restore->MiscOutReg);
219 for (i=1; i<5; i++) outw(0x3C4, (restore->Sequencer[i] << 8) | i);
221 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */
223 outw(vgaIOBase + 4, ((restore->CRTC[17] & 0x7F) << 8) | 17);
225 for (i=0; i<25; i++) outw(vgaIOBase + 4,(restore->CRTC[i] << 8) | i);
227 for (i=0; i<9; i++) outw(0x3CE, (restore->Graphics[i] << 8) | i);
229 for (i=0; i<21; i++) {
230 tmp = inb(vgaIOBase + 0x0A);
231 outb(0x3C0,i); outb(0x3C0, restore->Attribute[i]);
234 outb(0x3C6,0xFF);
237 vgaDACLoad(restore, 0, 256);
239 if (!onlyDac)
241 /* Turn on PAS bit */
242 tmp = inb(vgaIOBase + 0x0A);
243 outb(0x3C0, 0x20);
247 /****************************************************************************************/
250 ** vgaSave --
251 ** save the current video mode
253 void * vgaSave(struct vgaHWRec *save)
255 int i,tmp;
256 int first_time = FALSE; /* Should be static? */
259 * Here we are, when we first save the videostate. This means we came here
260 * to save the original Text mode. Because some drivers may depend
261 * on NoClock we set it here to a resonable value.
263 first_time = TRUE;
264 save->NoClock = (inb(0x3CC) >> 2) & 3;
265 save->MiscOutReg = inb(0x3CC);
267 tmp = inb(vgaIOBase + 0x0A); /* reset flip-flop */
268 outb(0x3C0, 0x00);
271 * save the colorlookuptable
273 outb(0x3C7,0x01);
274 for (i=3; i<768; i++)
276 save->DAC[i] = inb(0x3C9);
277 DACDelay;
280 for (i=0; i<25; i++)
282 outb(vgaIOBase + 4,i);
283 save->CRTC[i] = inb(vgaIOBase + 5);
286 for (i=0; i<21; i++)
288 tmp = inb(vgaIOBase + 0x0A);
289 outb(0x3C0,i);
290 save->Attribute[i] = inb(0x3C1);
293 for (i=0; i<9; i++)
295 outb(0x3CE,i);
296 save->Graphics[i] = inb(0x3CF);
299 for (i=0; i<5; i++)
301 outb(0x3C4,i);
302 save->Sequencer[i] = inb(0x3C5);
305 tmp = inb(vgaIOBase + 0x0A);
306 outb(0x3C0, 0x20);
308 return ((void *) save);
311 /****************************************************************************************/
314 ** Init VGA registers for given displaymode
316 int vgaInitMode(struct vgaModeDesc *mode, struct vgaHWRec *regs)
318 unsigned int i;
319 int hblankstart;
320 int hblankend;
321 int vblankstart;
322 int vblankend;
325 initialize default colormap for monochrome
327 for (i = 0; i < 3; i++) regs->DAC[i] = 0x00;
328 for (i = 3; i < 768; i++) regs->DAC[i] = 0x3F;
330 /* Initialise overscan register */
331 regs->Attribute[17] = 0xFF;
333 regs->NoClock = mode->clock;
336 compute correct Hsync & Vsync polarity
339 int VDisplay = mode->Height;
340 // if (mode->Flags & V_DBLSCAN)
341 // VDisplay *= 2;
342 if (VDisplay < 400)
343 regs->MiscOutReg = 0xA3; /* +hsync -vsync */
344 else if (VDisplay < 480)
345 regs->MiscOutReg = 0x63; /* -hsync +vsync */
346 else if (VDisplay < 768)
347 regs->MiscOutReg = 0xE3; /* -hsync -vsync 0xE3 */
348 else
349 regs->MiscOutReg = 0x23; /* +hsync +vsync */
352 regs->MiscOutReg |= (regs->NoClock & 0x03) << 2;
355 Time Sequencer
357 regs->Sequencer[0] = 0x02;
358 // if (mode->Flags & V_CLKDIV2) /* TODO */
359 // regs->Sequencer[1] = 0x09;
360 // else
361 regs->Sequencer[1] = 0x01;
363 regs->Sequencer[2] = 0x0F;
364 regs->Sequencer[3] = 0x00; /* Font select */
365 regs->Sequencer[4] = 0x06; /* Misc */
368 CRTC Controller
371 hblankstart = min(mode->HSyncStart, mode->HDisplay);
372 hblankend = max(mode->HSyncEnd, mode->HTotal);
373 if ((hblankend - hblankstart) >= 63 * 8)
375 hblankstart = hblankend - 63 * 8;
378 vblankstart = min(mode->VSyncStart, mode->VDisplay);
379 vblankend = max(mode->VSyncEnd, mode->VTotal);
380 if ((vblankend - vblankstart) >= 127)
382 vblankstart = vblankend - 127;
385 regs->CRTC[CRTC_H_TOTAL] = (mode->HTotal / 8) - 5;
386 regs->CRTC[CRTC_H_DISPLAY] = (mode->HDisplay / 8) - 1;
387 regs->CRTC[CRTC_H_BLANK_START] = (hblankstart / 8) -1;
388 regs->CRTC[CRTC_H_BLANK_END] = (((hblankend / 8) - 1) & 0x1F) | 0x80;
390 i = (((mode->HSkew << 2) + 0x10) & ~0x1F);
391 if (i < 0x80)
393 regs->CRTC[CRTC_H_BLANK_END] |= i;
396 regs->CRTC[CRTC_H_SYNC_START] = (mode->HSyncStart / 8);
397 regs->CRTC[CRTC_H_SYNC_END] = ((((hblankend / 8) - 1) & 0x20 ) << 2 ) |
398 (((mode->HSyncEnd / 8)) & 0x1F);
399 regs->CRTC[CRTC_V_TOTAL] = (mode->VTotal - 2) & 0xFF;
400 regs->CRTC[CRTC_OVERFLOW] = (((mode->VTotal -2) & 0x100) >> 8 ) |
401 (((mode->VDisplay -1) & 0x100) >> 7 ) |
402 ((mode->VSyncStart & 0x100) >> 6 ) |
403 (((vblankstart - 1) & 0x100) >> 5 ) |
404 0x10 |
405 (((mode->VTotal -2) & 0x200) >> 4 ) |
406 (((mode->VDisplay -1) & 0x200) >> 3 ) |
407 ((mode->VSyncStart & 0x200) >> 2 );
408 regs->CRTC[CRTC_PRESET_ROW] = 0x00;
409 regs->CRTC[CRTC_MAX_SCAN] = (((vblankstart - 1) & 0x200) >>4) | 0x40;
410 // if (mode->Flags & V_DBLSCAN)
411 // new->CRTC[9] |= 0x80;
412 regs->CRTC[CRTC_CURSOR_START] = 0x00;
413 regs->CRTC[CRTC_CURSOR_END] = 0x00;
414 regs->CRTC[CRTC_START_HI] = 0x00;
415 regs->CRTC[CRTC_START_LO] = 0x00;
416 regs->CRTC[CRTC_CURSOR_HI] = 0x00;
417 regs->CRTC[CRTC_CURSOR_LO] = 0x00;
418 regs->CRTC[CRTC_V_SYNC_START] = mode->VSyncStart & 0xFF;
419 regs->CRTC[CRTC_V_SYNC_END] = (mode->VSyncEnd & 0x0F) | 0x20;
420 regs->CRTC[CRTC_V_DISP_END] = (mode->VDisplay -1) & 0xFF;
421 regs->CRTC[CRTC_OFFSET] = mode->Width >> (8 - mode->Depth); /* just a guess */
422 regs->CRTC[CRTC_UNDERLINE] = 0x00;
423 regs->CRTC[CRTC_V_BLANK_START] = (vblankstart - 1) & 0xFF;
424 regs->CRTC[CRTC_V_BLANK_END] = (vblankend - 1) & 0xFF;
425 regs->CRTC[CRTC_MODE] = 0xE3;
426 regs->CRTC[CRTC_LINE_COMPARE] = 0xFF;
428 if ((hblankend / 8) == (mode->HTotal / 8))
430 i = (regs->CRTC[CRTC_H_BLANK_END] & 0x1f) | ((regs->CRTC[CRTC_H_SYNC_END] & 0x80) >> 2);
431 if ((i-- > (regs->CRTC[CRTC_H_BLANK_START] & 0x3F)) &&
432 (hblankend == mode->HTotal))
434 i = 0;
437 regs->CRTC[CRTC_H_BLANK_END] = (regs->CRTC[CRTC_H_BLANK_END] & ~0x1F) | (i & 0x1f);
438 regs->CRTC[CRTC_H_SYNC_END] = (regs->CRTC[CRTC_H_SYNC_END] & ~0x80) | ((i << 2) & 0x80);
441 if (vblankend == mode->VTotal)
443 i = regs->CRTC[CRTC_V_BLANK_END];
444 if ((i > regs->CRTC[CRTC_V_BLANK_START]) &&
445 ((i & 0x7F) > (regs->CRTC[CRTC_V_BLANK_START] & 0x7F)) &&
446 !(regs->CRTC[CRTC_MAX_SCAN] & 0x9f))
448 i = 0;
450 else
452 i = (UBYTE)(i - 1);
454 regs->CRTC[CRTC_V_BLANK_END] = i;
458 Graphics Display Controller
460 regs->Graphics[0] = 0x00;
461 regs->Graphics[1] = 0x00;
462 regs->Graphics[2] = 0x00;
463 regs->Graphics[3] = 0x00;
464 regs->Graphics[4] = 0x00;
465 regs->Graphics[5] = 0x00;
466 regs->Graphics[6] = 0x05; /* only map 64k VGA memory !!!! */
467 regs->Graphics[7] = 0x0F;
468 regs->Graphics[8] = 0xFF;
470 regs->Attribute[0] = 0x00; /* standard colormap translation */
471 regs->Attribute[1] = 0x01;
472 regs->Attribute[2] = 0x02;
473 regs->Attribute[3] = 0x03;
474 regs->Attribute[4] = 0x04;
475 regs->Attribute[5] = 0x05;
476 regs->Attribute[6] = 0x06;
477 regs->Attribute[7] = 0x07;
478 regs->Attribute[8] = 0x08;
479 regs->Attribute[9] = 0x09;
480 regs->Attribute[10] = 0x0A;
481 regs->Attribute[11] = 0x0B;
482 regs->Attribute[12] = 0x0C;
483 regs->Attribute[13] = 0x0D;
484 regs->Attribute[14] = 0x0E;
485 regs->Attribute[15] = 0x0F;
486 regs->Attribute[16] = 0x81; /* wrong for the ET4000 */
487 regs->Attribute[17] = 0x00; /* GJA -- overscan. */
489 Attribute[17] is the overscan, and is initalised above only at startup
490 time, and not when mode switching.
492 regs->Attribute[18] = 0x0F;
493 regs->Attribute[19] = 0x00;
494 regs->Attribute[20] = 0x00;
496 return TRUE;
499 /****************************************************************************************/
501 void vgaRefreshArea(struct bitmap_data *bmap, int num, struct Box *pbox)
503 int width, height, FBPitch, left, right, i, j, SRCPitch, phase;
504 register ULONG m;
505 unsigned char s1, s2, s3, s4;
506 ULONG *src, *srcPtr;
507 unsigned char *dst, *dstPtr;
509 FBPitch = bmap->width >> 3;
510 SRCPitch = bmap->width >> 2;
512 outw(0x3ce, 0x0005);
513 outw(0x3ce, 0x0001);
514 outw(0x3ce, 0x0000);
515 outw(0x3ce, 0x0003);
516 outw(0x3ce, 0xff08);
518 left = pbox->x1 & ~7;
519 right = (pbox->x2 & ~7) + 7;
521 while(num--)
523 width = (right - left + 1) >> 3;
524 height = pbox->y2 - pbox->y1 + 1;
525 src = (ULONG*)bmap->VideoData + (pbox->y1 * SRCPitch) + (left >> 2);
526 dst = (unsigned char*)0x000a0000 + (pbox->y1 * FBPitch) + (left >> 3);
528 if((phase = ((LONG)dst & 3L)))
530 phase = 4 - phase;
531 if(phase > width) phase = width;
532 width -= phase;
535 while(height--)
537 outw(0x3c4, 0x0102); //pvgaHW->writeSeq(pvgaHW, 0x02, 1);
538 dstPtr = dst;
539 srcPtr = src;
540 i = width;
541 j = phase;
543 while(j--)
545 m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4);
546 *dstPtr++ = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
547 srcPtr += 2;
550 while(i >= 4)
552 m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4);
553 s1 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
554 m = (srcPtr[3] & 0x01010101) | ((srcPtr[2] & 0x01010101) << 4);
555 s2 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
556 m = (srcPtr[5] & 0x01010101) | ((srcPtr[4] & 0x01010101) << 4);
557 s3 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
558 m = (srcPtr[7] & 0x01010101) | ((srcPtr[6] & 0x01010101) << 4);
559 s4 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
560 *((ULONG*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
561 srcPtr += 8;
562 dstPtr += 4;
563 i -= 4;
566 while(i--)
568 m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4);
569 *dstPtr++ = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
570 srcPtr += 2;
573 outw(0x3c4, 0x0202); //pvgaHW->writeSeq(pvgaHW, 0x02, 1 << 1);
574 dstPtr = dst;
575 srcPtr = src;
576 i = width;
577 j = phase;
579 while(j--)
581 m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4);
582 *dstPtr++ = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
583 srcPtr += 2;
586 while(i >= 4)
588 m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4);
589 s1 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
590 m = (srcPtr[3] & 0x02020202) | ((srcPtr[2] & 0x02020202) << 4);
591 s2 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
592 m = (srcPtr[5] & 0x02020202) | ((srcPtr[4] & 0x02020202) << 4);
593 s3 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
594 m = (srcPtr[7] & 0x02020202) | ((srcPtr[6] & 0x02020202) << 4);
595 s4 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
596 *((ULONG*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
597 srcPtr += 8;
598 dstPtr += 4;
599 i -= 4;
602 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); //pvgaHW->writeSeq(pvgaHW, 0x02, 1 << 2);
610 dstPtr = dst;
611 srcPtr = src;
612 i = width;
613 j = phase;
615 while(j--)
617 m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4);
618 *dstPtr++ = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
619 srcPtr += 2;
622 while(i >= 4) {
623 m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4);
624 s1 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
625 m = (srcPtr[3] & 0x04040404) | ((srcPtr[2] & 0x04040404) << 4);
626 s2 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
627 m = (srcPtr[5] & 0x04040404) | ((srcPtr[4] & 0x04040404) << 4);
628 s3 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
629 m = (srcPtr[7] & 0x04040404) | ((srcPtr[6] & 0x04040404) << 4);
630 s4 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
631 *((ULONG*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
632 srcPtr += 8;
633 dstPtr += 4;
634 i -= 4;
637 while(i--)
639 m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4);
640 *dstPtr++ = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
641 srcPtr += 2;
644 outw(0x3c4, 0x0802); //pvgaHW->writeSeq(pvgaHW, 0x02, 1 << 3);
645 dstPtr = dst;
646 srcPtr = src;
647 i = width;
648 j = phase;
650 while(j--)
652 m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4);
653 *dstPtr++ = (m >> 27) | (m >> 18) | (m >> 9) | m;
654 srcPtr += 2;
657 while(i >= 4)
659 m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4);
660 s1 = (m >> 27) | (m >> 18) | (m >> 9) | m;
661 m = (srcPtr[3] & 0x08080808) | ((srcPtr[2] & 0x08080808) << 4);
662 s2 = (m >> 27) | (m >> 18) | (m >> 9) | m;
663 m = (srcPtr[5] & 0x08080808) | ((srcPtr[4] & 0x08080808) << 4);
664 s3 = (m >> 27) | (m >> 18) | (m >> 9) | m;
665 m = (srcPtr[7] & 0x08080808) | ((srcPtr[6] & 0x08080808) << 4);
666 s4 = (m >> 27) | (m >> 18) | (m >> 9) | m;
667 *((ULONG*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
668 srcPtr += 8;
669 dstPtr += 4;
670 i -= 4;
673 while(i--)
675 m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4);
676 *dstPtr++ = (m >> 27) | (m >> 18) | (m >> 9) | m;
677 srcPtr += 2;
680 dst += FBPitch;
681 src += SRCPitch;
683 } /* while(height--) */
684 pbox++;
686 } /* while(num--) */
689 /****************************************************************************************/