DMT and GTF Added

Main
Glenwing 6 years ago
parent 9a113ad327
commit 8948104b6f

@ -0,0 +1,89 @@
ID,STD,H,V,SCAN,NOM_FREQ,V_FREQ,H_FREQ,CLK,H_FP,H_SW,H_BP,V_FP,V_SW,V_BP,Margin,H_POL,V_POL,H_BLANK,V_BLANK,H_EFF,V_EFF
01h,DMT,640,350,p,85.000,85.080,37.861,31.5,32,64,96,32,3,60,0,p,n,192,95,832,445
02h,DMT,640,400,p,85.000,85.080,37.861,31.5,32,64,96,1,3,41,0,n,p,192,45,832,445
03h,DMT,720,400,p,85.000,85.039,37.927,35.5,36,72,108,1,3,42,0,n,p,216,46,936,446
04h,DMT,640,480,p,60.000,59.940,31.469,25.175,8,96,40,2,2,25,8,n,n,160,45,800,525
05h,DMT,640,480,p,72.000,72.809,37.861,31.5,16,40,120,1,3,20,8,n,n,192,40,832,520
06h,DMT,640,480,p,75.000,75.000,37.5,31.5,16,64,120,1,3,16,0,n,n,200,20,840,500
07h,DMT,640,480,p,85.000,85.008,43.269,36,56,56,80,1,3,25,0,n,n,192,29,832,509
08h,DMT,800,600,p,56.000,56.250,35.156,36,24,72,128,1,2,22,0,p,p,224,25,1024,625
09h,DMT,800,600,p,60.000,60.317,37.879,40,40,128,88,1,4,23,0,p,p,256,28,1056,628
0Ah,DMT,800,600,p,75.000,72.188,48.077,50,56,120,64,37,6,23,0,p,p,240,66,1040,666
0Bh,DMT,800,600,p,75.000,75.000,46.875,49.5,16,80,160,1,3,21,0,p,p,256,25,1056,625
0Ch,DMT,800,600,p,85.000,85.061,53.674,56.25,32,64,152,1,3,27,0,p,p,248,31,1048,631
0Dh,CVTRB,800,600,p,120.000,119.972,76.302,73.25,48,32,80,3,4,29,0,p,n,160,36,960,636
0Eh,DMT,848,480,p,60.000,60.000,31.02,33.75,16,112,112,6,8,23,0,p,p,240,37,1088,517
0Fh,DMT,1024,768,i,43.000,86.957,35.522,44.9,8,176,56,0,4,20,0,p,p,240,24,1264,792
10h,DMT,1024,768,p,60.000,60.004,48.363,65,24,136,160,3,6,29,0,n,n,320,38,1344,806
11h,DMT,1024,768,p,70.000,70.069,56.476,75,24,136,144,3,6,29,0,n,n,304,38,1328,806
12h,DMT,1024,768,p,75.000,75.029,60.023,78.75,16,96,176,1,3,28,0,p,p,288,32,1312,800
13h,DMT,1024,768,p,85.000,84.997,68.677,94.5,48,96,208,1,3,36,0,p,p,352,40,1376,808
14h,CVTRB,1024,768,p,120.000,119.989,97.551,115.5,48,32,80,3,4,38,0,p,n,160,45,1184,813
15h,DMT,1152,864,p,75.000,75.000,67.5,108,64,128,256,1,3,32,0,p,p,448,36,1600,900
55h,CTA,1280,720,p,60.000,60.000,45,74.25,110,40,220,5,5,20,0,p,p,370,30,1650,750
16h,CVTRB,1280,768,p,60.000,59.995,47.396,68.25,48,32,80,3,7,12,0,p,n,160,22,1440,790
17h,CVT,1280,768,p,60.000,59.870,47.776,79.5,64,128,192,3,7,20,0,n,p,384,30,1664,798
18h,CVT,1280,768,p,75.000,74.893,60.289,102.25,80,128,208,3,7,27,0,n,p,416,37,1696,805
19h,CVT,1280,768,p,85.000,84.837,68.633,117.5,80,136,216,3,7,31,0,n,p,432,41,1712,809
1Ah,CVTRB,1280,768,p,120.000,119.798,97.396,140.25,48,32,80,3,7,35,0,p,n,160,45,1440,813
1Bh,CVTRB,1280,800,p,60.000,59.910,49.306,71,48,32,80,3,6,14,0,p,n,160,23,1440,823
1Ch,CVT,1280,800,p,60.000,59.810,49.702,83.5,72,128,200,3,6,22,0,n,p,400,31,1680,831
1Dh,CVT,1280,800,p,75.000,74.934,62.795,106.5,80,128,208,3,6,29,0,n,p,416,38,1696,838
1Eh,CVT,1280,800,p,85.000,84.880,71.554,122.5,80,136,216,3,6,34,0,n,p,432,43,1712,843
1Fh,CVTRB,1280,800,p,120.000,119.909,101.563,146.25,48,32,80,3,6,38,0,p,n,160,47,1440,847
20h,DMT,1280,960,p,60.000,60.000,60,108,96,112,312,1,3,36,0,p,p,520,40,1800,1000
21h,DMT,1280,960,p,85.000,85.002,85.938,148.5,64,160,224,1,3,47,0,p,p,448,51,1728,1011
22h,CVTRB,1280,960,p,120.000,119.838,121.875,175.5,48,32,80,3,4,50,0,p,n,160,57,1440,1017
23h,DMT,1280,1024,p,60.000,60.020,63.981,108,48,112,248,1,3,38,0,p,p,408,42,1688,1066
24h,DMT,1280,1024,p,75.000,75.025,79.976,135,16,144,248,1,3,38,0,p,p,408,42,1688,1066
25h,DMT,1280,1024,p,85.000,85.024,91.146,157.5,64,160,224,1,3,44,0,p,p,448,48,1728,1072
26h,CVTRB,1280,1024,p,120.000,119.958,130.035,187.25,48,32,80,3,7,50,0,p,n,160,60,1440,1084
27h,DMT,1360,768,p,60.000,60.015,47.712,85.5,64,112,256,3,6,18,0,p,p,432,27,1792,795
28h,CVTRB,1360,768,p,120.000,119.967,97.533,148.25,48,32,80,3,5,37,0,p,n,160,45,1520,813
51h,DMT,1366,768,p,60.000,59.790,47.712,85.5,70,143,213,3,3,24,0,p,p,426,30,1792,798
56h,DMT,1366,768,p,60.000,60.000,48,72,14,56,64,1,3,28,0,p,p,134,32,1500,800
29h,CVTRB,1400,1050,p,60.000,59.948,64.744,101,48,32,80,3,4,23,0,p,n,160,30,1560,1080
2Ah,CVT,1400,1050,p,60.000,,65.317,121.75,,,,,,,,,,,,,
2Bh,CVT,1400,1050,p,75.000,,82.3,156,,,,,,,,,,,,,
2Ch,CVT,1400,1050,p,85.000,,93.9,179.5,,,,,,,,,,,,,
2Dh,CVTRB,1400,1050,p,120.000,,133.3,208,,,,,,,,,,,,,
2Eh,CVTRB,1440,900,p,60.000,,55.5,88.75,,,,,,,,,,,,,
2Fh,CVT,1440,900,p,60.000,,55.9,106.5,,,,,,,,,,,,,
30h,CVT,1440,900,p,75.000,,70.6,136.75,,,,,,,,,,,,,
31h,CVT,1440,900,p,85.000,,80.4,157,,,,,,,,,,,,,
32h,CVTRB,1440,900,p,120.000,,114.2,182.75,,,,,,,,,,,,,
53h,DMT,1600,900,p,60.000,60.000,60,108,24,80,96,1,3,96,0,p,p,200,100,1800,1000
33h,DMT,1600,1200,p,60.000,60.000,75,162,64,192,304,1,3,46,0,p,p,560,50,2160,1250
34h,DMT,1600,1200,p,65.000,65.000,81.25,175.5,64,192,304,1,3,46,0,p,p,560,50,2160,1250
35h,DMT,1600,1200,p,70.000,70.000,87.5,189,64,192,304,1,3,46,0,p,p,560,50,2160,1250
36h,DMT,1600,1200,p,75.000,75.000,93.75,202.5,64,192,304,1,3,46,0,p,p,560,50,2160,1250
37h,DMT,1600,1200,p,85.000,85.000,106.25,229.5,64,192,304,1,3,46,0,p,p,560,50,2160,1250
38h,CVTRB,1600,1200,p,120.000,,152.415,268.25,,,,,,,,,,,,,
39h,CVTRB,1680,1050,p,60.000,,64.7,119,,,,,,,,,,,,,
3Ah,CVT,1680,1050,p,60.000,,65.3,146.25,,,,,,,,,,,,,
3Bh,CVT,1680,1050,p,75.000,,82.3,187,,,,,,,,,,,,,
3Ch,CVT,1680,1050,p,85.000,,93.9,214.75,,,,,,,,,,,,,
3Dh,CVTRB,1680,1050,p,120.000,,144.4,245.5,,,,,,,,,,,,,
3Eh,DMT,1792,1344,p,60.000,60.000,83.64,204.75,128,200,328,1,3,46,0,n,p,656,50,2448,1394
3Fh,DMT,1792,1344,p,75.000,74.997,106.270,261.000,96,216,352,1,3,69,0,n,p,664,73,2456,1417
40h,CVTRB,1792,1344,p,120.000,,170.700,333.25,,,,,,,,,,,,,
41h,DMT,1856,1392,p,60.000,59.995,86.333,218.25,96,224,352,1,3,43,0,n,p,672,47,2528,1439
42h,DMT,1856,1392,p,75.000,75.000,112.5,288.000,128,224,352,1,3,104,0,n,p,704,108,2560,1500
43h,CVTRB,1856,1392,p,120.000,,176.800,356.5,,,,,,,,,,,,,
52h,CTA,1920,1080,p,60.000,,67.5,148.500,,,,,,,,,,,,,
44h,CVTRB,1920,1200,p,60.000,,74,154,,,,,,,,,,,,,
45h,CVT,1920,1200,p,60.000,,74.600,193.25,,,,,,,,,,,,,
46h,CVT,1920,1200,p,75.000,,94,245.25,,,,,,,,,,,,,
47h,CVT,1920,1200,p,85.000,,107.2,281.25,,,,,,,,,,,,,
48h,CVTRB,1920,1200,p,120.000,,152.400,317.000,,,,,,,,,,,,,
49h,DMT,1920,1440,p,60.000,60.000,90,234,128,208,344,1,3,56,0,n,p,680,60,2600,1500
4Ah,DMT,1920,1440,p,75.000,75.000,112.500,297.000,144,224,352,1,3,56,0,n,p,720,60,2640,1500
4Bh,CVTRB,1920,1440,p,120.000,,182.9,380.5,,,,,,,,,,,,,
54h,CVTRB,2048,1152,p,60.000,,70.992,156.75,,,,,,,,,,,,,
4Ch,CVTRB,2560,1600,p,60.000,,98.700,268.500,,,,,,,,,,,,,
4Dh,CVT,2560,1600,p,60.000,,99.5,348.5,,,,,,,,,,,,,
4Eh,CVT,2560,1600,p,75.000,,125.4,443.25,,,,,,,,,,,,,
4Fh,CVT,2560,1600,p,85.000,,142.900,505.250,,,,,,,,,,,,,
50h,CVTRB,2560,1600,p,120.000,,203.2,552.75,,,,,,,,,,,,,
57h,CVTR2,4096,2160,p,60.000,,133.32,556.744,,,,,,,,,,,,,
58h,CVTR2,4096,2160,p,59.940,,133.187,556.188,,,,,,,,,,,,,

