2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
10 NOTE: This file is mostly based on XFree86 vgaWH.c sources
13 /****************************************************************************************/
15 #include <proto/exec.h>
23 /****************************************************************************************/
26 #define SysBase (*(struct ExecBase **)4UL)
28 /****************************************************************************************/
30 #define min(a,b) ((a) < (b) ? (a) : (b))
31 #define max(a,b) ((a) > (b) ? (a) : (b))
33 /****************************************************************************************/
35 /* Default ANSI (PC's) palette */
37 unsigned char vgaANSIPalette
[]=
39 0, 0, 0, 0, 0, 42, 0, 42, 0, 0, 42, 42,
40 42, 0, 0, 42, 0, 42, 42, 21, 0, 42, 42, 42,
41 21, 21, 21, 21, 21, 63, 21, 63, 21, 21, 63, 63,
42 63, 21, 21, 63, 21, 63, 63, 63, 21, 63, 63, 63,
43 0, 0, 0, 5, 5, 5, 8, 8, 8, 11, 11, 11,
44 14, 14, 14, 17, 17, 17, 20, 20, 20, 24, 24, 24,
45 28, 28, 28, 32, 32, 32, 36, 36, 36, 40, 40, 40,
46 45, 45, 45, 50, 50, 50, 56, 56, 56, 63, 63, 63,
47 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0, 63,
48 63, 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16,
49 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0,
50 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63, 0,
51 0, 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47,
52 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63,
53 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31, 63,
54 63, 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39,
55 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31,
56 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63, 31,
57 31, 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55,
58 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63,
59 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45, 63,
60 63, 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49,
61 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45,
62 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63, 45,
63 45, 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58,
64 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63,
65 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0, 28,
66 28, 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7,
67 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0,
68 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28, 0,
69 0, 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21,
70 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28,
71 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14, 28,
72 28, 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17,
73 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14,
74 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28, 14,
75 14, 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24,
76 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28,
77 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20, 28,
78 28, 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22,
79 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20,
80 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28, 20,
81 20, 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26,
82 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28,
83 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0, 16,
84 16, 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4,
85 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0,
86 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16, 0,
87 0, 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12,
88 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16,
89 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8, 16,
90 16, 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10,
91 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8,
92 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16, 8,
93 8, 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14,
94 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16,
95 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11, 16,
96 16, 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12,
97 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11,
98 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16, 11,
99 11, 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15,
100 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16,
101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105 /****************************************************************************************/
108 ** Load specified palette, if NULL load default
110 void vgaLoadPalette(struct vgaHWRec
*regs
, unsigned char *pal
)
115 pal
= (unsigned char *)&vgaANSIPalette
;
117 for (i
=0; i
<768; i
++)
119 regs
->DAC
[i
]=*(unsigned char*)pal
++;
123 /****************************************************************************************/
128 /****************************************************************************************/
132 ** perform a sequencer reset.
134 void vgaSaveScreen(int start
)
136 if (start
== SS_START
)
138 outw(0x3C4, 0x0100); /* synchronous reset */
142 outw(0x3C4, 0x0300); /* end reset */
146 /****************************************************************************************/
151 int vgaBlankScreen(int on
)
160 scrn
&= 0xDF; /* enable screen */
164 scrn
|= 0x20; /* blank screen */
167 vgaSaveScreen(SS_START
);
168 outw(0x3C4, (scrn
<< 8) | 0x01); /* change mode */
169 vgaSaveScreen(SS_FINISH
);
174 /****************************************************************************************/
176 #define vgaIOBase 0x3d0
178 /****************************************************************************************/
184 void vgaDACLoad(struct vgaHWRec
*restore
, unsigned char start
, int num
)
190 for (i
=0; i
<num
*3; i
++)
192 outb(0x3C9, restore
->DAC
[n
++]);
194 I beleive incrementing variables and checking cycle counter
195 provides enough delay. Uncomment this in case of problems */
201 ** restore a video mode
203 void vgaRestore(struct vgaHWRec
*restore
)
207 inb(vgaIOBase
+ 0x0A); /* Reset flip-flop */
208 outb(0x3C0, 0x00); /* Enables pallete access */
210 restore
->MiscOutReg
|= 0x01;
211 outb(0x3C2, restore
->MiscOutReg
);
213 for (i
=1; i
<5; i
++) outw(0x3C4, (restore
->Sequencer
[i
] << 8) | i
);
215 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */
217 outw(vgaIOBase
+ 4, ((restore
->CRTC
[17] & 0x7F) << 8) | 17);
219 for (i
=0; i
<25; i
++) outw(vgaIOBase
+ 4,(restore
->CRTC
[i
] << 8) | i
);
221 for (i
=0; i
<9; i
++) outw(0x3CE, (restore
->Graphics
[i
] << 8) | i
);
223 for (i
=0; i
<21; i
++) {
224 inb(vgaIOBase
+ 0x0A);
225 outb(0x3C0,i
); outb(0x3C0, restore
->Attribute
[i
]);
230 vgaDACLoad(restore
, 0, 256);
232 /* Turn on PAS bit */
233 inb(vgaIOBase
+ 0x0A);
237 /****************************************************************************************/
240 ** Init VGA registers for given displaymode
242 int vgaInitMode(struct vgaModeDesc
*mode
, struct vgaHWRec
*regs
)
251 initialize default colormap for monochrome
253 for (i
= 0; i
< 3; i
++) regs
->DAC
[i
] = 0x00;
254 for (i
= 3; i
< 768; i
++) regs
->DAC
[i
] = 0x3F;
256 /* Initialise overscan register */
257 regs
->Attribute
[17] = 0xFF;
259 regs
->NoClock
= mode
->clock
;
262 compute correct Hsync & Vsync polarity
265 int VDisplay
= mode
->Height
;
266 // if (mode->Flags & V_DBLSCAN)
269 regs
->MiscOutReg
= 0xA3; /* +hsync -vsync */
270 else if (VDisplay
< 480)
271 regs
->MiscOutReg
= 0x63; /* -hsync +vsync */
272 else if (VDisplay
< 768)
273 regs
->MiscOutReg
= 0xE3; /* -hsync -vsync 0xE3 */
275 regs
->MiscOutReg
= 0x23; /* +hsync +vsync */
278 regs
->MiscOutReg
|= (regs
->NoClock
& 0x03) << 2;
283 regs
->Sequencer
[0] = 0x02;
284 // if (mode->Flags & V_CLKDIV2) /* TODO */
285 // regs->Sequencer[1] = 0x09;
287 regs
->Sequencer
[1] = 0x01;
289 regs
->Sequencer
[2] = 0x0F;
290 regs
->Sequencer
[3] = 0x00; /* Font select */
291 regs
->Sequencer
[4] = 0x06; /* Misc */
297 hblankstart
= min(mode
->HSyncStart
, mode
->HDisplay
);
298 hblankend
= max(mode
->HSyncEnd
, mode
->HTotal
);
299 if ((hblankend
- hblankstart
) >= 63 * 8)
301 hblankstart
= hblankend
- 63 * 8;
304 vblankstart
= min(mode
->VSyncStart
, mode
->VDisplay
);
305 vblankend
= max(mode
->VSyncEnd
, mode
->VTotal
);
306 if ((vblankend
- vblankstart
) >= 127)
308 vblankstart
= vblankend
- 127;
311 regs
->CRTC
[CRTC_H_TOTAL
] = (mode
->HTotal
/ 8) - 5;
312 regs
->CRTC
[CRTC_H_DISPLAY
] = (mode
->HDisplay
/ 8) - 1;
313 regs
->CRTC
[CRTC_H_BLANK_START
] = (hblankstart
/ 8) -1;
314 regs
->CRTC
[CRTC_H_BLANK_END
] = (((hblankend
/ 8) - 1) & 0x1F) | 0x80;
316 i
= (((mode
->HSkew
<< 2) + 0x10) & ~0x1F);
319 regs
->CRTC
[CRTC_H_BLANK_END
] |= i
;
322 regs
->CRTC
[CRTC_H_SYNC_START
] = (mode
->HSyncStart
/ 8);
323 regs
->CRTC
[CRTC_H_SYNC_END
] = ((((hblankend
/ 8) - 1) & 0x20 ) << 2 ) |
324 (((mode
->HSyncEnd
/ 8)) & 0x1F);
325 regs
->CRTC
[CRTC_V_TOTAL
] = (mode
->VTotal
- 2) & 0xFF;
326 regs
->CRTC
[CRTC_OVERFLOW
] = (((mode
->VTotal
-2) & 0x100) >> 8 ) |
327 (((mode
->VDisplay
-1) & 0x100) >> 7 ) |
328 ((mode
->VSyncStart
& 0x100) >> 6 ) |
329 (((vblankstart
- 1) & 0x100) >> 5 ) |
331 (((mode
->VTotal
-2) & 0x200) >> 4 ) |
332 (((mode
->VDisplay
-1) & 0x200) >> 3 ) |
333 ((mode
->VSyncStart
& 0x200) >> 2 );
334 regs
->CRTC
[CRTC_PRESET_ROW
] = 0x00;
335 regs
->CRTC
[CRTC_MAX_SCAN
] = (((vblankstart
- 1) & 0x200) >>4) | 0x40;
336 // if (mode->Flags & V_DBLSCAN)
337 // new->CRTC[9] |= 0x80;
338 regs
->CRTC
[CRTC_CURSOR_START
] = 0x00;
339 regs
->CRTC
[CRTC_CURSOR_END
] = 0x00;
340 regs
->CRTC
[CRTC_START_HI
] = 0x00;
341 regs
->CRTC
[CRTC_START_LO
] = 0x00;
342 regs
->CRTC
[CRTC_CURSOR_HI
] = 0x00;
343 regs
->CRTC
[CRTC_CURSOR_LO
] = 0x00;
344 regs
->CRTC
[CRTC_V_SYNC_START
] = mode
->VSyncStart
& 0xFF;
345 regs
->CRTC
[CRTC_V_SYNC_END
] = (mode
->VSyncEnd
& 0x0F) | 0x20;
346 regs
->CRTC
[CRTC_V_DISP_END
] = (mode
->VDisplay
-1) & 0xFF;
347 regs
->CRTC
[CRTC_OFFSET
] = mode
->Width
>> (8 - mode
->Depth
); /* just a guess */
348 regs
->CRTC
[CRTC_UNDERLINE
] = 0x00;
349 regs
->CRTC
[CRTC_V_BLANK_START
] = (vblankstart
- 1) & 0xFF;
350 regs
->CRTC
[CRTC_V_BLANK_END
] = (vblankend
- 1) & 0xFF;
351 regs
->CRTC
[CRTC_MODE
] = 0xE3;
352 regs
->CRTC
[CRTC_LINE_COMPARE
] = 0xFF;
354 if ((hblankend
/ 8) == (mode
->HTotal
/ 8))
356 i
= (regs
->CRTC
[CRTC_H_BLANK_END
] & 0x1f) | ((regs
->CRTC
[CRTC_H_SYNC_END
] & 0x80) >> 2);
357 if ((i
-- > (regs
->CRTC
[CRTC_H_BLANK_START
] & 0x3F)) &&
358 (hblankend
== mode
->HTotal
))
363 regs
->CRTC
[CRTC_H_BLANK_END
] = (regs
->CRTC
[CRTC_H_BLANK_END
] & ~0x1F) | (i
& 0x1f);
364 regs
->CRTC
[CRTC_H_SYNC_END
] = (regs
->CRTC
[CRTC_H_SYNC_END
] & ~0x80) | ((i
<< 2) & 0x80);
367 if (vblankend
== mode
->VTotal
)
369 i
= regs
->CRTC
[CRTC_V_BLANK_END
];
370 if ((i
> regs
->CRTC
[CRTC_V_BLANK_START
]) &&
371 ((i
& 0x7F) > (regs
->CRTC
[CRTC_V_BLANK_START
] & 0x7F)) &&
372 !(regs
->CRTC
[CRTC_MAX_SCAN
] & 0x9f))
380 regs
->CRTC
[CRTC_V_BLANK_END
] = i
;
384 Graphics Display Controller
386 regs
->Graphics
[0] = 0x00;
387 regs
->Graphics
[1] = 0x00;
388 regs
->Graphics
[2] = 0x00;
389 regs
->Graphics
[3] = 0x00;
390 regs
->Graphics
[4] = 0x00;
391 regs
->Graphics
[5] = 0x00;
392 regs
->Graphics
[6] = 0x05; /* only map 64k VGA memory !!!! */
393 regs
->Graphics
[7] = 0x0F;
394 regs
->Graphics
[8] = 0xFF;
396 regs
->Attribute
[0] = 0x00; /* standard colormap translation */
397 regs
->Attribute
[1] = 0x01;
398 regs
->Attribute
[2] = 0x02;
399 regs
->Attribute
[3] = 0x03;
400 regs
->Attribute
[4] = 0x04;
401 regs
->Attribute
[5] = 0x05;
402 regs
->Attribute
[6] = 0x06;
403 regs
->Attribute
[7] = 0x07;
404 regs
->Attribute
[8] = 0x08;
405 regs
->Attribute
[9] = 0x09;
406 regs
->Attribute
[10] = 0x0A;
407 regs
->Attribute
[11] = 0x0B;
408 regs
->Attribute
[12] = 0x0C;
409 regs
->Attribute
[13] = 0x0D;
410 regs
->Attribute
[14] = 0x0E;
411 regs
->Attribute
[15] = 0x0F;
412 regs
->Attribute
[16] = 0x81; /* wrong for the ET4000 */
413 regs
->Attribute
[17] = 0x00; /* GJA -- overscan. */
415 Attribute[17] is the overscan, and is initialised above only at startup
416 time, and not when mode switching.
418 regs
->Attribute
[18] = 0x0F;
419 regs
->Attribute
[19] = 0x00;
420 regs
->Attribute
[20] = 0x00;
425 /****************************************************************************************/
427 void vgaRefreshPixel(struct bitmap_data
*data
, unsigned int x
, unsigned int y
)
432 unsigned int srcx
= x
- data
->xoffset
;
433 unsigned int srcy
= y
- data
->yoffset
;
435 ptr
= (char *)(data
->VideoData
+ srcx
+ (srcy
* data
->bpr
));
437 ptr2
= (char *)(IPTR
)(0xa0000 + (x
+ (y
* data
->disp_width
)) / 8);
438 pix
= 0x8000 >> (x
% 8);
444 outw(0x3ce,(fg
<< 8));
447 *ptr2
|= 1; // This or'ed value isn't important
450 /****************************************************************************************/
452 void vgaRefreshArea(struct bitmap_data
*bmap
, struct Box
*pbox
)
454 int width
, height
, FBPitch
, left
, right
, i
, j
, SRCPitch
, phase
;
456 unsigned char s1
, s2
, s3
, s4
;
458 unsigned char *dst
, *dstPtr
;
459 unsigned int srcx
, srcy
;
461 /* In 640x480x16 mode VRAM data has planar layout. All 4 bitplanes share
462 the same addresses, we use sequencer register in order to select
463 which plane to write to.
464 is very weird: we have LONGs in which first bytes contain bits 0 of
465 eight pixels, second bytes contain bits 1, third - bits 2 and fourth
466 - bits 3. Despite being planar, this is totally different to Amiga
467 native planar format.
468 Our pixelbuffer always has a simple chunky format, so we perform a
469 4-step chunky to planar conversion. In order to select VRAM bitplanes
470 we use a sequencer's plane select register */
472 /* Start and end coordinates of our box have to be on byte border */
473 left
= pbox
->x1
& ~7; /* Round down left (start) coordinate */
474 right
= (pbox
->x2
& ~7) + 7; /* Round up right (end) coordinate */
476 /* Check if refresh region is completely beyond physical display limits.
478 if ((left
>= bmap
->disp_width
) || (pbox
->y1
>= bmap
->disp_height
))
480 /* Now adjust bottom-right corner */
481 if (right
>= bmap
->disp_width
)
482 right
= bmap
->disp_width
- 1;
483 if (pbox
->y2
< bmap
->disp_height
)
484 height
= pbox
->y2
- pbox
->y1
+ 1;
486 height
= bmap
->disp_height
- pbox
->y1
;
488 /* We don't check top-left corner of the display.
489 We assume that refresh region will never have negative
490 coordinates. Also we assume that the entire screen is
491 covered with the bitmap (i.e. bitmap is not smaller than
492 physical display area and is not moved out of the view.
493 We could implement this, but we trade this off for speed */
495 FBPitch
= bmap
->disp_width
>> 3; /* UBYTEs per line for VRAM */
496 SRCPitch
= bmap
->bpr
>> 2; /* ULONGs per line for pixelbuffer */
498 /* Disable data preprocessing in graphics controller */
499 outw(0x3ce, 0x0005); /* MDR = 0 (direct write) */
500 outw(0x3ce, 0x0001); /* Disable Set/Reset operation */
501 outw(0x3ce, 0x0000); /* Set/Reset data = 0 */
502 outw(0x3ce, 0x0003); /* RFSR = 0 (no shift, no modify) */
503 outw(0x3ce, 0xff08); /* Bit mask = 0xFF (all bits from CPU) */
505 width
= (right
- left
+ 1) >> 3; /* Width of destination box in UBYTEs */
506 /* Calculate start addresses in the pixelbuffer and VRAM */
507 srcx
= left
- bmap
->xoffset
;
508 srcy
= pbox
->y1
- bmap
->yoffset
;
509 /* src is not ULONG-aligned here */
510 src
= (ULONG
*)(bmap
->VideoData
+ srcx
) + srcy
* SRCPitch
;
511 dst
= (unsigned char*)0x000a0000 + (pbox
->y1
* FBPitch
) + (left
>> 3);
513 /* In order to speedup we operate on LONGs. However since our start
514 coordinate may be not LONG-aligned, we probably have to copy
515 some BYTEs before we reach LONG border. phase is a number
517 phase
= (IPTR
)dst
& 3L;
520 if(phase
> width
) phase
= width
;
524 while(height
--) /* For each line */
526 outw(0x3c4, 0x0102); /* Enable write to plane 0 */
527 dstPtr
= dst
; /* Take start pointers */
534 /* Take bits 0 of the 8 pixels and combine them
535 (0B0B0B0B and 0A0A0A0A become BABABABA).
536 We take 8 pixels from source buffer because in one VRAM
537 plane one byte holds 8 bits for 8 different pixels.
538 After this we will get the following:
540 pixel 3 7 2 6 1 5 0 4
541 m 76543210 76543210 76543210 76543210
543 where bottom line is bitstring stored in m and top line
544 contains numbers of pixels these bits came from. Other
545 bits will be 0 (since we masked them out)
547 m
= (srcPtr
[1] & 0x01010101) | ((srcPtr
[0] & 0x01010101) << 4);
548 /* And here we recombine the data into single byte and write
549 them into VRAM. Result of these shift-or operations is:
554 again, bottom line is bit number and top one is pixel number
556 *dstPtr
++ = (m
>> 24) | (m
>> 15) | (m
>> 6) | (m
<< 3);
561 m
= (srcPtr
[1] & 0x01010101) | ((srcPtr
[0] & 0x01010101) << 4);
562 s1
= (m
>> 24) | (m
>> 15) | (m
>> 6) | (m
<< 3);
563 m
= (srcPtr
[3] & 0x01010101) | ((srcPtr
[2] & 0x01010101) << 4);
564 s2
= (m
>> 24) | (m
>> 15) | (m
>> 6) | (m
<< 3);
565 m
= (srcPtr
[5] & 0x01010101) | ((srcPtr
[4] & 0x01010101) << 4);
566 s3
= (m
>> 24) | (m
>> 15) | (m
>> 6) | (m
<< 3);
567 m
= (srcPtr
[7] & 0x01010101) | ((srcPtr
[6] & 0x01010101) << 4);
568 s4
= (m
>> 24) | (m
>> 15) | (m
>> 6) | (m
<< 3);
569 *((ULONG
*)dstPtr
) = s1
| (s2
<< 8) | (s3
<< 16) | (s4
<< 24);
576 m
= (srcPtr
[1] & 0x01010101) | ((srcPtr
[0] & 0x01010101) << 4);
577 *dstPtr
++ = (m
>> 24) | (m
>> 15) | (m
>> 6) | (m
<< 3);
581 outw(0x3c4, 0x0202); /* Enable write to plane 1 */
588 m
= (srcPtr
[1] & 0x02020202) | ((srcPtr
[0] & 0x02020202) << 4);
589 *dstPtr
++ = (m
>> 25) | (m
>> 16) | (m
>> 7) | (m
<< 2);
594 m
= (srcPtr
[1] & 0x02020202) | ((srcPtr
[0] & 0x02020202) << 4);
595 s1
= (m
>> 25) | (m
>> 16) | (m
>> 7) | (m
<< 2);
596 m
= (srcPtr
[3] & 0x02020202) | ((srcPtr
[2] & 0x02020202) << 4);
597 s2
= (m
>> 25) | (m
>> 16) | (m
>> 7) | (m
<< 2);
598 m
= (srcPtr
[5] & 0x02020202) | ((srcPtr
[4] & 0x02020202) << 4);
599 s3
= (m
>> 25) | (m
>> 16) | (m
>> 7) | (m
<< 2);
600 m
= (srcPtr
[7] & 0x02020202) | ((srcPtr
[6] & 0x02020202) << 4);
601 s4
= (m
>> 25) | (m
>> 16) | (m
>> 7) | (m
<< 2);
602 *((ULONG
*)dstPtr
) = s1
| (s2
<< 8) | (s3
<< 16) | (s4
<< 24);
609 m
= (srcPtr
[1] & 0x02020202) | ((srcPtr
[0] & 0x02020202) << 4);
610 *dstPtr
++ = (m
>> 25) | (m
>> 16) | (m
>> 7) | (m
<< 2);
614 outw(0x3c4, 0x0402); /* Enable write to plane 2 */
621 m
= (srcPtr
[1] & 0x04040404) | ((srcPtr
[0] & 0x04040404) << 4);
622 *dstPtr
++ = (m
>> 26) | (m
>> 17) | (m
>> 8) | (m
<< 1);
627 m
= (srcPtr
[1] & 0x04040404) | ((srcPtr
[0] & 0x04040404) << 4);
628 s1
= (m
>> 26) | (m
>> 17) | (m
>> 8) | (m
<< 1);
629 m
= (srcPtr
[3] & 0x04040404) | ((srcPtr
[2] & 0x04040404) << 4);
630 s2
= (m
>> 26) | (m
>> 17) | (m
>> 8) | (m
<< 1);
631 m
= (srcPtr
[5] & 0x04040404) | ((srcPtr
[4] & 0x04040404) << 4);
632 s3
= (m
>> 26) | (m
>> 17) | (m
>> 8) | (m
<< 1);
633 m
= (srcPtr
[7] & 0x04040404) | ((srcPtr
[6] & 0x04040404) << 4);
634 s4
= (m
>> 26) | (m
>> 17) | (m
>> 8) | (m
<< 1);
635 *((ULONG
*)dstPtr
) = s1
| (s2
<< 8) | (s3
<< 16) | (s4
<< 24);
642 m
= (srcPtr
[1] & 0x04040404) | ((srcPtr
[0] & 0x04040404) << 4);
643 *dstPtr
++ = (m
>> 26) | (m
>> 17) | (m
>> 8) | (m
<< 1);
647 outw(0x3c4, 0x0802); /* Enable write to plane 3 */
654 m
= (srcPtr
[1] & 0x08080808) | ((srcPtr
[0] & 0x08080808) << 4);
655 *dstPtr
++ = (m
>> 27) | (m
>> 18) | (m
>> 9) | m
;
660 m
= (srcPtr
[1] & 0x08080808) | ((srcPtr
[0] & 0x08080808) << 4);
661 s1
= (m
>> 27) | (m
>> 18) | (m
>> 9) | m
;
662 m
= (srcPtr
[3] & 0x08080808) | ((srcPtr
[2] & 0x08080808) << 4);
663 s2
= (m
>> 27) | (m
>> 18) | (m
>> 9) | m
;
664 m
= (srcPtr
[5] & 0x08080808) | ((srcPtr
[4] & 0x08080808) << 4);
665 s3
= (m
>> 27) | (m
>> 18) | (m
>> 9) | m
;
666 m
= (srcPtr
[7] & 0x08080808) | ((srcPtr
[6] & 0x08080808) << 4);
667 s4
= (m
>> 27) | (m
>> 18) | (m
>> 9) | m
;
668 *((ULONG
*)dstPtr
) = s1
| (s2
<< 8) | (s3
<< 16) | (s4
<< 24);
675 m
= (srcPtr
[1] & 0x08080808) | ((srcPtr
[0] & 0x08080808) << 4);
676 *dstPtr
++ = (m
>> 27) | (m
>> 18) | (m
>> 9) | m
;
683 } /* while(height--) */
686 /****************************************************************************************/
688 void vgaEraseArea(struct bitmap_data
*bmap
, struct Box
*pbox
)
690 int width
, height
, FBPitch
, left
, right
;
693 FBPitch
= bmap
->disp_width
>> 3; /* UBYTEs per line for VRAM */
695 /* Disable data preprocessing in graphics controller */
696 outw(0x3ce, 0x0005); /* MDR = 0 (direct write) */
697 outw(0x3ce, 0x0001); /* Disable Set/Reset operation */
698 outw(0x3ce, 0x0000); /* Set/Reset data = 0 */
699 outw(0x3ce, 0x0003); /* RFSR = 0 (no shift, no modify) */
700 outw(0x3ce, 0xff08); /* Bit mask = 0xFF (all bits from CPU) */
702 /* Start and end coordinates of our box have to be on byte border */
703 left
= (pbox
->x1
& ~7) + 7; /* Round up left (start) coordinate */
704 right
= (pbox
->x2
& ~7) + 7; /* Round up right (end) coordinate */
705 width
= (right
- left
+ 1) >> 3; /* Width of destination box in UBYTEs */
706 height
= pbox
->y2
- pbox
->y1
+ 1;
707 dst
= (unsigned char*)0x000a0000 + (pbox
->y1
* FBPitch
) + (left
>> 3);
709 outw(0x3c4, 0x0F02); /* Enable write to all planes */
711 while(height
--) /* For each line */
713 memset(dst
, 0, width
);
715 } /* while(height--) */
718 /****************************************************************************************/