ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

vgavideo.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS VGA display driver
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            drivers/video/displays/vga/vgavideo/vgavideo.c
00005  * PURPOSE:         
00006  * PROGRAMMERS:     
00007  */
00008 
00009 #include <vgaddi.h>
00010 
00011 UCHAR PreCalcReverseByte[256];
00012 int maskbit[640];
00013 int y80[480];
00014 int xconv[640];
00015 int bit8[640];
00016 int startmasks[8];
00017 int endmasks[8];
00018 PBYTE vidmem;
00019 static ULONG UnpackPixel[256];
00020 
00021 static unsigned char leftMask;
00022 static int byteCounter;
00023 static unsigned char rightMask;
00024 
00025 UCHAR bytesPerPixel(ULONG Format)
00026 {
00027     /* This function is taken from /subsys/win32k/eng/surface.c
00028      * FIXME: GDI bitmaps are supposed to be pixel-packed. Right now if the
00029      * pixel size if < 1 byte we expand it to 1 byte for simplicities sake */
00030 
00031     switch (Format)
00032     {
00033         case BMF_1BPP:
00034             return 1;
00035 
00036         case BMF_4BPP:
00037         case BMF_4RLE:
00038             return 1;
00039 
00040         case BMF_8BPP:
00041         case BMF_8RLE:
00042             return 1;
00043 
00044         case BMF_16BPP:
00045             return 2;
00046 
00047         case BMF_24BPP:
00048             return 3;
00049 
00050         case BMF_32BPP:
00051             return 4;
00052 
00053         default:
00054             return 0;
00055     }
00056 }
00057 
00058 VOID vgaPreCalc()
00059 {
00060     ULONG j;
00061 
00062     startmasks[0] = 255;
00063     startmasks[1] = 1;
00064     startmasks[2] = 3;
00065     startmasks[3] = 7;
00066     startmasks[4] = 15;
00067     startmasks[5] = 31;
00068     startmasks[6] = 63;
00069     startmasks[7] = 127;
00070 
00071     endmasks[0] = 0;
00072     endmasks[1] = 128;
00073     endmasks[2] = 192;
00074     endmasks[3] = 224;
00075     endmasks[4] = 240;
00076     endmasks[5] = 248;
00077     endmasks[6] = 252;
00078     endmasks[7] = 254;
00079 
00080     for (j = 0; j < 80; j++)
00081     {
00082         maskbit[j*8]   = 128;
00083         maskbit[j*8+1] = 64;
00084         maskbit[j*8+2] = 32;
00085         maskbit[j*8+3] = 16;
00086         maskbit[j*8+4] = 8;
00087         maskbit[j*8+5] = 4;
00088         maskbit[j*8+6] = 2;
00089         maskbit[j*8+7] = 1;
00090 
00091         bit8[j*8]   = 7;
00092         bit8[j*8+1] = 6;
00093         bit8[j*8+2] = 5;
00094         bit8[j*8+3] = 4;
00095         bit8[j*8+4] = 3;
00096         bit8[j*8+5] = 2;
00097         bit8[j*8+6] = 1;
00098         bit8[j*8+7] = 0;
00099     }
00100     for (j = 0; j < SCREEN_Y; j++)
00101         y80[j]  = j*80;
00102     for (j = 0; j < SCREEN_X; j++)
00103         xconv[j] = j >> 3;
00104 
00105     for (j = 0; j < 256; j++)
00106     {
00107         PreCalcReverseByte[j] =
00108             (((j >> 0) & 0x1) << 7) |
00109             (((j >> 1) & 0x1) << 6) |
00110             (((j >> 2) & 0x1) << 5) |
00111             (((j >> 3) & 0x1) << 4) |
00112             (((j >> 4) & 0x1) << 3) |
00113             (((j >> 5) & 0x1) << 2) |
00114             (((j >> 6) & 0x1) << 1) |
00115             (((j >> 7) & 0x1) << 0);
00116     }
00117 
00118     for (j = 0; j < 256; j++)
00119     {
00120         UnpackPixel[j] =
00121             (((j >> 0) & 0x1) << 4) |
00122             (((j >> 1) & 0x1) << 0) |
00123             (((j >> 2) & 0x1) << 12) |
00124             (((j >> 3) & 0x1) << 8) |
00125             (((j >> 4) & 0x1) << 20) |
00126             (((j >> 5) & 0x1) << 16) |
00127             (((j >> 6) & 0x1) << 28) |
00128             (((j >> 7) & 0x1) << 24);
00129     }
00130 }
00131 
00132 void
00133 get_masks(int x, int w)
00134 {
00135     register int tmp;
00136 
00137     leftMask = rightMask = 0;
00138     byteCounter = w;
00139     /* right margin */
00140     tmp = (x+w) & 7;
00141     if (tmp)
00142     {
00143         byteCounter -= tmp;
00144         rightMask = (unsigned char)(0xff00 >> tmp);
00145     }
00146     /* left margin */
00147     tmp = x & 7;
00148     if (tmp)
00149     {
00150         byteCounter -= (8 - tmp);
00151         leftMask = (0xff >> tmp);
00152     }
00153     /* too small ? */
00154     if (byteCounter < 0)
00155     {
00156         leftMask &= rightMask;
00157         rightMask = 0;
00158         byteCounter = 0;
00159     }
00160     byteCounter /= 8;
00161 }
00162 
00163 VOID vgaPutPixel(INT x, INT y, UCHAR c)
00164 {
00165     ULONG offset;
00166 
00167     offset = xconv[x]+y80[y];
00168 
00169     WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08);
00170     WRITE_PORT_UCHAR((PUCHAR)GRA_D,maskbit[x]);
00171 
00172     READ_REGISTER_UCHAR(vidmem + offset);
00173     WRITE_REGISTER_UCHAR(vidmem + offset, c);
00174 }
00175 
00176 VOID vgaPutByte(INT x, INT y, UCHAR c)
00177 {
00178     ULONG offset;
00179 
00180     offset = xconv[x]+y80[y];
00181 
00182     /* Set the write mode */
00183     WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08);
00184     WRITE_PORT_UCHAR((PUCHAR)GRA_D,0xff);
00185 
00186     WRITE_REGISTER_UCHAR(vidmem + offset, c);
00187 }
00188 
00189 VOID vgaGetByte(
00190     IN ULONG offset,
00191     OUT UCHAR *b,
00192     OUT UCHAR *g,
00193     OUT UCHAR *r,
00194     OUT UCHAR *i)
00195 {
00196     WRITE_PORT_USHORT((PUSHORT)GRA_I, 0x0304);
00197     *i = READ_REGISTER_UCHAR(vidmem + offset);
00198     WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
00199     *r = READ_REGISTER_UCHAR(vidmem + offset);
00200     WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x01);
00201     *g = READ_REGISTER_UCHAR(vidmem + offset);
00202     WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
00203     *b = READ_REGISTER_UCHAR(vidmem + offset);
00204 }
00205 
00206 INT vgaGetPixel(
00207     IN INT x,
00208     IN INT y)
00209 {
00210     UCHAR mask, b, g, r, i;
00211     ULONG offset;
00212 
00213     offset = xconv[x] + y80[y];
00214     vgaGetByte(offset, &b, &g, &r, &i);
00215 
00216     mask = maskbit[x];
00217     b = b & mask;
00218     g = g & mask;
00219     r = r & mask;
00220     i = i & mask;
00221 
00222     mask = bit8[x];
00223     g = g >> mask;
00224     b = b >> mask;
00225     r = r >> mask;
00226     i = i >> mask;
00227 
00228     return (b + 2 * g + 4 * r + 8 * i);
00229 }
00230 
00231 BOOL vgaHLine(INT x, INT y, INT len, UCHAR c)
00232 {
00233     ULONG orgx, pre1, midpre1;
00234     //ULONG orgpre1;
00235     LONG ileftpix, imidpix, irightpix;
00236 
00237     orgx = x;
00238 
00239     /*if ( len < 8 )
00240     {
00241         for (i = x; i < x+len; i++ )
00242             vgaPutPixel ( i, y, c );
00243 
00244         return TRUE;
00245     }*/
00246 
00247     /* Calculate the left mask pixels, middle bytes and right mask pixel */
00248     ileftpix = 7 - mod8(x-1);
00249     irightpix = mod8(x+len);
00250     imidpix = (len-ileftpix-irightpix) / 8;
00251 
00252     pre1 = xconv[(x-1)&~7] + y80[y];
00253     //orgpre1=pre1;
00254 
00255     /* check for overlap ( very short line ) */
00256     if ( (ileftpix+irightpix) > len )
00257     {
00258         int mask = startmasks[ileftpix] & endmasks[irightpix];
00259         /* Write left pixels */
00260         WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08);     // set the mask
00261         WRITE_PORT_UCHAR((PUCHAR)GRA_D,mask);
00262 
00263         READ_REGISTER_UCHAR(vidmem + pre1);
00264         WRITE_REGISTER_UCHAR(vidmem + pre1, c);
00265 
00266         return TRUE;
00267     }
00268 
00269     /* Left */
00270     if ( ileftpix > 0 )
00271     {
00272         /* Write left pixels */
00273         WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08);     // set the mask
00274         WRITE_PORT_UCHAR((PUCHAR)GRA_D,startmasks[ileftpix]);
00275 
00276         READ_REGISTER_UCHAR(vidmem + pre1);
00277         WRITE_REGISTER_UCHAR(vidmem + pre1, c);
00278 
00279         /* Prepare new x for the middle */
00280         x = orgx + 8;
00281     }
00282 
00283     if ( imidpix > 0 )
00284     {
00285         midpre1 = xconv[x] + y80[y];
00286 
00287         /* Set mask to all pixels in byte */
00288         WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);
00289         WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xff);
00290         memset(vidmem+midpre1, c, imidpix); // write middle pixels, no need to read in latch because of the width
00291     }
00292 
00293     if ( irightpix > 0 )
00294     {
00295         x = orgx + len - irightpix;
00296         pre1 = xconv[x] + y80[y];
00297 
00298         /* Write right pixels */
00299         WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08);     // set the mask bits
00300         WRITE_PORT_UCHAR((PUCHAR)GRA_D, endmasks[irightpix]);
00301         READ_REGISTER_UCHAR(vidmem + pre1);
00302         WRITE_REGISTER_UCHAR(vidmem + pre1, c);
00303     }
00304 
00305     return TRUE;
00306 }
00307 
00308 BOOL vgaVLine(INT x, INT y, INT len, UCHAR c)
00309 {
00310     INT offset, i;
00311 
00312     offset = xconv[x]+y80[y];
00313 
00314 #ifdef VGA_PERF
00315     vgaSetBitMaskRegister ( maskbit[x] );
00316 #else
00317     WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08);       // set the mask
00318     WRITE_PORT_UCHAR((PUCHAR)GRA_D,maskbit[x]);
00319 #endif
00320 
00321     for(i=y; i<y+len; i++)
00322     {
00323         READ_REGISTER_UCHAR(vidmem + offset);
00324         WRITE_REGISTER_UCHAR(vidmem + offset, c);
00325         offset += 80;
00326     }
00327 
00328     return TRUE;
00329 }
00330 
00331 static const RECTL rclEmpty = { 0, 0, 0, 0 };
00332 
00333 BOOL VGADDIIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2)
00334 {
00335     prcDst->left  = max(prcSrc1->left, prcSrc2->left);
00336     prcDst->right = min(prcSrc1->right, prcSrc2->right);
00337 
00338     if (prcDst->left < prcDst->right)
00339     {
00340         prcDst->top = max(prcSrc1->top, prcSrc2->top);
00341         prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
00342 
00343        if (prcDst->top < prcDst->bottom)
00344            return TRUE;
00345     }
00346 
00347     *prcDst = rclEmpty;
00348 
00349     return FALSE;
00350 }
00351 
00352 void DIB_BltFromVGA(int x, int y, int w, int h, void *b, int Dest_lDelta)
00353 {
00354     ULONG plane;
00355     ULONG left = x >> 3;
00356     ULONG shift = x - (x & ~0x7);
00357     UCHAR pixel, nextpixel;
00358     LONG rightcount;
00359     INT i, j;
00360     LONG stride = w >> 3;
00361 
00362     /* Calculate the number of rightmost bytes not in a dword block. */
00363     if (w >= 8)
00364     {
00365         rightcount = w % 8;
00366     }
00367     else
00368     {
00369         stride = 0;
00370         rightcount = w;
00371     }
00372 
00373     /* Reset the destination. */
00374     for (j = 0; j < h; j++)
00375         memset((PVOID)((ULONG_PTR)b + (j * Dest_lDelta)), 0, abs(Dest_lDelta));
00376 
00377     for (plane = 0; plane < 4; plane++)
00378     {
00379         PUCHAR dest = b;
00380 
00381         /* Select the plane we are reading in this iteration. */
00382         WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x04);
00383         WRITE_PORT_UCHAR((PUCHAR)GRA_D, plane);
00384 
00385         for (j = 0; j < h; j++)
00386         {
00387             PULONG destline = (PULONG)dest;
00388             PUCHAR src = vidmem + (y + j) * SCREEN_STRIDE + left;
00389             /* Read the data for one plane for an eight aligned pixel block. */
00390             nextpixel = PreCalcReverseByte[READ_REGISTER_UCHAR(src)];
00391             for (i = 0; i < stride; i++, src++, destline++)
00392             {
00393                 /* Form the data for one plane for an aligned block in the destination. */
00394                 pixel = nextpixel;
00395                 pixel >>= shift;
00396 
00397                 nextpixel = PreCalcReverseByte[READ_REGISTER_UCHAR(src + 1)];
00398                 pixel |= (nextpixel << (8 - shift));
00399 
00400                 /* Expand the plane data to 'chunky' format and store. */
00401                 *destline |= (UnpackPixel[pixel] << plane);
00402             }
00403             /* Handle any pixels not falling into a full block. */
00404             if (rightcount != 0)
00405             {
00406                 ULONG row;
00407 
00408                 /* Form the data for a complete block. */
00409                 pixel = nextpixel;
00410                 pixel >>= shift;
00411 
00412                 nextpixel = PreCalcReverseByte[READ_REGISTER_UCHAR(src + 1)];
00413                 pixel |= (nextpixel << (8 - shift));
00414 
00415                 row = UnpackPixel[pixel] << plane;
00416 
00417                 /* Store the data for each pixel in the destination. */
00418                 for (i = 0; i < rightcount; i++)
00419                 {
00420                     ((PUCHAR)destline)[i] |= (row & 0xFF);
00421                     row >>= 8;
00422                 }
00423             }
00424             dest += Dest_lDelta;
00425         }
00426     }
00427 
00428 #ifdef VGA_VERIFY
00429     for (j = 0; j < h; j++)
00430     {
00431         for (i = 0; i < w; i += 2)
00432         {
00433             UCHAR c1, c2;
00434             ULONG mask = (i < (w - 1)) ? 0xFF : 0xF0;
00435 
00436             c1 = (vgaGetPixel(x + i, y + j) << 4) | (vgaGetPixel(x + i + 1, y + j));
00437             c2 = ((PUCHAR)b)[(j * Dest_lDelta) + (i >> 1)];
00438             if ((c1 & mask) != (c2 & mask))
00439                 EngDebugBreak();
00440         }
00441     }
00442 #endif /* VGA_VERIFY */
00443 }
00444 
00445 /* DIB blt to the VGA. */
00446 void DIB_BltToVGA(int x, int y, int w, int h, void *b, int Source_lDelta, int StartMod)
00447 {
00448     PUCHAR pb, opb = b;
00449     LONG i, j;
00450     LONG x2 = x + w;
00451     LONG y2 = y + h;
00452     ULONG offset;
00453 
00454     for (i = x; i < x2; i++)
00455     {
00456         pb = opb;
00457         offset = xconv[i] + y80[y];
00458 
00459         WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);       // set the mask
00460         WRITE_PORT_UCHAR((PUCHAR)GRA_D, maskbit[i]);
00461 
00462         if (StartMod == ((i - x) % 2))
00463         {
00464             for (j = y; j < y2; j++)
00465             {
00466                 READ_REGISTER_UCHAR(vidmem + offset);
00467                 WRITE_REGISTER_UCHAR(vidmem + offset, (*pb & 0xf0) >> 4);
00468                 offset += 80;
00469                 pb += Source_lDelta;
00470             }
00471         }
00472         else
00473         {
00474             for (j = y; j < y2; j++)
00475             {
00476                 READ_REGISTER_UCHAR(vidmem + offset);
00477                 WRITE_REGISTER_UCHAR(vidmem + offset, *pb & 0x0f);
00478                 offset += 80;
00479                 pb += Source_lDelta;
00480             }
00481         }
00482 
00483         if (StartMod != ((i - x) % 2))
00484             opb++;
00485     }
00486 }
00487 
00488 
00489 /* DIB blt to the VGA. */
00490 void DIB_BltToVGAWithXlate(int x, int y, int w, int h, void *b, int Source_lDelta, XLATEOBJ* Xlate)
00491 {
00492     PUCHAR pb, opb = b;
00493     ULONG i, j;
00494     ULONG x2 = x + w;
00495     ULONG y2 = y + h;
00496     ULONG offset;
00497 
00498     for (i = x; i < x2; i++)
00499     {
00500         pb = opb;
00501         offset = xconv[i] + y80[y];
00502 
00503         WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);       // set the mask
00504         WRITE_PORT_UCHAR((PUCHAR)GRA_D, maskbit[i]);
00505 
00506         if (0 == ((i - x) % 2))
00507         {
00508             for (j = y; j < y2; j++)
00509             {
00510                 READ_REGISTER_UCHAR(vidmem + offset);
00511                 WRITE_REGISTER_UCHAR(vidmem + offset, XLATEOBJ_iXlate(Xlate, (*pb & 0xf0) >> 4));
00512                 offset += 80;
00513                 pb += Source_lDelta;
00514             }
00515         }
00516         else
00517         {
00518             for (j = y; j < y2; j++)
00519             {
00520                 READ_REGISTER_UCHAR(vidmem + offset);
00521                 WRITE_REGISTER_UCHAR(vidmem + offset, XLATEOBJ_iXlate(Xlate, *pb & 0x0f));
00522                 offset += 80;
00523                 pb += Source_lDelta;
00524             }
00525         }
00526 
00527         if (0 != ((i - x) % 2))
00528             opb++;
00529     }
00530 }
00531 
00532 /* DIB blt to the VGA.
00533  * For now we just do slow writes -- pixel by pixel,
00534  * packing each one into the correct 4BPP format. */
00535 void DIB_TransparentBltToVGA(int x, int y, int w, int h, void *b, int Source_lDelta, ULONG trans)
00536 
00537 {
00538     PUCHAR pb = b, opb = b;
00539     BOOLEAN edgePixel = FALSE;
00540     ULONG i, j;
00541     ULONG x2 = x + w;
00542     ULONG y2 = y + h;
00543     UCHAR b1, b2;
00544 
00545     /* Check if the width is odd */
00546     if(mod2(w) > 0)
00547     {
00548         edgePixel = TRUE;
00549         x2 -= 1;
00550     }
00551 
00552     for (j=y; j<y2; j++)
00553     {
00554         for (i=x; i<x2; i+=2)
00555         {
00556             b1 = (*pb & 0xf0) >> 4;
00557             b2 = *pb & 0x0f;
00558             if(b1 != trans) vgaPutPixel(i,   j, b1);
00559             if(b2 != trans) vgaPutPixel(i+1, j, b2);
00560             pb++;
00561         }
00562 
00563         if (edgePixel == TRUE)
00564         {
00565             b1 = *pb;
00566             if(b1 != trans) vgaPutPixel(x2, j, b1);
00567             pb++;
00568         }
00569 
00570         opb += Source_lDelta;
00571         pb = opb; // new test code
00572     }
00573 }
00574 
00575 // This algorithm goes from left to right, storing each 4BPP pixel
00576 // in an entire byte.
00577 void FASTCALL
00578 vgaReadScan( int x, int y, int w, void *b )
00579 {
00580     unsigned char *vp, *vpP;
00581     unsigned char data, mask, maskP;
00582     unsigned char *bp;
00583     unsigned char plane_mask;
00584     int plane, i;
00585 
00586     ASSIGNVP4(x, y, vpP)
00587     ASSIGNMK4(x, y, maskP)
00588     get_masks(x, w);
00589     WRITE_PORT_USHORT((PUSHORT)GRA_I, 0x0005);  // read mode 0
00590     WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x04);  // read map select
00591 
00592     memset ( b, 0, w );
00593 
00594     for ( plane=0, plane_mask=1; plane < 4; plane++, plane_mask<<=1 )
00595     {
00596         WRITE_PORT_UCHAR((PUCHAR)GRA_D, plane);  // read map select
00597 
00598         vp = vpP;
00599         bp = b;
00600         if ( leftMask )
00601         {
00602             mask = maskP;
00603             data = *vp++;
00604             do
00605             {
00606                 if (data & mask)
00607                     *bp |= plane_mask;
00608                 bp++;
00609                 mask >>= 1;
00610             } while (mask & leftMask);
00611         }
00612         if (byteCounter)
00613         {
00614             for (i=byteCounter; i>0; i--)
00615             {
00616                 data = *vp++;
00617                 if (data & 0x80) *bp |= plane_mask;
00618                 bp++;
00619                 
00620                 if (data & 0x40) *bp |= plane_mask;
00621                 bp++;
00622                 if (data & 0x20) *bp |= plane_mask;
00623                 bp++;
00624                 if (data & 0x10) *bp |= plane_mask;
00625                 bp++;
00626                 if (data & 0x08) *bp |= plane_mask;
00627                 bp++;
00628                 if (data & 0x04) *bp |= plane_mask;
00629                 bp++;
00630                 if (data & 0x02) *bp |= plane_mask;
00631                 bp++;
00632                 if (data & 0x01) *bp |= plane_mask;
00633                 bp++;
00634             }
00635         }
00636         if (rightMask)
00637         {
00638             mask = 0x80;
00639             data = *vp;
00640             do
00641             {
00642                 if (data & mask)
00643                 *bp |= plane_mask;
00644                 bp++;
00645                 mask >>= 1;
00646             } while (mask & rightMask);
00647         }
00648     }
00649 }
00650 
00651 /* This algorithm goes from left to right
00652  * It stores each 4BPP pixel in an entire byte. */
00653 void FASTCALL
00654 vgaWriteScan ( int x, int y, int w, void *b )
00655 {
00656     unsigned char *bp;
00657     unsigned char *vp;
00658     //unsigned char init_mask;
00659     volatile unsigned char dummy;
00660     //int byte_per_line;
00661     int i, j, off, init_off = x&7;
00662 
00663     bp = b;
00664     ASSIGNVP4(x, y, vp)
00665     //ASSIGNMK4(x, y, init_mask)
00666     //byte_per_line = SCREEN_X >> 3;
00667 
00668     WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);      // write mode 2
00669     WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
00670     WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);      // replace
00671     WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
00672     WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);      // bit mask
00673 
00674     for ( j = 0; j < 8; j++)
00675     {
00676         unsigned int mask = 0x80 >> j;
00677         WRITE_PORT_UCHAR ( (PUCHAR)GRA_D, (unsigned char)mask );
00678         i = j - init_off;
00679         off = 0;
00680         if (j < init_off)
00681             i += 8, off++;
00682         while (i < w)
00683         {
00684             dummy = vp[off];
00685             dummy = bp[i];
00686             vp[off] = dummy;
00687             i += 8;
00688             off++;
00689         }
00690     }
00691 }
00692 
00693 /* This algorithm goes from left to right, and inside that loop, top to bottom.
00694  * It also stores each 4BPP pixel in an entire byte. */
00695 void DFB_BltFromVGA(int x, int y, int w, int h, void *b, int bw)
00696 {
00697     unsigned char *vp, *vpY, *vpP;
00698     unsigned char data, mask, maskP;
00699     unsigned char *bp, *bpY;
00700     unsigned char plane_mask;
00701     int byte_per_line = SCREEN_X >> 3;
00702     int plane, i, j;
00703 
00704     ASSIGNVP4(x, y, vpP)
00705     ASSIGNMK4(x, y, maskP)
00706     get_masks(x, w);
00707     WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);  // read mode 0
00708     WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
00709     WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x04);  // read map select
00710 
00711     /* clear buffer */
00712     bp = b;
00713     for (j = h; j > 0; j--)
00714     {
00715         memset(bp, 0, w);
00716         bp += bw;
00717     }
00718 
00719     for (plane = 0, plane_mask = 1; plane < 4; plane++, plane_mask <<= 1)
00720     {
00721         WRITE_PORT_UCHAR((PUCHAR)GRA_D, plane);  // read map select
00722         vpY = vpP;
00723         bpY = b;
00724         for (j = h; j > 0; j--)
00725         {
00726             vp = vpY;
00727             bp = bpY;
00728             if (leftMask)
00729             {
00730                 mask = maskP;
00731                 data = *vp++;
00732                 do
00733                 {
00734                     if (data & mask)
00735                         *bp |= plane_mask;
00736                     bp++;
00737                     mask >>= 1;
00738                 } while (mask & leftMask);
00739             }
00740             if (byteCounter)
00741             {
00742                 for (i=byteCounter; i>0; i--)
00743                 {
00744                     data = *vp++;
00745                     if (data & 0x80) *bp |= plane_mask;
00746                     bp++;
00747                     if (data & 0x40) *bp |= plane_mask;
00748                     bp++;
00749                     if (data & 0x20) *bp |= plane_mask;
00750                     bp++;
00751                     if (data & 0x10) *bp |= plane_mask;
00752                     bp++;
00753                     if (data & 0x08) *bp |= plane_mask;
00754                     bp++;
00755                     if (data & 0x04) *bp |= plane_mask;
00756                     bp++;
00757                     if (data & 0x02) *bp |= plane_mask;
00758                     bp++;
00759                     if (data & 0x01) *bp |= plane_mask;
00760                     bp++;
00761                 }
00762             }
00763             if (rightMask)
00764             {
00765                 mask = 0x80;
00766                 data = *vp;
00767                 do
00768                 {
00769                     if (data & mask) *bp |= plane_mask;
00770                     bp++;
00771                     mask >>= 1;
00772                 } while (mask & rightMask);
00773             }
00774             bpY += bw;
00775             vpY += byte_per_line;
00776         }
00777     }
00778 
00779     // We don't need this if the next call is a DFB blt to VGA (as in the case of moving the mouse pointer)
00780     WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);      // write mode 2
00781     WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
00782     WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);      // replace
00783     WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
00784 }
00785 
00786 /* This algorithm goes from left to right, and inside that loop, top to bottom.
00787  * It also stores each 4BPP pixel in an entire byte. */
00788 void DFB_BltToVGA(int x, int y, int w, int h, void *b, int bw)
00789 {
00790     unsigned char *bp, *bpX;
00791     unsigned char *vp, *vpX;
00792     unsigned char mask;
00793     //volatile unsigned char dummy;
00794     int byte_per_line;
00795     int i, j;
00796 
00797     bpX = b;
00798     ASSIGNVP4(x, y, vpX)
00799     ASSIGNMK4(x, y, mask)
00800     byte_per_line = SCREEN_X >> 3;
00801 
00802     WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);      // write mode 2
00803     WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
00804     WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);      // replace
00805     WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
00806     WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);      // bit mask
00807 
00808     for (i=w; i>0; i--)
00809     {
00810         WRITE_PORT_UCHAR((PUCHAR)GRA_D, mask);
00811         bp = bpX;
00812         vp = vpX;
00813         for (j = h; j > 0; j--)
00814         {
00815             //dummy = *vp;
00816             *vp = *bp;
00817             bp += bw;
00818             vp += byte_per_line;
00819         }
00820         bpX++;
00821         if ((mask >>= 1) == 0)
00822         {
00823             vpX++;
00824             mask = 0x80;
00825         }
00826     }
00827 }
00828 
00829 /* This algorithm goes from goes from left to right, and inside that loop, top to bottom.
00830  * It also stores each 4BPP pixel in an entire byte. */
00831 void DFB_BltToVGA_Transparent(int x, int y, int w, int h, void *b, int bw, char Trans)
00832 {
00833     unsigned char *bp, *bpX;
00834     unsigned char *vp, *vpX;
00835     unsigned char mask;
00836     //volatile unsigned char dummy;
00837     int byte_per_line;
00838     int i, j;
00839 
00840     bpX = b;
00841     ASSIGNVP4(x, y, vpX)
00842     ASSIGNMK4(x, y, mask)
00843     byte_per_line = SCREEN_X >> 3;
00844 
00845     WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);      // write mode 2
00846     WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
00847     WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);      // replace
00848     WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
00849     WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);      // bit mask
00850 
00851     for (i=w; i>0; i--)
00852     {
00853         WRITE_PORT_UCHAR((PUCHAR)GRA_D, mask);
00854         bp = bpX;
00855         vp = vpX;
00856         for (j=h; j>0; j--)
00857         {
00858             if (*bp != Trans)
00859             {
00860                 //dummy = *vp;
00861                 *vp = *bp;
00862             }
00863             bp += bw;
00864             vp += byte_per_line;
00865         }
00866         bpX++;
00867         if ((mask >>= 1) == 0)
00868         {
00869             vpX++;
00870             mask = 0x80;
00871         }
00872     }
00873 }
00874 
00875 /* This algorithm converts a DFB into a DIB
00876  * WARNING: This algorithm is buggy */
00877 void DFB_BltToDIB(int x, int y, int w, int h, void *b, int bw, void *bdib, int dibw)
00878 {
00879     unsigned char *bp, *bpX, *dib, *dibTmp;
00880     int i, j, dib_shift;
00881 
00882     bpX = b;
00883     dib = (unsigned char *)bdib + y * dibw + (x / 2);
00884 
00885     for (i=w; i>0; i--)
00886     {
00887         /* determine the bit shift for the DIB pixel */
00888         dib_shift = mod2(w-i);
00889         if(dib_shift > 0)
00890             dib_shift = 4;
00891         dibTmp = dib;
00892 
00893         bp = bpX;
00894         for (j = h; j > 0; j--)
00895         {
00896             *dibTmp = *bp << dib_shift | *(bp + 1);
00897             dibTmp += dibw;
00898             bp += bw;
00899         }
00900         bpX++;
00901         if(dib_shift == 0)
00902             dib++;
00903     }
00904 }
00905 
00906 /* This algorithm converts a DIB into a DFB */
00907 void DIB_BltToDFB(int x, int y, int w, int h, void *b, int bw, void *bdib, int dibw)
00908 {
00909     unsigned char *bp, *bpX, *dib, *dibTmp;
00910     int i, j, dib_shift, dib_and;
00911 
00912     bpX = b;
00913     dib = (unsigned char *)bdib + y * dibw + (x / 2);
00914 
00915     for (i=w; i>0; i--)
00916     {
00917         /* determine the bit shift for the DIB pixel */
00918         dib_shift = mod2(w-i);
00919         if(dib_shift > 0)
00920         {
00921             dib_shift = 0;
00922             dib_and = 0x0f;
00923         }
00924         else
00925         {
00926             dib_shift = 4;
00927             dib_and = 0xf0;
00928         }
00929 
00930         dibTmp = dib;
00931         bp = bpX;
00932 
00933         for (j=h; j>0; j--)
00934         {
00935             *bp = (*dibTmp & dib_and) >> dib_shift;
00936             dibTmp += dibw;
00937             bp += bw;
00938         }
00939 
00940         bpX++;
00941         if (dib_shift == 0)
00942             dib++;
00943     }
00944 }

Generated on Fri May 25 2012 04:36:26 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.