⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtfcalc.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
字号:
/******************************************************************************				 	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 <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <math.h>#include "gtf.h"/*------------------------- 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 -------------------------------*/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.	 */	if (wantInterlace) {		vLines = round(vLines / 2);		vFieldRate = vFreq * 2;		dotClock = dotClock * 2;		interlace = 0.5;		}	else {		vFieldRate = vFreq;		interlace = 0;		}	/* 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);		rightMarginPixels = round(hPixels * c.margin) / (100 * c.cellGran);		}	else {		leftMarginPixels = 0;		rightMarginPixels = 0;		}	/* Find the total number of active pixels in image + margins */	hTotalActivePixels = hPixels + leftMarginPixels + rightMarginPixels;	if (type == GTF_lockVF) {		/* Find the ideal blanking duty cycle */		idealDutyCycle = c.c - ((c.m * hPeriod) / 1000);		}	else if (type == GTF_lockHF) {		/* Find the ideal blanking duty cycle */		idealDutyCycle = c.c - (c.m / hFreq);		}	else if (type == GTF_lockPF) {		/* Find ideal horizontal period from blanking duty cycle formula */		idealHPeriod = (((c.c - 100) + (sqrt((pow(100-c.c,2)) +			(0.4 * c.m * (hTotalActivePixels + rightMarginPixels +			leftMarginPixels) / dotClock)))) / (2 * c.m)) * 1000;		/* Find the ideal blanking duty cycle */		idealDutyCycle = c.c - ((c.m * idealHPeriod) / 1000);		}	/* Find the number of pixels in blanking time */	hBlankPixels = round((hTotalActivePixels * idealDutyCycle) /		((100 - idealDutyCycle) * 2 * c.cellGran)) * (2 * c.cellGran);	/* Find the total number of pixels */	hTotalPixels = hTotalActivePixels + hBlankPixels;	/* Find the horizontal back porch */	hBackPorch = round((hBlankPixels / 2) / c.cellGran) * c.cellGran;	/* Find the horizontal sync width */	hSyncWidth = round(((c.hSync/100) * hTotalPixels) / c.cellGran) * c.cellGran;	/* Find the horizontal sync + back porch */	hSyncBP = hBackPorch + hSyncWidth;	if (type == GTF_lockPF) {		/* Find the horizontal frequency */		hFreq = (dotClock / hTotalPixels) * 1000;		/* Find the horizontal period */		hPeriod = 1000 / hFreq;		/* 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;		/* Find the actual vertical field frequency */		vFieldRate = (hFreq / vTotalLines) * 1000;		}	else {		if (type == GTF_lockVF) {			/* Find the horizontal frequency */			hFreq = 1000 / hPeriod;			}		else if (type == GTF_lockHF) {			/* Find the horizontal frequency */			hPeriod = 1000 / hFreq;			}		/* Find the pixel clock frequency */		dotClock = hTotalPixels / hPeriod;		}	/* Find the vertical frame frequency */	if (wantInterlace) {		vFreq = vFieldRate / 2;		dotClock = dotClock / 2;		}	else		vFreq = vFieldRate;	/* Return the computed frequencies */	t->vFreq = vFreq;	t->hFreq = hFreq;	t->dotClock = dotClock;	/* Determine the vertical timing parameters */	t->h.hTotal = hTotalPixels;	t->h.hDisp = hTotalActivePixels;	t->h.hSyncStart = t->h.hTotal - hSyncBP;	t->h.hSyncEnd = t->h.hTotal - hBackPorch;	t->h.hFrontPorch = t->h.hSyncStart - t->h.hDisp;	t->h.hSyncWidth = hSyncWidth;	t->h.hBackPorch = hBackPorch;	/* Determine the vertical timing parameters */	t->v.vTotal = vTotalLines;	t->v.vDisp = vLines;	t->v.vSyncStart = t->v.vTotal - vSyncBP;	t->v.vSyncEnd = t->v.vTotal - vBackPorch;	t->v.vFrontPorch = t->v.vSyncStart - t->v.vDisp;	t->v.vSyncWidth = c.vSyncRqd;	t->v.vBackPorch = vBackPorch;	/* Mark as GTF timing using the sync polarities */	t->interlace = (wantInterlace) ? 'I' : 'N';	t->hSyncPol = '-';	t->vSyncPol = '+';}void GTF_getConstants(GTF_constants *constants){ *constants = GC; }void GTF_setConstants(GTF_constants *constants){ GC = *constants; }#ifdef	TESTING_GTFvoid main(int argc,char *argv[]){	FILE		*f;	double		xPixels,yPixels,freq;	ibool		interlace;	GTF_timings	t;	if (argc != 5 && argc != 6) {		printf("Usage: GTFCALC <xPixels> <yPixels> <freq> [[Hz] [KHz] [MHz]] [I]\n");		printf("\n");		printf("where <xPixels> is the horizontal resolution of the mode, <yPixels> is the\n");		printf("vertical resolution of the mode. The <freq> value will be the frequency to\n");		printf("drive the calculations, and will be either the vertical frequency (in Hz)\n");		printf("the horizontal frequency (in KHz) or the dot clock (in MHz). To generate\n");		printf("timings for an interlaced mode, add 'I' to the end of the command line.\n");		printf("\n");		printf("For example to generate timings for 640x480 at 60Hz vertical:\n");		printf("\n");		printf("    GTFCALC 640 480 60 Hz\n");		printf("\n");		printf("For example to generate timings for 640x480 at 31.5KHz horizontal:\n");		printf("\n");		printf("    GTFCALC 640 480 31.5 KHz\n");		printf("\n");		printf("For example to generate timings for 640x480 with a 25.175Mhz dot clock:\n");		printf("\n");		printf("    GTFCALC 640 480 25.175 MHz\n");		printf("\n");		printf("GTFCALC will print a summary of the results found, and dump the CRTC\n");		printf("values to the UVCONFIG.CRT file in the format used by SciTech Display Doctor.\n");		exit(1);		}	/* Get values from command line */	xPixels = atof(argv[1]);	yPixels = atof(argv[2]);	freq = atof(argv[3]);	interlace = ((argc == 6) && (argv[5][0] == 'I'));	/* Compute the CRTC timings */	if (toupper(argv[4][0]) == 'H')		GTF_calcTimings(xPixels,yPixels,freq,GTF_lockVF,false,interlace,&t);	else if (toupper(argv[4][0]) == 'K')		GTF_calcTimings(xPixels,yPixels,freq,GTF_lockHF,false,interlace,&t);	else if (toupper(argv[4][0]) == 'M')		GTF_calcTimings(xPixels,yPixels,freq,GTF_lockPF,false,interlace,&t);	else {		printf("Unknown command line!\n");		exit(1);		}	/* Dump summary info to standard output */	printf("CRTC values for %.0fx%.0f @ %.2f %s\n", xPixels, yPixels, freq, argv[4]);	printf("\n");	printf("  hTotal      = %-4d    vTotal      = %-4d\n",		t.h.hTotal, t.v.vTotal);	printf("  hDisp       = %-4d    vDisp       = %-4d\n",		t.h.hDisp, t.v.vDisp);	printf("  hSyncStart  = %-4d    vSyncStart  = %-4d\n",		t.h.hSyncStart, t.v.vSyncStart);	printf("  hSyncEnd    = %-4d    vSyncEnd    = %-4d\n",		t.h.hSyncEnd, t.v.vSyncEnd);	printf("  hFrontPorch = %-4d    vFrontPorch = %-4d\n",		t.h.hFrontPorch, t.v.vFrontPorch);	printf("  hSyncWidth  = %-4d    vSyncWidth  = %-4d\n",		t.h.hSyncWidth, t.v.vSyncWidth);	printf("  hBackPorch  = %-4d    vBackPorch  = %-4d\n",		t.h.hBackPorch, t.v.vBackPorch);	printf("\n");	printf("  Interlaced  = %s\n", (t.interlace == 'I') ? "Yes" : "No");	printf("  H sync pol  = %c\n", t.hSyncPol);	printf("  V sync pol  = %c\n", t.vSyncPol);	printf("\n");	printf("  Vert freq   = %.2f Hz\n", t.vFreq);	printf("  Horiz freq  = %.2f KHz\n", t.hFreq);	printf("  Dot Clock   = %.2f Mhz\n",	t.dotClock);        fprintf(stderr,"Modeline %c%ix%i@%.0f%c %.3f %i %i %i %i %i %i %i %i %s %chsync %cvsync\n",           		     '"',t.h.hDisp,t.v.vDisp,t.vFreq,'"',                 	     t.dotClock,            		     t.h.hDisp,		           		     t.h.hSyncStart,           		     t.h.hSyncEnd,                             t.h.hTotal,                             t.v.vDisp,                             t.v.vSyncStart,                             t.v.vSyncEnd,                             t.v.vTotal,                             (t.interlace == 'I') ? "Interlace" : "",                             t.hSyncPol,                             t.vSyncPol                                                          );	/* Dump to file in format used by SciTech Display Doctor */	if ((f = fopen("UVCONFIG.CRT","wt")) != NULL) {		fprintf(f, "[%.0f %.0f]\n", xPixels, yPixels);		fprintf(f, "%d %d %d %d '%c' %s\n",			t.h.hTotal, t.h.hDisp,			t.h.hSyncStart, t.h.hSyncEnd,			t.hSyncPol, (t.interlace == 'I') ? "I" : "NI");		fprintf(f, "%d %d %d %d '%c'\n",			t.v.vTotal, t.v.vDisp,			t.v.vSyncStart, t.v.vSyncEnd,			t.vSyncPol);		fprintf(f, "%.2f\n", t.dotClock);		fclose(f);		}}#endif	/* TESTING */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -