aboutsummaryrefslogtreecommitdiffstats
path: root/parse-base-block.cpp
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil-cisco@xs4all.nl>2020-02-12 13:45:43 +0100
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2020-02-12 13:45:43 +0100
commit423cfc63206e20ca45c8cf4e968700688363a811 (patch)
tree895308c7110f7151a5f448a759c40ccc20094fcb /parse-base-block.cpp
parent8f46a81ba8c7fb8d62e8f2b46735a956b0df8974 (diff)
edid-decode: major cleanup
This makes the layout of the parsed EDID data consistent. New sections start with 'Section Name:' and the following lines are one more indent to the right. Flags are shown as simple strings (no ':'). Values are shown as 'Value: 1234'. Also DMTs now show the DMT ID instead of just 'DMT'. Various new tests were also added. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Diffstat (limited to 'parse-base-block.cpp')
-rw-r--r--parse-base-block.cpp287
1 files changed, 157 insertions, 130 deletions
diff --git a/parse-base-block.cpp b/parse-base-block.cpp
index c512385..414af3e 100644
--- a/parse-base-block.cpp
+++ b/parse-base-block.cpp
@@ -257,7 +257,7 @@ static const struct {
18, 108, 54, false, 12, 2, 35, true }, "IBM" },
{ 0x04 },
{ 0x00, { 640, 480, 4, 3, 30240, 0, false,
- 64, 64, 96, false, 3, 3, 39, false }, "Mac" },
+ 64, 64, 96, false, 3, 3, 39, false }, "Apple" },
{ 0x05 },
{ 0x06 },
{ 0x08 },
@@ -266,7 +266,7 @@ static const struct {
{ 0x0a },
{ 0x0b },
{ 0x00, { 832, 624, 4, 3, 57284, 0, false,
- 32, 64, 224, false, 1, 3, 39, false }, "Mac" },
+ 32, 64, 224, false, 1, 3, 39, false }, "Apple" },
{ 0x0f },
{ 0x10 },
{ 0x11 },
@@ -274,7 +274,7 @@ static const struct {
{ 0x24 },
/* 0x25 bit 7 */
{ 0x00, { 1152, 870, 192, 145, 100000, 0, false,
- 48, 128, 128, true, 3, 3, 39, true }, "Mac" },
+ 48, 128, 128, true, 3, 3, 39, true }, "Apple" },
};
// The bits in the Established Timings III map to DMT timings,
@@ -342,13 +342,15 @@ const struct timings *find_dmt_id(unsigned char dmt_id)
return NULL;
}
-static const struct timings *find_std_id(unsigned short std_id)
+static const struct timings *find_std_id(unsigned short std_id, unsigned char &dmt_id)
{
unsigned i;
for (i = 0; i < ARRAY_SIZE(dmt_timings); i++)
- if (dmt_timings[i].std_id == std_id)
+ if (dmt_timings[i].std_id == std_id) {
+ dmt_id = dmt_timings[i].dmt_id;
return &dmt_timings[i].t;
+ }
return NULL;
}
@@ -821,6 +823,7 @@ void edid_state::print_standard_timing(const char *prefix, unsigned char b1, uns
struct timings formula = {};
unsigned hratio, vratio;
unsigned hact, vact, refresh;
+ unsigned char dmt_id = 0;
if (b1 <= 0x01) {
if (b1 != 0x01 || b2 != 0x01)
@@ -833,9 +836,11 @@ void edid_state::print_standard_timing(const char *prefix, unsigned char b1, uns
return;
}
- t = find_std_id((b1 << 8) | b2);
+ t = find_std_id((b1 << 8) | b2, dmt_id);
if (t) {
- print_timings(prefix, t, "DMT");
+ char type[16];
+ sprintf(type, "DMT 0x%02x", dmt_id);
+ print_timings(prefix, t, type);
return;
}
hact = (b1 + 31) * 8;
@@ -874,14 +879,14 @@ void edid_state::print_standard_timing(const char *prefix, unsigned char b1, uns
if (!gtf_only && edid_minor >= 4) {
uses_cvt = true;
edid_cvt_mode(refresh, formula);
- print_timings(prefix, &formula, "CVT", "EDID 1.4 source");
+ print_timings(prefix, &formula, "CVT ", "EDID 1.4 source");
/*
* A EDID 1.3 source will assume GTF, so both GTF and CVT
* have to be supported.
*/
uses_gtf = true;
edid_gtf_mode(refresh, formula);
- print_timings(prefix, &formula, "GTF", "EDID 1.3 source");
+ print_timings(prefix, &formula, "GTF ", "EDID 1.3 source");
} else if (gtf_only || edid_minor >= 2) {
uses_gtf = true;
edid_gtf_mode(refresh, formula);
@@ -903,7 +908,7 @@ void edid_state::detailed_display_range_limits(const unsigned char *x)
std::string range_class;
data_block = "Display Range Limits";
- printf("%s\n", data_block.c_str());
+ printf(" %s:\n", data_block.c_str());
has_display_range_descriptor = 1;
/*
* XXX todo: implement feature flags, vtd blocks
@@ -973,7 +978,7 @@ void edid_state::detailed_display_range_limits(const unsigned char *x)
fail("Min horizontal freq > max horizontal freq.\n");
min_display_hor_freq_hz = (x[7] + h_min_offset) * 1000;
max_display_hor_freq_hz = (x[8] + h_max_offset) * 1000;
- printf(" Monitor ranges (%s): %d-%d Hz V, %d-%d kHz H",
+ printf(" Monitor ranges (%s): %d-%d Hz V, %d-%d kHz H",
range_class.c_str(),
x[5] + v_min_offset, x[6] + v_max_offset,
x[7] + h_min_offset, x[8] + h_max_offset);
@@ -989,25 +994,25 @@ void edid_state::detailed_display_range_limits(const unsigned char *x)
if (has_sec_gtf) {
if (x[11])
fail("Byte 11 is 0x%02x instead of 0x00.\n", x[11]);
- printf(" GTF Secondary Curve Block\n");
- printf(" Start frequency: %u kHz\n", x[12] * 2);
- printf(" C: %f\n", x[13] / 2.0);
+ printf(" GTF Secondary Curve Block:\n");
+ printf(" Start frequency: %u kHz\n", x[12] * 2);
+ printf(" C: %f\n", x[13] / 2.0);
if (x[13] > 127)
fail("Byte 13 is > 127.\n");
- printf(" M: %u\n", (x[15] << 8) | x[14]);
- printf(" K: %u\n", x[16]);
- printf(" J: %f\n", x[17] / 2.0);
+ printf(" M: %u\n", (x[15] << 8) | x[14]);
+ printf(" K: %u\n", x[16]);
+ printf(" J: %f\n", x[17] / 2.0);
if (x[17] > 127)
fail("Byte 17 is > 127.\n");
} else if (is_cvt) {
int max_h_pixels = 0;
- printf(" CVT version %d.%d\n", (x[11] & 0xf0) >> 4, x[11] & 0x0f);
+ printf(" CVT version %d.%d\n", (x[11] & 0xf0) >> 4, x[11] & 0x0f);
if (x[12] & 0xfc) {
unsigned raw_offset = (x[12] & 0xfc) >> 2;
- printf(" Real max dotclock: %.2f MHz\n",
+ printf(" Real max dotclock: %.2f MHz\n",
(x[9] * 10) - (raw_offset * 0.25));
if (raw_offset >= 40)
warn("CVT block corrects dotclock by more than 9.75 MHz.\n");
@@ -1018,9 +1023,9 @@ void edid_state::detailed_display_range_limits(const unsigned char *x)
max_h_pixels |= x[13];
max_h_pixels *= 8;
if (max_h_pixels)
- printf(" Max active pixels per line: %d\n", max_h_pixels);
+ printf(" Max active pixels per line: %d\n", max_h_pixels);
- printf(" Supported aspect ratios:%s%s%s%s%s\n",
+ printf(" Supported aspect ratios:%s%s%s%s%s\n",
x[14] & 0x80 ? " 4:3" : "",
x[14] & 0x40 ? " 16:9" : "",
x[14] & 0x20 ? " 16:10" : "",
@@ -1029,7 +1034,7 @@ void edid_state::detailed_display_range_limits(const unsigned char *x)
if (x[14] & 0x07)
fail("Reserved bits of byte 14 are non-zero.\n");
- printf(" Preferred aspect ratio: ");
+ printf(" Preferred aspect ratio: ");
switch ((x[15] & 0xe0) >> 5) {
case 0x00:
printf("4:3");
@@ -1055,30 +1060,30 @@ void edid_state::detailed_display_range_limits(const unsigned char *x)
printf("\n");
if (x[15] & 0x08)
- printf(" Supports CVT standard blanking\n");
+ printf(" Supports CVT standard blanking\n");
if (x[15] & 0x10)
- printf(" Supports CVT reduced blanking\n");
+ printf(" Supports CVT reduced blanking\n");
if (x[15] & 0x07)
fail("Reserved bits of byte 15 are non-zero.\n");
if (x[16] & 0xf0) {
- printf(" Supported display scaling:\n");
+ printf(" Supported display scaling:\n");
if (x[16] & 0x80)
- printf(" Horizontal shrink\n");
+ printf(" Horizontal shrink\n");
if (x[16] & 0x40)
- printf(" Horizontal stretch\n");
+ printf(" Horizontal stretch\n");
if (x[16] & 0x20)
- printf(" Vertical shrink\n");
+ printf(" Vertical shrink\n");
if (x[16] & 0x10)
- printf(" Vertical stretch\n");
+ printf(" Vertical stretch\n");
}
if (x[16] & 0x0f)
fail("Reserved bits of byte 16 are non-zero.\n");
if (x[17])
- printf(" Preferred vertical refresh: %d Hz\n", x[17]);
+ printf(" Preferred vertical refresh: %d Hz\n", x[17]);
else
warn("CVT block does not set preferred refresh rate.\n");
} else {
@@ -1096,26 +1101,26 @@ void edid_state::detailed_display_range_limits(const unsigned char *x)
void edid_state::detailed_epi(const unsigned char *x)
{
data_block = "EPI Descriptor";
- printf("%s\n", data_block.c_str());
+ printf(" %s:\n", data_block.c_str());
unsigned v = x[5] & 0x07;
- printf(" Bits per pixel: %u\n", 18 + v * 6);
+ printf(" Bits per pixel: %u\n", 18 + v * 6);
if (v > 2)
fail("Invalid bits per pixel.\n");
v = (x[5] & 0x18) >> 3;
- printf(" Pixels per clock: %u\n", 1 << v);
+ printf(" Pixels per clock: %u\n", 1 << v);
if (v > 2)
fail("Invalid pixels per clock.\n");
v = (x[5] & 0x60) >> 5;
- printf(" Data color mapping: %sconventional\n", v ? "non-" : "");
+ printf(" Data color mapping: %sconventional\n", v ? "non-" : "");
if (v > 1)
fail("Unknown data color mapping (0x%02x).\n", v);
if (x[5] & 0x80)
fail("Non-zero reserved field in byte 5.\n");
v = x[6] & 0x0f;
- printf(" Interface type: ");
+ printf(" Interface type: ");
switch (v) {
case 0x00: printf("LVDS TFT\n"); break;
case 0x01: printf("monoSTN 4/8 Bit\n"); break;
@@ -1128,41 +1133,41 @@ void edid_state::detailed_epi(const unsigned char *x)
fail("Invalid interface type 0x%02x.\n", v);
break;
}
- printf(" DE polarity: DE %s active\n",
+ printf(" DE polarity: DE %s active\n",
(x[6] & 0x10) ? "low" : "high");
- printf(" FPSCLK polarity: FPSCLK %sinverted\n",
+ printf(" FPSCLK polarity: FPSCLK %sinverted\n",
(x[6] & 0x20) ? "" : "not ");
if (x[6] & 0xc0)
fail("Non-zero reserved field in byte 6.\n");
- printf(" Vertical display mode: %s\n",
+ printf(" Vertical display mode: %s\n",
(x[7] & 0x01) ? "Up/Down reverse mode" : "normal");
- printf(" Horizontal display mode: %s\n",
+ printf(" Horizontal display mode: %s\n",
(x[7] & 0x02) ? "Left/Right reverse mode" : "normal");
if (x[7] & 0xfc)
fail("Non-zero reserved field in byte 7.\n");
v = x[8] & 0x0f;
- printf(" Total power on sequencing delay: ");
+ printf(" Total power on sequencing delay: ");
if (v)
printf("%u ms\n", v * 10);
else
printf("VGA controller default\n");
v = (x[8] & 0xf0) >> 4;
- printf(" Total power off sequencing delay: ");
+ printf(" Total power off sequencing delay: ");
if (v)
printf("%u ms\n", v * 10);
else
printf("VGA controller default\n");
v = x[9] & 0x0f;
- printf(" Contrast power on sequencing delay: ");
+ printf(" Contrast power on sequencing delay: ");
if (v)
printf("%u ms\n", v * 10);
else
printf("VGA controller default\n");
v = (x[9] & 0xf0) >> 4;
- printf(" Contrast power off sequencing delay: ");
+ printf(" Contrast power off sequencing delay: ");
if (v)
printf("%u ms\n", v * 10);
else
@@ -1171,25 +1176,25 @@ void edid_state::detailed_epi(const unsigned char *x)
v = x[10] & 0x2f;
const char *s = (x[10] & 0x80) ? "" : " (ignored)";
- printf(" Backlight brightness control: %u steps%s\n", v, s);
- printf(" Backlight enable at boot: %s%s\n",
+ printf(" Backlight brightness control: %u steps%s\n", v, s);
+ printf(" Backlight enable at boot: %s%s\n",
(x[10] & 0x40) ? "off" : "on", s);
- printf(" Backlight control enable: %s\n",
+ printf(" Backlight control enable: %s\n",
(x[10] & 0x80) ? "enabled" : "disabled");
v = x[11] & 0x2f;
s = (x[11] & 0x80) ? "" : " (ignored)";
- printf(" Contrast voltable control: %u steps%s\n", v, s);
+ printf(" Contrast voltable control: %u steps%s\n", v, s);
if (x[11] & 0x40)
fail("Non-zero reserved field in byte 11.\n");
- printf(" Contrast control enable: %s\n",
+ printf(" Contrast control enable: %s\n",
(x[11] & 0x80) ? "enabled" : "disabled");
if (x[12] || x[13] || x[14] || x[15] || x[16])
fail("Non-zero values in reserved bytes 12-16.\n");
- printf(" EPI Version: %u.%u\n", (x[17] & 0xf0) >> 4, x[17] & 0x0f);
+ printf(" EPI Version: %u.%u\n", (x[17] & 0xf0) >> 4, x[17] & 0x0f);
}
void edid_state::detailed_timings(const char *prefix, const unsigned char *x)
@@ -1324,7 +1329,7 @@ void edid_state::detailed_timings(const char *prefix, const unsigned char *x)
fail("Mismatch of image size vs display size: image size is not set, but display size is.\n");
}
if (has_spwg && detailed_block_cnt == 2)
- printf("SPWG Module Revision: %hhu\n", x[17]);
+ printf("%sSPWG Module Revision: %hhu\n", prefix, x[17]);
if (!ok) {
std::string s = prefix;
@@ -1341,7 +1346,7 @@ void edid_state::detailed_block(const unsigned char *x)
detailed_block_cnt++;
if (x[0] || x[1]) {
- detailed_timings("", x);
+ detailed_timings(" ", x);
if (seen_non_detailed_descriptor)
fail("Invalid detailed timing descriptor ordering.\n");
return;
@@ -1364,7 +1369,7 @@ void edid_state::detailed_block(const unsigned char *x)
if (!memcmp(x, zero_descr, sizeof(zero_descr))) {
data_block = "Empty Descriptor";
- printf("%s\n", data_block.c_str());
+ printf(" %s\n", data_block.c_str());
fail("Use Dummy Descriptor instead of all zeroes.\n");
return;
}
@@ -1375,7 +1380,7 @@ void edid_state::detailed_block(const unsigned char *x)
return;
case 0x10:
data_block = "Dummy Descriptor";
- printf("%s\n", data_block.c_str());
+ printf(" %s:\n", data_block.c_str());
for (i = 5; i < 18; i++) {
if (x[i]) {
fail("Dummy block filled with garbage.\n");
@@ -1385,39 +1390,44 @@ void edid_state::detailed_block(const unsigned char *x)
return;
case 0xf7:
data_block = "Established timings III";
- printf("%s\n", data_block.c_str());
+ printf(" %s:\n", data_block.c_str());
for (i = 0; i < 44; i++)
- if (x[6 + i / 8] & (1 << (7 - i % 8)))
- print_timings(" ", find_dmt_id(established_timings3_dmt_ids[i]), "DMT");
+ if (x[6 + i / 8] & (1 << (7 - i % 8))) {
+ unsigned char dmt_id = established_timings3_dmt_ids[i];
+ char type[16];
+
+ sprintf(type, "DMT 0x%02x", dmt_id);
+ print_timings(" ", find_dmt_id(dmt_id), type);
+ }
return;
case 0xf8:
data_block = "CVT 3 Byte Timing Codes";
- printf("%s\n", data_block.c_str());
+ printf(" %s:\n", data_block.c_str());
if (x[5] != 0x01) {
fail("Invalid version number %u.\n", x[5]);
return;
}
for (i = 0; i < 4; i++)
- detailed_cvt_descriptor(" ", x + 6 + (i * 3), !i);
+ detailed_cvt_descriptor(" ", x + 6 + (i * 3), !i);
return;
case 0xf9:
data_block = "Display Color Management Data";
- printf("%s\n", data_block.c_str());
- printf(" Version: %d\n", x[5]);
- printf(" Red a3: %.2f\n", (short)(x[6] | (x[7] << 8)) / 100.0);
- printf(" Red a2: %.2f\n", (short)(x[8] | (x[9] << 8)) / 100.0);
- printf(" Green a3: %.2f\n", (short)(x[10] | (x[11] << 8)) / 100.0);
- printf(" Green a2: %.2f\n", (short)(x[12] | (x[13] << 8)) / 100.0);
- printf(" Blue a3: %.2f\n", (short)(x[14] | (x[15] << 8)) / 100.0);
- printf(" Blue a2: %.2f\n", (short)(x[16] | (x[17] << 8)) / 100.0);
+ printf(" %s:\n", data_block.c_str());
+ printf(" Version : %d\n", x[5]);
+ printf(" Red a3 : %.2f\n", (short)(x[6] | (x[7] << 8)) / 100.0);
+ printf(" Red a2 : %.2f\n", (short)(x[8] | (x[9] << 8)) / 100.0);
+ printf(" Green a3: %.2f\n", (short)(x[10] | (x[11] << 8)) / 100.0);
+ printf(" Green a2: %.2f\n", (short)(x[12] | (x[13] << 8)) / 100.0);
+ printf(" Blue a3 : %.2f\n", (short)(x[14] | (x[15] << 8)) / 100.0);
+ printf(" Blue a2 : %.2f\n", (short)(x[16] | (x[17] << 8)) / 100.0);
return;
case 0xfa:
data_block = "Standard Timing Identifications";
- printf("%s\n", data_block.c_str());
+ printf(" %s:\n", data_block.c_str());
for (cnt = i = 0; i < 6; i++) {
if (x[5 + i * 2] != 0x01 || x[5 + i * 2 + 1] != 0x01)
cnt++;
- print_standard_timing(" ", x[5 + i * 2], x[5 + i * 2 + 1]);
+ print_standard_timing(" ", x[5 + i * 2], x[5 + i * 2 + 1]);
}
if (!cnt)
warn("%s block without any timings.\n", data_block.c_str());
@@ -1427,11 +1437,11 @@ void edid_state::detailed_block(const unsigned char *x)
unsigned gamma;
data_block = "Color Point Data";
- printf("%s\n", data_block.c_str());
+ printf(" %s:\n", data_block.c_str());
w_x = (x[7] << 2) | ((x[6] >> 2) & 3);
w_y = (x[8] << 2) | (x[6] & 3);
gamma = x[9];
- printf(" Index: %u White: 0.%04u, 0.%04u", x[5],
+ printf(" Index: %u White: 0.%04u, 0.%04u", x[5],
(w_x * 10000) / 1024, (w_y * 10000) / 1024);
if (gamma == 0xff)
printf(" Gamma: is defined in an extension block");
@@ -1443,7 +1453,7 @@ void edid_state::detailed_block(const unsigned char *x)
w_x = (x[12] << 2) | ((x[11] >> 2) & 3);
w_y = (x[13] << 2) | (x[11] & 3);
gamma = x[14];
- printf(" Index: %u White: 0.%04u, 0.%04u", x[10],
+ printf(" Index: %u White: 0.%04u, 0.%04u", x[10],
(w_x * 10000) / 1024, (w_y * 10000) / 1024);
if (gamma == 0xff)
printf(" Gamma: is defined in an extension block");
@@ -1455,7 +1465,7 @@ void edid_state::detailed_block(const unsigned char *x)
case 0xfc:
data_block = "Display Product Name";
has_name_descriptor = 1;
- printf("%s: '%s'\n", data_block.c_str(), extract_string(x + 5, 13));
+ printf(" %s: '%s'\n", data_block.c_str(), extract_string(x + 5, 13));
return;
case 0xfd:
detailed_display_range_limits(x);
@@ -1463,7 +1473,7 @@ void edid_state::detailed_block(const unsigned char *x)
case 0xfe:
if (!has_spwg || detailed_block_cnt < 3) {
data_block = "Alphanumeric Data String";
- printf("%s: '%s'\n", data_block.c_str(),
+ printf(" %s: '%s'\n", data_block.c_str(),
extract_string(x + 5, 13));
return;
}
@@ -1471,31 +1481,33 @@ void edid_state::detailed_block(const unsigned char *x)
char buf[6] = { 0 };
data_block = "SPWG Descriptor #3";
+ printf(" %s:\n", data_block.c_str());
memcpy(buf, x + 5, 5);
if (strlen(buf) != 5)
fail("Invalid PC Maker P/N length.\n");
- printf("SPWG PC Maker P/N: '%s'\n", buf);
- printf("SPWG LCD Supplier EEDID Revision: %hhu\n", x[10]);
- printf("SPWG Manufacturer P/N: '%s'\n", extract_string(x + 11, 7));
+ printf(" SPWG PC Maker P/N: '%s'\n", buf);
+ printf(" SPWG LCD Supplier EEDID Revision: %hhu\n", x[10]);
+ printf(" SPWG Manufacturer P/N: '%s'\n", extract_string(x + 11, 7));
} else {
data_block = "SPWG Descriptor #4";
- printf("SMBUS Values: 0x%02hhx 0x%02hhx 0x%02hhx 0x%02hhx"
+ printf(" %s:\n", data_block.c_str());
+ printf(" SMBUS Values: 0x%02hhx 0x%02hhx 0x%02hhx 0x%02hhx"
" 0x%02hhx 0x%02hhx 0x%02hhx 0x%02hhx\n",
x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12]);
- printf("LVDS Channels: %hhu\n", x[13]);
- printf("Panel Self Test %sPresent\n", x[14] ? "" : "Not ");
+ printf(" LVDS Channels: %hhu\n", x[13]);
+ printf(" Panel Self Test %sPresent\n", x[14] ? "" : "Not ");
if (x[15] != 0x0a || x[16] != 0x20 || x[17] != 0x20)
fail("Invalid trailing data.\n");
}
return;
case 0xff:
data_block = "Display Product Serial Number";
- printf("%s: '%s'\n", data_block.c_str(),
+ printf(" %s: '%s'\n", data_block.c_str(),
extract_string(x + 5, 13));
has_serial_string = 1;
return;
default:
- printf("%s Display Descriptor (0x%02hhx):",
+ printf(" %s Display Descriptor (0x%02hhx):",
x[3] <= 0x0f ? "Manufacturer-Specified" : "Unknown", x[3]);
hex_block(" ", x + 2, 16);
if (x[3] > 0x0f)
@@ -1513,7 +1525,7 @@ void edid_state::parse_base_block(const unsigned char *x)
int has_preferred_timing = 0;
data_block = "EDID Structure Version & Revision";
- printf("EDID version: %hhu.%hhu\n", x[0x12], x[0x13]);
+ printf(" %s: %hhu.%hhu\n", data_block.c_str(), x[0x12], x[0x13]);
if (x[0x12] == 1) {
edid_minor = x[0x13];
if (edid_minor > 4)
@@ -1525,7 +1537,8 @@ void edid_state::parse_base_block(const unsigned char *x)
}
data_block = "Vendor & Product Identification";
- printf("Manufacturer: %s Model %u Serial Number %u\n",
+ printf(" %s:\n", data_block.c_str());
+ printf(" Manufacturer: %s\n Model: %u\n Serial Number: %u\n",
manufacturer_name(x + 0x08),
(unsigned short)(x[0x0a] + (x[0x0b] << 8)),
(unsigned)(x[0x0c] + (x[0x0d] << 8) +
@@ -1549,30 +1562,32 @@ void edid_state::parse_base_block(const unsigned char *x)
if (week != 0xff && week > 54)
fail("Invalid week %u of manufacture.\n", week);
if (week != 0xff)
- printf("Made in week %hhu of %d\n", week, year);
+ printf(" Made in: week %hhu of %d\n", week, year);
}
if (week == 0xff)
- printf("Model year %d\n", year);
+ printf(" Model year: %d\n", year);
else if (!week)
- printf("Made in year %d\n", year);
+ printf(" Made in: %d\n", year);
if (year - 1 > ptm->tm_year + 1900)
fail("The year %d is more than one year in the future.\n", year);
/* display section */
data_block = "Basic Display Parameters & Features";
+ printf(" %s:\n", data_block.c_str());
if (x[0x14] & 0x80) {
analog = 0;
- printf("Digital display\n");
+ printf(" Digital display\n");
if (edid_minor >= 4) {
if ((x[0x14] & 0x70) == 0x00)
- printf("Color depth is undefined\n");
+ printf(" Color depth is undefined\n");
else if ((x[0x14] & 0x70) == 0x70)
fail("Color Bit Depth set to reserved value.\n");
else
- printf("%u bits per primary color channel\n",
+ printf(" Bits per primary color channel: %u\n",
((x[0x14] & 0x70) >> 3) + 4);
+ printf(" ");
switch (x[0x14] & 0x0f) {
case 0x00: printf("Digital interface is not defined\n"); break;
case 0x01: printf("DVI interface\n"); break;
@@ -1581,13 +1596,13 @@ void edid_state::parse_base_block(const unsigned char *x)
case 0x04: printf("MDDI interface\n"); break;
case 0x05: printf("DisplayPort interface\n"); break;
default:
- printf("Unknown (0x%02x) interface\n", x[0x14] & 0x0f);
+ printf("Unknown interface: 0x%02x\n", x[0x14] & 0x0f);
fail("Digital Video Interface Standard set to reserved value 0x%02x.\n", x[0x14] & 0x0f);
break;
}
} else if (edid_minor >= 2) {
if (x[0x14] & 0x01) {
- printf("DFP 1.x compatible TMDS\n");
+ printf(" DFP 1.x compatible TMDS\n");
}
if (x[0x14] & 0x7e)
fail("Digital Video Interface Standard set to reserved value 0x%02x.\n", x[0x14] & 0x7e);
@@ -1599,7 +1614,8 @@ void edid_state::parse_base_block(const unsigned char *x)
unsigned sync = (x[0x14] & 0x0f);
analog = 1;
- printf("Analog display, Input voltage level: %s V\n",
+ printf(" Analog display\n");
+ printf(" Input voltage level: %s V\n",
voltage == 3 ? "0.7/0.7" :
voltage == 2 ? "1.0/0.4" :
voltage == 1 ? "0.714/0.286" :
@@ -1607,27 +1623,28 @@ void edid_state::parse_base_block(const unsigned char *x)
if (edid_minor >= 4) {
if (x[0x14] & 0x10)
- printf("Blank-to-black setup/pedestal\n");
+ printf(" Blank-to-black setup/pedestal\n");
else
- printf("Blank level equals black level\n");
+ printf(" Blank level equals black level\n");
} else if (x[0x14] & 0x10) {
/*
* XXX this is just the X text. 1.3 says "if set, display expects
* a blank-to-black setup or pedestal per appropriate Signal
* Level Standard". Whatever _that_ means.
*/
- printf("Configurable signal levels\n");
+ printf(" Configurable signal levels\n");
}
- printf("Sync:%s%s%s%s\n",
- sync & 0x08 ? " Separate" : "",
- sync & 0x04 ? " Composite" : "",
- sync & 0x02 ? " SyncOnGreen" : "",
- sync & 0x01 ? " Serration" : "");
+ if (sync)
+ printf(" Sync:%s%s%s%s\n",
+ sync & 0x08 ? " Separate" : "",
+ sync & 0x04 ? " Composite" : "",
+ sync & 0x02 ? " SyncOnGreen" : "",
+ sync & 0x01 ? " Serration" : "");
}
if (x[0x15] && x[0x16]) {
- printf("Maximum image size: %u cm x %u cm\n", x[0x15], x[0x16]);
+ printf(" Maximum image size: %u cm x %u cm\n", x[0x15], x[0x16]);
max_display_width_mm = x[0x15] * 10;
max_display_height_mm = x[0x16] * 10;
if ((max_display_height_mm && !max_display_width_mm) ||
@@ -1640,24 +1657,24 @@ void edid_state::parse_base_block(const unsigned char *x)
}
else if (edid_minor >= 4 && (x[0x15] || x[0x16])) {
if (x[0x15])
- printf("Aspect ratio is %f (landscape)\n", 100.0/(x[0x16] + 99));
+ printf(" Aspect ratio: %f (landscape)\n", 100.0 / (x[0x16] + 99));
else
- printf("Aspect ratio is %f (portrait)\n", 100.0/(x[0x15] + 99));
+ printf(" Aspect ratio: %f (portrait)\n", 100.0 / (x[0x15] + 99));
} else {
/* Either or both can be zero for 1.3 and before */
- printf("Image size is variable\n");
+ printf(" Image size is variable\n");
}
if (x[0x17] == 0xff) {
if (edid_minor >= 4)
- printf("Gamma is defined in an extension block\n");
+ printf(" Gamma is defined in an extension block\n");
else
/* XXX Technically 1.3 doesn't say this... */
- printf("Gamma: 1.0\n");
- } else printf("Gamma: %.2f\n", ((x[0x17] + 100.0) / 100.0));
+ printf(" Gamma: 1.0\n");
+ } else printf(" Gamma: %.2f\n", ((x[0x17] + 100.0) / 100.0));
if (x[0x18] & 0xe0) {
- printf("DPMS levels:");
+ printf(" DPMS levels:");
if (x[0x18] & 0x80) printf(" Standby");
if (x[0x18] & 0x40) printf(" Suspend");
if (x[0x18] & 0x20) printf(" Off");
@@ -1665,6 +1682,7 @@ void edid_state::parse_base_block(const unsigned char *x)
}
if (analog || edid_minor < 4) {
+ printf(" ");
switch (x[0x18] & 0x18) {
case 0x00: printf("Monochrome or grayscale display\n"); break;
case 0x08: printf("RGB color display\n"); break;
@@ -1672,7 +1690,7 @@ void edid_state::parse_base_block(const unsigned char *x)
case 0x18: printf("Undefined display color type\n");
}
} else {
- printf("Supported color formats: RGB 4:4:4");
+ printf(" Supported color formats: RGB 4:4:4");
if (x[0x18] & 0x08)
printf(", YCrCb 4:4:4");
if (x[0x18] & 0x10)
@@ -1691,15 +1709,15 @@ void edid_state::parse_base_block(const unsigned char *x)
static const unsigned char srgb_chromaticity[10] = {
0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, 0x0f, 0x50, 0x54
};
- printf("Default (sRGB) color space is primary color space\n");
+ printf(" Default (sRGB) color space is primary color space\n");
if (memcmp(x + 0x19, srgb_chromaticity, sizeof(srgb_chromaticity)))
fail("sRGB is signaled, but the chromaticities do not match.\n");
}
if (x[0x18] & 0x02) {
if (edid_minor >= 4)
- printf("First detailed timing includes the native pixel format and preferred refresh rate\n");
+ printf(" First detailed timing includes the native pixel format and preferred refresh rate\n");
else
- printf("First detailed timing is preferred timing\n");
+ printf(" First detailed timing is preferred timing\n");
has_preferred_timing = 1;
} else if (edid_minor >= 4) {
/* 1.4 always has a preferred timing and this bit means something else. */
@@ -1709,51 +1727,53 @@ void edid_state::parse_base_block(const unsigned char *x)
if (x[0x18] & 0x01) {
if (edid_minor >= 4) {
supports_continuous_freq = true;
- printf("Display is continuous frequency\n");
+ printf(" Display is continuous frequency\n");
} else {
- printf("Supports GTF timings within operating range\n");
+ printf(" Supports GTF timings within operating range\n");
supports_gtf = true;
}
}
data_block = "Color Characteristics";
- printf("%s\n", data_block.c_str());
+ printf(" %s:\n", data_block.c_str());
col_x = (x[0x1b] << 2) | (x[0x19] >> 6);
col_y = (x[0x1c] << 2) | ((x[0x19] >> 4) & 3);
- printf(" Red: 0.%04u, 0.%04u\n",
+ printf(" Red : 0.%04u, 0.%04u\n",
(col_x * 10000) / 1024, (col_y * 10000) / 1024);
col_x = (x[0x1d] << 2) | ((x[0x19] >> 2) & 3);
col_y = (x[0x1e] << 2) | (x[0x19] & 3);
- printf(" Green: 0.%04u, 0.%04u\n",
+ printf(" Green: 0.%04u, 0.%04u\n",
(col_x * 10000) / 1024, (col_y * 10000) / 1024);
col_x = (x[0x1f] << 2) | (x[0x1a] >> 6);
col_y = (x[0x20] << 2) | ((x[0x1a] >> 4) & 3);
- printf(" Blue: 0.%04u, 0.%04u\n",
+ printf(" Blue : 0.%04u, 0.%04u\n",
(col_x * 10000) / 1024, (col_y * 10000) / 1024);
col_x = (x[0x21] << 2) | ((x[0x1a] >> 2) & 3);
col_y = (x[0x22] << 2) | (x[0x1a] & 3);
- printf(" White: 0.%04u, 0.%04u\n",
+ printf(" White: 0.%04u, 0.%04u\n",
(col_x * 10000) / 1024, (col_y * 10000) / 1024);
data_block = "Established Timings I & II";
if (x[0x23] || x[0x24] || x[0x25]) {
- printf("%s\n", data_block.c_str());
+ printf(" %s:\n", data_block.c_str());
for (i = 0; i < 17; i++) {
if (x[0x23 + i / 8] & (1 << (7 - i % 8))) {
+ unsigned char dmt_id = established_timings12[i].dmt_id;
const struct timings *t;
- const char *type = "DMT";
+ char type[16];
- if (established_timings12[i].dmt_id) {
- t = find_dmt_id(established_timings12[i].dmt_id);
+ if (dmt_id) {
+ sprintf(type, "DMT 0x%02x", dmt_id);
+ t = find_dmt_id(dmt_id);
} else {
t = &established_timings12[i].t;
- type = established_timings12[i].type;
+ sprintf(type, "%-8s", established_timings12[i].type);
}
- print_timings(" ", t, type);
+ print_timings(" ", t, type);
}
}
} else {
- printf("%s: none\n", data_block.c_str());
+ printf(" %s: none\n", data_block.c_str());
}
has_640x480p60_est_timing = x[0x23] & 0x20;
@@ -1762,14 +1782,15 @@ void edid_state::parse_base_block(const unsigned char *x)
for (i = 0; i < 8; i++) {
if (x[0x26 + i * 2] != 0x01 || x[0x26 + i * 2 + 1] != 0x01) {
found = true;
+ break;
}
}
if (found) {
- printf("%s\n", data_block.c_str());
+ printf(" %s:\n", data_block.c_str());
for (i = 0; i < 8; i++)
- print_standard_timing(" ", x[0x26 + i * 2], x[0x26 + i * 2 + 1]);
+ print_standard_timing(" ", x[0x26 + i * 2], x[0x26 + i * 2 + 1]);
} else {
- printf("%s: none\n", data_block.c_str());
+ printf(" %s: none\n", data_block.c_str());
}
/* 18 byte descriptors */
@@ -1788,14 +1809,20 @@ void edid_state::parse_base_block(const unsigned char *x)
if (x[0x36 + i * 18] || x[0x37 + i * 18])
preparse_total_dtds++;
+ data_block = "Detailed Timing Descriptors";
+ printf(" %s:\n", data_block.c_str());
detailed_block(x + 0x36);
detailed_block(x + 0x48);
detailed_block(x + 0x5a);
detailed_block(x + 0x6c);
has_spwg = false;
+ data_block = block;
if (x[0x7e])
- printf("Has %u extension block%s\n", x[0x7e], x[0x7e] > 1 ? "s" : "");
+ printf(" Extension blocks: %u\n", x[0x7e]);
+ if (x[0x7e] + 1U != num_blocks)
+ fail("EDID specified %u extension block(s), but found %u extension block(s).\n",
+ x[0x7e], num_blocks - 1);
block = block_name(0x00);
data_block.clear();

Privacy Policy