Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenvgavideo.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
1.7.6.1
|