home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- * File ATIPAT2.C v1.00
- *
- * Date: 1992/05/18
- *
- * Author: Joel Armengaud
- *
- * This file is the source code of ATIPAT2.EXE, the utility to
- * patch the 256c PM video driver for ATI Wonder video adapter.
- * I included this source because some customers reported problems
- * with some Wonder models. So a hacker will be able with this
- * source code to see what happens... and eventually report to
- * me how to modify it! I can be reached at the following
- * e-mail address:
- *
- * ARMENGAU@FRECP12.BITNET
- *
- * How it works:
- *
- * The ATI Wonder cards have special extended registers to access hi-res
- * modes. These registers can be accessed using I/O ports 1BEh/1BFh.
- * When the PM driver must switch to the 256-color mode, it has to initialize
- * both standard VGA registers and ATI extended registers to the values
- * required for 256c. When you leave the PM screen (switching
- * to a full-screen session), the OS/2 base video handler (BVHVGA.DLL)
- * will only initialize the standard VGA registers, because it does not
- * know about the ATI extended registers. Therefore we must restore
- * the ATI extended registers when leaving the PM session.
- *
- * So I have declared, at the beginning of this file, 2 data
- * structures:
- *
- * Data1 To completely initialize the video registers for
- * for the 256c mode (both standard and extended registers)
- * Data2 To restore to standard VGA.
- *
- * These 2 data structures are used to patch 2 areas in the
- * driver .DLL file. I use two special strings to find the offset
- * of the areas in the file ("Magic1" and "Magic2").
- * These strings just precede the actual area. Let me describe the
- * 2 areas:
- *
- * Area 1 (Precede by string "Magic1"):
- * (To initialize to 256-color mode)
- * Offset Value (hex) Comment
- * 00 64 *do not patch*
- * 01 29 *do not patch*
- * 02 0E *do not patch*
- * 03 00 *do not patch*
- * 04 F0 *do not patch*
- * 05 01 Sequencer register index 1
- * 06 0F Sequencer register index 2
- * 07 00 Sequencer register index 3
- * 08 5A Sequencer register index 4
- * 09 23 Miscellaneous output register
- * 0A 7F CRT register index 0
- * 0B 63 CRT register index 1
- * 0C 65 CRT register index 2
- * 0D 9D CRT register index 3
- * 0E 66 CRT register index 4
- * 0F 9C CRT register index 5
- * 10 38 CRT register index 6
- * 11 1F CRT register index 7
- * 12 00 CRT register index 8
- * 13 00 CRT register index 9
- * 14 00 CRT register index 10
- * 15 00 CRT register index 11
- * 16 00 CRT register index 12
- * 17 00 CRT register index 13
- * 18 00 CRT register index 14
- * 19 00 CRT register index 15
- * 1A 2C CRT register index 16
- * 1B 8E CRT register index 17
- * 1C 2B CRT register index 18
- * 1D 32 CRT register index 19
- * 1E 0F CRT register index 20
- * 1F 32 CRT register index 21
- * 20 34 CRT register index 22
- * 21 E7 CRT register index 23
- * 22 FF CRT register index 24
- * 23 00 Attribute Controller register 0
- * 24 01 Attribute Controller register 1
- * 25 02 Attribute Controller register 2
- * 26 03 Attribute Controller register 3
- * 27 04 Attribute Controller register 4
- * 28 05 Attribute Controller register 5
- * 29 14 Attribute Controller register 6
- * 2A 07 Attribute Controller register 7
- * 2B 38 Attribute Controller register 8
- * 2C 39 Attribute Controller register 9
- * 2D 3A Attribute Controller register 10
- * 2E 3B Attribute Controller register 11
- * 2F 3C Attribute Controller register 12
- * 30 3D Attribute Controller register 13
- * 31 3E Attribute Controller register 14
- * 32 3F Attribute Controller register 15
- * 33 01 Attribute Controller register 16
- * 34 00 Attribute Controller register 17
- * 35 0F Attribute Controller register 18
- * 36 00 Attribute Controller register 19
- * 37 80 Graphics Controller register 0
- * 38 00 Graphics Controller register 1
- * 39 00 Graphics Controller register 2
- * 3A 00 Graphics Controller register 3
- * 3B 00 Graphics Controller register 4
- * 3C 00 Graphics Controller register 5
- * 3D 05 Graphics Controller register 6
- * 3E 0F Graphics Controller register 7
- * 3F FF Graphics Controller register 8
- * 40 B0 Index of ATI extended register
- * 41 29 Value for extended register B0
- * 42 B1 Index of ATI extended register
- * 43 00 Value for extended register B1
- * 44 B3 Index of ATI extended register
- * 45 00 Value for extended register B3
- * 46 B5 Index of ATI extended register
- * 47 08 Value for extended register B5
- * 48 B6 Index of ATI extended register
- * 49 04 Value for extended register B6
- * 4A B8 Index of ATI extended register
- * 4B 00 Value for extended register B8
- * 4C B9 Index of ATI extended register
- * 4D 33 Value for extended register B9
- * 4E BE Index of ATI extended register
- * 4F 00 Value for extended register BE
- * 50 A7 Index of ATI extended register
- * 51 00 Value for extended register A7
- *
- * Area 2 (Precede by string "Magic2"):
- * (To restore to VGA standard mode)
- * Offset Value (hex) Comment
- * 00 50 *do not patch*
- * 01 18 *do not patch*
- * 02 10 *do not patch*
- * 03 00 *do not patch*
- * 04 10 *do not patch*
- * 05 00 Sequencer register index 1
- * 06 03 Sequencer register index 2
- * 07 00 Sequencer register index 3
- * 08 02 Sequencer register index 4
- * 09 67 Miscellaneous output register
- * 0A 5F CRT register index 0
- * 0B 4F CRT register index 1
- * 0C 50 CRT register index 2
- * 0D 82 CRT register index 3
- * 0E 55 CRT register index 4
- * 0F 81 CRT register index 5
- * 10 BF CRT register index 6
- * 11 1F CRT register index 7
- * 12 00 CRT register index 8
- * 13 00 CRT register index 9
- * 14 00 CRT register index 10
- * 15 00 CRT register index 11
- * 16 00 CRT register index 12
- * 17 00 CRT register index 13
- * 18 00 CRT register index 14
- * 19 00 CRT register index 15
- * 1A 9C CRT register index 16
- * 1B 8E CRT register index 17
- * 1C 8F CRT register index 18
- * 1D 28 CRT register index 19
- * 1E 1F CRT register index 20
- * 1F 96 CRT register index 21
- * 20 B9 CRT register index 22
- * 21 A3 CRT register index 23
- * 22 FF CRT register index 24
- * 23 00 Attribute Controller register 0
- * 24 01 Attribute Controller register 1
- * 25 02 Attribute Controller register 2
- * 26 03 Attribute Controller register 3
- * 27 04 Attribute Controller register 4
- * 28 05 Attribute Controller register 5
- * 29 14 Attribute Controller register 6
- * 2A 07 Attribute Controller register 7
- * 2B 38 Attribute Controller register 8
- * 2C 39 Attribute Controller register 9
- * 2D 3A Attribute Controller register 10
- * 2E 3B Attribute Controller register 11
- * 2F 3C Attribute Controller register 12
- * 30 3D Attribute Controller register 13
- * 31 3E Attribute Controller register 14
- * 32 3F Attribute Controller register 15
- * 33 0C Attribute Controller register 16
- * 34 00 Attribute Controller register 17
- * 35 0F Attribute Controller register 18
- * 36 08 Attribute Controller register 19
- * 37 00 Graphics Controller register 0
- * 38 00 Graphics Controller register 1
- * 39 00 Graphics Controller register 2
- * 3A 00 Graphics Controller register 3
- * 3B 00 Graphics Controller register 4
- * 3C 10 Graphics Controller register 5
- * 3D 0E Graphics Controller register 6
- * 3E 00 Graphics Controller register 7
- * 3F FF Graphics Controller register 8
- * 40 B0 Index of ATI extended register
- * 41 08 Value for extended register B0
- * 42 B1 Index of ATI extended register
- * 43 00 Value for extended register B1
- * 44 B3 Index of ATI extended register
- * 45 00 Value for extended register B3
- * 46 B5 Index of ATI extended register
- * 47 08 Value for extended register B5
- * 48 B6 Index of ATI extended register
- * 49 00 Value for extended register B6
- * 4A B8 Index of ATI extended register
- * 4B 40 Value for extended register B8
- * 4C B9 Index of ATI extended register
- * 4D 33 Value for extended register B9
- * 4E BE Index of ATI extended register
- * 4F 10 Value for extended register BE
- * 50 A7 Index of ATI extended register
- * 51 00 Value for extended register A7
- *
- * The following program tries to switch to 256c mode (bios
- * mode 63h or 64h), read the video registers in this mode, goes back to
- * standard VGA mode (bios mode 03, color text), and read extended
- * register values in this mode.
- * Then it tries to apply patches to the file.
- *
- * The Data1 and Data2 structures determine the video registers
- * we want to patch.
- *
- * On some configurations, switching to hires bios video modedoes not
- * work (why??). That's why I test the CRT registers in this mode
- * to determine if the hardware number of video lines is correct.
- * If it is not, I print a warning message.
- *
- * This file is compiled with Microsoft C6.00A, as a DOS program.
- * No special considerations to compile it.
- *
- * Now I let you dig into the code to understand it!
- *
- * -Joel Armengaud
- *
- */
-
- #include <stdio.h>
- #include <dos.h>
-
- typedef unsigned short USHORT ;
- typedef unsigned char BYTE ;
-
- #define INDEXE 0x0001
- #define DIRECT 0x0002
- #define ATTR_TYPE 0x0003
- #define ATI_TYPE 0x0004
- #define THEEND 0x8000
-
- /***********************/
- /* Video i/o addresses */
-
- #define CRT 0x3D4 /* CRT address on color board */
- #define SEQ 0x3C4 /* Sequencer */
- #define GRC 0x3CE /* Graphics Controller */
- #define MISC 0x3CC /* Misc Output Reg (read addr)*/
- #define ATT 0x3C0 /* Attribute Controller */
- #define ATI 0x1CE /* ATI extended registers */
-
- #define NB_MAGIC_STRINGS 2
- #define MAX_STRUCT 0x52
-
-
- typedef struct _DATASTRUCT {
- BYTE Data ; /* Data read from hardware */
- USHORT Flag ; /* Type of video register */
- USHORT Port ; /* I/O port */
- BYTE Index ; /* Register index */
- long FileOffset ; /* Offset from Magic string */
- } DATASTRUCT ;
-
-
- DATASTRUCT Data1 [] = { // Hires mode
- {0x00, DIRECT, MISC, 0x00, 0x09}, /* We patch the misc register */
- {0x00, INDEXE, CRT, 0x00, 0x0A}, /* And so on... */
- {0x00, INDEXE, CRT, 0x01, 0x0B},
- {0x00, INDEXE, CRT, 0x02, 0x0C},
- {0x00, INDEXE, CRT, 0x03, 0x0D},
- {0x00, INDEXE, CRT, 0x04, 0x0E},
- {0x00, INDEXE, CRT, 0x05, 0x0F},
- {0x00, INDEXE, CRT, 0x06, 0x10},
- {0x00, INDEXE, CRT, 0x07, 0x11}, // Needed for CRT lines
- {0x00, INDEXE, CRT, 0x08, 0x12},
- {0x00, INDEXE, CRT, 0x09, 0x13},
- {0x00, INDEXE, CRT, 0x10, 0x1A},
- {0x00, INDEXE, CRT, 0x11, 0x1B},
- {0x00, INDEXE, CRT, 0x12, 0x1C}, // Needed for CRT lines
- {0x00, INDEXE, CRT, 0x13, 0x1D},
- {0x00, INDEXE, CRT, 0x14, 0x1E},
- {0x00, INDEXE, CRT, 0x15, 0x1F},
- {0x00, INDEXE, CRT, 0x16, 0x20},
- {0x00, INDEXE, CRT, 0x17, 0x21},
- {0x09, ATI_TYPE, ATI, 0xB0, 0x41},
- {0x00, ATI_TYPE, ATI, 0xB1, 0x43},
- {0x00, ATI_TYPE, ATI, 0xB3, 0x45},
- {0x08, ATI_TYPE, ATI, 0xB5, 0x47},
- {0x00, ATI_TYPE, ATI, 0xB6, 0x49},
- {0x00, ATI_TYPE, ATI, 0xB8, 0x4B},
- {0x33, ATI_TYPE, ATI, 0xB9, 0x4D},
- {0x00, ATI_TYPE, ATI, 0xBE, 0x4F},
- {0x00, ATI_TYPE, ATI, 0xA7, 0x51},
- {0x00, THEEND, CRT, 0x00},
- } ;
-
- DATASTRUCT Data2 [] = { // Lowres mode (mode 3)
- {0x00, DIRECT, MISC, 0x00, 0x09},
- {0x00, INDEXE, CRT, 0x00, 0x0A},
- {0x00, INDEXE, CRT, 0x01, 0x0B},
- {0x00, INDEXE, CRT, 0x02, 0x0C},
- {0x00, INDEXE, CRT, 0x03, 0x0D},
- {0x00, INDEXE, CRT, 0x04, 0x0E},
- {0x00, INDEXE, CRT, 0x05, 0x0F},
- {0x00, INDEXE, CRT, 0x06, 0x10},
- {0x00, INDEXE, CRT, 0x07, 0x11},
- {0x00, INDEXE, CRT, 0x10, 0x1A},
- {0x00, INDEXE, CRT, 0x11, 0x1B},
- {0x00, INDEXE, CRT, 0x12, 0x1C},
- {0x00, INDEXE, CRT, 0x15, 0x1F},
- {0x00, INDEXE, CRT, 0x16, 0x20},
- {0x09, ATI_TYPE, ATI, 0xB0, 0x41},
- {0x00, ATI_TYPE, ATI, 0xB1, 0x43},
- {0x00, ATI_TYPE, ATI, 0xB3, 0x45},
- {0x08, ATI_TYPE, ATI, 0xB5, 0x47},
- {0x00, ATI_TYPE, ATI, 0xB6, 0x49},
- {0x00, ATI_TYPE, ATI, 0xB8, 0x4B},
- {0x33, ATI_TYPE, ATI, 0xB9, 0x4D},
- {0x00, ATI_TYPE, ATI, 0xBE, 0x4F},
- {0x00, ATI_TYPE, ATI, 0xA7, 0x51},
- {0x00, THEEND, CRT, 0x00},
- } ;
-
- typedef struct _PATCH {
- char *pszMagicString ;
- DATASTRUCT *psData ;
- } PATCH ;
-
- PATCH Patch [NB_MAGIC_STRINGS] = {
- {"Magic1", Data1 },
- {"Magic2", Data2 }
- } ;
-
- #define MAGIC_STRING_RESOLUTION "MagicResolution"
-
-
- /*************************************************************************
- * Locate a string in a file (case sensitive...)
- * Return seek position of the first char following the string
- * or LONG_ERROR
- * or LONG_NOT_FOUND (both are negative values)
- *
- * Limitation: string size should be less than SIZE_BUFFER
- */
-
- #define STAGE_0 0
- #define STAGE_1 1
- #define STAGE_2 2
- #define STAGE_3 3
-
- #define LONG_ERROR -2L
- #define LONG_NOT_FOUND -1L
- #define SIZE_BUFFER 512
-
- BYTE achBuffer [2 * SIZE_BUFFER] ;
-
-
- long FindString (FILE *hFile, char *szString)
- {
- BYTE fStage ;
- size_t cRead ;
- size_t cCharInFirstPartBuffer ;
- size_t cSizeString ;
- USHORT i ;
- long lFilePos ;
-
- /* Return to begining of file */
- if (fseek (hFile, 0L, SEEK_SET))
- return LONG_ERROR ; /* fseek failed */
-
- cSizeString = strlen (szString) ;
- lFilePos = 0L ;
- fStage = STAGE_0 ;
- do
- {
- if (fStage == STAGE_0)
- {
- cRead = fread (achBuffer, 1, SIZE_BUFFER, hFile) ;
- if (cRead == SIZE_BUFFER)
- fStage = STAGE_1 ;
- else
- fStage = STAGE_2 ;
- }
-
- if (fStage == STAGE_1)
- {
- cRead = fread (&achBuffer[SIZE_BUFFER], 1, SIZE_BUFFER, hFile) ;
- }
-
- /***********************************************/
- /* Try to find first char in first part buffer */
- cCharInFirstPartBuffer = (fStage == STAGE_2 ? cRead : SIZE_BUFFER) ;
- for (i = 0; i < cCharInFirstPartBuffer; i++)
- {
- if (achBuffer[i] == *szString)
- {
- /*********************************/
- /* Then compare the whole string */
- if ( strncmp (&achBuffer[i], szString, cSizeString) == 0
- && (i + cSizeString <=
- cCharInFirstPartBuffer
- + (fStage == STAGE_1 ? cRead : 0) ))
- {
- /* String found! */
- return (lFilePos + i + cSizeString) ;
- }
- }
- }
-
- /* Copy second part into first part */
- memcpy (achBuffer, &achBuffer[SIZE_BUFFER], SIZE_BUFFER) ;
-
- lFilePos += SIZE_BUFFER ;
-
- if (fStage == STAGE_1 && cRead < SIZE_BUFFER)
- fStage = STAGE_2 ;
- else if (fStage == STAGE_2)
- fStage = STAGE_3 ;
- }
- while (fStage != STAGE_3) ;
-
- return LONG_NOT_FOUND ;
- }
-
-
- /*************************************************************************
- *
- * Patch file with new video register values
- */
-
- void PatchFile (char *szFileName)
- {
- USHORT i, j ;
- long lFilePos ;
- BYTE achTempBuffer[MAX_STRUCT+1] ; /* Room for all registers */
- FILE *hFile ;
-
-
- hFile = fopen (szFileName, "rb+") ; /* Both read and write */
- if (hFile == NULL)
- {
- printf ("Error: cannot open file %s\n", szFileName) ;
- exit (1) ;
- }
-
- /* For each magic strings */
- for (i = 0; i < NB_MAGIC_STRINGS; i++)
- {
- /* Locate magic string in file */
- lFilePos = FindString (hFile, Patch[i].pszMagicString) ;
- if (lFilePos < 0)
- {
- if (lFilePos == LONG_NOT_FOUND)
- printf ("Error: incorrect file\n") ;
- else
- printf ("Error: cannot read file\n") ;
- exit (1) ;
- }
-
- /* Read zone to patch */
- if (fseek (hFile, lFilePos, SEEK_SET))
- {
- printf ("Error: cannot read file\n") ;
- exit (1) ;
- }
- if (fread (achTempBuffer, 1, MAX_STRUCT, hFile)
- != MAX_STRUCT)
- {
- printf ("Error: cannot read file\n") ;
- exit (1) ;
- }
-
- /* Now patch the buffer */
- for (j = 0; Patch[i].psData[j].Flag != THEEND; j++)
- {
- if (achTempBuffer[ (USHORT)Patch[i].psData[j].FileOffset ]
- != Patch[i].psData[j].Data)
- {
- #ifdef DEBUG
- printf ("File patched at offset %08lX %02X->%02X\n",
- lFilePos+Patch[i].psData[j].FileOffset,
- achTempBuffer[ (USHORT)Patch[i].psData[j].FileOffset ],
- Patch[i].psData[j].Data) ;
- #endif
- achTempBuffer[ (USHORT)Patch[i].psData[j].FileOffset ]
- = Patch[i].psData[j].Data ;
- }
- }
-
- /* And write back to the file */
- if (fseek (hFile, lFilePos, SEEK_SET))
- {
- printf ("Error: cannot read file\n") ;
- exit (1) ;
- }
- if (fwrite (achTempBuffer, 1, MAX_STRUCT, hFile)
- != MAX_STRUCT)
- {
- printf ("Error: cannot write to file\n") ;
- exit (1) ;
- }
- }
-
- fclose (hFile) ; /* Done! */
- }
-
-
- /*************************************************************************
- *
- * Find driver resolution. The resolution is encoded in the .DLL
- * file immediately after the string "MagicResolution".
- */
- BYTE FindBiosVideoMode (char *szFileName, USHORT *pusHiresLines)
- {
- long lFilePos ;
- FILE *hFile ;
-
- hFile = fopen (szFileName, "rb") ; /* Read a binary file */
- if (hFile == NULL)
- {
- printf ("Error: cannot open file %s\n", szFileName) ;
- exit (1) ;
- }
-
- /* Locate magic string */
- lFilePos = FindString (hFile, MAGIC_STRING_RESOLUTION) ;
- if (lFilePos < 0)
- {
- if (lFilePos == LONG_NOT_FOUND)
- printf ("Error: incorrect file\n") ;
- else
- printf ("Error: cannot read file\n") ;
- exit (1) ;
- }
-
- /* Read zone to patch */
- if (fseek (hFile, lFilePos, SEEK_SET))
- {
- printf ("Error: cannot read file\n") ;
- exit (1) ;
- }
- if (fread (pusHiresLines, 1, 2, hFile) /* Read 2 bytes */
- != 2)
- {
- printf ("Error: cannot read file\n") ;
- exit (1) ;
- }
- fclose (hFile) ;
-
- /* Now return bios video mode */
- /* 600 lines -> 0x63 */
- /* 768 lines -> 0x64 */
- return (*pusHiresLines == 600 ? 0x63 : 0x64) ;
- }
-
- /*************************************************************************
- *
- * Read video registers, and fill the data structure.
- */
-
- void ReadRegisters (DATASTRUCT *psData)
- {
- USHORT Port ;
- USHORT i ;
- BYTE Index ;
- BYTE bResult ;
-
- for (i = 0; psData[i].Flag != THEEND; i++)
- {
- switch (psData[i].Flag)
- {
- case INDEXE:
- {
- Port = psData[i].Port ;
- Index = psData[i].Index ;
- _asm { /* Dirty, but efficient... */
- mov dx, Port
- mov al, Index
- cli
- out dx, al
- inc dx
- in al, dx
- sti
- mov bResult, al
- } ;
- }
- break ;
- case ATTR_TYPE:
- {
- Port = psData[i].Port ;
- Index = psData[i].Index ;
- _asm {
- cli
- mov dx, 03BAh /* Reset flip-flop */
- in al, dx
- mov dx, 03DAh
- in al, dx
- mov dx, Port
- mov al, Index
- or al, 20H
- out dx, al
- inc dx
- in al, dx
- sti
- mov bResult, al
- } ;
- }
- break ;
- case ATI_TYPE: /* How to access ATI registers... */
- {
- Port = psData[i].Port ;
- Index = psData[i].Index ;
- _asm {
- mov dx, Port
- mov al, Index
- cli
- out dx, al
- inc dx
- in al, dx
- sti
- mov bResult, al
- } ;
- }
- break ;
- case DIRECT:
- {
- Port = psData[i].Port ;
- _asm {
- mov dx, Port
- in al, dx
- mov bResult, al
- } ;
- }
- break ;
- }
- psData[i].Data = bResult ;
- }
- }
-
- int SelectMode (BYTE Mode) /* Switch to a BIOS video mode */
- {
- BYTE ActualMode ;
-
- _asm {
- mov al, Mode
- xor ah, ah
- int 10H
- mov ah, 0Fh
- int 10H
- mov ActualMode, al
- }
- if (ActualMode == Mode)
- return 1 ;
- else return 0 ;
- }
-
- main (argc, argv)
- int argc ;
- char *argv[] ;
- {
- BYTE bCrt07 ;
- BYTE bCrt12 ;
- BYTE bHires ;
- USHORT i ;
- USHORT usNumLines ;
- USHORT usHiresLines ;
-
- if (argc != 2)
- {
- printf ("Usage: ATIPAT2 <file_name>\n"
- "Where file_name is the name of the driver file\n") ;
- exit (1) ;
- }
-
- /**********************************************************/
- /* Find hires bios video mode, using the driver file. */
- /* That is: */
- /* 0x63 for 800x600x256 */
- /* 0x64 for 1024x768x256 */
- bHires = FindBiosVideoMode (argv[1], &usHiresLines) ;
-
- SelectMode (bHires) ; /* Enable 256c mode */
- ReadRegisters (Patch[0].psData) ; /* Fill Data1 structure */
- SelectMode (0x03) ; /* Back to 80x25 color text */
- ReadRegisters (Patch[1].psData) ; /* Fill Data2 structure */
-
- #ifdef DEBUG
- printf ("Number of lines: %d\n", usHiresLines) ;
- #endif
-
- /**********************************************/
- /* Find index for CRT registers 0x07 and 0x12 */
- for (i = 0; Patch[0].psData[i].Flag != THEEND; i++)
- {
- if (Patch[0].psData[i].Port == CRT)
- {
- if (Patch[0].psData[i].Index == 0x07)
- bCrt07 = Patch[0].psData[i].Data ;
- else if (Patch[0].psData[i].Index == 0x12)
- bCrt12 = Patch[0].psData[i].Data ;
- }
- }
- /***************************************************************/
- /* Find actual number of video lines using registers 07 and 12 */
- usNumLines = (bCrt12 + ((USHORT)(bCrt07 & 0x02) << 7)
- + ((USHORT)(bCrt07 & 0x40) << 3))
- + 1 ;
-
- /******************/
- /* Patch the file */
- PatchFile (argv[1]) ;
-
- /**************************/
- /* Check number of lines. */
- if (usNumLines != usHiresLines && usNumLines != usHiresLines/2)
- printf ("*** Warning *** Problem initializing VGA Wonder in 256-color mode!\n"
- "Driver will probably not work!\n") ;
- else
- printf ("\n File %s successfully patched!\n", argv[1]) ;
- }