xref: /aosp_15_r20/external/edid-decode/parse-di-ext-block.cpp (revision 193032a37cc83cffc1526215991f3c21671f4245)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright 2020 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
4  *
5  * Author: Hans Verkuil <[email protected]>
6  */
7 
8 #include "edid-decode.h"
9 
parse_digital_interface(const unsigned char * x)10 void edid_state::parse_digital_interface(const unsigned char *x)
11 {
12 	data_block = "Digital Interface";
13 	printf("  %s:\n", data_block.c_str());
14 
15 	printf("    Supported Digital Interface: ");
16 	unsigned short v = x[2];
17 	switch (v) {
18 	case 0x00:
19 		printf("Analog Video Input\n");
20 		if (!memchk(x + 2, 12))
21 			fail("Bytes 0x02-0x0d should be 0.\n");
22 		return;
23 	case 0x01: printf("DVI\n"); break;
24 	case 0x02: printf("DVI Single Link\n"); break;
25 	case 0x03: printf("DVI Dual Link - High Resolution\n"); break;
26 	case 0x04: printf("DVI Dual Link - High Color\n"); break;
27 	case 0x05: printf("DVI - Consumer Electronics\n"); break;
28 	case 0x06: printf("Plug & Display\n"); break;
29 	case 0x07: printf("DFP\n"); break;
30 	case 0x08: printf("Open LDI - Single Link\n"); break;
31 	case 0x09: printf("Open LDI - Dual Link\n"); break;
32 	case 0x0a: printf("Open LDI - Consumer Electronics\n"); break;
33 	default:
34 		   printf("Unknown (0x%02x)\n", v);
35 		   fail("Unknown Digital Interface 0x%02x.\n", v);
36 		   break;
37 	}
38 
39 	switch ((x[3]) >> 6) {
40 	case 0x00:
41 		if (!memchk(x + 3, 4))
42 			fail("Bytes 0x03-0x06 should be 0.\n");
43 		break;
44 	case 0x01:
45 		printf("    Version: %u.%u\n    Release: %u.%u\n", x[3] & 0x3f, x[4], x[5], x[6]);
46 		if (x[4] > 99)
47 			fail("Version number > 99.\n");
48 		if (x[6] > 99)
49 			fail("Release number > 99.\n");
50 		break;
51 	case 0x02:
52 		if (x[3] & 0x3f)
53 			fail("Bits 5-0 of byte 0x03 should be 0.\n");
54 		if (x[5] || x[6])
55 			fail("Bytes 0x05-0x06 should be 0.\n");
56 		printf("    Letter Designation: %c\n", x[4]);
57 		break;
58 	case 0x03:
59 		if (x[3] & 0x3f)
60 			fail("Bits 5-0 of byte 0x03 should be 0.\n");
61 		printf("    Date Code: Year %u Week %u Day %u\n", 1990 + x[4], x[5], x[6]);
62 		if (!x[5] || x[5] > 12)
63 			fail("Bad month number.\n");
64 		if (!x[6] || x[6] > 31)
65 			fail("Bad day number.\n");
66 		break;
67 	}
68 
69 	v = x[7];
70 	printf("    Data Enable Signal Usage %sAvailable\n",
71 	       (v & 0x80) ? "" : "Not ");
72 	if (v & 0x80)
73 		printf("    Data Enable Signal %s\n",
74 		       (v & 0x40) ? "High" : "Low");
75 	else if (v & 0x40)
76 		fail("Bit 6 of byte 0x07 should be 0.\n");
77 	printf("    Edge of Shift Clock: ");
78 	switch ((v >> 4) & 0x03) {
79 	case 0: printf("Not specified\n"); break;
80 	case 1: printf("Use rising edge of shift clock\n"); break;
81 	case 2: printf("Use falling edge of shift clock\n"); break;
82 	case 3: printf("Use both edges of shift clock\n"); break;
83 	}
84 	printf("    HDCP is %ssupported\n", (v & 0x08) ? "" : "not ");
85 	printf("    Digital Receivers %ssupport Double Clocking of Input Data\n",
86 	       (v & 0x04) ? "" : "do not ");
87 	printf("    Packetized Digital Video is %ssupported\n", (v & 0x02) ? "" : "not ");
88 	if (v & 0x01)
89 		fail("Bit 0 of byte 0x07 should be 0.\n");
90 
91 	v = x[8];
92 	printf("    Data Formats: ");
93 	switch (v) {
94 	case 0x15: printf("8-Bit Over 8-Bit RGB\n"); break;
95 	case 0x19: printf("12-Bit Over 12-Bit RGB\n"); break;
96 	case 0x24: printf("24-Bit MSB-Aligned RGB (Single Link)\n"); break;
97 	case 0x48: printf("48-Bit MSB-Aligned RGB (Dual Link - High Resolution)\n"); break;
98 	case 0x49: printf("48-Bit MSB-Aligned RGB (Dual Link - High Color)\n"); break;
99 	default:
100 		   printf("Unknown (0x%02x)\n", v);
101 		   fail("Unknown Data Format 0x%02x.\n", v);
102 		   break;
103 	}
104 	if (x[2] == 0x03 && v != 0x48)
105 		fail("Data Format should be 0x48, not 0x%02x.\n", v);
106 	if (x[2] == 0x04 && v != 0x49)
107 		fail("Data Format should be 0x49, not 0x%02x.\n", v);
108 
109 	v = x[9];
110 	if (v) {
111 		printf("    Minimum Pixel Clock Frequency Per Link: %u MHz\n", v);
112 		if (v == 0xff)
113 			fail("Invalid Min-PCF 0x%02x.\n", v);
114 	}
115 
116 	v = x[10] | (x[11] << 8);
117 	if (v) {
118 		printf("    Maximum Pixel Clock Frequency Per Link: %u MHz\n", v);
119 		if (v == 0xffff)
120 			fail("Invalid Max-PCF 0x%04x.\n", v);
121 	}
122 
123 	v = x[12] | (x[13] << 8);
124 	if (v == 0xffff)
125 		printf("    Crossover Frequency: None - Single Link\n");
126 	else if (v)
127 		printf("    Crossover Frequency: %u MHz\n", v);
128 }
129 
parse_display_device(const unsigned char * x)130 void edid_state::parse_display_device(const unsigned char *x)
131 {
132 	data_block = "Display Device";
133 	printf("  %s:\n", data_block.c_str());
134 
135 	printf("    Sub-Pixel Layout: ");
136 	unsigned char v = x[0x0e];
137 	switch (v) {
138 	case 0x00: printf("Not defined\n"); break;
139 	case 0x01: printf("RGB\n"); break;
140 	case 0x02: printf("BGR\n"); break;
141 	case 0x03: printf("Quad Pixel - G at bottom left & top right\n"); break;
142 	case 0x04: printf("Quad Pixel - G at bottom right & top left\n"); break;
143 	default:
144 		   printf("Unknown (0x%02x)\n", v);
145 		   fail("Unknown Sub-Pixel Layout 0x%02x.\n", v);
146 		   break;
147 	}
148 	printf("    Sub-Pixel Configuration: ");
149 	v = x[0x0f];
150 	switch (v) {
151 	case 0x00: printf("Not defined\n"); break;
152 	case 0x01: printf("Delta (Tri-ad)\n"); break;
153 	case 0x02: printf("Stripe\n"); break;
154 	case 0x03: printf("Stripe Offset\n"); break;
155 	case 0x04: printf("Quad Pixel\n"); break;
156 	default:
157 		   printf("Unknown (0x%02x)\n", v);
158 		   fail("Unknown Sub-Pixel Configuration 0x%02x.\n", v);
159 		   break;
160 	}
161 	printf("    Sub-Pixel Shape: ");
162 	v = x[0x10];
163 	switch (v) {
164 	case 0x00: printf("Not defined\n"); break;
165 	case 0x01: printf("Round\n"); break;
166 	case 0x02: printf("Square\n"); break;
167 	case 0x03: printf("Rectangular\n"); break;
168 	case 0x04: printf("Oval\n"); break;
169 	case 0x05: printf("Elliptical\n"); break;
170 	default:
171 		   printf("Unknown (0x%02x)\n", v);
172 		   fail("Unknown Sub-Pixel Shape 0x%02x.\n", v);
173 		   break;
174 	}
175 	if (x[0x11])
176 		printf("    Horizontal Dot/Pixel Pitch: %.2f mm\n",
177 		       x[0x11] / 100.0);
178 	if (x[0x12])
179 		printf("    Vertical Dot/Pixel Pitch: %.2f mm\n",
180 		       x[0x12] / 100.0);
181 	v = x[0x13];
182 	printf("    Display Device %s a Fixed Pixel Format\n",
183 	       (v & 0x80) ? "has" : "does not have");
184 	printf("    View Direction: ");
185 	switch ((v & 0x60) >> 5) {
186 	case 0x00: printf("Not specified\n"); break;
187 	case 0x01: printf("Direct\n"); break;
188 	case 0x02: printf("Reflected\n"); break;
189 	case 0x03: printf("Direct & Reflected\n"); break;
190 	}
191 	printf("    Display Device uses %stransparent background\n",
192 	       (v & 0x10) ? "" : "non-");
193 	printf("    Physical Implementation: ");
194 	switch ((v & 0x0c) >> 2) {
195 	case 0x00: printf("Not specified\n"); break;
196 	case 0x01: printf("Large Image device for group viewing\n"); break;
197 	case 0x02: printf("Desktop or personal display\n"); break;
198 	case 0x03: printf("Eyepiece type personal display\n"); break;
199 	}
200 	printf("    Monitor/display does %ssupport DDC/CI\n",
201 	       (v & 0x02) ? "" : "not ");
202 	if (v & 0x01)
203 		fail("Bit 0 of byte 0x13 should be 0.\n");
204 }
205 
parse_display_caps(const unsigned char * x)206 void edid_state::parse_display_caps(const unsigned char *x)
207 {
208 	data_block = "Display Capabities & Feature Support Set";
209 	printf("  %s:\n", data_block.c_str());
210 
211 	unsigned short v = x[0x14];
212 
213 	printf("    Legacy Modes: %s VGA/DOS Legacy Timing Modes are supported\n",
214 	       (v & 0x80) ? "All" : "Not all");
215 	printf("    Stereo Video: ");
216 	switch ((v & 0x70) >> 4) {
217 	case 0x00: printf("No direct stereo\n"); break;
218 	case 0x01: printf("Field seq. stereo via stereo sync signal\n"); break;
219 	case 0x02: printf("auto-stereoscopic, column interleave\n"); break;
220 	case 0x03: printf("auto-stereoscopic, line interleave\n"); break;
221 	default:
222 		   printf("Unknown (0x%02x)\n", (v & 0x70) >> 4);
223 		   fail("Unknown Stereo Video 0x%02x.\n", (v & 0x70) >> 4);
224 		   break;
225 	}
226 	printf("    Scaler On Board: %s\n", (v & 0x08) ? "Yes" : "No");
227 	printf("    Image Centering: %s\n", (v & 0x04) ? "Yes" : "No");
228 	printf("    Conditional Update: %s\n", (v & 0x02) ? "Yes" : "No");
229 	printf("    Interlaced Video: %s\n", (v & 0x01) ? "Yes" : "No");
230 
231 	v = x[0x15];
232 	printf("    Frame Lock: %s\n", (v & 0x80) ? "Yes" : "No");
233 	printf("    Frame Rate Conversion: ");
234 	switch ((v & 0x60) >> 5) {
235 	case 0x00: printf("Not supported\n"); break;
236 	case 0x01: printf("Vertical is converted to a single frequency\n"); break;
237 	case 0x02: printf("Horizontal is convertred to a single frequency\n"); break;
238 	case 0x03: printf("Both Vertical & Horizontal are converted to single frequencies\n"); break;
239 	}
240 	if (v & 0x1f)
241 		fail("Bits 4-0 of byte 0x15 should be 0.\n");
242 	v = x[0x16] | (x[0x17] << 8);
243 	printf("    Vertical Frequency: ");
244 	if (!v) {
245 		printf("Not available\n");
246 	} else if (v == 0xffff) {
247 		printf("Reserved\n");
248 		fail("Vertical Frequency uses 0xffff (reserved value).\n");
249 	} else {
250 		printf("%.2f kHz\n", v / 100.0);
251 	}
252 	v = x[0x18] | (x[0x19] << 8);
253 	printf("    Horizontal Frequency: ");
254 	if (!v) {
255 		printf("Not available\n");
256 	} else if (v == 0xffff) {
257 		printf("Reserved\n");
258 		fail("Horizontal Frequency uses 0xffff (reserved value).\n");
259 	} else {
260 		printf("%.2f kHz\n", v / 100.0);
261 	}
262 
263 	v = x[0x1a];
264 	printf("    Display/Scan Orientation Definition Type: ");
265 	switch ((v & 0xc0) >> 6) {
266 	case 0x00: printf("Not defined\n"); break;
267 	case 0x01: printf("Fixed Orientation\n"); break;
268 	case 0x02: printf("Pivots: Default Orientation\n"); break;
269 	case 0x03: printf("Pivots: Current Orientation (requires multiple EDID Extension Tables)\n"); break;
270 	}
271 	printf("    Screen Orientation: %s\n",
272 	       (v & 0x20) ? "Portrait" : "Landscape");
273 	printf("    Zero Pixel Location: ");
274 	switch ((v & 0x18) >> 3) {
275 	case 0x00: printf("Upper Left\n"); break;
276 	case 0x01: printf("Upper Right\n"); break;
277 	case 0x02: printf("Lower Left\n"); break;
278 	case 0x03: printf("Lower Right\n"); break;
279 	}
280 	printf("    Scan Direction: ");
281 	switch ((v & 0x06) >> 1) {
282 	case 0x00: printf("Not defined\n"); break;
283 	case 0x01: printf("Fast Scan is on the Major (Long) Axis and Slow Scan is on the Minor Axis\n"); break;
284 	case 0x02: printf("Fast Scan is on the Minor (Short) Axis and Slow Scan is on the Major Axis\n"); break;
285 	case 0x03:
286 		   printf("Reserved\n");
287 		   fail("Scan Direction used the reserved value 0x03.\n");
288 		   break;
289 	}
290 	printf("    Standalone Projector: %s\n",
291 	       (v & 0x01) ? "Yes" : "No");
292 
293 	v = x[0x1b];
294 	printf("    Default Color/Luminance Decoding: ");
295 	switch (v) {
296 	case 0x00: printf("Not defined\n"); break;
297 	case 0x01: printf("BGR\n"); break;
298 	case 0x02: printf("Y/C (S-Video) NTSC\n"); break;
299 	case 0x03: printf("Y/C (S-Video) PAL\n"); break;
300 	case 0x04: printf("Y/C (S-Video) SECAM\n"); break;
301 	case 0x05: printf("YCrCb 4:4:4 per SMPTE 293M & 294M\n"); break;
302 	case 0x06: printf("YCrCb 4:2:2 per SMPTE 293M & 294M\n"); break;
303 	case 0x07: printf("YCrCb 4:2:0 per SMPTE 293M & 294M\n"); break;
304 	case 0x08: printf("YCrCb per SMPTE 260M (Legacy HDTV)\n"); break;
305 	case 0x09: printf("YPbPr per SMPTE 240M (Legacy HDTV)\n"); break;
306 	case 0x0a: printf("YCrCb per SMPTE 274M (Modern HDTV)\n"); break;
307 	case 0x0b: printf("YPbPr per SMPTE 274M (Modern HDTV)\n"); break;
308 	case 0x0c: printf("Y B-Y R-Y BetaCam (Sony)\n"); break;
309 	case 0x0d: printf("Y B-Y R-Y M-2 (Matsushita)\n"); break;
310 	case 0x0e: printf("Monochrome\n"); break;
311 	default:
312 		   printf("Unknown (0x%02x)\n", v);
313 		   fail("Unknown Default Color/Luminance Decoding 0x%02x.\n", v);
314 		   break;
315 	}
316 	v = x[0x1c];
317 	printf("    Preferred Color/Luminance Decoder: ");
318 	switch (v) {
319 	case 0x00: printf("Uses Default Decoding\n"); break;
320 	case 0x01: printf("BGR\n"); break;
321 	case 0x02: printf("Y/C (S-Video)\n"); break;
322 	case 0x03: printf("Yxx (SMPTE 2xxM)\n"); break;
323 	case 0x04: printf("Monochrome\n"); break;
324 	default:
325 		   printf("Unknown (0x%02x)\n", v);
326 		   fail("Unknown Preferred Color/Luminance Decoding 0x%02x.\n", v);
327 		   break;
328 	}
329 	v = x[0x1d];
330 	if (v && (x[0x1e] & 0xfc)) {
331 		printf("    Color/Luminance Decoding Capabilities:\n");
332 		printf("      BGR: %s\n", (v & 0x80) ? "Yes" : "No");
333 		printf("      Y/C (S-Video) NTSC: %s\n", (v & 0x40) ? "Yes" : "No");
334 		printf("      Y/C (S-Video) PAL: %s\n", (v & 0x20) ? "Yes" : "No");
335 		printf("      Y/C (S-Video) SECAM: %s\n", (v & 0x10) ? "Yes" : "No");
336 		printf("      YCrCb 4:4:4 per SMPTE 293M & 294M: %s\n", (v & 0x08) ? "Yes" : "No");
337 		printf("      YCrCb 4:2:2 per SMPTE 293M & 294M: %s\n", (v & 0x04) ? "Yes" : "No");
338 		printf("      YCrCb 4:2:0 per SMPTE 293M & 294M: %s\n", (v & 0x02) ? "Yes" : "No");
339 		printf("      YCrCb per SMPTE 260M (Legacy HDTV): %s\n", (v & 0x01) ? "Yes" : "No");
340 		v = x[0x1e];
341 		printf("      YPbPr per SMPTE 240M (Legacy HDTV): %s\n", (v & 0x80) ? "Yes" : "No");
342 		printf("      YCrCb per SMPTE 274M (Modern HDTV): %s\n", (v & 0x40) ? "Yes" : "No");
343 		printf("      YPbPr per SMPTE 274M (Modern HDTV): %s\n", (v & 0x20) ? "Yes" : "No");
344 		printf("      Y B-Y R-Y BetaCam (Sony): %s\n", (v & 0x10) ? "Yes" : "No");
345 		printf("      Y B-Y R-Y M-2 (Matsushita): %s\n", (v & 0x08) ? "Yes" : "No");
346 		printf("      Monochrome: %s\n", (v & 0x04) ? "Yes" : "No");
347 	} else {
348 		printf("    Color/Luminance Decoding Capabilities: None\n");
349 	}
350 	if (v & 0x03)
351 		fail("Bits 1-0 of byte 0x1e should be 0.\n");
352 
353 	v = x[0x1f];
354 	printf("    Dithering: %s\n", (v & 0x80) ? "Yes" : "No");
355 	if (v & 0x7f)
356 		fail("Bits 6-0 of byte 0x1f should be 0.\n");
357 	v = x[0x20];
358 	printf("    Supported Color Bit-Depth of Sub-Channel 0 (Blue): ");
359 	if (!v) {
360 		printf("No Information\n");
361 	} else if (v <= 16) {
362 		printf("%u\n", v);
363 	} else {
364 		printf("Reserved (0x%02x)\n", v);
365 		fail("Supported Color Bit-Depth of Sub-Channel Blue value is 0x%02x.\n", v);
366 	}
367 	v = x[0x21];
368 	printf("    Supported Color Bit-Depth of Sub-Channel 1 (Green): ");
369 	if (!v) {
370 		printf("No Information\n");
371 	} else if (v <= 16) {
372 		printf("%u\n", v);
373 	} else {
374 		printf("Reserved (0x%02x)\n", v);
375 		fail("Supported Color Bit-Depth of Sub-Channel Green value is 0x%02x.\n", v);
376 	}
377 	v = x[0x22];
378 	printf("    Supported Color Bit-Depth of Sub-Channel 2 (Red): ");
379 	if (!v) {
380 		printf("No Information\n");
381 	} else if (v <= 16) {
382 		printf("%u\n", v);
383 	} else {
384 		printf("Reserved (0x%02x)\n", v);
385 		fail("Supported Color Bit-Depth of Sub-Channel Red value is 0x%02x.\n", v);
386 	}
387 	v = x[0x23];
388 	printf("    Supported Color Bit-Depth of Sub-Channel 0 (Cb/Pb): ");
389 	if (!v) {
390 		printf("No Information\n");
391 	} else if (v <= 16) {
392 		printf("%u\n", v);
393 	} else {
394 		printf("Reserved (0x%02x)\n", v);
395 		fail("Supported Color Bit-Depth of Sub-Channel Cb/Pb value is 0x%02x.\n", v);
396 	}
397 	v = x[0x24];
398 	printf("    Supported Color Bit-Depth of Sub-Channel 1 (Y): ");
399 	if (!v) {
400 		printf("No Information\n");
401 	} else if (v <= 16) {
402 		printf("%u\n", v);
403 	} else {
404 		printf("Reserved (0x%02x)\n", v);
405 		fail("Supported Color Bit-Depth of Sub-Channel Y value is 0x%02x.\n", v);
406 	}
407 	v = x[0x25];
408 	printf("    Supported Color Bit-Depth of Sub-Channel 2 (Cr/Pr): ");
409 	if (!v) {
410 		printf("No Information\n");
411 	} else if (v <= 16) {
412 		printf("%u\n", v);
413 	} else {
414 		printf("Reserved (0x%02x)\n", v);
415 		fail("Supported Color Bit-Depth of Sub-Channel Cr/Pr value is 0x%02x.\n", v);
416 	}
417 
418 	v = x[0x26];
419 	printf("    Aspect Ratio Conversion Modes:");
420 	if (!v) {
421 		printf(" None\n");
422 	} else {
423 		printf("\n");
424 		printf("      Full Mode: %s\n", (v & 0x80) ? "Yes" : "No");
425 		printf("      Zoom Mode: %s\n", (v & 0x40) ? "Yes" : "No");
426 		printf("      Squeeze (Side Bars/Letterbox) Mode: %s\n", (v & 0x20) ? "Yes" : "No");
427 		printf("      Variable (Expand/Shrink) Mode: %s\n", (v & 0x10) ? "Yes" : "No");
428 	}
429 	if (v & 0x0f)
430 		fail("Bits 3-0 of byte 0x26 should be 0.\n");
431 }
432 
parse_display_xfer(const unsigned char * x)433 void edid_state::parse_display_xfer(const unsigned char *x)
434 {
435 	data_block = "Display Transfer Characteristics - Gamma";
436 	printf("  %s:\n", data_block.c_str());
437 
438 	unsigned char v = x[0x51];
439 	unsigned num_entries = v & 0x3f;
440 
441 	switch ((v & 0xc0) >> 6) {
442 	case 0x00:
443 		printf("    No Display Transfer Characteristics\n");
444 		if (!memchk(x + 0x51, 46))
445 			fail("Bytes 0x51-0x7e should be 0.\n");
446 		return;
447 	case 0x03:
448 		fail("Bits 7-6 of byte 0x51 cannot be 0x03.\n");
449 		return;
450 	default:
451 		break;
452 	}
453 
454 	if (((v & 0xc0) >> 6) == 0x01) {
455 		if (!num_entries || num_entries > 45)
456 			fail("White Curve with %u entries.\n", num_entries);
457 		if (num_entries > 45)
458 			num_entries = 45;
459 		if (!memchk(x + 0x52 + num_entries, 45 - num_entries))
460 			fail("Bytes 0x%02x-0x7e should be 0.\n", 0x52 + num_entries);
461 		printf("    White Curve (%u entries):\n", num_entries);
462 		hex_block("      ", x + 0x52, num_entries, false, 15);
463 	} else {
464 		if (!num_entries || num_entries > 15)
465 			fail("Sub-Channel Curve with %u entries.\n", num_entries);
466 		if (num_entries > 15)
467 			num_entries = 15;
468 		printf("    Sub-Channel 0 (Blue) Curve with %u entries:\n", num_entries);
469 		hex_block("      ", x + 0x52, num_entries, false);
470 		if (!memchk(x + 0x52 + num_entries, 15 - num_entries))
471 			fail("Bytes 0x%02x-0x7e should be 0.\n", 0x52 + num_entries);
472 		printf("    Sub-Channel 1 (Green) Curve with %u entries:\n", num_entries);
473 		hex_block("      ", x + 0x52 + 15, num_entries, false);
474 		if (!memchk(x + 0x52 + 15 + num_entries, 15 - num_entries))
475 			fail("Bytes 0x%02x-0x7e should be 0.\n", 0x52 + 15 + num_entries);
476 		printf("    Sub-Channel 2 (Red) Curve with %u entries:\n", num_entries);
477 		hex_block("      ", x + 0x52 + 30, num_entries, false);
478 		if (!memchk(x + 0x52 + 30 + num_entries, 15 - num_entries))
479 			fail("Bytes 0x%02x-0x7e should be 0.\n", 0x52 + 30 + num_entries);
480 	}
481 }
482 
parse_di_ext_block(const unsigned char * x)483 void edid_state::parse_di_ext_block(const unsigned char *x)
484 {
485 	printf("  Version: %u\n", x[1]);
486 	if (!x[1])
487 		fail("Invalid version 0.\n");
488 
489 	parse_digital_interface(x);
490 	parse_display_device(x);
491 	parse_display_caps(x);
492 	if (!memchk(x + 0x27, 16))
493 		fail("Bytes 0x27-0x36 should be 0.\n");
494 	if (!memchk(x + 0x37, 17))
495 		fail("Bytes 0x37-0x47 should be 0.\n");
496 	if (!memchk(x + 0x48, 9))
497 		fail("Bytes 0x48-0x50 should be 0.\n");
498 	parse_display_xfer(x);
499 }
500