gtfcalc.c
来自「适合KS8695X」· C语言 代码 · 共 437 行 · 第 1/2 页
C
437 行
/****************************************************************************
*
* VESA Generalized Timing Formula (GTF)
* Version 1.1
*
* ========================================================================
*
* The contents of this file are subject to the SciTech MGL Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.scitechsoft.com/mgl-license.txt
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
*
* The Initial Developer of the Original Code is SciTech Software, Inc.
* All Rights Reserved.
*
* ========================================================================
*
* Developed by: SciTech Software, Inc.
*
* Language: ANSI C
* Environment: Any.
*
* Description: C module for generating GTF compatible timings given a set
* of input requirements. Translated from the original GTF
* 1.14 spreadsheet definition.
*
* Compile with #define TESTING to build a command line test
* program.
*
* NOTE: The code in here has been written for clarity and
* to follow the original GTF spec as closely as
* possible.
*
****************************************************************************/
#include "gtf.h"
#ifndef __WIN32_VXD__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#endif
/*------------------------- Global Variables ------------------------------*/
static GTF_constants GC = {
1.8, /* Margin size as percentage of display */
8, /* Character cell granularity */
1, /* Minimum front porch in lines/chars */
3, /* Width of V sync in lines */
8, /* Width of H sync as percent of total */
550, /* Minimum vertical sync + back porch (us) */
600, /* Blanking formula gradient */
40, /* Blanking formula offset */
128, /* Blanking formula scaling factor */
20, /* Blanking formula scaling factor weight */
};
/*-------------------------- Implementation -------------------------------*/
#ifdef __WIN32_VXD__
/* These functions are not supported in a VxD, so we stub them out so this
* module will at least compile. Calling the functions in here will do
* something wierd!
*/
double sqrt(double x)
{ return x; }
double floor(double x)
{ return x; }
double pow(double x,double y)
{ return x*y; }
#endif
static double round(double v)
{
return floor(v + 0.5);
}
static void GetInternalConstants(GTF_constants *c)
/****************************************************************************
*
* Function: GetInternalConstants
* Parameters: c - Place to store the internal constants
*
* Description: Calculates the rounded, internal set of GTF constants.
* These constants are different to the real GTF constants
* that can be set up for the monitor. The calculations to
* get these real constants are defined in the 'Work Area'
* after the constants are defined in the Excel spreadsheet.
*
****************************************************************************/
{
c->margin = GC.margin;
c->cellGran = round(GC.cellGran);
c->minPorch = round(GC.minPorch);
c->vSyncRqd = round(GC.vSyncRqd);
c->hSync = GC.hSync;
c->minVSyncBP = GC.minVSyncBP;
if (GC.k == 0)
c->k = 0.001;
else
c->k = GC.k;
c->m = (c->k / 256) * GC.m;
c->c = (GC.c - GC.j) * (c->k / 256) + GC.j;
c->j = GC.j;
}
void GTF_calcTimings(double hPixels,double vLines,double freq,
int type,ibool wantMargins,ibool wantInterlace,GTF_timings *t)
/****************************************************************************
*
* Function: GTF_calcTimings
* Parameters: hPixels - X resolution
* vLines - Y resolution
* freq - Frequency (Hz, KHz or MHz depending on type)
* type - 1 - vertical, 2 - horizontal, 3 - dot clock
* margins - True if margins should be generated
* interlace - True if interlaced timings to be generated
* t - Place to store the resulting timings
*
* Description: Calculates a set of GTF timing parameters given a specified
* resolution and vertical frequency. The horizontal frequency
* and dot clock will be automatically generated by this
* routines.
*
* For interlaced modes the CRTC parameters are calculated for
* a single field, so will be half what would be used in
* a non-interlaced mode.
*
****************************************************************************/
{
double interlace,vFieldRate,hPeriod;
double topMarginLines,botMarginLines;
double leftMarginPixels,rightMarginPixels;
double hPeriodEst,vSyncBP,vBackPorch;
double vTotalLines,vFieldRateEst;
double hTotalPixels,hTotalActivePixels,hBlankPixels;
double idealDutyCycle,hSyncWidth,hSyncBP,hBackPorch;
double idealHPeriod;
double vFreq,hFreq,dotClock;
GTF_constants c;
/* Get rounded GTF constants used for internal calculations */
GetInternalConstants(&c);
/* Move input parameters into appropriate variables */
vFreq = hFreq = dotClock = freq;
/* Round pixels to character cell granularity */
hPixels = round(hPixels / c.cellGran) * c.cellGran;
/* For interlaced mode halve the vertical parameters, and double
* the required field refresh rate.
*/
vFieldRate = vFreq;
interlace = 0;
if (wantInterlace)
dotClock *= 2;
/* Determine the lines for margins */
if (wantMargins) {
topMarginLines = round(c.margin / 100 * vLines);
botMarginLines = round(c.margin / 100 * vLines);
}
else {
topMarginLines = 0;
botMarginLines = 0;
}
if (type != GTF_lockPF) {
if (type == GTF_lockVF) {
/* Estimate the horizontal period */
hPeriodEst = ((1/vFieldRate) - (c.minVSyncBP/1000000)) /
(vLines + (2*topMarginLines) + c.minPorch + interlace) * 1000000;
/* Find the number of lines in vSync + back porch */
vSyncBP = round(c.minVSyncBP / hPeriodEst);
}
else if (type == GTF_lockHF) {
/* Find the number of lines in vSync + back porch */
vSyncBP = round((c.minVSyncBP * hFreq) / 1000);
}
/* Find the number of lines in the V back porch alone */
vBackPorch = vSyncBP - c.vSyncRqd;
/* Find the total number of lines in the vertical period */
vTotalLines = vLines + topMarginLines + botMarginLines + vSyncBP
+ interlace + c.minPorch;
if (type == GTF_lockVF) {
/* Estimate the vertical frequency */
vFieldRateEst = 1000000 / (hPeriodEst * vTotalLines);
/* Find the actual horizontal period */
hPeriod = (hPeriodEst * vFieldRateEst) / vFieldRate;
/* Find the actual vertical field frequency */
vFieldRate = 1000000 / (hPeriod * vTotalLines);
}
else if (type == GTF_lockHF) {
/* Find the actual vertical field frequency */
vFieldRate = (hFreq / vTotalLines) * 1000;
}
}
/* Find the number of pixels in the left and right margins */
if (wantMargins) {
leftMarginPixels = round(hPixels * c.margin) / (100 * c.cellGran);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?