@ -9,6 +9,7 @@ DebugConfig({
CTA861 = {};
DMT_List = {};
// The intepreted current state of all input fields is stored here
@ -217,7 +218,7 @@ function submitVar(id, val) {
else if (id == 'V_FP' || id == 'V_BP' || id == 'V_SW' ||
id == 'H_FP' || id == 'H_BP' || id == 'H_SW' ||
id == 'V_FP_ODD' || id == 'V_SW_ODD' || id == 'V_BP_ODD') {
id == 'V_FP_INT' || id == 'V_SW_INT' || id == 'V_BP_INT') {
GlobalVars_Key = id;
val = parseFloat(parseNum(val));
if (isNum(val)) {
@ -226,7 +227,7 @@ function submitVar(id, val) {
$('#' + id).val(val);
$('#V_BLANK').html(Global_InputVars['V_FP'] + Global_InputVars['V_BP'] + Global_InputVars['V_SW']);
$('#H_BLANK').html(Global_InputVars['H_FP'] + Global_InputVars['H_BP'] + Global_InputVars['H_SW']);
$('#V_BLANK_ODD').html(Global_InputVars['V_FP_ODD'] + Global_InputVars['V_BP_ODD'] + Global_InputVars['V_SW_ODD']);
$('#V_BLANK_INT').html(Global_InputVars['V_FP_INT'] + Global_InputVars['V_BP_INT'] + Global_InputVars['V_SW_INT']);
}
else {
DEBUG(id + ' input is not a number:', val);
@ -234,7 +235,7 @@ function submitVar(id, val) {
$('#' + id).val('');
$('#V_BLANK').html('');
$('#H_BLANK').html('');
$('#V_BLANK_ODD').html('');
$('#V_BLANK_INT').html('');
}
DEBUG("Global_InputVars['" + GlobalVars_Key + "'] was set to", Global_InputVars[GlobalVars_Key]);
@ -368,6 +369,7 @@ function calcMain() {
// Get timing parameters
Timing = getTiming(timing_standard);
if (!Timing) { clearResults(); return; } // Abort if getTiming returns false, it indicates the format is not defined for that timing standard.
DEBUG('Timing:', Timing);
var results = {
@ -425,6 +427,10 @@ function getTiming(timing_standard) {
'H_BP': '',
'H_SW': '',
'V_FP_INT': '',
'V_BP_INT': '',
'V_SW_INT': '',
'V_BL': '',
'H_BL': '',
@ -435,21 +441,39 @@ function getTiming(timing_standard) {
if (timing_standard != 'Custom') {
if (timing_standard == 'CVT-R2') {
Timing = CVT_R(2);
$('#TIMING_FORMAT_NAME').html('<b>VESA Name:</b> ' + (Global_InputVars['HRES'] * Global_InputVars['VRES'] / 1000000).toFixed(2) + 'M' + Timing['VESA_AR'] + '-R');
}
else if (timing_standard == 'CVT-RB') {
Timing = CVT_R(1);
$('#TIMING_FORMAT_NAME').html('<b>VESA Name:</b> ' + (Global_InputVars['HRES'] * Global_InputVars['VRES'] / 1000000).toFixed(2) + 'M' + Timing['VESA_AR'] + '-R');
}
else if (timing_standard == 'CVT') {
Timing = CVT();
$('#TIMING_FORMAT_NAME').html('<b>VESA Name:</b> ' + (Global_InputVars['HRES'] * Global_InputVars['VRES'] / 1000000).toFixed(2) + 'M' + Timing['VESA_AR']);
}
else if (timing_standard == 'GTF') {
Timing = GTF();
$('#TIMING_FORMAT_NAME').html('');
}
else if (timing_standard == 'DMT') {
Timing = DMT();
if (!Timing) {
DEBUG ('Not a DMT Format. DMT Function returned false.');
$('#TIMING_FORMAT_NAME').html('');
return false; }
else {
$('#TIMING_FORMAT_NAME').html('<b>DMT ID:</b> ' + Timing['ID']);
}
}
else if (timing_standard == 'CTA-861') {
Timing = CTA();
if (!Timing) {
DEBUG ('Not a CTA Format. CTA Function returned false.');
$('#TIMING_FORMAT_NAME').html('');
return false; }
else {
$('#TIMING_FORMAT_NAME').html('<b>CTA VIC:</b> ' + Timing['VIC']);
}
}
else if (timing_standard == 'None') {
Timing = {
@ -460,16 +484,21 @@ function getTiming(timing_standard) {
'H_BP': 0,
'H_SW': 0,
'V_FP_ODD': 0,
'V_BP_ODD': 0,
'V_SW_ODD': 0,
'V_FP_INT': 0,
'V_BP_INT': 0,
'V_SW_INT': 0,
'V_BL': 0,
'H_BL': 0,
'V_EFF': Global_InputVars['VRES'],
'H_EFF': Global_InputVars['HRES'],
'F_ACTUAL': Global_InputVars['FREQ'],
}
$('#TIMING_FORMAT_NAME').html('');
}
// Update UI timing parameter fields with the newly generated timings
submitVar('V_FP', Timing['V_FP']);
submitVar('V_BP', Timing['V_BP']);
@ -477,9 +506,10 @@ function getTiming(timing_standard) {
submitVar('H_FP', Timing['H_FP']);
submitVar('H_BP', Timing['H_BP']);
submitVar('H_SW', Timing['H_SW']);
submitVar('V_FP_ODD', Timing['V_FP_ODD']);
submitVar('V_SW_ODD', Timing['V_SW_ODD']);
submitVar('V_BP_ODD', Timing['V_BP_ODD']);
submitVar('V_FP_INT', Timing['V_FP_INT']);
submitVar('V_SW_INT', Timing['V_SW_INT']);
submitVar('V_BP_INT', Timing['V_BP_INT']);
}
else if (timing_standard == 'Custom') {
@ -490,9 +520,9 @@ function getTiming(timing_standard) {
submitVar('H_FP', $('#H_FP').val());
submitVar('H_BP', $('#H_BP').val());
submitVar('H_SW', $('#H_SW').val());
submitVar('V_FP_ODD', Global_InputVars['V_FP'] + 0.5);
submitVar('V_SW_ODD', Global_InputVars['V_SW']);
submitVar('V_BP_ODD', Global_InputVars['V_BP'] + 0.5);
submitVar('V_FP_INT', Global_InputVars['V_FP'] + 0.5);
submitVar('V_SW_INT', Global_InputVars['V_SW']);
submitVar('V_BP_INT', Global_InputVars['V_BP'] + 0.5);
Timing = {
'V_FP': Global_InputVars['V_FP'],
@ -502,15 +532,19 @@ function getTiming(timing_standard) {
'H_BP': Global_InputVars['H_BP'],
'H_SW': Global_InputVars['H_SW'],
'V_FP_ODD': Global_InputVars['V_FP_ODD'],
'V_BP_ODD': Global_InputVars['V_BP_ODD'],
'V_SW_ODD': Global_InputVars['V_SW_ODD'],
'V_FP_INT': Global_InputVars['V_FP_INT'],
'V_BP_INT': Global_InputVars['V_BP_INT'],
'V_SW_INT': Global_InputVars['V_SW_INT'],
'V_BL': Global_InputVars['V_FP'] + Global_InputVars['V_BP'] + Global_InputVars['V_SW'],
'H_BL': Global_InputVars['H_FP'] + Global_InputVars['H_BP'] + Global_InputVars['H_SW'],
'V_EFF': Global_InputVars['VRES'] + Global_InputVars['V_FP'] + Global_InputVars['V_BP'] + Global_InputVars['V_SW'],
'H_EFF': Global_InputVars['HRES'] + Global_InputVars['H_FP'] + Global_InputVars['H_BP'] + Global_InputVars['H_SW'],
'F_ACTUAL': Global_InputVars['FREQ'],
}
$('#TIMING_FORMAT_NAME').html('');
}
$('#V_BLANK').html(Timing['V_BL']);
@ -527,6 +561,8 @@ function CVT_R(R) { // Variable R is an integer representing the reduced blankin
var S = Global_InputVars['SCAN']; // 1 for progressive scan, 2 for interlaced
var M = Global_InputVars['MARGINS']; // Margins (%)
var I = (S - 1) / 2; // 0 for progressive, 0.5 for interlaced
// Declaring variables for all results
var V_FP; // Vertical front porch
var V_SW; // Vertical sync width
@ -561,25 +597,29 @@ function CVT_R(R) { // Variable R is an integer representing the reduced blankin
// Determine vertical sync width (V_SW) from table of magic numbers defined in VESA CVT standard
var V_SYNC_TABLE = [
[4/3, 4],
[16/9, 5],
[8/5, 6],
[5/3, 7],
[5/4, 7],
[4/3, 4, '3'],
[16/9, 5, '9'],
[8/5, 6, 'A'],
[5/3, 7, '9'],
[5/4, 7, '4'],
]
var AR_NAME = '';
V_SW = 10; // default value defined in standard
for (var i = 0; i < V_SYNC_TABLE.length; i++) {
if ((H / V) - V_SYNC_TABLE[i][0] < 0.05) { // Check if aspect ratio of image (H/V) matches an aspect ratio defined in table, within 0.05
if (Math.abs((H / V) - V_SYNC_TABLE[i][0]) < 0.05) { // Check if aspect ratio of image (H/V) matches an aspect ratio defined in table, within 0.05
V_SW = V_SYNC_TABLE[i][1];
AR_NAME = V_SYNC_TABLE[i][2];
DEBUG('AR_NAME', AR_NAME)
break;
}
}
// V_BP is determined in reverse, by calculating V_BLANK first (the sum of V_FP, V_SW, and V_BP) and subtracting out V_FP and V_SW.
var CellGran = 8; // Cell granularity constant defined by CVT standard
var H_RND = Math.floor(H / CellGran) * CellGran; // Round down horizontal resolution to be a multiple 8
var G = 8; // Cell granularity constant defined by CVT standard
var H_RND = Math.floor(H / G) * G; // Round down horizontal resolution to be a multiple 8
var V_MARGIN = Math.floor(M / 100) * V_LINES; // If margins percent (M) is 0, this result is 0
var H_MARGIN = Math.floor(H_RND * M / 100 / CellGran) * CellGran; // If margins percent (M) is 0, this result is 0
var H_MARGIN = Math.floor(H_RND * M / 100 / G) * G; // If margins percent (M) is 0, this result is 0
var H_PER_EST = ((1 / F) - V_PER_MIN) / (V_LINES + (2 * V_MARGIN)); // Horizontal blanking period estimate
V_BLANK = Math.floor((V_PER_MIN / H_PER_EST) + 1);
@ -589,7 +629,7 @@ function CVT_R(R) { // Variable R is an integer representing the reduced blankin
V_BP = V_BLANK - (V_FP + V_SW);
V_EFF = V_LINES + V_BLANK + V_MARGIN + ((S - 1)/2); // (S-1)/2 = 0 for progressive, 0.5 for interlaced
V_EFF = V_LINES + V_BLANK + V_MARGIN + I; // (S-1)/2 = 0 for progressive, 0.5 for interlaced
H_EFF = H_RND + H_BLANK + H_MARGIN;
// Calculate pixel clock, to enforce pixel clock rounding to the nearest 250 kHz, as required by the CVT standard
@ -613,7 +653,7 @@ function CVT_R(R) { // Variable R is an integer representing the reduced blankin
// V_FP is determined in reverse, by calculating V_BLANK first (the sum of V_FP, V_SW, and V_BP) and subtracting V_SW and V_BP out.
var V_MARGIN = Math.floor(M / 100) * V_LINES; // If margins percent (M) is 0, this result is 0
var H_MARGIN = Math.floor(H * M / 100); // If margins percent (M) is 0, this result is 0
var H_MARGIN = Math.floor(H * (M / 100)); // If margins percent (M) is 0, this result is 0
var H_PER_EST = ((1 / F) - V_PER_MIN) / (V_LINES + (2 * V_MARGIN)); // Horizontal blanking period estimate
V_BLANK = Math.floor((V_PER_MIN / H_PER_EST) + 1);
@ -623,7 +663,7 @@ function CVT_R(R) { // Variable R is an integer representing the reduced blankin
V_FP = V_BLANK - (V_BP + V_SW);
V_EFF = V_LINES + V_BLANK + V_MARGIN + ((S - 1)/2); // (S-1)/2 = 0 for progressive, 0.5 for interlaced
V_EFF = V_LINES + V_BLANK + V_MARGIN + I; // (S-1)/2 = 0 for progressive, 0.5 for interlaced
H_EFF = H + H_BLANK + H_MARGIN;
// Calculate pixel clock, to enforce pixel clock rounding to the nearest 1 kHz, as required by the CVT standard
@ -632,6 +672,20 @@ function CVT_R(R) { // Variable R is an integer representing the reduced blankin
F_HOR = CLK / (H_EFF); // Horizontal refresh frequency (Hz)
F_ACTUAL = F_HOR / (V_EFF);
var V_SYNC_TABLE = [
[4/3, 4, '3'],
[16/9, 5, '9'],
[8/5, 6, 'A'],
[5/3, 7, '9'],
[5/4, 7, '4'],
]
var AR_NAME = '';
for (var i = 0; i < V_SYNC_TABLE.length; i++) {
if (Math.abs((H / V) - V_SYNC_TABLE[i][0]) < 0.05) {
AR_NAME = V_SYNC_TABLE[i][2];
}
}
}
//DEBUG('CLK', CLK);
//DEBUG('F_HOR', F_HOR);
@ -639,35 +693,379 @@ function CVT_R(R) { // Variable R is an integer representing the reduced blankin
//DEBUG(V_BLANK);
return {
V_FP: V_FP, // For interlaced, these vertical timing are used for the even fields
V_BP: V_BP,
V_SW: V_SW,
H_FP: H_FP,
H_BP: H_BP,
H_SW: H_SW,
'V_FP': V_FP, // For interlaced, these vertical timing are used for the odd fields
'V_BP': V_BP,
'V_SW': V_SW,
'H_FP': H_FP,
'H_BP': H_BP,
'H_SW': H_SW,
V_FP_ODD: V_FP + 0.5, // For interlaced, V_FP and V_BP are 0.5 higher for odd fields (V_SW is same)
V_SW_ODD: V_SW,
V_BP_ODD: V_BP + 0.5,
'V_FP_INT': V_FP + I, // For interlaced, V_FP and V_BP are 0.5 higher for even fields (V_SW is same)
'V_BP_INT': V_BP + I,
'V_SW_INT': V_SW,
V_BL: V_BLANK,
H_BL: H_BLANK,
'V_BL': V_BLANK,
'H_BL': H_BLANK,
V_EFF: V_EFF,
H_EFF: H_EFF,
'V_EFF': V_EFF,
'H_EFF': H_EFF,
F_ACTUAL: F_ACTUAL,
'F_ACTUAL': F_ACTUAL,
'VESA_AR': AR_NAME,
};
}
function CVT() {
return;
var H = Global_InputVars['HRES']; // Horizontal active pixels
var V = Global_InputVars['VRES']; // Vertical active pixels
var F = Global_InputVars['FREQ']; // Nominal vertical refresh frequency
var S = Global_InputVars['SCAN']; // 1 for progressive scan, 2 for interlaced
var M = Global_InputVars['MARGINS']; // Margins (%)
var INTERLACE = (S - 1) / 2;
// Declaring variables for all results
var V_FP; // Vertical front porch
var V_SW; // Vertical sync width
var V_BP; // Vertical back porch
var H_FP; // Horizontal front porch
var H_SW; // Horizontal sync width
var H_BP; // Horizontal back porch
var V_BLANK; // Total vertical blanking (V_FP + V_SW + V_BP)
var H_BLANK; // Total horizontal blanking (H_FP + H_SW + H_BP)
var V_EFF; // V + V_Blank + V_Margins
var H_EFF; // H + H_Blank + H_Margins
var F_ACTUAL; // Actual vertical refresh frequency (after pixel clock rounding)
var F_HOR; // Horizontal refresh frequency
// Constants
var V_SBP_MIN = 0.00055; /* Minimum duration of vertical sync + back porch (seconds) */
var V_BP_MIN = 6; // Minimum vertical back porch value (lines)
var V_LINES = Math.floor(V / S) // If progressive scan, S = 1 and V_LINES = V. If interlaced, V_LINES = floor(V / 2).
V_FP = 3; // Vertical front porch value (lines)
var G = 8; // Cell Granularity constant
var H_RND = Math.floor(H / G) * G;
var V_MARGIN = Math.floor(M / 100 * V_LINES); // If margins percent (M) is 0, this result is 0
var H_MARGIN = Math.floor(H_RND * M / 100 / G) * G; // If margins percent (M) is 0, this result is 0
var H_SYNC_TARGET_WIDTH = 0.08 // Nominal horizontal sync pulse duration (percent of horizontal draw period)
// Determine V_SW from table
var V_SYNC_TABLE = [
[4/3, 4, '3'],
[16/9, 5, '9'],
[8/5, 6, 'A'],
[5/3, 7, '9'],
[5/4, 7, '4'],
]
var AR_NAME = '';
V_SW = 10; // default value defined in standard
for (var i = 0; i < V_SYNC_TABLE.length; i++) {
if (Math.abs((H / V) - V_SYNC_TABLE[i][0]) < 0.05) { // Check if aspect ratio of image (H/V) matches an aspect ratio defined in table, within 0.05
V_SW = V_SYNC_TABLE[i][1];
AR_NAME = V_SYNC_TABLE[i][2];
}
}
// Estimate horizontal refresh period (seconds)
var H_EST = ((1/F) - V_SBP_MIN) / (V_LINES + (2 * V_MARGIN) + V_FP + INTERLACE)
// Estimate vertical sync + vertical back porch (lines), subtract V_SW to get V_BP
var V_BP = (Math.floor(V_SBP_MIN / H_EST) + 1) - V_SW;
if (V_BP < V_BP_MIN) { V_BP = V_BP_MIN; } // Enforce minimum value for V_BP
// Total vertical resolution including blanking and margins
V_EFF = V_LINES + (2 * V_MARGIN) + V_FP + V_SW + V_BP + INTERLACE;
// Horizontal blanking is determined by formula from GTF standard
// Calculate Ideal Duty Cycle (%) from GTF formula
var IDC = 30 - (300000 * H_EST);
if (IDC < 20) { IDC = 20; } // Enforce minimum value for IDC
// Calculate horizontal blanking time (to next lowest character cell)
H_BLANK = Math.floor((H_RND + (2 * H_MARGIN)) * IDC / (100 - IDC) / (2 * G)) * (2 * G);
// Total horizontal resolution including blanking and margins
H_EFF = H_RND + (2 * H_MARGIN) + H_BLANK;
// Determing horizontal timing parameters from magic formulas defined by standard
H_BP = H_BLANK / 2;
H_SW = Math.floor((H_SYNC_TARGET_WIDTH * H_EFF) / G) * G;
H_FP = H_BLANK - (H_BP + H_SW);
// Calculate Pixel Clock (Hz)
var CLK = H_EFF / H_EST;
CLK = Math.floor(CLK / 250000) * 250000; // Enforce pixel clock rounding to nearest 0.25 MHz (250,000 Hz)
// Calculate Horizontal Refresh Frequency (Hz)
F_HOR = CLK / H_EFF;
// Calculate Vertical Refresh Frequency (Hz) after adjusting for pixel clock rounding
F_ACTUAL = F_HOR / V_EFF;
return {
'V_FP': V_FP, // For interlaced, these vertical timing are used for the odd fields
'V_BP': V_BP,
'V_SW': V_SW,
'H_FP': H_FP,
'H_BP': H_BP,
'H_SW': H_SW,
'V_FP_INT': V_FP + INTERLACE, // For interlaced, V_FP and V_BP are 0.5 higher for even fields (V_SW is same)
'V_BP_INT': V_BP + INTERLACE,
'V_SW_INT': V_SW,
'V_BL': V_BLANK,
'H_BL': H_BLANK,
'V_EFF': V_EFF,
'H_EFF': H_EFF,
'F_ACTUAL': F_ACTUAL,
'VESA_AR': AR_NAME,
};
}
function CTA() {
return;
DEBUG('Starting CTA');
var H = Global_InputVars['HRES'];
var V = Global_InputVars['VRES'];
var F = Global_InputVars['FREQ'];
var S = Global_InputVars['SCAN'];
// No CTA formats are below these points, no need to search entire list
if (H < 640 || V < 240 || F < 23.9) { DEBUG('Search aborted, one or more inputs is below the minimum value found in CTA.', H, V, F); return false; }
if (S == 1) { S = 'p'; }
else if (S == 2) { S = 'i'; }
DEBUG('Input:', H, V, F, S);
var CTA_H;
var CTA_V;
var CTA_F;
var CTA_S;
for (var i = 0; i < CTA861.length; i++) {
CTA_H = parseFloat(CTA861[i]['H']);
CTA_V = parseFloat(CTA861[i]['V']);
CTA_F = parseFloat(CTA861[i]['V_FREQ']);
CTA_S = CTA861[i]['SCAN'];
DEBUG('Parsing: VIC', CTA861[i]['VIC'], '|', CTA_H, (H == CTA_H), '|', CTA_V, (V == CTA_V), '|' , (CTA_F).toFixed(3), (Math.abs(F - CTA_F) < 0.01), '|', CTA_S, (S == CTA_S));
//DEBUG( (V == CTA_V), (Math.abs(F - CTA_F) < 0.01), (S == CTA_S))
if ((H == CTA_H) && (V == CTA_V) && (Math.abs(F - CTA_F) < 0.01) && (S == CTA_S)) {
DEBUG('Match Found');
// Special modifications to values based on whether interlacing is selected or not
if (S == 'p') { S = 0; }
else if (S == 'i') { S = 0.5; }
return {
'V_FP': parseFloat(CTA861[i]['V_FP']),
'V_BP': parseFloat(CTA861[i]['V_BP']),
'V_SW': parseFloat(CTA861[i]['V_SW']),
'H_FP': parseFloat(CTA861[i]['H_FP']),
'H_BP': parseFloat(CTA861[i]['H_BP']),
'H_SW': parseFloat(CTA861[i]['H_SW']),
'V_FP_INT': parseFloat(CTA861[i]['V_FP']) + S,
'V_BP_INT': parseFloat(CTA861[i]['V_BP']) + S,
'V_SW_INT': parseFloat(CTA861[i]['V_SW']),
'V_BL': parseFloat(CTA861[i]['V_BLANK']) - S,
'H_BL': parseFloat(CTA861[i]['H_BLANK']),
'V_EFF': parseFloat(CTA861[i]['V_EFF']) * (1 - S),
'H_EFF': parseFloat(CTA861[i]['H_EFF']),
'F_ACTUAL': parseFloat(CTA861[i]['V_FREQ']),
'VIC': parseFloat(CTA861[i]['VIC']),
'CTA_REV': CTA861[i]['CTA'],
}
}
}
// Not found in CTA list
return false;
}
function GTF() {
// Input Variables
var V_FREQ_NOM = Global_InputVars['FREQ'];
var H = Global_InputVars['HRES'];
var V = Global_InputVars['VRES'];
var S = Global_InputVars['SCAN'];
var MARGINS = Global_InputVars['MARGINS'];
// Constants
var V_SW = 3; // Vertical sync pulse width (lines)
var V_FP = 1; // Vertical front porch (lines)
var V_MIN = 0.00055; // Min V_Blank period (seconds)
var G = 8; // Cell granularity (pixels)
var H_SYNC_WIDTH_TARGET = 0.08; // Nominal horizontal sync pulse duration (percent of horizontal draw period)
var INTERLACE = (S - 1) / 2; // 0 for progressive, 0.5 for interlaced
// var m = 600 // Gradient (%/kHz)
// var c = 40 // offset (%)
// var k = 128 // blanking time scaling factor
// var j = 20 // scaling factor weighting
var M = 300 // m * (k / 256); // "M prime"
var C = 30 // (((c - j) * k) / 256) + j; // "C prime"
// Result Variables
var V_BP;
var H_FP;
var H_SW;
var H_BP;
var H_EFF
var V_EFF;
var V_BLANK;
var H_BLANK;
// Calculations
var V_LINES = Math.round(V / S);
var V_MARGIN = Math.round((MARGINS / 100) * V_LINES);
var H_EST = ((1 / V_FREQ_NOM) - V_MIN) / (V_LINES + (2 * V_MARGIN) + V_FP + INTERLACE); // Horizontal refresh period estimate (seconds)
V_BP = Math.round(V_MIN / H_EST) - V_SW;
V_BLANK = V_FP + V_SW + V_BP;
V_EFF = V_LINES + V_BLANK + (2 * V_MARGIN) + INTERLACE; // Total lines
//var V_FREQ_EST = 1 / (H_EST * V_EFF); // Hz
//var H_PER = (H_EST * V_FREQ_EST) / V_FREQ_NOM
var H_PER = 1 / (V_EFF * V_FREQ_NOM); // Actual horizontal refresh period (seconds)
//var V_FREQ_ACT = 1 / (H_PER * V_EFF); // Hz
var IDC = C - (M * H_PER * 1000);
DEBUG('IDC:', IDC);
var H_MARGIN = Math.round((H * (MARGINS / 100)) / G) * G;
H_BLANK = Math.round((((H + (2 * H_MARGIN)) * IDC)/(100 - IDC)) / (2 * G)) * (2 * G);
H_EFF = (H + H_BLANK + (2 * H_MARGIN));
H_SW = Math.round((H_EFF * H_SYNC_WIDTH_TARGET) / G) * G;
H_BP = (H_BLANK / 2);
H_FP = H_BP - H_SW;
//var CLK = H_EFF / H_PER;
//var H_FREQ = 1 / H_PER;
return {
'V_FP': V_FP,
'V_BP': V_BP,
'V_SW': V_SW,
'H_FP': H_FP,
'H_BP': H_BP,
'H_SW': H_SW,
'V_FP_INT': V_FP + INTERLACE,
'V_BP_INT': V_BP + INTERLACE,
'V_SW_INT': V_SW,
'H_BLANK': H_BLANK,
'V_BLANK': V_BLANK,
'H_EFF': H_EFF,
'V_EFF': V_EFF,
'F_ACTUAL': V_FREQ_NOM,
};
}
function DMT() {
DEBUG('Starting DMT Search');
var H = Global_InputVars['HRES'];
var V = Global_InputVars['VRES'];
var F = Global_InputVars['FREQ'];
var S = Global_InputVars['SCAN'];
// No DMT formats are below these points, no need to search entire list
if (H < 640 || V < 350 || F < 43) { DEBUG('Search aborted, one or more inputs is below the minimum value found in DMT.', H, V, F); return false; }
if (S == 1) { S = 'p'; }
else if (S == 2) { S = 'i'; }
DEBUG('Input:', H, V, F, S);
var DMT_H;
var DMT_V;
var DMT_F;
var DMT_S;
for (var i = 0; i < DMT_List.length; i++) {
DMT_H = parseFloat(DMT_List[i]['H']);
DMT_V = parseFloat(DMT_List[i]['V']);
DMT_F = parseFloat(DMT_List[i]['NOM_FREQ']);
DMT_F_ACTUAL = parseFloat(DMT_List[i]['V_FREQ'])
DMT_S = DMT_List[i]['SCAN'];
DEBUG('Parsing: DMT ID', DMT_List[i]['ID'], '|', DMT_H, (H == DMT_H), '|', DMT_V, (V == DMT_V), '|' , (DMT_F).toFixed(3), (Math.abs(F - DMT_F) < 0.01), '|', DMT_S, (S == DMT_S));
//DEBUG( (V == DMT_V), (Math.abs(F - DMT_F) < 0.01), (S == DMT_S))
if ((H == DMT_H) && (V == DMT_V) && ((F == DMT_F) || (Math.abs(F - DMT_F_ACTUAL) < 0.01)) && (S == DMT_S)) {
DEBUG('Match Found');
// Special modifications to values based on whether interlacing is selected or not
if (S == 'p') { S = 0; }
else if (S == 'i') { S = 0.5; }
var Timing;
if (DMT_List[i]['STD'] == 'CVT') {
Timing = CVT();
Timing['ID'] = DMT_List[i]['ID'];
}
else if (DMT_List[i]['STD'] == 'CVTRB') {
Timing = CVT_R(1);
Timing['ID'] = DMT_List[i]['ID'];
}
else if (DMT_List[i]['STD'] == 'CVTR2') {
Timing = CVT_R(2);
Timing['ID'] = DMT_List[i]['ID'];
}
else {
Timing = {
'V_FP': parseFloat(DMT_List[i]['V_FP']),
'V_BP': parseFloat(DMT_List[i]['V_BP']),
'V_SW': parseFloat(DMT_List[i]['V_SW']),
'H_FP': parseFloat(DMT_List[i]['H_FP']),
'H_BP': parseFloat(DMT_List[i]['H_BP']),
'H_SW': parseFloat(DMT_List[i]['H_SW']),
'V_FP_INT': parseFloat(DMT_List[i]['V_FP']) + S,
'V_BP_INT': parseFloat(DMT_List[i]['V_BP']) + S,
'V_SW_INT': parseFloat(DMT_List[i]['V_SW']),
'V_BL': parseFloat(DMT_List[i]['V_BLANK']) - S,
'H_BL': parseFloat(DMT_List[i]['H_BLANK']),
'V_EFF': parseFloat(DMT_List[i]['V_EFF']) * (1 - S),
'H_EFF': parseFloat(DMT_List[i]['H_EFF']),
'F_ACTUAL': parseFloat(DMT_List[i]['V_FREQ']),
'ID': parseFloat(DMT_List[i]['ID']),
}
}
return Timing;
}
}
// Not found in DMT list
return false;
}
@ -711,19 +1109,19 @@ function timingUIChange() {
}
value = $('input[name=SCAN_SLCT]:checked').val();
if (value == 'i') {
$('#V_BLANK_ODD_LABEL').css('display', 'table-cell');
$('#V_FP_ODD_CONTAINER').css('display', 'table-cell');
$('#V_BP_ODD_CONTAINER').css('display', 'table-cell');
$('#V_SW_ODD_CONTAINER').css('display', 'table-cell');
$('#V_BLANK_ODD_CONTAINER').css('display', 'table-cell');
$('#V_BLANK_INT_LABEL').css('display', 'table-cell');
$('#V_FP_INT_CONTAINER').css('display', 'table-cell');
$('#V_BP_INT_CONTAINER').css('display', 'table-cell');
$('#V_SW_INT_CONTAINER').css('display', 'table-cell');
$('#V_BLANK_INT_CONTAINER').css('display', 'table-cell');
$('#V_BLANK_EVEN_LABEL').html('(Even)&nbsp;V<sub>blank</sub>');
}
else if (value == 'p') {
$('#V_BLANK_ODD_LABEL').css('display', 'none');
$('#V_FP_ODD_CONTAINER').css('display', 'none');
$('#V_BP_ODD_CONTAINER').css('display', 'none');
$('#V_SW_ODD_CONTAINER').css('display', 'none');
$('#V_BLANK_ODD_CONTAINER').css('display', 'none');
$('#V_BLANK_INT_LABEL').css('display', 'none');
$('#V_FP_INT_CONTAINER').css('display', 'none');
$('#V_BP_INT_CONTAINER').css('display', 'none');
$('#V_SW_INT_CONTAINER').css('display', 'none');
$('#V_BLANK_INT_CONTAINER').css('display', 'none');
$('#V_BLANK_EVEN_LABEL').html('V<sub>blank</sub>');
}
else {
@ -1059,15 +1457,14 @@ function SI_set_precision(SI_options, prefixDef, pre2num) {
function LoadCTA861(){
// read text from URL location
DEBUG('CTA Test 11');
// Loads the timing definitions for the CTA-861 standard from a txt file
//DEBUG('CTA Test 11');
var request = new XMLHttpRequest();
request.open('GET', 'CTA861.txt', true);
request.send(null);
request.onreadystatechange = function () {
DEBUG('request.status:', request.status)
if (request.readyState === 4 && request.status === 200) {
DEBUG(request.responseText);
if (request.readyState === 4 && (request.status === 200 || request.status === 0)) {
CTA861 = $.csv.toObjects(request.responseText);
DEBUG(CTA861);
}
@ -1076,11 +1473,20 @@ function LoadCTA861(){
}
async function LoadCTA861_Async() {
DEBUG('CTA Test 8');
// Loads the timing definitions for the CTA-861 standard from a txt file
response = await fetch('CTA861.txt');
CTA861 = $.csv.toObjects(await response.text());
function LoadDMT(){
// Loads the timing definitions for the DMT standard from a txt file
DEBUG('DMT Test 1');
var request = new XMLHttpRequest();
request.open('GET', 'DMT.txt', true);
request.send(null);
request.onreadystatechange = function () {
DEBUG('request.status:', request.status)
if (request.readyState === 4 && (request.status === 200 || request.status === 0)) {
DMT_List = $.csv.toObjects(request.responseText);
//DEBUG(CTA861);
}
}
DEBUG('Finished');
}
@ -1453,6 +1859,7 @@ function isFloat(num) {
window.onpageshow = function() {
generate_table('Interface Support', -1);
LoadCTA861();
LoadDMT();
$('#INPUT_HRES')[0].onchange();
$('#INPUT_VRES')[0].onchange();
$('#INPUT_F')[0].onchange();

@ -50,11 +50,11 @@
<tr>
<td>
<div align="center">
<input id="INPUT_HRES" class="res_input number" style="text-align:right;" type="text" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange()" onfocus="this.select();" tabindex="2" autofocus />
<input id="INPUT_HRES" class="res_input number" style="text-align:right;" type="text" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange()" onfocus="this.select();" autofocus />
<span class="res_x">&#10005;</span>
<input id="INPUT_VRES" class="res_input number" style="text-align:left;" type="text" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange()" onfocus="this.select();" tabindex="2" />
<input id="INPUT_VRES" class="res_input number" style="text-align:left;" type="text" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange()" onfocus="this.select();" />
<span>@</span>
<input id="INPUT_F" class="freq_input number" type="text" onchange="submitVar(this.id, this.value), calcMain();" oninput="this.onchange()" onfocus="this.select();" tabindex="3" />
<input id="INPUT_F" class="freq_input number" type="text" onchange="submitVar(this.id, this.value), calcMain();" oninput="this.onchange()" onfocus="this.select();" />
<span>Hz</span>
</div>
<div id="warning_box" style="text-align:left; width:400px; margin-top:32px; border:1px solid black; padding:16px;">
@ -165,7 +165,7 @@
<option value="Custom">Custom</option>
</select><br />
<div style="padding:4px;">
<b>VIC: </b><span id="TIMING_VIC">218</span>
<span id="TIMING_FORMAT_NAME"></span>
</div>
</td>
@ -210,20 +210,20 @@
</td>
</tr>
<tr id="Interlaced_Timing_Row" style="height:30px;">
<td id="V_BLANK_ODD_LABEL" style="text-align:right; width:100px; padding-right:8px;">
<td id="V_BLANK_INT_LABEL" style="text-align:right; width:100px; padding-right:8px;">
(Odd)&nbsp;V<sub>blank</sub>
</td>
<td id="V_FP_ODD_CONTAINER">
<input id="V_FP_ODD" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
<td id="V_FP_INT_CONTAINER">
<input id="V_FP_INT" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
</td>
<td id="V_SW_ODD_CONTAINER">
<input id="V_SW_ODD" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
<td id="V_SW_INT_CONTAINER">
<input id="V_SW_INT" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
</td>
<td id="V_BP_ODD_CONTAINER">
<input id="V_BP_ODD" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
<td id="V_BP_INT_CONTAINER">
<input id="V_BP_INT" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
</td>
<td id="V_BLANK_ODD_CONTAINER" style="text-align:right; width:100px;">
<span id="V_BLANK_ODD">0</span>&nbsp;px
<td id="V_BLANK_INT_CONTAINER" style="text-align:right; width:100px;">
<span id="V_BLANK_INT">0</span>&nbsp;px
</td>
</tr>
</table>

@ -106,7 +106,7 @@ input.res_input {
width: 48px;
}
input.freq_input {
width: 28px;
width: 40px;
}
input.color_depth_input {
width: 25px;

Loading…
Cancel
Save