Microsoft KB Archive/108289

{|
 * width="100%"|

PRB: Video Image Corrupted If Stored on Compressed Drive

 * }

Q108289

5.10 6.00 6.00a 7.00 | 1.00 1.50 MS-DOS | WINDOWS kbother kbprb -- The information in this article applies to: - Microsoft C for MS-DOS, versions 5.1 and 6.0 - Microsoft C/C++ for MS-DOS, version 7.0 - Microsoft Visual C++ for Windows, versions 1.0 and 1.5 -- SYMPTOMS ======== A video image stored in a file on a compressed drive is corrupted when written to video memory. If the file is stored on an uncompressed drive, it displays correctly. CAUSE ===== If the amount of data read into a buffer from a file on a compressed drive is less than 8K then DoubleSpace uses an internal buffer for decompression. For larger amounts of data, however, DoubleSpace may use the user's buffer, which in this case is video memory, for temporary storage. DoubleSpace assumes that it can read back from memory the same data it writes. Unfortunately, video memory is write-only on some systems, which results in the video display becoming corrupted. RESOLUTION ========== Workarounds are: - Move the file storing the video image to an uncompressed drive. -or- - Do not read more than 8K at one time from a file on a compressed drive directly into video memory. See the sample code below. -or- - Call setvbuf to increase the buffer for file stream input and output to a value larger than the amount being read in. For example, in the following sample code, a call is made to increase the buffer to 28,500 bytes. STATUS ====== This behavior is by design and is a limitation of DoubleSpace. Similar behavior may be observed with other drive compression utilities. Sample Code --- FILE1.C and FILE2.C create two data files, FILE1.DAT and FILE2.DAT. Place these files on a compressed drive and then run FILE3.EXE. /* FILE1. C Compile options needed: /AL */ #include #include #include FILE *FilePtr; // File pointer char far *VidPtr; // Pointer to video memory int loop1, loop2; // Loop variables int k = 0,l = 10; // Intermediate loop variables void main(void) { _setvideomode( _ERESCOLOR ); // Display some rectangles and lines for (loop1 = 0; loop1 < 6 ; loop1++) { for ( loop2 = 0 ; loop2 < 500; loop2 +=50 ) _rectangle( _GBORDER, loop2, k, loop2+10 , l ); _moveto( 0, k+5); _lineto( loop2, k+5); k+=50; l+=50; } getch; // Set up a pointer to video memory FP_SEG( VidPtr ) = 0xA000; FP_OFF( VidPtr ) = 0x0000; // Open a file to store the video image in FilePtr = fopen( "file1.dat", "w+" ); fwrite( VidPtr, 1, 28000, FilePtr ); fclose ( FilePtr ); _setvideomode( _DEFAULTMODE); } /* FILE2.C Compile options needed: /AL */ #include #include #include FILE *FilePtr; // File pointer char far *VidPtr; // Pointer to video memory int var1; // Loop variable void main(void) { _setvideomode( _ERESCOLOR ); // Draw some lines for (var1 = 5 ; var1 < 555; var1+=50 ) { _moveto( var1, 0); _lineto( var1, 300); } getch; // Initialize the video pointer FP_SEG( VidPtr ) = 0xA000; FP_OFF( VidPtr ) = 0x0000; // Open a file to store the video image FilePtr = fopen( "file2.dat", "w+" ); fwrite( VidPtr, 1, 28000, FilePtr ); fclose ( FilePtr ); _setvideomode( _DEFAULTMODE); } /* FILE3. C Compile options needed: /AL */ #include #include #include #include FILE *FilePtr; // File pointer char far *VidPtr; // Pointer to video memory int var; // Loop variable for workaround #2 char * tmpbuf, *tmpbuf1; // Temporary buffers--se for workaround #3 void main(void) { // Initialize the video pointer FP_SEG( VidPtr ) = 0xA000; FP_OFF( VidPtr ) = 0x0000; _setvideomode( _ERESCOLOR ); // Load the map mask register with a data value. // For further information on this step see the "Programmer's // Guide to PC & PS/2 Video Systems" by Richard Wilton, // published by Microsoft Press. outp( 0x3c4,2); outp( 0x3c5,1); // Open and read FILE1.DAT into video memory FilePtr = fopen( "file1.dat", "rb+" ); /* Uncomment for workaround #3 */ /* if ((tmpbuf = (char*)malloc( 28500 )) == NULL) */ /* exit(5); */ /* setvbuf( FilePtr, tmpbuf, _IOFBF, 28500); */ fread( VidPtr, 1, 28000, FilePtr ); /* Replace the above fread call with this for workaround #2 */ /* for (var = 0; var < 28000; var+=7000) { */ /* fread( VidPtr, 1 , 7000, FilePtr ); */ /* VidPtr += 7000; */ /* } */ // Reset the video pointer FP_OFF( VidPtr ) = 0x0000; // Load the map mask register with a data value outp( 0x3c4,2); outp( 0x3c5,2); // Open and read FILE2.DAT into video memory FilePtr = fopen( "file2.dat", "rb+" ); /* Uncomment for workaround #3 */ /* if ((tmpbuf1 = (char*)malloc( 28500 )) == NULL) */ /* exit(5); */ /* setvbuf( FilePtr, tmpbuf1, _IOFBF, 28500); */ fread( VidPtr, 1 , 28000, FilePtr ); /* Replace the above fread call with this for workaround #2 */ /* for (var = 0; var < 28000; var+=7000) { */ /* fread( VidPtr, 1 , 7000, FilePtr ); */ /* VidPtr += 7000; */ /* } */ getch; _setvideomode( _DEFAULTMODE); } Additional reference words: 5.10 6.00 6.00a 7.00 1.00 1.50 KBCategory: kbprg kbprb KBSubcategory: VCGenIss

Keywords : kb16bitonly

Issue type :

Technology : kbVCsearch kbAudDeveloper kbPTProdChange kbvc150 kbvc100 kbCCompSearch kbZNotKeyword3 kbCComp510DOS kbCComp600DOS kbCVC700DOS