2 #include <ddk/ntddvid.h>
3 #include <ddk/winddi.h>
4 #include <ntos/minmax.h>
7 UCHAR PreCalcReverseByte[256];
16 static unsigned char saved_SEQ_mask; /* 0x02 */
17 static unsigned char saved_GC_eSR; /* 0x01 */
18 static unsigned char saved_GC_fun; /* 0x03 */
19 static unsigned char saved_GC_rmap; /* 0x04 */
20 static unsigned char saved_GC_mode; /* 0x05 */
21 static unsigned char saved_GC_mask; /* 0x08 */
22 static unsigned char leftMask;
23 static int byteCounter;
24 static unsigned char rightMask;
37 div_t div(int num, int denom)
40 if (num > 0 && denom < 0) {
46 if (num < 0 && denom > 0)
57 int mod(int num, int denom)
59 div_t dvt = div(num, denom);
63 BYTE bytesPerPixel(ULONG Format)
65 // This function is taken from /subsys/win32k/eng/surface.c
66 // FIXME: GDI bitmaps are supposed to be pixel-packed. Right now if the
67 // pixel size if < 1 byte we expand it to 1 byte for simplicities sake
73 if((Format==BMF_4BPP) || (Format==BMF_4RLE))
77 if((Format==BMF_8BPP) || (Format==BMF_8RLE))
150 for (j = 0; j < 256; j++)
152 PreCalcReverseByte[j] =
153 (((j >> 0) & 0x1) << 7) |
154 (((j >> 1) & 0x1) << 6) |
155 (((j >> 2) & 0x1) << 5) |
156 (((j >> 3) & 0x1) << 4) |
157 (((j >> 4) & 0x1) << 3) |
158 (((j >> 5) & 0x1) << 2) |
159 (((j >> 6) & 0x1) << 1) |
160 (((j >> 7) & 0x1) << 0);
165 get_masks(int x, int w)
169 leftMask = rightMask = 0;
175 rightMask = (unsigned char)(0xff00 >> tmp);
180 byteCounter -= (8 - tmp);
181 leftMask = (0xff >> tmp);
184 if (byteCounter < 0) {
185 leftMask &= rightMask;
192 VOID vgaPutPixel(INT x, INT y, UCHAR c)
197 offset = xconv[x]+y80[y];
199 WRITE_PORT_UCHAR((PUCHAR)0x3ce,0x08);
200 WRITE_PORT_UCHAR((PUCHAR)0x3cf,maskbit[x]);
202 a = READ_REGISTER_UCHAR(vidmem + offset);
203 WRITE_REGISTER_UCHAR(vidmem + offset, c);
206 VOID vgaPutByte(INT x, INT y, UCHAR c)
210 offset = xconv[x]+y80[y];
212 // Set the write mode
213 WRITE_PORT_UCHAR((PUCHAR)0x3ce,0x08);
214 WRITE_PORT_UCHAR((PUCHAR)0x3cf,0xff);
216 WRITE_REGISTER_UCHAR(vidmem + offset, c);
219 VOID vgaGetByte(ULONG offset,
223 WRITE_PORT_USHORT((PUSHORT)0x03ce, 0x0304);
224 *i = READ_REGISTER_UCHAR(vidmem + offset);
225 WRITE_PORT_USHORT((PUSHORT)0x03ce, 0x0204);
226 *r = READ_REGISTER_UCHAR(vidmem + offset);
227 WRITE_PORT_USHORT((PUSHORT)0x03ce, 0x0104);
228 *g = READ_REGISTER_UCHAR(vidmem + offset);
229 WRITE_PORT_USHORT((PUSHORT)0x03ce, 0x0004);
230 *b = READ_REGISTER_UCHAR(vidmem + offset);
233 INT vgaGetPixel(INT x, INT y)
235 UCHAR mask, b, g, r, i;
238 offset = xconv[x]+y80[y];
239 vgaGetByte(offset, &b, &g, &r, &i);
253 return(b+2*g+4*r+8*i);
256 BOOL vgaHLine(INT x, INT y, INT len, UCHAR c)
260 ULONG orgpre1, orgx, midpre1;
261 ULONG ileftpix, imidpix, irightpix;
267 for (i=x; i<x+len; i++)
268 vgaPutPixel(i, y, c);
271 // Calculate the left mask pixels, middle bytes and right mask pixel
272 ileftpix = 8-mod(x, 8);
273 irightpix = mod(x+len, 8);
274 imidpix = (len-ileftpix-irightpix) / 8;
276 pre1=xconv[x-(8-ileftpix)]+y80[y];
283 WRITE_PORT_UCHAR((PUCHAR)0x3ce,0x08); // set the mask
284 WRITE_PORT_UCHAR((PUCHAR)0x3cf,startmasks[ileftpix]);
286 a = READ_REGISTER_UCHAR(vidmem + pre1);
287 WRITE_REGISTER_UCHAR(vidmem + pre1, c);
289 // Prepare new x for the middle
295 midpre1=xconv[x]+y80[y];
297 // Set mask to all pixels in byte
298 WRITE_PORT_UCHAR((PUCHAR)0x3ce, 0x08);
299 WRITE_PORT_UCHAR((PUCHAR)0x3cf, 0xff);
300 memset(vidmem+midpre1, c, imidpix); // write middle pixels, no need to read in latch because of the width
303 x=orgx+len-irightpix;
304 pre1=xconv[x]+y80[y];
306 // Write right pixels
307 WRITE_PORT_UCHAR((PUCHAR)0x3ce,0x08); // set the mask bits
308 WRITE_PORT_UCHAR((PUCHAR)0x3cf, endmasks[irightpix]);
310 a = READ_REGISTER_UCHAR(vidmem + pre1);
311 WRITE_REGISTER_UCHAR(vidmem + pre1, c);
317 BOOL vgaVLine(INT x, INT y, INT len, UCHAR c)
322 offset = xconv[x]+y80[y];
324 WRITE_PORT_UCHAR((PUCHAR)0x3ce,0x08); // set the mask
325 WRITE_PORT_UCHAR((PUCHAR)0x3cf,maskbit[x]);
329 for(i=y; i<y+len; i++)
331 a = READ_REGISTER_UCHAR(vidmem + offset);
332 WRITE_REGISTER_UCHAR(vidmem + offset, c);
339 static const RECTL rclEmpty = { 0, 0, 0, 0 };
341 BOOL VGADDIIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2)
343 prcDst->left = max(prcSrc1->left, prcSrc2->left);
344 prcDst->right = min(prcSrc1->right, prcSrc2->right);
346 if (prcDst->left < prcDst->right) {
347 prcDst->top = max(prcSrc1->top, prcSrc2->top);
348 prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
350 if (prcDst->top < prcDst->bottom)
361 void DIB_BltFromVGA(int x, int y, int w, int h, void *b, int Dest_lDelta)
363 // DIB blt from the VGA.
364 // For now we just do slow reads -- pixel by pixel, packing each one into the correct 4BPP format.
366 PBYTE pb = b, opb = b;
367 BOOLEAN edgePixel = FALSE;
373 // Check if the width is odd
382 for (i=x; i<x2; i+=2)
384 b1 = vgaGetPixel(i, j);
385 b2 = vgaGetPixel(i+1, j);
386 *pb = b2 | (b1 << 4);
390 if(edgePixel == TRUE)
392 b1 = vgaGetPixel(x2, j);
397 opb += Dest_lDelta; // new test code
398 pb = opb; // new test code
402 void DIB_BltToVGA(int x, int y, int w, int h, void *b, int Source_lDelta)
404 // DIB blt to the VGA.
405 // For now we just do slow writes -- pixel by pixel, packing each one into the correct 4BPP format.
407 PBYTE pb = b, opb = b;
408 BOOLEAN edgePixel = FALSE;
414 // Check if the width is odd
423 for (i=x; i<x2; i+=2)
425 b1 = (*pb & 0xf0) >> 4;
427 vgaPutPixel(i, j, b1);
428 vgaPutPixel(i+1, j, b2);
432 if(edgePixel == TRUE)
435 vgaPutPixel(x2, j, b1);
439 opb += Source_lDelta;
446 void DIB_TransparentBltToVGA(int x, int y, int w, int h, void *b, int Source_lDelta, ULONG trans)
448 // DIB blt to the VGA.
449 // For now we just do slow writes -- pixel by pixel, packing each one into the correct 4BPP format.
451 PBYTE pb = b, opb = b;
452 BOOLEAN edgePixel = FALSE;
458 // Check if the width is odd
467 for (i=x; i<x2; i+=2)
469 b1 = (*pb & 0xf0) >> 4;
471 if(b1 != trans) vgaPutPixel(i, j, b1);
472 if(b2 != trans) vgaPutPixel(i+1, j, b2);
476 if(edgePixel == TRUE)
479 if(b1 != trans) vgaPutPixel(x2, j, b1);
483 opb += Source_lDelta;
484 pb = opb; // new test code
489 void DFB_BltFromVGA(int x, int y, int w, int h, void *b, int bw)
491 // This algorithm goes from goes from left to right, and inside that loop, top to bottom.
492 // It also stores each 4BPP pixel in an entire byte.
494 unsigned char *vp, *vpY, *vpP;
495 unsigned char data, mask, maskP;
496 unsigned char *bp, *bpY;
497 unsigned char plane_mask;
498 int byte_per_line = SCREEN_X >> 3;
502 ASSIGNMK4(x, y, maskP)
504 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05); // read mode 0
505 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
506 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x04); // read map select
510 for (j=h; j>0; j--) {
515 for (plane=0, plane_mask=1; plane<4; plane++, plane_mask<<=1) {
516 WRITE_PORT_UCHAR((PUCHAR)GRA_D, plane); // read map select
519 for (j=h; j>0; j--) {
526 if (data & mask) *bp |= plane_mask;
529 } while (mask & leftMask);
533 for (i=byteCounter; i>0; i--) {
535 if (data & 0x80) *bp |= plane_mask;
537 if (data & 0x40) *bp |= plane_mask;
539 if (data & 0x20) *bp |= plane_mask;
541 if (data & 0x10) *bp |= plane_mask;
543 if (data & 0x08) *bp |= plane_mask;
545 if (data & 0x04) *bp |= plane_mask;
547 if (data & 0x02) *bp |= plane_mask;
549 if (data & 0x01) *bp |= plane_mask;
557 if (data & mask) *bp |= plane_mask;
560 } while (mask & rightMask);
563 vpY += byte_per_line;
567 // We don't need this if the next call is a DFB blt to VGA (as in the case of moving the mouse pointer)
568 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05); // write mode 2
569 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
570 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03); // replace
571 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
574 void DFB_BltToVGA(int x, int y, int w, int h, void *b, int bw)
576 // This algorithm goes from goes from left to right, and inside that loop, top to bottom.
577 // It also stores each 4BPP pixel in an entire byte.
579 unsigned char *bp, *bpX;
580 unsigned char *vp, *vpX;
582 volatile unsigned char dummy;
588 ASSIGNMK4(x, y, mask)
589 byte_per_line = SCREEN_X >> 3;
591 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05); // write mode 2
592 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
593 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03); // replace
594 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
595 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08); // bit mask
597 for (i=w; i>0; i--) {
598 WRITE_PORT_UCHAR((PUCHAR)GRA_D, mask);
601 for (j=h; j>0; j--) {
608 if ((mask >>= 1) == 0) {
615 void DFB_BltToVGA_Transparent(int x, int y, int w, int h, void *b, int bw, char Trans)
617 // This algorithm goes from goes from left to right, and inside that loop, top to bottom.
618 // It also stores each 4BPP pixel in an entire byte.
620 unsigned char *bp, *bpX;
621 unsigned char *vp, *vpX;
623 volatile unsigned char dummy;
629 ASSIGNMK4(x, y, mask)
630 byte_per_line = SCREEN_X >> 3;
632 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05); // write mode 2
633 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
634 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03); // replace
635 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
636 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08); // bit mask
638 for (i=w; i>0; i--) {
639 WRITE_PORT_UCHAR((PUCHAR)GRA_D, mask);
642 for (j=h; j>0; j--) {
652 if ((mask >>= 1) == 0) {
659 void DFB_BltToDIB(int x, int y, int w, int h, void *b, int bw, void *bdib, int dibw)
661 // This algorithm converts a DFB into a DIB
662 // WARNING: This algorithm is buggy
664 unsigned char *bp, *bpX, *dib, *dibTmp;
668 dib = bdib + y * dibw + (x / 2);
670 for (i=w; i>0; i--) {
672 // determine the bit shift for the DIB pixel
673 dib_shift = mod(w-i, 2);
674 if(dib_shift > 0) dib_shift = 4;
678 for (j=h; j>0; j--) {
679 *dibTmp = *bp << dib_shift | *(bp + 1);
684 if(dib_shift == 0) dib++;
689 void DIB_BltToDFB(int x, int y, int w, int h, void *b, int bw, void *bdib, int dibw)
691 // This algorithm converts a DIB into a DFB
693 unsigned char *bp, *bpX, *dib, *dibTmp;
694 int i, j, dib_shift, dib_and;
697 dib = bdib + y * dibw + (x / 2);
699 for (i=w; i>0; i--) {
701 // determine the bit shift for the DIB pixel
702 dib_shift = mod(w-i, 2);
714 for (j=h; j>0; j--) {
715 *bp = (*dibTmp & dib_and) >> dib_shift;
721 if(dib_shift == 0) dib++;