mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1175 lines
45 KiB
1175 lines
45 KiB
/************************************************************************/
|
|
/* */
|
|
/* CVTVDIF.C */
|
|
/* */
|
|
/* July 12 1995 (c) 1993, 1995 ATI Technologies Incorporated. */
|
|
/************************************************************************/
|
|
|
|
/********************** PolyTron RCS Utilities
|
|
|
|
$Revision: 1.5 $
|
|
$Date: 23 Jan 1996 11:45:32 $
|
|
$Author: RWolff $
|
|
$Log: S:/source/wnt/ms11/miniport/archive/cvtvdif.c_v $
|
|
*
|
|
* Rev 1.5 23 Jan 1996 11:45:32 RWolff
|
|
* Protected against false values of TARGET_BUILD.
|
|
*
|
|
* Rev 1.4 11 Jan 1996 19:39:06 RWolff
|
|
* Now restricts "canned" mode tables by both maximum index and maximum
|
|
* pixel clock frequency, and VDIF mode tables by maximum pixel clock
|
|
* frequency only, rather than both by maximum refresh rate.
|
|
*
|
|
* Rev 1.3 19 Dec 1995 14:07:14 RWolff
|
|
* Added debug print statements.
|
|
*
|
|
* Rev 1.2 30 Oct 1995 12:09:42 MGrubac
|
|
* Fixed bug in calculating CRTC parameters based on read in data from VDIF files.
|
|
*
|
|
* Rev 1.1 26 Jul 1995 13:06:44 mgrubac
|
|
* Moved mode tables merging to VDIFCallback() routine.
|
|
*
|
|
* Rev 1.0 20 Jul 1995 18:19:12 mgrubac
|
|
* Initial revision.
|
|
|
|
|
|
End of PolyTron RCS section *****************/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <math.h>
|
|
|
|
#include "dderror.h"
|
|
#include "miniport.h"
|
|
#include "ntddvdeo.h"
|
|
|
|
#include "video.h" /* for VP_STATUS definition */
|
|
#include "vidlog.h"
|
|
|
|
#include "stdtyp.h"
|
|
#include "amach.h"
|
|
#include "amach1.h"
|
|
#include "atimp.h"
|
|
#include "atint.h"
|
|
#include "cvtvga.h"
|
|
#include "diskutil.h"
|
|
#include "atioem.h"
|
|
#include "services.h"
|
|
#include "vdptocrt.h"
|
|
#include "vdpdata.h"
|
|
#include "cvtvdif.h"
|
|
|
|
|
|
/*
|
|
* Allow miniport to be swapped out when not needed.
|
|
*/
|
|
#if defined (ALLOC_PRAGMA)
|
|
#pragma alloc_text(PAGE_COM, ReadString)
|
|
#pragma alloc_text(PAGE_COM, FindVDASection)
|
|
#pragma alloc_text(PAGE_COM, VDIFCallback)
|
|
#pragma alloc_text(PAGE_COM, GetParameterValue)
|
|
#pragma alloc_text(PAGE_COM, SetOtherModeParameters)
|
|
#pragma alloc_text(PAGE_COM, IsFileBinary)
|
|
#endif
|
|
|
|
void *pCallbackArgs; /* Pointer for passing parameters to VDIFCallback() */
|
|
|
|
|
|
/***************************************************************************
|
|
* char *ReadString(DestPtr, SourcePtr, DestSize);
|
|
*
|
|
* char *SourcePtr; Pointer to string in buffer to read
|
|
* char *DestPtr; Pointer to destination string
|
|
* short DestSize; Maximum allowed size of a null-terminated returned
|
|
* string (including '\0'). Must never be larger than
|
|
* size of destination string buffer pointed to by DestPtr.
|
|
*
|
|
* DESCRIPTION:
|
|
* Read the string data from the the beginning of SourcePtr and copy it
|
|
* to passed string buffer DestPtr. Source string end marker is '\0',
|
|
* ';', Carriage return (= EndOfLine), "//", space or HORIZTAB.
|
|
*
|
|
* RETURN VALUE:
|
|
* Pointer to buffer containing a null terminated string data
|
|
* for the Keyword, i.e. DestPtr.
|
|
* NULL if length of the string found is not shorter than DestSize.
|
|
*
|
|
* GLOBALS CHANGED:
|
|
* None
|
|
*
|
|
* CALLED BY:
|
|
* GetParameterValue()
|
|
*
|
|
* AUTHOR:
|
|
* Miroslav Grubac
|
|
*
|
|
* CHANGE HISTORY:
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
|
|
|
|
char *ReadString(char *DestPtr, char *SourcePtr, short DestSize)
|
|
{
|
|
|
|
char *EndPtr, /* Pointer to end of string data */
|
|
EndChar; /* Holds char at end of data */
|
|
|
|
|
|
EndPtr = SourcePtr; /* Copy pointer */
|
|
|
|
/*
|
|
* Find end of string data
|
|
*/
|
|
while(*EndPtr && *EndPtr != ';' && *EndPtr != ' ' &&
|
|
*EndPtr != HORIZTAB && *EndPtr != CARRETURN)
|
|
{
|
|
if(*EndPtr == '/' && *(EndPtr + 1) == '/')
|
|
break; /* Comment sign follows */
|
|
++EndPtr;
|
|
}
|
|
if (EndPtr - SourcePtr >= DestSize)
|
|
return NULL; /* String found longer than max. size */
|
|
EndChar = *EndPtr; /* Save char at end of data */
|
|
*EndPtr = 0; /* Null terminate string */
|
|
strcpy(DestPtr, SourcePtr); /* Copy string to buffer */
|
|
*EndPtr = EndChar; /* Restore char at end of data */
|
|
|
|
return(DestPtr);
|
|
|
|
} /* ReadString() */
|
|
|
|
|
|
/***************************************************************************
|
|
* char *FindVDASection(Name, Buffer);
|
|
*
|
|
* char *Name; Name of section to look for
|
|
* char *Buffer; Buffer containing .VDA-format data, from where to
|
|
* start search.
|
|
* DESCRIPTION:
|
|
* Finds the next section with Name in Buffer containing VDIF ASCII file
|
|
*
|
|
* RETURN VALUE:
|
|
* Pointer to start of line after the section name,
|
|
* NULL if no section by that name found.
|
|
*
|
|
* GLOBALS CHANGED:
|
|
* None
|
|
*
|
|
* CALLED BY:
|
|
* VDIFCallback()
|
|
*
|
|
* AUTHOR:
|
|
* Miroslav Grubac
|
|
*
|
|
* CHANGE HISTORY:
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
|
|
char *FindVDASection(char *Name, unsigned char *Buffer)
|
|
{
|
|
char *PstrAux1 = Name; /* Current ptr. into Name */
|
|
|
|
|
|
while(1)
|
|
{
|
|
while((*Buffer != '/') && (*Buffer != '[' && *Buffer))
|
|
++Buffer;
|
|
|
|
switch(*Buffer)
|
|
{
|
|
case '/':
|
|
if (* ++Buffer == '/')
|
|
{
|
|
/*
|
|
* Comment sign - skip rest of the line
|
|
*/
|
|
while(* ++Buffer != LINEFEED && *Buffer);
|
|
if(! *Buffer)
|
|
return NULL; /* Comment sign in the last line */
|
|
++Buffer;
|
|
}
|
|
continue;
|
|
case '[': /* Beginning of a section name */
|
|
/*
|
|
* Skip spaces and tabs
|
|
*/
|
|
while(* ++Buffer == ' ' || *Buffer == HORIZTAB);
|
|
|
|
while(* Buffer++ == *PstrAux1++); /* Comparing strings */
|
|
if (! *(PstrAux1 - 1))
|
|
{
|
|
/*
|
|
* Name found.
|
|
* Find end of line. If no more lines NULL is returned,
|
|
* otherwise pointer to start of the next line
|
|
*/
|
|
|
|
if(Buffer = strchr(Buffer,LINEFEED))
|
|
++Buffer;
|
|
|
|
return(Buffer);
|
|
|
|
}
|
|
else
|
|
PstrAux1 = Name;
|
|
continue;
|
|
|
|
default:
|
|
|
|
return NULL; /* Section name not found */
|
|
}
|
|
}
|
|
|
|
} /* FindVDASection() */
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* VP_STATUS VDIFCallback(phwDeviceExtension, Context, Name, Data, Length);
|
|
*
|
|
* PHW_DEVICE_EXTENSION phwDeviceExtension; Miniport device extension
|
|
* PVOID Context; Context parameter passed to the callback routine
|
|
* PWSTR Name; Pointer to the name of the requested field
|
|
* PVOID Data; Pointer to a buffer containing the VDIF file
|
|
* ULONG Length; Length of the data
|
|
*
|
|
*
|
|
* DESCRIPTION:
|
|
* Merges canned mode tables from BookValues[] with tables found in a
|
|
* memory mapped VDIF file (either ASCII or binary) pointed to by Data.
|
|
* Global pointer variable pCallbackArgs is used to point to a structure
|
|
* that passes data in both directions between this function and
|
|
* SetFixedModes(). For details on input and output data see definition
|
|
* of stVDIFCallbackData structure.
|
|
*
|
|
* RETURN VALUE:
|
|
* Always returns NO_ERROR, since we can't be sure that an error code
|
|
* returned here will be returned unmodified by
|
|
* VideoPortGetRegistryParameters().
|
|
*
|
|
* GLOBALS CHANGED:
|
|
* None
|
|
*
|
|
* CALLED BY:
|
|
* SetFixedModes() via VideoPortGetRegistryParameters()
|
|
*
|
|
* AUTHOR:
|
|
* Miroslav Grubac
|
|
*
|
|
* CHANGE HISTORY:
|
|
* 95 07 24 Miroslav Grubac
|
|
* Now the routine accepts parameters Index and EndIndex that define the
|
|
* range of frame rate values from BookValues[], instead of filling mode
|
|
* tables from VDIF file with frame rate in range between just two consecutive
|
|
* values of Index. This allows for just one calling of this routine from
|
|
* SetFixedModes avoiding multiple reading of VDIF file in a memory buffer.
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
VP_STATUS VDIFCallback(PHW_DEVICE_EXTENSION phwDeviceExtension,
|
|
PVOID Context,
|
|
PWSTR Name,
|
|
PVOID Data,
|
|
ULONG Length)
|
|
{
|
|
|
|
/*
|
|
* ValidTableFound; TRUE if at least one table found in file
|
|
* that meets LowBound and pArgs->MaxDotClock criteria
|
|
*/
|
|
BOOL ValidTableFound;
|
|
|
|
BOOL FileTypeBinary;
|
|
|
|
/*
|
|
* pArgs; Pointer to Argument structure passed by SetFixedModes() via
|
|
* global pCallbackArgs
|
|
*/
|
|
struct stVDIFCallbackData *pArgs;
|
|
|
|
/*
|
|
* AlterTables[2]; Working tables used while searching for table with the
|
|
* lowest FrameRate. They are necessary for ASCII file processing because
|
|
* we don't know if a timings section is valid or not until we read all
|
|
* the needed parameters and check their validity. If that section contains
|
|
* lower frame rate than previous sections processed, the belonging
|
|
* parameters read are kept in one of these tables not to be unnecessarily
|
|
* read again when the end of file is reached and section with the lowest
|
|
* frame rate found.
|
|
*/
|
|
struct VDIFInputs AlterTables[2];
|
|
|
|
/*
|
|
* TableSelector; Points which struct in AlterTables[] is to be filled next.
|
|
* It can have just two values: 0 or 1. When a table with lower
|
|
* frame rate is found, this selector is XORed with 1 to point to
|
|
* another table.
|
|
*/
|
|
UCHAR TableSelector;
|
|
|
|
short FrameRate; /* Rounded frame rate in current section */
|
|
|
|
/*
|
|
* ExactFrameRate; Non-rounded frame rate that currently meets the
|
|
* best LowBound and pArgs->MaxDotClock criteria in search for table
|
|
* (section) with the lowest frame rate in the range in the entire file.
|
|
*/
|
|
ULONG ExactFrameRate;
|
|
BOOL InterlacedFlag; /* Scan type read from the same table as ExactFrameRate */
|
|
WORD NextHigherFRate;
|
|
|
|
/*
|
|
* Calculated parameters, based on data read from VDIF file
|
|
*/
|
|
ULONG HorFrontPorch;
|
|
ULONG VerFrontPorch;
|
|
ULONG HorRightBorder;
|
|
ULONG VerRightBorder;
|
|
|
|
/*
|
|
* Variables for binary file processing
|
|
*/
|
|
VDIFRec *MonitDescr;
|
|
VDIFLimitsRec *CurrLimits;
|
|
VDIFTimingRec *CurrTimings;
|
|
VDIFTimingRec *MinimFRateTiming; /* Holds lowest frame rate found */
|
|
ULONG LimitsLeft;
|
|
ULONG TimingsLeft;
|
|
USHORT LowestFRateFound;
|
|
|
|
/*
|
|
* Variables for ASCII file processing
|
|
*/
|
|
char *CurrSection; /* Ptr to PREADJUSTEDTIMING section */
|
|
char *NextSection; /* Beginning of next section */
|
|
char GotStr[80]; /* Buffer for string returned by GetParameterValue() */
|
|
char *DataPtr; /* Pointer to string ret. by ReadString */
|
|
|
|
ULONG Scratch; /* Temporary variable */
|
|
|
|
pArgs = (struct stVDIFCallbackData *) pCallbackArgs;
|
|
VideoDebugPrint((DEBUG_DETAIL, "Length of file VDIF = %d \n",Length));
|
|
|
|
if ((FileTypeBinary = IsFileBinary((PUCHAR) Data, Length)) == FALSE)
|
|
{
|
|
/*
|
|
* Null terminate file buffer and capitalize letters.
|
|
* It is safe to replace the last character in file with '\0'
|
|
* as each line ends with semicolon and GetParameterValue()
|
|
* does not necessarily expect semicolon there.
|
|
*/
|
|
*((char *)((char *)Data + Length - 1)) = '\0';
|
|
UpperCase((PUCHAR) Data);
|
|
}
|
|
|
|
/*
|
|
* Fill in our list of mode tables. If we run out of tables to
|
|
* use, rather than space to store them in, we will exit from
|
|
* the loop by means other than failing the loop condition.
|
|
*/
|
|
while (pArgs->FreeTables > 0)
|
|
{
|
|
/*
|
|
* Initialize variables used to find the desired (lowest frame
|
|
* rate which is greater than the highest frame rate we have
|
|
* already dealt with) table in the VDIF file. Since the initial
|
|
* value for NextHigherFRate is the largest value which can be
|
|
* stored in an unsigned short, it is guaranteed to be higher than
|
|
* any legitimate frame rate (rates higher than 100Hz are extremely
|
|
* rare), so the first legitimate rate will be lower (and therfore
|
|
* more desirable) than the initial value.
|
|
*/
|
|
LowestFRateFound = 65535;
|
|
TableSelector = 0;
|
|
ValidTableFound = FALSE;
|
|
|
|
if (FileTypeBinary)
|
|
{
|
|
/*
|
|
* Binary file is searched for Minimum Frame Rate in
|
|
* given limits. After finding such a frame rate, if any, and
|
|
* reading other data for that preadjusted timing
|
|
* from the binary file, a common code section for both
|
|
* ASCII and binary file follows, where elements of a
|
|
* new mode table are calculated.
|
|
* TableSelector == 0 all the time in this section, because
|
|
* for binary file one table is sufficient.
|
|
*/
|
|
|
|
|
|
MonitDescr = (VDIFRec *) Data;
|
|
LimitsLeft = MonitDescr->NumberOperationalLimits;
|
|
CurrLimits = OPER_LIMITS(MonitDescr);
|
|
for ( ; LimitsLeft; --LimitsLeft,
|
|
CurrLimits = NEXT_OPER_LIMITS(CurrLimits))
|
|
{
|
|
TimingsLeft = CurrLimits->NumberPreadjustedTimings;
|
|
CurrTimings = PREADJ_TIMING(CurrLimits);
|
|
|
|
for ( ; TimingsLeft; --TimingsLeft,
|
|
CurrTimings = NEXT_PREADJ_TIMING(CurrTimings))
|
|
{
|
|
/*
|
|
* Reject any timings entry which is not for the
|
|
* resolution we are working on.
|
|
*/
|
|
if (CurrTimings->HorPixel != pArgs->HorRes)
|
|
continue;
|
|
if (CurrTimings->VerPixel != pArgs->VerRes)
|
|
continue;
|
|
|
|
Scratch = THOUSAND * CurrTimings->PixelClock;
|
|
|
|
/*
|
|
* Reject any timings entry which uses a pixel
|
|
* clock frequency higher than the maximum which
|
|
* we support.
|
|
*/
|
|
if (Scratch > pArgs->MaxDotClock)
|
|
{
|
|
VideoDebugPrint((DEBUG_DETAIL, "Rejecting mode - clock = %d, max = %d\n", Scratch, pArgs->MaxDotClock));
|
|
continue;
|
|
}
|
|
|
|
AlterTables[TableSelector].VerFrequency = CurrTimings->VerFrequency;
|
|
|
|
/*
|
|
* Get vertical frequency rounded to the nearest Hz
|
|
*/
|
|
FrameRate = (short) ((AlterTables[TableSelector].VerFrequency
|
|
+ 500) / 1000);
|
|
if (CurrTimings->ScanType == VDIF_SCAN_INTERLACED)
|
|
{
|
|
AlterTables[TableSelector].Interlaced = TRUE;
|
|
FrameRate /= 2;
|
|
}
|
|
else
|
|
AlterTables[TableSelector].Interlaced = FALSE;
|
|
|
|
/*
|
|
* Reject frame rate we have already dealth with, since
|
|
* we deal with frame rates in ascending order. The
|
|
* first test looks for frame rates below those already
|
|
* in the list, while the second looks for frame rates
|
|
* lower than those we have found while looking for
|
|
* the mode table to add to the list.
|
|
*/
|
|
if (FrameRate < pArgs->LowBound)
|
|
continue;
|
|
|
|
if (ValidTableFound && (FrameRate >= LowestFRateFound))
|
|
continue;
|
|
|
|
/*
|
|
* Now we have a table with FrameRate higher than
|
|
* the last mode table which we added to our list,
|
|
* but lower than for any other tables we have
|
|
* found that meet this critereon in our search
|
|
* for the next mode table to add to our list.
|
|
*
|
|
* Preserve its position and keep searching for a
|
|
* possible table with lower frame rate. VerFrequency
|
|
* and ScanType are also preserved, although we could
|
|
* read them later again as table position is known.
|
|
* Since their values in AlterTables[] will be
|
|
* overwritten if we find another table for the
|
|
* desired resolution, even if we reject it because
|
|
* it has a frame rate either lower than the last
|
|
* one added to the list of mode tables or higher
|
|
* than the one we have now, we must use the preserved
|
|
* values rather than the values in AlterTables[]
|
|
* when calculating CRT parameters.
|
|
*/
|
|
ValidTableFound = TRUE;
|
|
MinimFRateTiming = CurrTimings;
|
|
LowestFRateFound = FrameRate;
|
|
ExactFrameRate = AlterTables[TableSelector].VerFrequency;
|
|
InterlacedFlag = AlterTables[TableSelector].Interlaced;
|
|
}
|
|
}
|
|
if (!ValidTableFound)
|
|
{
|
|
/*
|
|
* Take a canned table from BookValues[]
|
|
*/
|
|
VideoDebugPrint((DEBUG_DETAIL, "No valid tables found in binary file - using \"canned\" table\n"));
|
|
}
|
|
|
|
|
|
AlterTables[TableSelector].MinFrameRate = LowestFRateFound;
|
|
|
|
/*
|
|
* Read in other variables from file
|
|
*/
|
|
AlterTables[TableSelector].HorFrequency =
|
|
MinimFRateTiming->HorFrequency;
|
|
AlterTables[TableSelector].PixelClock =
|
|
THOUSAND * MinimFRateTiming->PixelClock;
|
|
AlterTables[TableSelector].HorSyncStart =
|
|
MinimFRateTiming->HorSyncStart;
|
|
AlterTables[TableSelector].VerSyncStart =
|
|
MinimFRateTiming->VerSyncStart;
|
|
AlterTables[TableSelector].HorSyncTime =
|
|
MinimFRateTiming->HorSyncTime;
|
|
AlterTables[TableSelector].HorAddrTime =
|
|
MinimFRateTiming->HorAddrTime;
|
|
AlterTables[TableSelector].HorBlankTime =
|
|
MinimFRateTiming->HorBlankTime;
|
|
AlterTables[TableSelector].HorBlankStart =
|
|
MinimFRateTiming->HorBlankStart;
|
|
AlterTables[TableSelector].VerSyncTime =
|
|
MinimFRateTiming->VerSyncTime;
|
|
AlterTables[TableSelector].VerAddrTime =
|
|
MinimFRateTiming->VerAddrTime;
|
|
AlterTables[TableSelector].VerBlankTime =
|
|
MinimFRateTiming->VerBlankTime;
|
|
AlterTables[TableSelector].VerBlankStart =
|
|
MinimFRateTiming->VerBlankStart;
|
|
AlterTables[TableSelector].HorPolarity =
|
|
(MinimFRateTiming->HorSyncPolarity == VDIF_POLARITY_NEGATIVE) ?
|
|
NEGATIVE : POSITIVE;
|
|
AlterTables[TableSelector].VerPolarity =
|
|
(MinimFRateTiming->VerSyncPolarity == VDIF_POLARITY_NEGATIVE) ?
|
|
NEGATIVE : POSITIVE;
|
|
|
|
|
|
}
|
|
|
|
else
|
|
{
|
|
/*
|
|
* ASCII file: Read current section parameters and
|
|
* check their validity. If any found invalid quit
|
|
* the section and go to the next section.
|
|
*/
|
|
|
|
CurrSection = NULL;
|
|
NextSection = (char *) 1;
|
|
|
|
while (NextSection)
|
|
{
|
|
/*
|
|
* This loop is repeated as many times as there are
|
|
* PREADJUSTED_TIMING sections in the file.
|
|
*/
|
|
|
|
if(CurrSection)
|
|
{
|
|
CurrSection = NextSection;
|
|
NextSection = FindVDASection(TIMINGSECTION, NextSection);
|
|
}
|
|
else if((CurrSection = FindVDASection(TIMINGSECTION,
|
|
Data)) == NULL) /* Search from beg. of buffer */
|
|
{
|
|
break; /* No section found */
|
|
}
|
|
else
|
|
{
|
|
NextSection = FindVDASection(TIMINGSECTION, CurrSection);
|
|
}
|
|
|
|
/*
|
|
* Find if HORPIXEL field exists in the section we are
|
|
* looking at, and it is the screen width we are working on
|
|
*/
|
|
if ((DataPtr = GetParameterValue(HORPIXEL, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if (atoi(DataPtr) != pArgs->HorRes)
|
|
continue;
|
|
|
|
/*
|
|
* Find if VERPIXEL field exists in the section we are
|
|
* looking at, and it is the screen height we are working on
|
|
*/
|
|
if ((DataPtr = GetParameterValue(VERPIXEL, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if (atoi(DataPtr) != pArgs->VerRes)
|
|
continue;
|
|
|
|
if ((DataPtr = GetParameterValue(VERFREQUENCY, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if ((AlterTables[TableSelector].VerFrequency = SynthAToF(DataPtr)) == 0)
|
|
continue; /* Invalid string found */
|
|
|
|
/*
|
|
* Transfer VertFrequency into integer [Hz]
|
|
*/
|
|
FrameRate = (short) ((AlterTables[TableSelector].VerFrequency + 500) / 1000);
|
|
|
|
if ((DataPtr = GetParameterValue(SCANTYPE, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if (!strcmp(DataPtr, "INTERLACED")) /* If interlaced divide VerFreq by 2 */
|
|
{
|
|
AlterTables[TableSelector].Interlaced = TRUE;
|
|
FrameRate /= 2;
|
|
}
|
|
else
|
|
{
|
|
AlterTables[TableSelector].Interlaced = FALSE;
|
|
}
|
|
|
|
/*
|
|
* Reject frame rate we have already dealth with, since
|
|
* we deal with frame rates in ascending order. The
|
|
* first test looks for frame rates below those already
|
|
* in the list, while the second looks for frame rates
|
|
* lower than those we have found while looking for
|
|
* the mode table to add to the list.
|
|
*/
|
|
if (FrameRate < pArgs->LowBound)
|
|
continue;
|
|
|
|
if (ValidTableFound && (FrameRate >= LowestFRateFound))
|
|
continue;
|
|
|
|
AlterTables[TableSelector].MinFrameRate = FrameRate;
|
|
|
|
/*
|
|
* Now we have a table with FrameRate in range, but we
|
|
* don't know if all necessary timing parameters in the
|
|
* table (section) are valid because contrary to .VDB file
|
|
* that contains checksum of its contents, .VDA file
|
|
* doesn't have anything like that.
|
|
* VerFrequency and ScanType are preserved.
|
|
*/
|
|
ExactFrameRate = AlterTables[TableSelector].VerFrequency;
|
|
InterlacedFlag = AlterTables[TableSelector].Interlaced;
|
|
|
|
/*
|
|
* Read other VDIF parameters and check their validity
|
|
* If any is found to be invalid, stop and go to
|
|
* next section
|
|
*/
|
|
if ((DataPtr = GetParameterValue(HORFREQUENCY, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if ((AlterTables[TableSelector].HorFrequency =
|
|
SynthAToF(DataPtr)) == 0)
|
|
continue;
|
|
|
|
if ((DataPtr = GetParameterValue(PIXELCLOCK, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if ((AlterTables[TableSelector].PixelClock =
|
|
SynthAToF(DataPtr)) == 0)
|
|
continue;
|
|
|
|
AlterTables[TableSelector].PixelClock *= THOUSAND;
|
|
|
|
/*
|
|
* Reject any timings entry which uses a pixel
|
|
* clock frequency higher than the maximum which
|
|
* we support.
|
|
*/
|
|
if (AlterTables[TableSelector].PixelClock > pArgs->MaxDotClock)
|
|
{
|
|
VideoDebugPrint((DEBUG_DETAIL, "Rejecting mode - clock = %d, max = %d\n", AlterTables[TableSelector].PixelClock, pArgs->MaxDotClock));
|
|
continue;
|
|
}
|
|
|
|
if ((DataPtr = GetParameterValue(HORSYNCSTART, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if ((AlterTables[TableSelector].HorSyncStart =
|
|
SynthAToF(DataPtr)) == 0)
|
|
continue;
|
|
|
|
if ((DataPtr = GetParameterValue(VERSYNCSTART, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if ((AlterTables[TableSelector].VerSyncStart = SynthAToF(DataPtr)) == 0)
|
|
continue;
|
|
|
|
if ((DataPtr = GetParameterValue(HORADDRTIME, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if ((AlterTables[TableSelector].HorAddrTime = SynthAToF(DataPtr)) == 0)
|
|
continue;
|
|
|
|
if ((DataPtr = GetParameterValue(HORBLANKTIME, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if ((AlterTables[TableSelector].HorBlankTime = SynthAToF(DataPtr)) == 0)
|
|
continue;
|
|
|
|
if ((DataPtr = GetParameterValue(VERADDRTIME, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if ((AlterTables[TableSelector].VerAddrTime = SynthAToF(DataPtr)) == 0)
|
|
continue;
|
|
|
|
if ((DataPtr = GetParameterValue(VERBLANKTIME, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if ((AlterTables[TableSelector].VerBlankTime = SynthAToF(DataPtr)) == 0)
|
|
continue;
|
|
|
|
if ((DataPtr = GetParameterValue(HORBLANKSTART, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if ((AlterTables[TableSelector].HorBlankStart = SynthAToF(DataPtr)) == 0)
|
|
continue;
|
|
|
|
if ((DataPtr = GetParameterValue(VERBLANKSTART, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if ((AlterTables[TableSelector].VerBlankStart = SynthAToF(DataPtr)) == 0)
|
|
continue;
|
|
|
|
if ((DataPtr = GetParameterValue(HORSYNCTIME, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if ((AlterTables[TableSelector].HorSyncTime = SynthAToF(DataPtr)) == 0)
|
|
continue;
|
|
|
|
|
|
|
|
if ((DataPtr = GetParameterValue(VERSYNCTIME, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if ((AlterTables[TableSelector].VerSyncTime = SynthAToF(DataPtr)) == 0)
|
|
continue;
|
|
|
|
if ((DataPtr = GetParameterValue(HORSYNCPOLARITY, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if (! strcmp(DataPtr, "NEGATIVE"))
|
|
AlterTables[TableSelector].HorPolarity = NEGATIVE;
|
|
else if (! strcmp(DataPtr, "POSITIVE"))
|
|
AlterTables[TableSelector].HorPolarity = POSITIVE;
|
|
else
|
|
continue;
|
|
|
|
if ((DataPtr = GetParameterValue(VERSYNCPOLARITY, CurrSection,
|
|
NextSection, GotStr, sizeof(GotStr))) == NULL)
|
|
continue;
|
|
|
|
if (! strcmp(DataPtr, "NEGATIVE"))
|
|
AlterTables[TableSelector].VerPolarity = NEGATIVE;
|
|
else if (! strcmp(DataPtr, "POSITIVE"))
|
|
AlterTables[TableSelector].VerPolarity = POSITIVE;
|
|
else
|
|
continue;
|
|
|
|
/*
|
|
* Valid Table Found
|
|
*/
|
|
|
|
TableSelector ^= 1; /* Alternate working tables */
|
|
if (ValidTableFound)
|
|
NextHigherFRate = AlterTables[TableSelector].MinFrameRate;
|
|
|
|
ValidTableFound = TRUE;
|
|
LowestFRateFound = FrameRate;
|
|
|
|
|
|
} /* while(NextSection) */
|
|
|
|
if (ValidTableFound)
|
|
TableSelector ^= 1; /* Point to the last filled table */
|
|
else
|
|
VideoDebugPrint((DEBUG_DETAIL, "No valid tables found in ASCII file - using \"canned\" table\n"));
|
|
|
|
} /* else of ASCII file */
|
|
|
|
|
|
HorRightBorder = AlterTables[TableSelector].HorBlankStart -
|
|
AlterTables[TableSelector].HorAddrTime;
|
|
HorFrontPorch = AlterTables[TableSelector].HorSyncStart -
|
|
AlterTables[TableSelector].HorAddrTime - HorRightBorder;
|
|
VerRightBorder = AlterTables[TableSelector].VerBlankStart -
|
|
AlterTables[TableSelector].VerAddrTime;
|
|
VerFrontPorch = AlterTables[TableSelector].VerSyncStart -
|
|
AlterTables[TableSelector].VerAddrTime - VerRightBorder;
|
|
|
|
if (InterlacedFlag)
|
|
{
|
|
/*
|
|
* Adjust values for interlaced displays
|
|
*/
|
|
ExactFrameRate /= 2;
|
|
VerFrontPorch *= 2;
|
|
AlterTables[TableSelector].VerSyncTime *= 2;
|
|
}
|
|
|
|
/*
|
|
* We have now either found the best (lowest refresh rate which
|
|
* we have not already dealt with, and pixel clock rate is
|
|
* an acceptable value) mode table from the VDIF file,
|
|
* or there is no suitable mode table in the file. The decision
|
|
* on whether to use the mode table from the VDIF file or the
|
|
* next one from the list of "canned" tables is made as follows:
|
|
*
|
|
* If only one of the sources has an acceptable table, use the
|
|
* table from that source.
|
|
*
|
|
* If both sources have acceptable tables, use the one with the
|
|
* lower refresh rate (we will catch the other one on the next
|
|
* pass through the loop). If both have the same refresh rate,
|
|
* use the table from the VDIF file, since this allows field
|
|
* updates of our standard mode tables through updates of the
|
|
* VDIF file.
|
|
*
|
|
* If neither source has an acceptable table, exit the loop
|
|
* since we have run out of tables to use.
|
|
*/
|
|
if (ValidTableFound &&
|
|
((AlterTables[TableSelector].MinFrameRate <= BookValues[pArgs->Index].Refresh) ||
|
|
(pArgs->Index > pArgs->EndIndex) ||
|
|
(BookValues[pArgs->Index].ClockFreq > pArgs->MaxDotClock)))
|
|
{
|
|
/*
|
|
* Use mode table from VDIF file
|
|
*/
|
|
VideoDebugPrint((DEBUG_DETAIL, "Copying %dHz table from VDIF\n", AlterTables[TableSelector].MinFrameRate));
|
|
(*pArgs->ppFreeTables)->m_x_size = pArgs->HorRes;
|
|
(*pArgs->ppFreeTables)->m_y_size = pArgs->VerRes;
|
|
(*pArgs->ppFreeTables)->Refresh = AlterTables[TableSelector].MinFrameRate;
|
|
|
|
(*pArgs->ppFreeTables)->m_h_total =
|
|
(UCHAR)((AlterTables[TableSelector].PixelClock/
|
|
AlterTables[TableSelector].HorFrequency - 4) / 8);
|
|
|
|
(*pArgs->ppFreeTables)->m_v_total = (short)
|
|
normal_to_skip2((((AlterTables[TableSelector].HorFrequency
|
|
* 2 * THOUSAND) / ExactFrameRate) -1) / 2);
|
|
(*pArgs->ppFreeTables)->m_h_disp =
|
|
(UCHAR)((*pArgs->ppFreeTables)->m_x_size / 8 - 1);
|
|
|
|
(*pArgs->ppFreeTables)->m_v_disp = (short) normal_to_skip2((long)
|
|
((*pArgs->ppFreeTables)->m_y_size - 1));
|
|
|
|
(*pArgs->ppFreeTables)->m_h_sync_wid =
|
|
(UCHAR)(((AlterTables[TableSelector].HorSyncTime *
|
|
(AlterTables[TableSelector].PixelClock / THOUSAND) +
|
|
4 * MILLION) / (8 * MILLION)) |
|
|
(UCHAR)(AlterTables[TableSelector].HorPolarity << 5));
|
|
|
|
(*pArgs->ppFreeTables)->m_v_sync_wid =
|
|
(UCHAR)(((AlterTables[TableSelector].VerSyncTime *
|
|
AlterTables[TableSelector].HorFrequency + HALF_MILLION) / MILLION)
|
|
| (UCHAR)(AlterTables[TableSelector].VerPolarity << 5));
|
|
|
|
/*
|
|
* m_h_sync_strt = (HSS * PC + 0.5)/8 - 1;
|
|
*/
|
|
(*pArgs->ppFreeTables)->m_h_sync_strt = (UCHAR)(((pArgs->HorRes *
|
|
MILLION) + (((AlterTables[TableSelector].PixelClock / THOUSAND)
|
|
* HorFrontPorch) + HALF_MILLION)) / (8 * MILLION) -1);
|
|
|
|
/*
|
|
* m_v_sync_strt = n_to_s2((VSS * HF + 0.5) - 1);
|
|
*/
|
|
(*pArgs->ppFreeTables)->m_v_sync_strt = (short)
|
|
normal_to_skip2((((VerFrontPorch *
|
|
AlterTables[TableSelector].HorFrequency) +
|
|
HALF_MILLION) / MILLION) + pArgs->VerRes -1);
|
|
(*pArgs->ppFreeTables)->m_clock_select = 0x800;
|
|
|
|
(*pArgs->ppFreeTables)->ClockFreq = AlterTables[TableSelector].PixelClock;
|
|
(*pArgs->ppFreeTables)->m_vfifo_24 = 8;
|
|
|
|
(*pArgs->ppFreeTables)->m_vfifo_16 = 8;
|
|
(*pArgs->ppFreeTables)->m_h_overscan = 0;
|
|
(*pArgs->ppFreeTables)->m_v_overscan = 0;
|
|
(*pArgs->ppFreeTables)->m_overscan_8b = 0;
|
|
(*pArgs->ppFreeTables)->m_overscan_gr = 0;
|
|
(*pArgs->ppFreeTables)->m_status_flags = 0;
|
|
|
|
VideoDebugPrint((DEBUG_DETAIL, "\nVDIF_MinFRate = %d \n", AlterTables[TableSelector].MinFrameRate));
|
|
VideoDebugPrint((DEBUG_DETAIL, "VDIF_ExactFRate = %d \n", ExactFrameRate));
|
|
VideoDebugPrint((DEBUG_DETAIL, "VDIF_Interlac = %d \n", InterlacedFlag));
|
|
VideoDebugPrint((DEBUG_DETAIL, "VDIF_PixClock = %d \n", AlterTables[TableSelector].PixelClock));
|
|
VideoDebugPrint((DEBUG_DETAIL, "VDIF_HorzFreq = %d \n", AlterTables[TableSelector].HorFrequency));
|
|
VideoDebugPrint((DEBUG_DETAIL, "VDIF_HorSyncStart = %d \n", AlterTables[TableSelector].HorSyncStart));
|
|
VideoDebugPrint((DEBUG_DETAIL, "VDIF_HorBlankStart = %d \n", AlterTables[TableSelector].HorBlankStart));
|
|
VideoDebugPrint((DEBUG_DETAIL, "VDIF_VerSyncStart = %d \n", AlterTables[TableSelector].VerSyncStart));
|
|
VideoDebugPrint((DEBUG_DETAIL, "VDIF_VerBlankStart = %d \n", AlterTables[TableSelector].VerBlankStart));
|
|
VideoDebugPrint((DEBUG_DETAIL, "VDIF_HorSyncTime = %d \n", AlterTables[TableSelector].HorSyncTime));
|
|
VideoDebugPrint((DEBUG_DETAIL, "VDIF_HorBlankTime = %d \n", AlterTables[TableSelector].HorBlankTime));
|
|
VideoDebugPrint((DEBUG_DETAIL, "VDIF_HorAddrTime = %d \n", AlterTables[TableSelector].HorAddrTime));
|
|
VideoDebugPrint((DEBUG_DETAIL, "VDIF_VerSyncTime = %d \n", AlterTables[TableSelector].VerSyncTime));
|
|
VideoDebugPrint((DEBUG_DETAIL, "VDIF_VerBlankTime = %d \n", AlterTables[TableSelector].VerBlankTime));
|
|
VideoDebugPrint((DEBUG_DETAIL, "VDIF_VerAddrTime = %d \n", AlterTables[TableSelector].VerAddrTime));
|
|
VideoDebugPrint((DEBUG_DETAIL, "VDIF_HorPolarity = %d \n", AlterTables[TableSelector].HorPolarity));
|
|
VideoDebugPrint((DEBUG_DETAIL, "VDIF_VerPolarity = %d \n", AlterTables[TableSelector].VerPolarity));
|
|
|
|
VideoDebugPrint((DEBUG_DETAIL, "\nCalculated_M_x_size = %d \n", (*pArgs->ppFreeTables)->m_x_size));
|
|
VideoDebugPrint((DEBUG_DETAIL, "Calculated_M_y_size = %d \n", (*pArgs->ppFreeTables)->m_y_size));
|
|
VideoDebugPrint((DEBUG_DETAIL, "Calculated_Refresh = %d \n", (*pArgs->ppFreeTables)->Refresh));
|
|
VideoDebugPrint((DEBUG_DETAIL, "Calculated_Pix_Clk = %d \n", (*pArgs->ppFreeTables)->ClockFreq));
|
|
VideoDebugPrint((DEBUG_DETAIL, "Calculated_M_h_totl = 0x%X \n", (*pArgs->ppFreeTables)->m_h_total));
|
|
VideoDebugPrint((DEBUG_DETAIL, "Calculated_M_v_totl = 0x%X \n", (*pArgs->ppFreeTables)->m_v_total));
|
|
VideoDebugPrint((DEBUG_DETAIL, "Calculated_M_h_disp = 0x%X \n", (*pArgs->ppFreeTables)->m_h_disp));
|
|
VideoDebugPrint((DEBUG_DETAIL, "Calculated_M_v_disp = 0x%X \n", (*pArgs->ppFreeTables)->m_v_disp));
|
|
VideoDebugPrint((DEBUG_DETAIL, "Calculated_M_h_widt = 0x%X \n", (*pArgs->ppFreeTables)->m_h_sync_wid));
|
|
VideoDebugPrint((DEBUG_DETAIL, "Calculated_M_v_widt = 0x%X \n", (*pArgs->ppFreeTables)->m_v_sync_wid));
|
|
VideoDebugPrint((DEBUG_DETAIL, "Calculated_M_h_strt = 0x%X \n", (*pArgs->ppFreeTables)->m_h_sync_strt));
|
|
VideoDebugPrint((DEBUG_DETAIL, "Calculated_M_v_strt = 0x%X \n", (*pArgs->ppFreeTables)->m_v_sync_strt));
|
|
|
|
(*pArgs->ppFreeTables)->m_disp_cntl = 0x21;
|
|
|
|
if(InterlacedFlag)
|
|
(*pArgs->ppFreeTables)->m_disp_cntl |= 0x10;
|
|
|
|
/*
|
|
* if not skip1 mode, adjust disp_cntl value!
|
|
* (for 68800 assume that it is not skip1 mode!)
|
|
*/
|
|
if(!skip1)
|
|
(*pArgs->ppFreeTables)->m_disp_cntl |= 0x02;
|
|
|
|
|
|
SetOtherModeParameters(pArgs->PixelDepth, pArgs->Pitch,
|
|
pArgs->Multiplier, *pArgs->ppFreeTables);
|
|
pArgs->LowBound = (*pArgs->ppFreeTables)->Refresh + 1;
|
|
++ *pArgs->ppFreeTables;
|
|
++pArgs->NumModes;
|
|
--pArgs->FreeTables;
|
|
|
|
/*
|
|
* Skip any "canned" tables which have a refresh rate we
|
|
* have already dealt with (i.e. less than or equal to
|
|
* that of the table we have just added to the list)
|
|
*/
|
|
while ((pArgs->Index <= pArgs->EndIndex) &&
|
|
(BookValues[pArgs->Index].Refresh < pArgs->LowBound))
|
|
{
|
|
VideoDebugPrint((DEBUG_DETAIL, "Skipping %dHz \"canned\" table\n", BookValues[pArgs->Index].Refresh));
|
|
pArgs->Index++;
|
|
}
|
|
|
|
}
|
|
else if ((BookValues[pArgs->Index].ClockFreq <= pArgs->MaxDotClock) &&
|
|
(pArgs->Index <= pArgs->EndIndex))
|
|
{
|
|
/*
|
|
* Use the "canned" mode table
|
|
*/
|
|
VideoDebugPrint((DEBUG_DETAIL, "Copying %dHz \"canned\" table\n", BookValues[pArgs->Index].Refresh));
|
|
BookVgaTable(pArgs->Index, *pArgs->ppFreeTables);
|
|
SetOtherModeParameters(pArgs->PixelDepth, pArgs->Pitch,
|
|
pArgs->Multiplier, *pArgs->ppFreeTables);
|
|
|
|
++ *pArgs->ppFreeTables;
|
|
++pArgs->NumModes;
|
|
--pArgs->FreeTables;
|
|
pArgs->LowBound = BookValues[pArgs->Index].Refresh + 1;
|
|
++pArgs->Index;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* We have run out of mode tables
|
|
*/
|
|
break;
|
|
}
|
|
|
|
} /* end while (more space to store mode tables) */
|
|
|
|
VideoDebugPrint((DEBUG_DETAIL, "Space for %d more mode tables\n", pArgs->FreeTables));
|
|
|
|
return NO_ERROR;
|
|
|
|
} /* VDIFCallback() */
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
*char *GetParameterValue(KeyWord, PtrBuf1, PtrBuf2, DestPtr, DestSize)
|
|
*
|
|
*char *KeyWord; String for which data is requested
|
|
*char *PtrBuf1; Ptr. to location from where to start search for the
|
|
* given Keyword
|
|
*char *PtrBuf2; Ptr. to the end of searching area
|
|
*char *DestPtr; Pointer to array to contain string on return
|
|
*short DestSize; Maximum allowed size of a null-terminated returned
|
|
* string (including '\0'). Must never be larger than
|
|
* size of destination string buffer pointed to by
|
|
* DestPtr.
|
|
*
|
|
* DESCRIPTION:
|
|
* Searches for a data string belonging to the given KeyWord within
|
|
* the section, from PtrBuf1 up to PtrBuf2.
|
|
*
|
|
* RETURN VALUE:
|
|
* Pointer (== the passed pointer DestPtr) to a null terminated data
|
|
* string for the KeyWord if found, otherwise NULL
|
|
*
|
|
* GLOBALS CHANGED:
|
|
* None
|
|
*
|
|
* CALLED BY:
|
|
* VDIFCallback()
|
|
*
|
|
* AUTHOR:
|
|
* Miroslav Grubac
|
|
*
|
|
* CHANGE HISTORY:
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
|
|
char *GetParameterValue(char *KeyWord, char *PtrBuf1, char *PtrBuf2,
|
|
char *DestPtr, short DestSize)
|
|
{
|
|
char *DataPtr; /* Pointer to string ret. by ReadString */
|
|
char *RetVal; /* Returned value from PointToData */
|
|
|
|
|
|
if (PtrBuf1 == NULL)
|
|
return NULL; /* Invalid input parameter */
|
|
|
|
if ((RetVal = PointToData(PtrBuf1, PtrBuf2, KeyWord)) == NULL)
|
|
return NULL; /* No KeyWord found in given buffer range */
|
|
|
|
if ((DataPtr = ReadString(DestPtr, RetVal, DestSize)) == NULL)
|
|
return NULL; /* Too long parameter value string found */
|
|
|
|
return(DataPtr);
|
|
|
|
} /* GetParameterValue() */
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* void SetOtherModeParameters( PixelDepth, Pitch, Multiplier, pmode)
|
|
* WORD Multiplier; What needs to be done to the pixel clock
|
|
* WORD PixelDepth; Number of bits per pixel
|
|
* WORD Pitch; Screen pitch to use
|
|
* struct st_mode_table *pmode; Pointer to structure that must contain
|
|
* at least the member ClockFreq
|
|
*
|
|
*
|
|
* DESCRIPTION:
|
|
* Sets parameters PixelDepth, Pitch and adjusts ClockFreq
|
|
*
|
|
* RETURN VALUE:
|
|
* None
|
|
*
|
|
* GLOBALS CHANGED:
|
|
* None
|
|
*
|
|
* CALLED BY:
|
|
* SetFixedModes and VDIFCallback
|
|
*
|
|
* AUTHOR:
|
|
* Miroslav Grubac
|
|
*
|
|
* CHANGE HISTORY:
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
void SetOtherModeParameters( WORD PixelDepth,
|
|
WORD Pitch,
|
|
WORD Multiplier,
|
|
struct st_mode_table *pmode)
|
|
{
|
|
pmode->m_pixel_depth = (UCHAR) PixelDepth;
|
|
pmode->m_screen_pitch = Pitch;
|
|
|
|
/*
|
|
* Take care of any pixel clock multiplication that is needed.
|
|
*/
|
|
switch(Multiplier)
|
|
{
|
|
case CLOCK_TRIPLE:
|
|
pmode->ClockFreq *= 3;
|
|
break;
|
|
|
|
case CLOCK_DOUBLE:
|
|
pmode->ClockFreq *= 2;
|
|
break;
|
|
|
|
case CLOCK_THREE_HALVES:
|
|
pmode->ClockFreq *= 3;
|
|
pmode->ClockFreq >>= 1;
|
|
break;
|
|
|
|
case CLOCK_SINGLE:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
} /* SetOtherModeParameters() */
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* BOOL IsFileBinary(Buffer, Length)
|
|
*
|
|
* PUCHAR Buffer; Pointer to buffer containing file to be tested
|
|
* ULONG Length; Length of file to be checked in bytes
|
|
*
|
|
*
|
|
* DESCRIPTION:
|
|
* Tests if the passed file is a file in VDIF binary format (.VDB)
|
|
*
|
|
* RETURN VALUE:
|
|
* TRUE if file is binary, otherwise FALSE
|
|
*
|
|
* GLOBALS CHANGED:
|
|
* None
|
|
*
|
|
* CALLED BY:
|
|
* VDIFCallback()
|
|
*
|
|
* AUTHOR:
|
|
* Miroslav Grubac
|
|
*
|
|
* CHANGE HISTORY:
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
BOOL IsFileBinary(PUCHAR Buffer, ULONG Length)
|
|
{
|
|
ULONG CheckSum = 0;
|
|
VDIFRec *MonitDescr = (VDIFRec *) Buffer;
|
|
|
|
if (strncmp(MonitDescr->VDIFId, "VDIF", 4))
|
|
return FALSE;
|
|
|
|
Buffer = (UCHAR *) &MonitDescr->VDIFVersion;
|
|
Length -= (4 * sizeof(UCHAR) + 2 * sizeof(ULONG));
|
|
|
|
for ( ;Length; --Length, ++Buffer)
|
|
CheckSum += (ULONG) *Buffer;
|
|
|
|
if (CheckSum == MonitDescr->Checksum)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
|
|
} /* IsFileBinary() */
|