📄 timing.c
字号:
&& t->VDisplay >= y && timing_within_monitor_spec(t) && t->HDisplay <= *bestx && t->VDisplay <= *besty && t->pixelClock>=bestclock ) { bestclock = t->pixelClock; *bestx=t->HDisplay; *besty=t->VDisplay; *bestmodetiming = t; }; }; for (t = __svgalib_standard_timings; t; t = t->next) { if (t->HDisplay >= x && t->VDisplay >= y && timing_within_monitor_spec(t) && t->HDisplay <= *bestx && t->VDisplay <= *besty && t->pixelClock>=bestclock ) { bestclock = t->pixelClock; *bestx=t->HDisplay; *besty=t->VDisplay; *bestmodetiming = t; }; }; return *bestmodetiming!=NULL;};static int find_down_timing(int x, int y, int *bestx, int *besty, MonitorModeTiming **bestmodetiming){ MonitorModeTiming *t; int bestclock=0; int mode_ar; *bestmodetiming=NULL; *bestx=*besty=0; for (t = user_timings; t; t = t->next) { if ((mode_ar=1000*t->VDisplay/t->HDisplay)<=765 && mode_ar>=735 && t->HDisplay <= x && t->VDisplay <= y && timing_within_monitor_spec(t) && t->HDisplay >= *bestx && t->VDisplay >= *besty && t->pixelClock>=bestclock ) { bestclock = t->pixelClock; *bestx=t->HDisplay; *besty=t->VDisplay; *bestmodetiming = t; }; }; for (t = __svgalib_standard_timings; t; t = t->next) { if (t->HDisplay <= x && t->VDisplay <= y && timing_within_monitor_spec(t) && t->HDisplay >= *bestx && t->VDisplay >= *besty && t->pixelClock>=bestclock ) { bestclock = t->pixelClock; *bestx=t->HDisplay; *besty=t->VDisplay; *bestmodetiming = t; }; }; return *bestmodetiming!=NULL;};int vga_guesstiming(int x, int y, int clue, int arg){/* This functions tries to add timings that fit a specific mode, by changing the timings of a similar mode currently only works for x:y = 4:3, clue means:0- scale down timing of a higher res mode1- scale up timings of a lower res mode*/ MonitorModeTiming mmt, *bestmodetiming = NULL ; int bestx,besty /*, bestclock */ ; int aspect_ratio=1000*y/x; switch(clue) { case 0: case 1: if((aspect_ratio>765)||(aspect_ratio<735))return 0; if(clue==0)find_up_timing(x,y,&bestx,&besty,&bestmodetiming); if(clue==1)find_down_timing(x,y,&bestx,&besty,&bestmodetiming); if(bestmodetiming){ mmt=*bestmodetiming; mmt.pixelClock=(mmt.pixelClock*x)/bestx; mmt.HDisplay=x; mmt.VDisplay=y; mmt.HSyncStart=(mmt.HSyncStart*x)/bestx; mmt.HSyncEnd=(mmt.HSyncEnd*x)/bestx; mmt.HTotal=(mmt.HTotal*x)/bestx; mmt.VSyncStart=(mmt.VSyncStart*x)/bestx; mmt.VSyncEnd=(mmt.VSyncEnd*x)/bestx; mmt.VTotal=(mmt.VTotal*x)/bestx; __svgalib_addusertiming(&mmt); return 1; }; break; case 256: case 257: { int mx; mx=y*4/3; if((clue&1)==0)find_up_timing(mx,y,&bestx,&besty,&bestmodetiming); if((clue&1)==1)find_down_timing(mx,y,&bestx,&besty,&bestmodetiming); if(bestmodetiming){ mmt=*bestmodetiming; mmt.pixelClock=(mmt.pixelClock*x)/bestx; mmt.HDisplay=x; mmt.HSyncStart=(mmt.HSyncStart*x)/bestx; mmt.HSyncEnd=(mmt.HSyncEnd*x)/bestx; mmt.HTotal=(mmt.HTotal*x)/bestx; mmt.VDisplay=y; mmt.VSyncStart=(mmt.VSyncStart*mx)/bestx; mmt.VSyncEnd=(mmt.VSyncEnd*mx)/bestx; mmt.VTotal=(mmt.VTotal*mx)/bestx; __svgalib_addusertiming(&mmt); return 1; }; }; case 258: case 259: { int my; my=(x*3)>>2; if((clue&1)==0)find_up_timing(x,my,&bestx,&besty,&bestmodetiming); if((clue&1)==1)find_down_timing(x,my,&bestx,&besty,&bestmodetiming); if(bestmodetiming){ mmt=*bestmodetiming; mmt.pixelClock=(mmt.pixelClock*x)/bestx; mmt.HDisplay=x; mmt.HSyncStart=(mmt.HSyncStart*x)/bestx; mmt.HSyncEnd=(mmt.HSyncEnd*x)/bestx; mmt.HTotal=(mmt.HTotal*x)/bestx; mmt.VDisplay=y; mmt.VSyncStart=(mmt.VSyncStart*y)/besty; mmt.VSyncEnd=(mmt.VSyncEnd*y)/besty; mmt.VTotal=(mmt.VTotal*y)/besty; __svgalib_addusertiming(&mmt); return 1; }; }; }; return 0;};#ifdef GTF/* Everything from here to the end of the file is copyright by scitechsoft. See their original program in utils/gtf subdirectory */ typedef struct { double margin; /* Margin size as percentage of display */ double cellGran; /* Character cell granularity */ double minPorch; /* Minimum front porch in lines/chars */ double vSyncRqd; /* Width of V sync in lines */ double hSync; /* Width of H sync as percent of total */ double minVSyncBP; /* Minimum vertical sync + back porch (us) */ double m; /* Blanking formula gradient */ double c; /* Blanking formula offset */ double k; /* Blanking formula scaling factor */ double j; /* Blanking formula scaling factor weight */} GTF_constants;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 */};static double round(double v){ double u=v; long j; if(u<0) u=-u; u=u+0.5; j=u; if(v<0) j=-j; return j;}static double sqrt(double u){ double v,w; int i; v=0; if(u==0) return 0; if(u<0) u=-u; w=u; if(u<1) w=1; for(i=0;i<50;i++){ w=w/2; if(v*v==u)break; if(v*v<u)v=v+w; if(v*v>u)v=v-w; }; return v;}static void GetInternalConstants(GTF_constants *c){ 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;}static void GTF_calcTimings(double hPixels,double vLines,double freq, int type,int wantMargins,int wantInterlace, int wantDblscan, MonitorModeTiming *mmt){ double interlace,vFieldRate,hPeriod=0; double topMarginLines,botMarginLines; double leftMarginPixels,rightMarginPixels; double hPeriodEst=0,vSyncBP=0,vBackPorch=0; double vTotalLines=0,vFieldRateEst; double hTotalPixels,hTotalActivePixels,hBlankPixels; double idealDutyCycle=0,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(wantDblscan) vLines = vLines * 2; 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(((100-c.c)*(100-c.c)) + (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; } else vFreq = vFieldRate; mmt->pixelClock = dotClock; /* Determine the vertical timing parameters */ mmt->HTotal = hTotalPixels; mmt->HDisplay = hTotalActivePixels; mmt->HSyncStart = mmt->HTotal - hSyncBP; mmt->HSyncEnd = mmt->HTotal - hBackPorch; /* Determine the vertical timing parameters */ mmt->VTotal = vTotalLines; mmt->VDisplay = vLines; mmt->VSyncStart = mmt->VTotal - vSyncBP; mmt->VSyncEnd = mmt->VTotal - vBackPorch; if(wantDblscan) { mmt->VTotal >>= 1; mmt->VDisplay >>= 1 ; mmt->VSyncStart >>= 1 ; mmt->VSyncEnd >>= 1 ; }; if(wantInterlace) { mmt->VTotal <<= 1; mmt->VDisplay <<= 1 ; mmt->VSyncStart <<= 1 ; mmt->VSyncEnd <<= 1 ; }; mmt->flags = NHSYNC | PVSYNC | ((wantInterlace) ? INTERLACED : 0) | ((wantDblscan) ? DOUBLESCAN : 0);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -