Codebase list edid-decode / 31e3c40
New upstream version 0.1~git20220315.cb74358c2896 Andrej Shadura 2 years ago
91 changed file(s) with 4636 addition(s) and 2492 deletion(s). Raw diff Collapse all Expand all
00 edid-decode
1 *.dSYM
0 bindir ?= /usr/bin
1 mandir ?= /usr/share/man
0 ifeq ($(OS),Windows_NT)
1 bindir ?= /usr/bin
2 mandir ?= /usr/share/man
3 else
4 UNAME_S := $(shell uname -s)
5 ifeq ($(UNAME_S),Darwin)
6 bindir ?= /usr/local/sbin
7 mandir ?= /usr/local/share/man
8 else
9 bindir ?= /usr/bin
10 mandir ?= /usr/share/man
11 endif
12 endif
213
314 EMXX ?= em++
415
516 SOURCES = edid-decode.cpp parse-base-block.cpp parse-cta-block.cpp \
617 parse-displayid-block.cpp parse-ls-ext-block.cpp \
7 parse-di-ext-block.cpp parse-vtb-ext-block.cpp
8 WARN_FLAGS = -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter
18 parse-di-ext-block.cpp parse-vtb-ext-block.cpp \
19 calc-gtf-cvt.cpp calc-ovt.cpp
20 WARN_FLAGS = -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -Wimplicit-fallthrough
921
1022 all: edid-decode
1123
1224 sha = -DSHA=$(shell if test -d .git ; then git rev-parse --short=12 HEAD ; fi)
13 date = -DDATE=$(shell if test -d .git ; then printf '"'; TZ=UTC git show --quiet --date='format-local:%F %T"' --format="%cd"; fi)
25 date = -DDATE=$(shell if test -d .git ; then TZ=UTC git show --quiet --date='format-local:"%F %T"' --format='%cd'; fi)
1426
15 edid-decode: $(SOURCES) edid-decode.h Makefile
27 edid-decode: $(SOURCES) edid-decode.h oui.h Makefile
1628 $(CXX) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(WARN_FLAGS) -g $(sha) $(date) -o $@ $(SOURCES) -lm
1729
18 edid-decode.js: $(SOURCES) edid-decode.h Makefile
30 edid-decode.js: $(SOURCES) edid-decode.h oui.h Makefile
1931 $(EMXX) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(WARN_FLAGS) $(sha) $(date) -s EXPORTED_FUNCTIONS='["_parse_edid"]' -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -o $@ $(SOURCES) -lm
2032
2133 clean:
0 // SPDX-License-Identifier: MIT
1 /*
2 * Copyright 2006-2012 Red Hat, Inc.
3 * Copyright 2018-2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
4 *
5 * Author: Adam Jackson <ajax@nwnk.net>
6 * Maintainer: Hans Verkuil <hverkuil-cisco@xs4all.nl>
7 */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <math.h>
12 #include <time.h>
13
14 #include "edid-decode.h"
15
16 #define CELL_GRAN 8.0
17 #define MARGIN_PERC 1.8
18 #define GTF_MIN_PORCH 1.0
19 #define GTF_V_SYNC_RQD 3.0
20 #define GTF_H_SYNC_PERC 8.0
21 #define GTF_MIN_VSYNC_BP 550.0
22
23 timings edid_state::calc_gtf_mode(unsigned h_pixels, unsigned v_lines,
24 double ip_freq_rqd, bool int_rqd,
25 enum gtf_ip_parm ip_parm, bool margins_rqd,
26 bool secondary, double C, double M, double K, double J)
27 {
28 timings t = {};
29 /* C' and M' are part of the Blanking Duty Cycle computation */
30 double C_PRIME = ((C - J) * K / 256.0) + J;
31 double M_PRIME = K / 256.0 * M;
32
33 double h_pixels_rnd = round(h_pixels / CELL_GRAN) * CELL_GRAN;
34 double v_lines_rnd = int_rqd ? round(v_lines / 2.0) : v_lines;
35 unsigned hor_margin = margins_rqd ?
36 round(h_pixels_rnd * MARGIN_PERC / 100.0 / CELL_GRAN) * CELL_GRAN : 0;
37 unsigned vert_margin = margins_rqd ? round(MARGIN_PERC / 100.0 * v_lines_rnd) : 0;
38 double interlace = int_rqd ? 0.5 : 0;
39 double total_active_pixels = h_pixels_rnd + hor_margin * 2;
40
41 t.hact = h_pixels_rnd;
42 t.vact = v_lines;
43 t.interlaced = int_rqd;
44
45 double pixel_freq;
46 double h_blank_pixels;
47 double total_pixels;
48 double v_sync_bp;
49
50 if (ip_parm == gtf_ip_vert_freq) {
51 // vertical frame frequency (Hz)
52 double v_field_rate_rqd = int_rqd ? ip_freq_rqd * 2 : ip_freq_rqd;
53 double h_period_est = ((1.0 / v_field_rate_rqd) - GTF_MIN_VSYNC_BP / 1000000.0) /
54 (v_lines_rnd + vert_margin * 2 + GTF_MIN_PORCH + interlace) * 1000000.0;
55 v_sync_bp = round(GTF_MIN_VSYNC_BP / h_period_est);
56 double total_v_lines = v_lines_rnd + vert_margin * 2 +
57 v_sync_bp + interlace + GTF_MIN_PORCH;
58 double v_field_rate_est = 1.0 / h_period_est / total_v_lines * 1000000.0;
59 double h_period = h_period_est / (v_field_rate_rqd / v_field_rate_est);
60 double ideal_duty_cycle = C_PRIME - (M_PRIME * h_period / 1000.0);
61 h_blank_pixels = round(total_active_pixels * ideal_duty_cycle /
62 (100.0 - ideal_duty_cycle) /
63 (2 * CELL_GRAN)) * 2 * CELL_GRAN;
64 total_pixels = total_active_pixels + h_blank_pixels;
65 pixel_freq = total_pixels / h_period;
66 } else if (ip_parm == gtf_ip_hor_freq) {
67 // horizontal frequency (kHz)
68 double h_freq = ip_freq_rqd;
69 v_sync_bp = round(GTF_MIN_VSYNC_BP * h_freq / 1000.0);
70 double ideal_duty_cycle = C_PRIME - (M_PRIME / h_freq);
71 h_blank_pixels = round(total_active_pixels * ideal_duty_cycle /
72 (100.0 - ideal_duty_cycle) /
73 (2 * CELL_GRAN)) * 2 * CELL_GRAN;
74 total_pixels = total_active_pixels + h_blank_pixels;
75 pixel_freq = total_pixels * h_freq / 1000.0;
76 } else {
77 // pixel clock rate (MHz)
78 pixel_freq = ip_freq_rqd;
79 double ideal_h_period =
80 ((C_PRIME - 100.0) +
81 sqrt(((100.0 - C_PRIME) * (100.0 - C_PRIME) +
82 (0.4 * M_PRIME * (total_active_pixels + hor_margin * 2) /
83 pixel_freq)))) / 2.0 / M_PRIME * 1000.0;
84 double ideal_duty_cycle = C_PRIME - (M_PRIME * ideal_h_period) / 1000.0;
85 h_blank_pixels = round(total_active_pixels * ideal_duty_cycle /
86 (100.0 - ideal_duty_cycle) /
87 (2 * CELL_GRAN)) * 2 * CELL_GRAN;
88 total_pixels = total_active_pixels + h_blank_pixels;
89 double h_freq = pixel_freq / total_pixels * 1000.0;
90 v_sync_bp = round(GTF_MIN_VSYNC_BP * h_freq / 1000.0);
91 }
92
93 double v_back_porch = v_sync_bp - GTF_V_SYNC_RQD;
94
95 t.vbp = v_back_porch;
96 t.vsync = GTF_V_SYNC_RQD;
97 t.vfp = GTF_MIN_PORCH;
98 t.pixclk_khz = round(1000.0 * pixel_freq);
99 t.hsync = round(GTF_H_SYNC_PERC / 100.0 * total_pixels / CELL_GRAN) * CELL_GRAN;
100 t.hfp = (h_blank_pixels / 2.0) - t.hsync;
101 t.hbp = t.hfp + t.hsync;
102 t.hborder = hor_margin;
103 t.vborder = vert_margin;
104 t.pos_pol_hsync = secondary;
105 t.pos_pol_vsync = !secondary;
106 t.rb = secondary ? RB_GTF : RB_NONE;
107 return t;
108 }
109
110 void edid_state::edid_gtf_mode(unsigned refresh, struct timings &t)
111 {
112 unsigned hratio = t.hratio;
113 unsigned vratio = t.vratio;
114 t = calc_gtf_mode(t.hact, t.vact, refresh, t.interlaced);
115 t.hratio = hratio;
116 t.vratio = vratio;
117 }
118
119 #define CVT_MIN_VSYNC_BP 550.0
120 #define CVT_MIN_V_PORCH 3
121 /* Minimum vertical backporch for CVT and CVT RBv1 */
122 #define CVT_MIN_V_BPORCH 7
123 /* Fixed vertical backporch for CVT RBv2 and RBv3 */
124 #define CVT_FIXED_V_BPORCH 6
125 #define CVT_C_PRIME 30.0
126 #define CVT_M_PRIME 300.0
127 #define CVT_RB_MIN_VBLANK 460.0
128
129 // If rb == RB_CVT_V2, then alt means video-optimized (i.e. 59.94 instead of 60 Hz, etc.).
130 // If rb == RB_CVT_V3, then alt means that rb_h_blank is 160 instead of 80.
131 timings edid_state::calc_cvt_mode(unsigned h_pixels, unsigned v_lines,
132 double ip_freq_rqd, unsigned rb, bool int_rqd,
133 bool margins_rqd, bool alt, unsigned rb_h_blank,
134 unsigned rb_v_blank, bool early_vsync_rqd)
135 {
136 timings t = {};
137
138 t.hact = h_pixels;
139 t.vact = v_lines;
140 t.interlaced = int_rqd;
141
142 if (rb_v_blank < CVT_RB_MIN_VBLANK)
143 rb_v_blank = CVT_RB_MIN_VBLANK;
144
145 double cell_gran = rb == RB_CVT_V2 ? 1 : CELL_GRAN;
146 double h_pixels_rnd = floor(h_pixels / cell_gran) * cell_gran;
147 double v_lines_rnd = int_rqd ? floor(v_lines / 2.0) : v_lines;
148 unsigned hor_margin = margins_rqd ?
149 floor((h_pixels_rnd * MARGIN_PERC / 100.0) / cell_gran) * cell_gran : 0;
150 unsigned vert_margin = margins_rqd ? floor(MARGIN_PERC / 100.0 * v_lines_rnd) : 0;
151 double interlace = int_rqd ? 0.5 : 0;
152 double total_active_pixels = h_pixels_rnd + hor_margin * 2;
153 double v_field_rate_rqd = int_rqd ? ip_freq_rqd * 2 : ip_freq_rqd;
154 double clock_step = rb == RB_CVT_V2 ? 0.001 : 0.25;
155 double h_blank = (rb == RB_CVT_V1 || (rb == RB_CVT_V3 && alt)) ? 160 : 80;
156 double rb_v_fporch = rb == RB_CVT_V1 ? 3 : 1;
157 double refresh_multiplier = (rb == RB_CVT_V2 && alt) ? 1000.0 / 1001.0 : 1;
158 double rb_min_vblank = rb == RB_CVT_V3 ? rb_v_blank : CVT_RB_MIN_VBLANK;
159 double h_sync = 32;
160
161 double v_sync;
162 double pixel_freq;
163 double v_blank;
164 double v_sync_bp;
165
166 if (rb == RB_CVT_V3 && rb_h_blank) {
167 h_blank = rb_h_blank & ~7;
168 if (h_blank < 80)
169 h_blank = 80;
170 else if (h_blank > 200)
171 h_blank = 200;
172 }
173
174 /* Determine VSync Width from aspect ratio */
175 if ((t.vact * 4 / 3) == t.hact)
176 v_sync = 4;
177 else if ((t.vact * 16 / 9) == t.hact)
178 v_sync = 5;
179 else if ((t.vact * 16 / 10) == t.hact)
180 v_sync = 6;
181 else if (!(t.vact % 4) && ((t.vact * 5 / 4) == t.hact))
182 v_sync = 7;
183 else if ((t.vact * 15 / 9) == t.hact)
184 v_sync = 7;
185 else /* Custom */
186 v_sync = 10;
187
188 if (rb >= RB_CVT_V2)
189 v_sync = 8;
190
191 if (rb == RB_NONE) {
192 double h_period_est = ((1.0 / v_field_rate_rqd) - CVT_MIN_VSYNC_BP / 1000000.0) /
193 (v_lines_rnd + vert_margin * 2 + CVT_MIN_V_PORCH + interlace) * 1000000.0;
194 v_sync_bp = floor(CVT_MIN_VSYNC_BP / h_period_est) + 1;
195 if (v_sync_bp < v_sync + CVT_MIN_V_BPORCH)
196 v_sync_bp = v_sync + CVT_MIN_V_BPORCH;
197 v_blank = v_sync_bp + CVT_MIN_V_PORCH;
198 double ideal_duty_cycle = CVT_C_PRIME - (CVT_M_PRIME * h_period_est / 1000.0);
199 if (ideal_duty_cycle < 20)
200 ideal_duty_cycle = 20;
201 h_blank = floor(total_active_pixels * ideal_duty_cycle /
202 (100.0 - ideal_duty_cycle) /
203 (2 * CELL_GRAN)) * 2 * CELL_GRAN;
204 double total_pixels = total_active_pixels + h_blank;
205 h_sync = floor(total_pixels * 0.08 / CELL_GRAN) * CELL_GRAN;
206 pixel_freq = floor((total_pixels / h_period_est) / clock_step) * clock_step;
207 } else {
208 double h_period_est = ((1000000.0 / v_field_rate_rqd) - rb_min_vblank) /
209 (v_lines_rnd + vert_margin * 2);
210 double vbi_lines = floor(rb_min_vblank / h_period_est) + 1;
211 double rb_v_bporch = (rb == RB_CVT_V1 ? CVT_MIN_V_BPORCH : CVT_FIXED_V_BPORCH);
212 double rb_min_vbi = rb_v_fporch + v_sync + rb_v_bporch;
213 v_blank = vbi_lines < rb_min_vbi ? rb_min_vbi : vbi_lines;
214 double total_v_lines = v_blank + v_lines_rnd + vert_margin * 2 + interlace;
215 if (rb == RB_CVT_V3 && early_vsync_rqd)
216 rb_v_bporch = floor(vbi_lines / 2.0);
217 if (rb == RB_CVT_V1)
218 v_sync_bp = v_blank - rb_v_fporch;
219 else
220 v_sync_bp = v_sync + rb_v_bporch;
221 double total_pixels = h_blank + total_active_pixels;
222 double freq = v_field_rate_rqd * total_v_lines * total_pixels * refresh_multiplier;
223 if (rb == RB_CVT_V3)
224 pixel_freq = ceil((freq / 1000000.0) / clock_step) * clock_step;
225 else
226 pixel_freq = floor((freq / 1000000.0) / clock_step) * clock_step;
227 }
228
229 t.vbp = v_sync_bp - v_sync;
230 t.vsync = v_sync;
231 t.vfp = v_blank - t.vbp - t.vsync;
232 t.pixclk_khz = round(1000.0 * pixel_freq);
233 t.hsync = h_sync;
234 if (rb == RB_CVT_V3)
235 t.hfp = 8;
236 else
237 t.hfp = (h_blank / 2.0) - t.hsync;
238 t.hbp = h_blank - t.hfp - t.hsync;
239 t.hborder = hor_margin;
240 t.vborder = vert_margin;
241 t.rb = rb;
242 if (alt && (rb == RB_CVT_V2 || rb == RB_CVT_V3))
243 t.rb |= RB_ALT;
244 t.pos_pol_hsync = t.rb;
245 t.pos_pol_vsync = !t.rb;
246 calc_ratio(&t);
247 return t;
248 }
249
250 void edid_state::edid_cvt_mode(unsigned refresh, struct timings &t, unsigned rb_h_blank,
251 unsigned rb_v_blank, bool early_vsync_rqd)
252 {
253 unsigned hratio = t.hratio;
254 unsigned vratio = t.vratio;
255
256 t = calc_cvt_mode(t.hact, t.vact, refresh, t.rb & ~RB_ALT, t.interlaced,
257 false, t.rb & RB_ALT, rb_h_blank, rb_v_blank, early_vsync_rqd);
258 t.hratio = hratio;
259 t.vratio = vratio;
260 }
0 // SPDX-License-Identifier: MIT
1 /*
2 * Copyright 2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
3 *
4 * Author: Hans Verkuil <hverkuil-cisco@xs4all.nl>
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <math.h>
10 #include <time.h>
11 #include <numeric>
12
13 #include "edid-decode.h"
14
15 #define MinVblankDuration 460
16 #define MinVsyncLeadingEdge 400
17 #define MinClockRate420 590000000
18 #define PixelFactor420 2
19 #define MinHblank444 80
20 #define MinHblank420 128
21 #define PixelClockGranularity 1000
22 #define MinHtotalGranularity 8
23 #define MaxChunkRate 650000000
24 #define AudioPacketRate 195000
25 #define AudioPacketSize 32
26 #define LineOverhead 32
27
28 static unsigned roundup_to_power_of_two(unsigned v)
29 {
30 unsigned shift = 1;
31 unsigned mask = 0;
32
33 if (!v || v > 0x80000000) {
34 fprintf(stderr, "roundup_to_power_of_two: invalid input %u.\n", v);
35 exit(1);
36 }
37
38 v--;
39 do {
40 mask = v >> shift;
41 v |= mask;
42 shift <<= 1;
43 } while (mask);
44 return v + 1;
45 }
46
47 static unsigned greatest_power_of_two_divider(unsigned x)
48 {
49 return x & ~(x - 1);
50 }
51
52 timings edid_state::calc_ovt_mode(unsigned Hactive, unsigned Vactive,
53 unsigned Hratio, unsigned Vratio,
54 unsigned Vrate)
55 {
56 timings t = {};
57
58 t.hact = Hactive;
59 t.vact = Vactive;
60 t.hratio = Hratio;
61 t.vratio = Vratio;
62
63 unsigned MaxVrate = Vrate;
64 unsigned VtotalGranularity = 1;
65
66 // Step 1
67 switch (Vrate) {
68 case 24: case 25: case 30:
69 MaxVrate = 30;
70 VtotalGranularity = 20;
71 break;
72 case 48: case 50: case 60:
73 MaxVrate = 60;
74 VtotalGranularity = 20;
75 break;
76 case 100: case 120:
77 MaxVrate = 120;
78 VtotalGranularity = 5;
79 break;
80 case 200: case 240:
81 MaxVrate = 240;
82 VtotalGranularity = 5;
83 break;
84 case 300: case 360:
85 MaxVrate = 360;
86 VtotalGranularity = 5;
87 break;
88 case 400: case 480:
89 MaxVrate = 480;
90 VtotalGranularity = 5;
91 break;
92 }
93
94 // Step 2
95 double MaxActiveTime = (1000000.0 / MaxVrate) - MinVblankDuration;
96 double MinLineTime = MaxActiveTime / Vactive;
97 unsigned MinVblank = ceil(MinVblankDuration / MinLineTime);
98 unsigned MinVtotal = Vactive + MinVblank;
99
100 if (MinVtotal % VtotalGranularity)
101 MinVtotal += VtotalGranularity - (MinVtotal % VtotalGranularity);
102
103 // Step 3
104 unsigned MinLineRate = MaxVrate * MinVtotal;
105 unsigned MaxAudioPacketsPerLine = ceil((double)AudioPacketRate / MinLineRate);
106
107 // Step 4
108 unsigned MinHtotal = Hactive +
109 max(MinHblank444, LineOverhead + AudioPacketSize * MaxAudioPacketsPerLine);
110 double MinPixelClockRate = (double)MaxVrate * MinHtotal * MinVtotal;
111 double HCalcGranularity = roundup_to_power_of_two(ceil(MinPixelClockRate / MaxChunkRate));
112 unsigned HtotalGranularity = max(MinHtotalGranularity, HCalcGranularity);
113
114 if (MinHtotal % HtotalGranularity)
115 MinHtotal += HtotalGranularity - (MinHtotal % HtotalGranularity);
116
117 unsigned ResolutionGranularity = PixelClockGranularity /
118 gcd(PixelClockGranularity, MaxVrate);
119 unsigned Htotal = 0;
120 unsigned Vtotal = 0;
121 unsigned long long PixelClockRate = 0;
122
123 for (;;) {
124 // Step 5
125 unsigned long long RMin = 0;
126 unsigned V = MinVtotal;
127
128 for (;;) {
129 unsigned H = MinHtotal;
130 unsigned long long R = H * V;
131 if (RMin && R > RMin)
132 break;
133 while (R % ResolutionGranularity ||
134 MaxVrate * R / greatest_power_of_two_divider(H) > MaxChunkRate) {
135 H += HtotalGranularity;
136 R = H * V;
137 }
138 if (!RMin || R < RMin) {
139 Htotal = H;
140 Vtotal = V;
141 RMin = R;
142 }
143 V += VtotalGranularity;
144 }
145 PixelClockRate = MaxVrate * RMin;
146
147 // Step 6
148 MinHtotal = Hactive + max(MinHblank420, PixelFactor420 *
149 (LineOverhead + AudioPacketSize * MaxAudioPacketsPerLine));
150 if (PixelClockRate >= MinClockRate420 &&
151 Htotal < MinHtotal)
152 continue;
153 break;
154 }
155
156 // Step 7
157 Vtotal = Vtotal * MaxVrate / Vrate;
158
159 // Step 8
160 unsigned Vblank = Vtotal - Vactive;
161 unsigned VsyncPosition = ceil((double)MinVsyncLeadingEdge * PixelClockRate / (1000000.0 * Htotal));
162 t.vfp = Vblank - VsyncPosition;
163
164 t.vsync = 8;
165 t.vbp = Vblank - t.vfp - t.vsync;
166 t.pos_pol_vsync = true;
167 unsigned Hblank = Htotal - Hactive;
168 t.hsync = 32;
169 t.hbp = 32;
170 t.hfp = Hblank - t.hsync - t.hbp;
171 t.pos_pol_hsync = true;
172 t.pixclk_khz = PixelClockRate / 1000;
173 if (!t.hratio || !t.vratio)
174 calc_ratio(&t);
175 return t;
176 }
Binary diff not shown
data/acer-xv273k-dp less more
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
8787 is the actual HDMI VIC code.
8888 .TP
8989 DTD #: Detailed Timings Descriptor (see EDID standard). Also used for
90 DisplayID Video Timing Modes Types I, II, VI and VII. The number denotes that
91 this is the Nth DTD in the EDID.
90 DisplayID Video Timing Modes Types I, II, VI, VII, VIII and X. The number denotes that
91 this is the Nth DTD in the Base Block and CTA Extension Blocks.
92 .TP
93 VTDB #: 20-byte DTD or 6- or 7-byte CVT descriptor in a CTA Extension Block.
94 The number denotes that this is the Nth such timing in the CTA Extension Blocks.
95 .TP
96 RID #@#: A CTA-861.6 Video Format Descriptor with the given Resolution ID (first
97 number) at the given framerate (second number).
9298 .RE
9399
94100 By default DTDs are shown in the long format while others are just shown in
110116 .TP
111117 DisplayID 1.3: VESA Display Identification Data (DisplayID) Standard, Version 1.3
112118 .TP
113 DisplayID 2.0: VESA DisplayID Standard, Version 2.0
119 DisplayID 2.1: VESA DisplayID Standard, Version 2.1
114120 .TP
115121 DI-EXT: VESA Display Information Extension Block Standard, Release A
116122 .TP
130136 .TP
131137 CTA-861-H: A DTV Profile for Uncompressed High Speed Digital Interfaces
132138 .TP
139 CTA-861.6: Improvements on Audio and Video Signaling
140 .TP
133141 SPWG Notebook Panel Specification, Version 3.5
134142 .TP
135143 EPI Embedded Panel Interface, Revision 1.0
144 .TP
145 Microsoft EDID extension for head-mounted and specialized monitors, Version 3
136146 .RE
137147
138148 .TP
141151 .TP
142152 DMT 1.3: VESA and Industry Standards and Guidelines for Computer Display Monitor Timing (DMT), Version 1.0, Rev. 13
143153 .TP
154 CVT 2.0: VESA Coordinated Video Timings (CVT) Standard, Version 2.0
155 .TP
144156 CVT 1.2: VESA Coordinated Video Timings (CVT) Standard, Version 1.2
157 .TP
158 CVT 1.2: VESA CVT v1.2 Errata E2
145159 .TP
146160 GTF 1.1: VESA Generalized Timing Formula Standard, Version: 1.1
147161 .RE
151165 \fB\-h\fR, \fB\-\-help\fR
152166 Prints the help message.
153167 .TP
154 \fB\-o\fR, \fB\-\-output\-format\fR=\fI<fmt>\fR
168 \fB\-o\fR, \fB\-\-output\-format\fR \fI<fmt>\fR
155169 If [out] is specified, then write the EDID in format \fI<fmt>\fR.
156 .br
170
157171 The output format can be one of:
158172 .br
159173 hex: hex numbers in ascii text (default for stdout)
172186 Check if the EDID conforms to the standards. Warnings and failures are
173187 reported as they happen.
174188 .TP
175 \fB\-n\fR, \fB\-\-native\-timings\fR
176 Report the native timings at the end. There may be multiple native timing reports
189 \fB\-n\fR, \fB\-\-native\-resolution\fR
190 Report the native resolution at the end. There may be multiple native resolution reports
177191 depending on whether the Source only parses Block 0 (e.g. DVI outputs) or Block 0
178 and the CTA-861 Extension Blocks (HDMI).
192 and the CTA-861 Extension Blocks (HDMI), or just the DisplayID Extension Blocks
193 (typical for DisplayPort). If all blocks contain the same native resolution, then
194 only that resolution is reported. For older displays there may be two separate native
195 resolutions: progressive and interlaced.
179196 .TP
180197 \fB\-p\fR, \fB\-\-preferred\-timings\fR
181 Report the preferred timings at the end. There may be multiple native timing reports
198 Report the preferred timings at the end. There may be multiple preferred timing reports
182199 depending on whether the Source only parses Block 0 (e.g. DVI outputs), or Block 0
183200 and the CTA-861 Extension Blocks (HDMI), or Block 0 and the DisplayID Extension Blocks
184201 (typical for DisplayPort).
202 .TP
203 \fB\-\-diagonal\fR \fI<inches>\fR
204 Specify the diagonal of the display in inches. This will enable additional checks
205 for the image size, checking if it corresponds to the diagonal. This assumes
206 square pixels.
185207 .TP
186208 \fB\-P\fR, \fB\-\-physical\-address\fR
187209 Just report the HDMI Source Physical Address and nothing else. Reports f.f.f.f
196218 \fB\-L\fR, \fB\-\-long\-timings\fR
197219 Report all video timings in a long format.
198220 .TP
221 \fB\-N\fR, \fB\-\-ntsc\fR
222 Report the video timings with values suitable for NTSC-based video.
223 E.g., this will show refresh rates of 29.97 Hz instead of 30 Hz.
224 This is only done for timings with refresh rates that are a multiple of 6.
225 .TP
199226 \fB\-X\fR, \fB\-\-xmodeline\fR
200227 Report all long video timings in the ModeLine format as defined in xorg.conf(5).
201228 This ModeLine can be used in the xorg.conf file or passed to xrandr(1) with the
210237 .TP
211238 \fB\-s\fR, \fB\-\-skip\-hex\-dump\fR
212239 Skip the initial hex dump of the EDID.
240 .TP
241 \fB\-H\fR, \fB\-\-only\-hex\-dump\fR
242 Only show the hex dump of the EDID, then exit.
213243 .TP
214244 \fB\-\-skip\-sha\fR
215245 Don't show the SHA hash. Normally edid-decode will show the SHA, i.e. the
227257 \fB\-\-version\fR
228258 Show the SHA hash and the last commit date.
229259
260 .SH TIMING OPTIONS
261 The following options report the timings for DMT, VIC and HDMI VIC codes and
262 calculate the timings for CVT or GTF timings, based on the given parameters.
263 The EDID will not be shown, although it can be used with the \fB\-\-gtf\fR
264 option in order to read the secondary curve parameters.
265 .TP
266 \fB\-\-std\fR \fI<byte1>\fR,\fI<byte2>\fR
267 Show the standard timing represented by these two bytes.
268 .TP
269 \fB\-\-dmt\fR \fI<dmt>\fR
270 Show the timings for the DMT with the given DMT ID.
271 .TP
272 \fB\-\-vic\fR \fI<vic>\fR
273 Show the timings for this VIC.
274 .TP
275 \fB\-\-hdmi\-vic\fR \fI<hdmivic>\fR
276 Show the timings for this HDMI VIC.
277 .TP
278 \fB\-\-cvt\fR \fBw\fR=\fI<width>\fR,\fBh\fR=\fI<height>\fR,\fBfps\fR=\fI<fps>\fR[,\fBrb\fR=\fI<rb>\fR][,\fBinterlaced\fR][,\fBoverscan\fR]
279 [,\fBalt\fR][,\fBhblank\fR=\fI<hblank>\fR][,\fBvblank\fR=\fI<vblank>\fR][,\fBearly\-vsync\fR]
280 .br
281 Calculate the CVT timings for the given format.
282
283 \fI<width>\fR is the width in pixels, \fI<height>\fR is the frame (not field!) height in lines.
284 .br
285 \fI<fps>\fR is frames per second for progressive timings and fields per second for interlaced timings.
286 .br
287 \fI<rb>\fR can be 0 (no reduced blanking, default), or 1-3 for the reduced blanking version.
288 .br
289 If \fBinterlaced\fR is given, then this is an interlaced format.
290 .br
291 If \fBoverscan\fR is given, then this is an overscanned format. I.e., margins are required.
292 .br
293 If \fBalt\fR is given and \fI<rb>\fR=2, then report the timings
294 optimized for video: 1000 / 1001 * \fI<fps>\fR.
295 .br
296 If \fBalt\fR is given and \fI<rb>\fR=3, then the horizontal blanking
297 is 160 instead of 80 pixels.
298 .br
299 If \fBhblank\fR is given and \fI<rb>\fR=3, then the horizontal blanking
300 is \fI<hblank>\fR pixels (range of 80-200 and divisible by 8), overriding \fBalt\fR.
301 .br
302 If \fBvblank\fR is given and \fI<rb>\fR=3, then the vertical blanking time
303 is \fI<vblank>\fR microseconds (460 minimum, values > 705 might not be supported by
304 all RBv3 timings compliant source devices.
305 .br
306 If \fBearly\-vsync\fR is given and \fI<rb>\fR=3, then select an early vsync timing.
307 .TP
308 \fB\-\-gtf\fR \fBw\fR=\fI<width>\fR,\fBh\fR=\fI<height>\fR[,\fBfps\fR=\fI<fps>\fR][,\fBhorfreq\fR=\fI<horfreq>\fR][,\fBpixclk\fR=\fI<pixclk>\fR]
309 [,\fBinterlaced\fR][,\fBoverscan\fR][,\fBsecondary\fR][,\fBC\fR=\fI<c>\fR][,\fBM\fR=\fI<m>\fR][,\fBK\fR=\fI<k>\fR][,\fBJ\fR=\fI<j>\fR]
310 .br
311 Calculate the GTF timings for the given format.
312
313 \fI<width>\fR is the width in pixels, \fI<height>\fR is the frame (not field!) height in lines.
314 .br
315 \fI<fps>\fR is frames per second for progressive timings and fields per second for interlaced timings.
316 .br
317 \fI<horfreq>\fR is the horizontal frequency in kHz.
318 .br
319 \fI<pixclk>\fR is the pixel clock frequency in MHz.
320 Only one of \fBfps\fR, \fBhorfreq\fR or \fBpixclk\fR must be given.
321 .br
322 If \fBinterlaced\fR is given, then this is an interlaced format.
323 .br
324 If \fBoverscan\fR is given, then this is an overscanned format. I.e., margins are required.
325 .br
326 If \fBsecondary\fR is given, then the secondary GTF is used for
327 reduced blanking, where \fI<c>\fR, \fI<m>\fR, \fI<k>\fR and \fI<j>\fR are parameters
328 for the secondary curve. If none of the secondary curve parameters
329 were set, and an EDID file is passed as command line option, then the
330 secondary curve parameters are read from that EDID.
331 .br
332 The default secondary curve parameters are 40 for \fI<c>\fR, 600 for \fI<m>\fR,
333 128 for \fI<k>\fR and 20 for \fI<j>\fR.
334 These values correspond to the normal curve that GTF uses.
335 .TP
336 \fB\-\-ovt\fR (\fBrid\fR=\fI<rid>\fR|\fBw\fR=\fI<width>\fR,\fBh\fR=\fI<height>\fR),\fBfps\fR=\fI<fps>\fR
337 Calculate the OVT timings for the given format.
338 Either specify a \fI<rid>\fR or specify \fI<width>\fR and \fI<height>\fR.
339 \fI<fps>\fR is frames per second.
340 .TP
341 \fB\-\-list\-established\-timings\fR
342 List all known Established Timings.
343 .TP
344 \fB\-\-list\-dmts\fR
345 List all known DMTs.
346 .TP
347 \fB\-\-list\-vics\fR
348 List all known VICs.
349 .TP
350 \fB\-\-list\-hdmi\-vics\fR
351 List all known HDMI VICs.
352 .TP
353 \fB\-\-list\-rids\fR
354 List all known CTA-861 RIDs.
355 .TP
356 \fB\-\-list\-rid\-timings\fR \fI<rid>\fR
357 List all timings for the specified \fI<rid>\fR or all known RIDs if \fI<rid>\fR is 0.
358
230359 .PP
231360 .SH NOTES
232 Not all fields are decoded, or decoded completely. Some fields' decoding
233 may appear to corrupt the output (for example, detailed string sections
234 have their contents printed literally).
361 Not all fields are decoded, or decoded completely.
235362 .B edid-decode
236363 does attempt to validate its input against the relevant standards, but its
237364 opinions have not been double-checked with the relevant standards bodies,
4141 enum Option {
4242 OptCheck = 'c',
4343 OptCheckInline = 'C',
44 OptFBModeTimings = 'F',
4445 OptHelp = 'h',
45 OptNativeTimings = 'n',
46 OptOnlyHexDump = 'H',
47 OptLongTimings = 'L',
48 OptNativeResolution = 'n',
49 OptNTSC = 'N',
4650 OptOutputFormat = 'o',
4751 OptPreferredTimings = 'p',
4852 OptPhysicalAddress = 'P',
49 OptLongTimings = 'L',
53 OptSkipHexDump = 's',
5054 OptShortTimings = 'S',
51 OptFBModeTimings = 'F',
55 OptV4L2Timings = 'V',
5256 OptXModeLineTimings = 'X',
53 OptV4L2Timings = 'V',
54 OptSkipHexDump = 's',
5557 OptSkipSHA = 128,
5658 OptHideSerialNumbers,
5759 OptVersion,
60 OptDiag,
61 OptSTD,
62 OptDMT,
63 OptVIC,
64 OptHDMIVIC,
65 OptCVT,
66 OptGTF,
67 OptOVT,
68 OptListEstTimings,
69 OptListDMTs,
70 OptListVICs,
71 OptListHDMIVICs,
72 OptListRIDTimings,
73 OptListRIDs,
5874 OptLast = 256
5975 };
6076
6379 static struct option long_options[] = {
6480 { "help", no_argument, 0, OptHelp },
6581 { "output-format", required_argument, 0, OptOutputFormat },
66 { "native-timings", no_argument, 0, OptNativeTimings },
82 { "native-resolution", no_argument, 0, OptNativeResolution },
6783 { "preferred-timings", no_argument, 0, OptPreferredTimings },
6884 { "physical-address", no_argument, 0, OptPhysicalAddress },
6985 { "skip-hex-dump", no_argument, 0, OptSkipHexDump },
86 { "only-hex-dump", no_argument, 0, OptOnlyHexDump },
7087 { "skip-sha", no_argument, 0, OptSkipSHA },
7188 { "hide-serial-numbers", no_argument, 0, OptHideSerialNumbers },
7289 { "version", no_argument, 0, OptVersion },
7491 { "check", no_argument, 0, OptCheck },
7592 { "short-timings", no_argument, 0, OptShortTimings },
7693 { "long-timings", no_argument, 0, OptLongTimings },
94 { "ntsc", no_argument, 0, OptNTSC },
7795 { "xmodeline", no_argument, 0, OptXModeLineTimings },
7896 { "fbmode", no_argument, 0, OptFBModeTimings },
7997 { "v4l2-timings", no_argument, 0, OptV4L2Timings },
98 { "diagonal", required_argument, 0, OptDiag },
99 { "std", required_argument, 0, OptSTD },
100 { "dmt", required_argument, 0, OptDMT },
101 { "vic", required_argument, 0, OptVIC },
102 { "hdmi-vic", required_argument, 0, OptHDMIVIC },
103 { "cvt", required_argument, 0, OptCVT },
104 { "gtf", required_argument, 0, OptGTF },
105 { "ovt", required_argument, 0, OptOVT },
106 { "list-established-timings", no_argument, 0, OptListEstTimings },
107 { "list-dmts", no_argument, 0, OptListDMTs },
108 { "list-vics", no_argument, 0, OptListVICs },
109 { "list-hdmi-vics", no_argument, 0, OptListHDMIVICs },
110 { "list-rid-timings", required_argument, 0, OptListRIDTimings },
111 { "list-rids", no_argument, 0, OptListRIDs },
80112 { 0, 0, 0, 0 }
81113 };
82114
89121 " if the output filename is '-'.\n"
90122 "\nOptions:\n"
91123 " -o, --output-format <fmt>\n"
92 " if [out] is specified, then write the EDID in this format\n"
124 " If [out] is specified, then write the EDID in this format.\n"
93125 " <fmt> is one of:\n"
94126 " hex: hex numbers in ascii text (default for stdout)\n"
95127 " raw: binary data (default unless writing to stdout)\n"
96128 " carray: c-program struct\n"
97129 " xml: XML data\n"
98 " -c, --check check if the EDID conforms to the standards, failures and\n"
130 " -c, --check Check if the EDID conforms to the standards, failures and\n"
99131 " warnings are reported at the end.\n"
100 " -C, --check-inline check if the EDID conforms to the standards, failures and\n"
132 " -C, --check-inline Check if the EDID conforms to the standards, failures and\n"
101133 " warnings are reported inline.\n"
102 " -n, --native-timings report the native timings\n"
103 " -p, --preferred-timings report the preferred timings\n"
104 " -P, --physical-address only report the CEC physical address\n"
105 " -S, --short-timings report all video timings in a short format\n"
106 " -L, --long-timings report all video timings in a long format\n"
107 " -X, --xmodeline report all long video timings in Xorg.conf format\n"
108 " -F, --fbmode report all long video timings in fb.modes format\n"
109 " -V, --v4l2-timings report all long video timings in v4l2-dv-timings.h format\n"
110 " -s, --skip-hex-dump skip the initial hex dump of the EDID\n"
111 " --skip-sha skip the SHA report\n"
112 " --hide-serial-numbers replace serial numbers with '...'\n"
113 " --version show the edid-decode version (SHA)\n"
114 " -h, --help display this help message\n");
134 " -n, --native-resolution Report the native resolution.\n"
135 " -p, --preferred-timings Report the preferred timings.\n"
136 " -P, --physical-address Only report the CEC physical address.\n"
137 " -S, --short-timings Report all video timings in a short format.\n"
138 " -L, --long-timings Report all video timings in a long format.\n"
139 " -N, --ntsc Report the video timings suitable for NTSC-based video.\n"
140 " -X, --xmodeline Report all long video timings in Xorg.conf format.\n"
141 " -F, --fbmode Report all long video timings in fb.modes format.\n"
142 " -V, --v4l2-timings Report all long video timings in v4l2-dv-timings.h format.\n"
143 " -s, --skip-hex-dump Skip the initial hex dump of the EDID.\n"
144 " -H, --only-hex-dump Only output the hex dump of the EDID.\n"
145 " --skip-sha Skip the SHA report.\n"
146 " --hide-serial-numbers Replace serial numbers with '...'.\n"
147 " --version Show the edid-decode version (SHA).\n"
148 " --diagonal <inches> Set the display's diagonal in inches.\n"
149 " --std <byte1>,<byte2> Show the standard timing represented by these two bytes.\n"
150 " --dmt <dmt> Show the timings for the DMT with the given DMT ID.\n"
151 " --vic <vic> Show the timings for this VIC.\n"
152 " --hdmi-vic <hdmivic> Show the timings for this HDMI VIC.\n"
153 " --cvt w=<width>,h=<height>,fps=<fps>[,rb=<rb>][,interlaced][,overscan][,alt][,hblank=<hblank>][,vblank=<vblank>][,early-vsync]\n"
154 " Calculate the CVT timings for the given format.\n"
155 " <fps> is frames per second for progressive timings,\n"
156 " or fields per second for interlaced timings.\n"
157 " <rb> can be 0 (no reduced blanking, default), or\n"
158 " 1-3 for the reduced blanking version.\n"
159 " If 'interlaced' is given, then this is an interlaced format.\n"
160 " If 'overscan' is given, then this is an overscanned format.\n"
161 " If 'alt' is given and <rb>=2, then report the timings\n"
162 " optimized for video: 1000 / 1001 * <fps>.\n"
163 " If 'alt' is given and <rb>=3, then the horizontal blanking\n"
164 " is 160 instead of 80 pixels.\n"
165 " If 'hblank' is given and <rb>=3, then the horizontal blanking\n"
166 " is <hblank> pixels (range of 80-200), overriding 'alt'.\n"
167 " If 'vblank' is given and <rb>=3, then the vertical blanking\n"
168 " time is <vblank> microseconds (range of 460-705).\n"
169 " If 'early-vsync' is given and <rb=3>, then select early vsync.\n"
170 " --gtf w=<width>,h=<height>[,fps=<fps>][,horfreq=<horfreq>][,pixclk=<pixclk>][,interlaced]\n"
171 " [,overscan][,secondary][,C=<c>][,M=<m>][,K=<k>][,J=<j>]\n"
172 " Calculate the GTF timings for the given format.\n"
173 " <fps> is frames per second for progressive timings,\n"
174 " or fields per second for interlaced timings.\n"
175 " <horfreq> is the horizontal frequency in kHz.\n"
176 " <pixclk> is the pixel clock frequency in MHz.\n"
177 " Only one of fps, horfreq or pixclk must be given.\n"
178 " If 'interlaced' is given, then this is an interlaced format.\n"
179 " If 'overscan' is given, then this is an overscanned format.\n"
180 " If 'secondary' is given, then the secondary GTF is used for\n"
181 " reduced blanking, where <c>, <m>, <k> and <j> are parameters\n"
182 " for the secondary curve.\n"
183 " --ovt (rid=<rid>|w=<width>,h=<height>),fps=<fps>\n"
184 " Calculate the OVT timings for the given format.\n"
185 " Either specify a RID or explicitly specify width and height.\n"
186 " --list-established-timings List all known Established Timings.\n"
187 " --list-dmts List all known DMTs.\n"
188 " --list-vics List all known VICs.\n"
189 " --list-hdmi-vics List all known HDMI VICs.\n"
190 " --list-rids List all known RIDs.\n"
191 " --list-rid-timings <rid> List all timings for RID <rid> or all known RIDs if <rid> is 0.\n"
192 " -h, --help Display this help message.\n");
115193 }
116194
117195 static std::string s_msgs[EDID_MAX_BLOCKS + 1][2];
175253 printf("\n");
176254 }
177255
178 static unsigned gcd(unsigned a, unsigned b)
256 unsigned gcd(unsigned a, unsigned b)
179257 {
180258 while (b) {
181259 unsigned t = b;
200278
201279 std::string edid_state::dtd_type(unsigned cnt)
202280 {
203 unsigned len = std::to_string(cta.preparse_total_dtds).length();
281 unsigned len = std::to_string(cta.preparsed_total_dtds).length();
204282 char buf[16];
205283 sprintf(buf, "DTD %*u", len, cnt);
206284 return buf;
238316 num_flags++;
239317 }
240318
319 /*
320 * Return true if the timings are a close, but not identical,
321 * match. The only differences allowed are polarities and
322 * porches and syncs, provided the total blanking remains the
323 * same.
324 */
325 bool timings_close_match(const timings &t1, const timings &t2)
326 {
327 // We don't want to deal with borders, you're on your own
328 // if you are using those.
329 if (t1.hborder || t1.vborder ||
330 t2.hborder || t2.vborder)
331 return false;
332 if (t1.hact != t2.hact || t1.vact != t2.vact ||
333 t1.interlaced != t2.interlaced ||
334 t1.pixclk_khz != t2.pixclk_khz ||
335 t1.hfp + t1.hsync + t1.hbp != t2.hfp + t2.hsync + t2.hbp ||
336 t1.vfp + t1.vsync + t1.vbp != t2.vfp + t2.vsync + t2.vbp)
337 return false;
338 if (t1.hfp == t2.hfp &&
339 t1.hsync == t2.hsync &&
340 t1.hbp == t2.hbp &&
341 t1.pos_pol_hsync == t2.pos_pol_hsync &&
342 t1.vfp == t2.vfp &&
343 t1.vsync == t2.vsync &&
344 t1.vbp == t2.vbp &&
345 t1.pos_pol_vsync == t2.pos_pol_vsync)
346 return false;
347 return true;
348 }
349
241350 static void print_modeline(unsigned indent, const struct timings *t, double refresh)
242351 {
243352 unsigned offset = (!t->even_vtotal && t->interlaced) ? 1 : 0;
353 unsigned hfp = t->hborder + t->hfp;
354 unsigned hbp = t->hborder + t->hbp;
355 unsigned vfp = t->vborder + t->vfp;
356 unsigned vbp = t->vborder + t->vbp;
244357
245358 printf("%*sModeline \"%ux%u_%.2f%s\" %.3f %u %u %u %u %u %u %u %u %cHSync",
246359 indent, "",
247360 t->hact, t->vact, refresh,
248361 t->interlaced ? "i" : "", t->pixclk_khz / 1000.0,
249 t->hact, t->hact + t->hfp, t->hact + t->hfp + t->hsync,
250 t->hact + t->hfp + t->hsync + t->hbp,
251 t->vact, t->vact + t->vfp, t->vact + t->vfp + t->vsync,
252 t->vact + t->vfp + t->vsync + t->vbp + offset,
362 t->hact, t->hact + hfp, t->hact + hfp + t->hsync,
363 t->hact + hfp + t->hsync + hbp,
364 t->vact, t->vact + vfp, t->vact + vfp + t->vsync,
365 t->vact + vfp + t->vsync + vbp + offset,
253366 t->pos_pol_hsync ? '+' : '-');
254367 if (!t->no_pol_vsync)
255368 printf(" %cVSync", t->pos_pol_vsync ? '+' : '-');
274387 t->hact, t->vact, t->hact, t->vact);
275388 unsigned mult = t->interlaced ? 2 : 1;
276389 unsigned offset = !t->even_vtotal && t->interlaced;
390 unsigned hfp = t->hborder + t->hfp;
391 unsigned hbp = t->hborder + t->hbp;
392 unsigned vfp = t->vborder + t->vfp;
393 unsigned vbp = t->vborder + t->vbp;
277394 printf("%*stimings %llu %d %d %d %u %u %u\n",
278395 indent + 8, "",
279396 (unsigned long long)(1000000000.0 / (double)(t->pixclk_khz) + 0.5),
280 t->hbp, t->hfp, mult * t->vbp, mult * t->vfp + offset, t->hsync, mult * t->vsync);
397 hbp, hfp, mult * vbp, mult * vfp + offset, t->hsync, mult * t->vsync);
281398 if (t->interlaced)
282399 printf("%*slaced true\n", indent + 8, "");
283400 if (t->pos_pol_hsync)
304421 printf("V4L2_DV_HSYNC_POS_POL, \\\n");
305422 else
306423 printf("V4L2_DV_VSYNC_POS_POL, \\\n");
424 unsigned hfp = t->hborder + t->hfp;
425 unsigned hbp = t->hborder + t->hbp;
426 unsigned vfp = t->vborder + t->vfp;
427 unsigned vbp = t->vborder + t->vbp;
307428 printf("\t\t\t%lluULL, %d, %u, %d, %u, %u, %d, %u, %u, %d, \\\n",
308 t->pixclk_khz * 1000ULL, t->hfp, t->hsync, t->hbp,
309 t->vfp, t->vsync, t->vbp,
310 t->interlaced ? t->vfp : 0,
429 t->pixclk_khz * 1000ULL, hfp, t->hsync, hbp,
430 vfp, t->vsync, vbp,
431 t->interlaced ? vfp : 0,
311432 t->interlaced ? t->vsync : 0,
312 t->interlaced ? t->vbp + !t->even_vtotal : 0);
433 t->interlaced ? vbp + !t->even_vtotal : 0);
313434
314435 std::string flags;
315436 unsigned num_flags = 0;
356477
357478 static void print_detailed_timing(unsigned indent, const struct timings *t)
358479 {
359 printf("%*sHfront %4d Hsync %3u Hback %3d Hpol %s",
480 printf("%*sHfront %4d Hsync %3u Hback %4d Hpol %s",
360481 indent, "",
361482 t->hfp, t->hsync, t->hbp, t->pos_pol_hsync ? "P" : "N");
362483 if (t->hborder)
363484 printf(" Hborder %u", t->hborder);
364485 printf("\n");
365486
366 printf("%*sVfront %4u Vsync %3u Vback %3d",
487 printf("%*sVfront %4u Vsync %3u Vback %4d",
367488 indent, "", t->vfp, t->vsync, t->vbp);
368489 if (!t->no_pol_vsync)
369490 printf(" Vpol %s", t->pos_pol_vsync ? "P" : "N");
373494 printf(" Both Fields");
374495 } else if (t->interlaced) {
375496 printf(" Vfront +0.5 Odd Field\n");
376 printf("%*sVfront %4d Vsync %3u Vback %3d",
497 printf("%*sVfront %4d Vsync %3u Vback %4d",
377498 indent, "", t->vfp, t->vsync, t->vbp);
378499 if (!t->no_pol_vsync)
379500 printf(" Vpol %s", t->pos_pol_vsync ? "P" : "N");
386507
387508 bool edid_state::print_timings(const char *prefix, const struct timings *t,
388509 const char *type, const char *flags,
389 bool detailed)
510 bool detailed, bool do_checks)
390511 {
391512 if (!t) {
392513 // Should not happen
393 fail("Unknown video timings.\n");
514 if (do_checks)
515 fail("Unknown video timings.\n");
394516 return false;
395517 }
396518
400522 detailed = true;
401523
402524 unsigned vact = t->vact;
403 unsigned hbl = t->hfp + t->hsync + t->hbp;
404 unsigned vbl = t->vfp + t->vsync + t->vbp;
525 unsigned hbl = t->hfp + t->hsync + t->hbp + 2 * t->hborder;
526 unsigned vbl = t->vfp + t->vsync + t->vbp + 2 * t->vborder;
405527 unsigned htotal = t->hact + hbl;
406528 double hor_freq_khz = htotal ? (double)t->pixclk_khz / htotal : 0;
407529
408530 if (t->interlaced)
409531 vact /= 2;
410532
533 double out_hor_freq_khz = hor_freq_khz;
411534 if (t->ycbcr420)
412535 hor_freq_khz /= 2;
413536
417540
418541 if (!t->hact || !hbl || !t->hfp || !t->hsync ||
419542 !vact || !vbl || (!t->vfp && !t->interlaced && !t->even_vtotal) || !t->vsync) {
420 fail("0 values in the video timing:\n"
421 " Horizontal Active/Blanking %u/%u\n"
422 " Horizontal Frontporch/Sync Width %u/%u\n"
423 " Vertical Active/Blanking %u/%u\n"
424 " Vertical Frontporch/Sync Width %u/%u\n",
425 t->hact, hbl, t->hfp, t->hsync, vact, vbl, t->vfp, t->vsync);
543 if (do_checks)
544 fail("0 values in the video timing:\n"
545 " Horizontal Active/Blanking %u/%u\n"
546 " Horizontal Frontporch/Sync Width %u/%u\n"
547 " Vertical Active/Blanking %u/%u\n"
548 " Vertical Frontporch/Sync Width %u/%u\n",
549 t->hact, hbl, t->hfp, t->hsync, vact, vbl, t->vfp, t->vsync);
426550 ok = false;
427551 }
428552
431555 else if (t->interlaced)
432556 vtotal = vact + t->vfp + t->vsync + t->vbp + 0.5;
433557
434 double refresh = (double)t->pixclk_khz * 1000.0 / (htotal * vtotal);
558 double refresh = t->pixclk_khz * 1000.0 / (htotal * vtotal);
559 double pixclk = t->pixclk_khz * 1000.0;
560 if (options[OptNTSC] && fmod(refresh, 6.0) == 0) {
561 const double ntsc_fact = 1000.0 / 1001.0;
562 pixclk *= ntsc_fact;
563 refresh *= ntsc_fact;
564 out_hor_freq_khz *= ntsc_fact;
565 }
435566
436567 std::string s;
437 if (t->rb) {
568 unsigned rb = t->rb & ~RB_ALT;
569 if (rb) {
570 bool alt = t->rb & RB_ALT;
438571 s = "RB";
439 if (t->rb == 2)
440 s += "v2";
441 else if (t->rb == 3)
442 s += "v3";
572 if (rb == RB_CVT_V2)
573 s += std::string("v2") + (alt ? ",video-optimized" : "");
574 else if (rb == RB_CVT_V3)
575 s += std::string("v3") + (alt ? ",h-blank-160" : "");
443576 }
444577 add_str(s, flags);
445578 if (t->hsize_mm || t->vsize_mm)
446579 add_str(s, std::to_string(t->hsize_mm) + " mm x " + std::to_string(t->vsize_mm) + " mm");
580 if (t->hsize_mm > dtd_max_hsize_mm)
581 dtd_max_hsize_mm = t->hsize_mm;
582 if (t->vsize_mm > dtd_max_vsize_mm)
583 dtd_max_vsize_mm = t->vsize_mm;
447584 if (!s.empty())
448585 s = " (" + s + ")";
449586 unsigned pixclk_khz = t->pixclk_khz / (t->ycbcr420 ? 2 : 1);
451588 char buf[10];
452589
453590 sprintf(buf, "%u%s", t->vact, t->interlaced ? "i" : "");
454 printf("%s%s: %5ux%-5s %7.3f Hz %3u:%-3u %7.3f kHz %7.3f MHz%s\n",
591 printf("%s%s: %5ux%-5s %10.6f Hz %3u:%-3u %8.3f kHz %13.6f MHz%s\n",
455592 prefix, type,
456593 t->hact, buf,
457594 refresh,
458595 t->hratio, t->vratio,
459 hor_freq_khz,
460 pixclk_khz / 1000.0,
596 out_hor_freq_khz,
597 pixclk / 1000000.0,
461598 s.c_str());
462599
463600 unsigned len = strlen(prefix) + 2;
471608 else if (detailed)
472609 print_detailed_timing(len + strlen(type) + 6, t);
473610
611 if (!do_checks)
612 return ok;
613
614 if (!memcmp(type, "DTD", 3)) {
615 unsigned vic, dmt;
616 const timings *vic_t = cta_close_match_to_vic(*t, vic);
617
618 if (vic_t)
619 warn("DTD is similar but not identical to VIC %u.\n", vic);
620
621 const timings *dmt_t = close_match_to_dmt(*t, dmt);
622 if (!vic_t && dmt_t)
623 warn("DTD is similar but not identical to DMT 0x%02x.\n", dmt);
624 }
625
626 if (refresh) {
627 min_vert_freq_hz = min(min_vert_freq_hz, refresh);
628 max_vert_freq_hz = max(max_vert_freq_hz, refresh);
629 }
630 if (hor_freq_khz) {
631 min_hor_freq_hz = min(min_hor_freq_hz, hor_freq_khz * 1000.0);
632 max_hor_freq_hz = max(max_hor_freq_hz, hor_freq_khz * 1000.0);
633 max_pixclk_khz = max(max_pixclk_khz, pixclk_khz);
634 if (t->pos_pol_hsync && !t->pos_pol_vsync && t->vsync == 3)
635 base.max_pos_neg_hor_freq_khz = hor_freq_khz;
636 }
637
474638 if (t->ycbcr420 && t->pixclk_khz < 590000)
475 warn_once("Some YCbCr 4:2:0 timings are invalid for HDMI (which requires an RGB timings pixel rate >= 590 MHz).\n");
639 warn_once("Some YCbCr 4:2:0 timings are invalid for HDMI 2.1 (which requires an RGB timings pixel rate >= 590 MHz).\n");
476640 if (t->hfp <= 0)
477641 fail("0 or negative horizontal front porch.\n");
478642 if (t->hbp <= 0)
479643 fail("0 or negative horizontal back porch.\n");
480644 if (t->vbp <= 0)
481645 fail("0 or negative vertical back porch.\n");
482 if ((!base.max_display_width_mm && t->hsize_mm) ||
483 (!base.max_display_height_mm && t->vsize_mm)) {
484 fail("Mismatch of image size vs display size: image size is set, but not display size.\n");
646 if (!base.max_display_width_mm && !base.max_display_height_mm) {
647 /* this is valid */
485648 } else if (!t->hsize_mm && !t->vsize_mm) {
486649 /* this is valid */
487650 } else if (t->hsize_mm > base.max_display_width_mm + 9 ||
493656 fail("Mismatch of image size %ux%u mm vs display size %ux%u mm.\n",
494657 t->hsize_mm, t->vsize_mm, base.max_display_width_mm, base.max_display_height_mm);
495658 }
496 if (refresh) {
497 min_vert_freq_hz = min(min_vert_freq_hz, refresh);
498 max_vert_freq_hz = max(max_vert_freq_hz, refresh);
499 }
500 if (pixclk_khz && (t->hact + hbl)) {
501 min_hor_freq_hz = min(min_hor_freq_hz, (pixclk_khz * 1000) / (t->hact + hbl));
502 max_hor_freq_hz = max(max_hor_freq_hz, (pixclk_khz * 1000) / (t->hact + hbl));
503 max_pixclk_khz = max(max_pixclk_khz, pixclk_khz);
504 }
505659 return ok;
660 }
661
662 std::string containerid2s(const unsigned char *x)
663 {
664 char buf[40];
665
666 sprintf(buf, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
667 x[0], x[1], x[2], x[3],
668 x[4], x[5],
669 x[6], x[7],
670 x[8], x[9],
671 x[10], x[11], x[12], x[13], x[14], x[15]);
672 return buf;
506673 }
507674
508675 std::string utohex(unsigned char x)
513680 return buf;
514681 }
515682
516 const char *oui_name(unsigned oui, bool reverse)
517 {
518 if (reverse)
519 oui = (oui >> 16) | (oui & 0xff00) | ((oui & 0xff) << 16);
520
683 const char *oui_name(unsigned oui, unsigned *ouinum)
684 {
685 unsigned ouinumscratch;
686 if (!ouinum) ouinum = &ouinumscratch;
687 const char *name;
521688 switch (oui) {
522 case 0x00001a: return "AMD";
523 case 0x000c03: return "HDMI";
524 case 0x00044b: return "NVIDIA";
525 case 0x000c6e: return "ASUS";
526 case 0x0010fa: return "Apple";
527 case 0x0014b9: return "MSTAR";
528 case 0x00d046: return "Dolby";
529 case 0x00e047: return "InFocus";
530 case 0x3a0292: return "VESA";
531 case 0x90848b: return "HDR10+";
532 case 0xc45dd8: return "HDMI Forum";
533 case 0xca125c: return "Microsoft";
534 default: return NULL;
689 #define oneoui(c,k,n) case c: *ouinum = kOUI_##k; name = n; break;
690 #include "oui.h"
691 default: *ouinum = 0; name = NULL; break;
692 }
693 return name;
694 }
695
696 void edid_state::data_block_oui(std::string block_name, const unsigned char *x,
697 unsigned length, unsigned *ouinum, bool ignorezeros, bool do_ascii, bool big_endian)
698 {
699 std::string buf;
700 char ascii[4];
701 unsigned oui;
702 const char *ouiname = NULL;
703 bool matched_reverse = false;
704 bool matched_ascii = false;
705 bool valid_ascii = false;
706
707 if (big_endian)
708 oui = ((length > 0 ? x[0] : 0) << 16) + ((length > 1 ? x[1] : 0) << 8) + (length > 2 ? x[2] : 0);
709 else
710 oui = ((length > 2 ? x[2] : 0) << 16) + ((length > 1 ? x[1] : 0) << 8) + (length > 0 ? x[0] : 0);
711
712 buf = ouitohex(oui);
713 if (length < 3) {
714 sprintf(ascii, "?"); // some characters are null
715 if (ouinum) *ouinum = 0; // doesn't match a known OUI
716 } else {
717 valid_ascii = (x[0] >= 'A' && x[1] >= 'A' && x[2] >= 'A' && x[0] <= 'Z' && x[1] <= 'Z' && x[2] <= 'Z');
718 sprintf(ascii, "%c%c%c", x[0], x[1], x[2]);
719
720 ouiname = oui_name(oui, ouinum);
721 if (!ouiname) {
722 big_endian = !big_endian;
723 unsigned reversedoui = ((oui & 0xff) << 16) + (oui & 0x00ff00) + (oui >> 16);
724 ouiname = oui_name(reversedoui, ouinum);
725 if (ouiname) {
726 oui = reversedoui;
727 buf = ouitohex(oui);
728 matched_reverse = true;
729 } else if (do_ascii && valid_ascii) {
730 unsigned asciioui = (x[0] << 24) + (x[1] << 16) + (x[2] << 8);
731 ouiname = oui_name(asciioui, ouinum);
732 if (ouiname) {
733 matched_ascii = true;
734 }
735 }
736 }
737 }
738
739 std::string name;
740 if (ouiname) {
741 if (matched_ascii)
742 name = block_name + " (" + ouiname + ")" + ", PNP ID '" + ascii + "'";
743 else
744 name = block_name + " (" + ouiname + ")" + ", OUI " + buf;
745 } else if (do_ascii && valid_ascii) {
746 name = block_name + ", PNP ID '" + ascii + "'";
747 } else {
748 name = block_name + ", OUI " + buf;
749 }
750 // assign string to data_block before outputting errors
751 data_block = name;
752
753 if (oui || !ignorezeros) {
754 printf(" %s:\n", data_block.c_str());
755 if (length < 3)
756 fail("Data block length (%d) is not enough to contain an OUI.\n", length);
757 else if (ouiname) {
758 if (do_ascii && !valid_ascii)
759 warn("Expected PNP ID but found OUI.\n");
760 if (matched_reverse)
761 fail("Endian-ness (%s) of OUI is different than expected (%s).\n", big_endian ? "be" : "le", big_endian ? "le" : "be");
762 }
763 else {
764 if (valid_ascii)
765 warn("Unknown OUI %s (possible PNP %s).\n", buf.c_str(), ascii);
766 else
767 warn("Unknown OUI %s.\n", buf.c_str());
768 }
535769 }
536770 }
537771
555789 unsigned length, bool show_ascii, unsigned step)
556790 {
557791 unsigned i, j;
558
559 if (!length)
560 return;
561792
562793 for (i = 0; i < length; i += step) {
563794 unsigned len = min(step, length - i);
733964 edid_data.insert(edid_data.end(), buf, buf + i);
734965 }
735966
736 if (edid_data.empty())
967 if (edid_data.empty()) {
968 state.edid_size = 0;
737969 return false;
970 }
738971
739972 const char *data = &edid_data[0];
740973 const char *start;
9261159
9271160 odd_hex_digits = false;
9281161 if (!extract_edid(fd, error)) {
1162 if (!state.edid_size) {
1163 fprintf(error, "EDID of '%s' was empty.\n", from_file);
1164 return -1;
1165 }
9291166 fprintf(error, "EDID extract of '%s' failed: ", from_file);
9301167 if (odd_hex_digits)
9311168 fprintf(error, "odd number of hexadecimal digits.\n");
10721309 do_checksum("", x, EDID_PAGE_SIZE);
10731310 }
10741311
1312 void edid_state::print_preferred_timings()
1313 {
1314 if (base.preferred_timing.is_valid()) {
1315 printf("\n----------------\n");
1316 printf("\nPreferred Video Timing if only Block 0 is parsed:\n");
1317 print_timings(" ", base.preferred_timing, true, false);
1318 }
1319
1320 if (!cta.preferred_timings.empty()) {
1321 printf("\n----------------\n");
1322 printf("\nPreferred Video Timing%s if Block 0 and CTA-861 Blocks are parsed:\n",
1323 cta.preferred_timings.size() > 1 ? "s" : "");
1324 for (vec_timings_ext::iterator iter = cta.preferred_timings.begin();
1325 iter != cta.preferred_timings.end(); ++iter)
1326 print_timings(" ", *iter, true, false);
1327 }
1328
1329 if (!dispid.preferred_timings.empty()) {
1330 printf("\n----------------\n");
1331 printf("\nPreferred Video Timing%s if Block 0 and DisplayID Blocks are parsed:\n",
1332 dispid.preferred_timings.size() > 1 ? "s" : "");
1333 for (vec_timings_ext::iterator iter = dispid.preferred_timings.begin();
1334 iter != dispid.preferred_timings.end(); ++iter)
1335 print_timings(" ", *iter, true, false);
1336 }
1337 }
1338
1339 void edid_state::print_native_res()
1340 {
1341 typedef std::pair<unsigned, unsigned> resolution;
1342 typedef std::set<resolution> resolution_set;
1343 resolution_set native_prog, native_int;
1344 unsigned native_width = 0, native_height = 0;
1345 unsigned native_width_int = 0, native_height_int = 0;
1346
1347 // Note: it is also a mismatch if Block 0 does not define a
1348 // native resolution, but other blocks do.
1349 bool native_mismatch = false;
1350 bool native_int_mismatch = false;
1351
1352 if (base.preferred_timing.is_valid() && base.preferred_is_also_native) {
1353 if (base.preferred_timing.t.interlaced) {
1354 native_width_int = base.preferred_timing.t.hact;
1355 native_height_int = base.preferred_timing.t.vact;
1356 } else {
1357 native_width = base.preferred_timing.t.hact;
1358 native_height = base.preferred_timing.t.vact;
1359 }
1360 }
1361
1362 if (!native_width && dispid.native_width) {
1363 native_width = dispid.native_width;
1364 native_height = dispid.native_height;
1365 native_mismatch = true;
1366 } else if (dispid.native_width && native_width &&
1367 (dispid.native_width != native_width ||
1368 dispid.native_height != native_height)) {
1369 native_mismatch = true;
1370 }
1371
1372 for (vec_timings_ext::iterator iter = cta.native_timings.begin();
1373 iter != cta.native_timings.end(); ++iter) {
1374 if (iter->t.interlaced) {
1375 native_int.insert(std::pair<unsigned, unsigned>(iter->t.hact, iter->t.vact));
1376 if (!native_width_int) {
1377 native_width_int = iter->t.hact;
1378 native_height_int = iter->t.vact;
1379 native_int_mismatch = true;
1380 } else if (native_width_int &&
1381 (iter->t.hact != native_width_int ||
1382 iter->t.vact != native_height_int)) {
1383 native_int_mismatch = true;
1384 }
1385 } else {
1386 native_prog.insert(std::pair<unsigned, unsigned>(iter->t.hact, iter->t.vact));
1387 if (!native_width) {
1388 native_width = iter->t.hact;
1389 native_height = iter->t.vact;
1390 native_mismatch = true;
1391 } else if (native_width &&
1392 (iter->t.hact != native_width ||
1393 iter->t.vact != native_height)) {
1394 native_mismatch = true;
1395 }
1396 }
1397 }
1398
1399 if (diagonal) {
1400 if (image_width) {
1401 double w = image_width;
1402 double h = image_height;
1403 double d = sqrt(w * w + h * h) / 254.0;
1404
1405 if (fabs(diagonal - d) >= 0.1)
1406 warn("Specified diagonal is %.1f\", calculated diagonal is %.1f\".\n",
1407 diagonal, d);
1408 }
1409 if (native_width) {
1410 double w = native_width;
1411 double h = native_height;
1412 double d = diagonal * 254.0;
1413 double c = sqrt((d * d) / (w * w + h * h));
1414
1415 w *= c;
1416 h *= c;
1417
1418 if (image_width) {
1419 if (fabs((double)image_width - w) >= 100.0 ||
1420 fabs((double)image_height - h) >= 100.0)
1421 warn("Calculated image size is %.1fx%.1fmm, EDID image size is %.1fx%.1fmm.\n",
1422 w / 10.0, h / 10.0,
1423 image_width / 10.0, image_height / 10.0);
1424 } else {
1425 warn("No image size was specified, but it is calculated as %.1fx%.1fmm.\n",
1426 w / 10.0, h / 10.0);
1427 }
1428 }
1429 }
1430
1431 if (!options[OptNativeResolution])
1432 return;
1433
1434 if (native_width == 0 && native_width_int == 0) {
1435 printf("\n----------------\n");
1436 printf("\nNo Native Video Resolution was defined.\n");
1437 return;
1438 }
1439
1440 if ((native_width || native_width_int) &&
1441 !native_mismatch && !native_int_mismatch) {
1442 printf("\n----------------\n");
1443 printf("\nNative Video Resolution%s:\n",
1444 native_width && native_width_int ? "s" : "");
1445 if (native_width)
1446 printf(" %ux%u\n", native_width, native_height);
1447 if (native_width_int)
1448 printf(" %ux%ui\n", native_width_int, native_height_int);
1449 return;
1450 }
1451
1452 if (base.preferred_timing.is_valid() && base.preferred_is_also_native) {
1453 printf("\n----------------\n");
1454 printf("\nNative Video Resolution if only Block 0 is parsed:\n");
1455 printf(" %ux%u%s\n",
1456 base.preferred_timing.t.hact, base.preferred_timing.t.vact,
1457 base.preferred_timing.t.interlaced ? "i" : "");
1458 }
1459
1460 if (!cta.native_timings.empty()) {
1461 printf("\n----------------\n");
1462 printf("\nNative Video Resolution%s if Block 0 and CTA-861 Blocks are parsed:\n",
1463 native_prog.size() + native_int.size() > 1 ? "s" : "");
1464 for (resolution_set::iterator iter = native_prog.begin();
1465 iter != native_prog.end(); ++iter)
1466 printf(" %ux%u\n", iter->first, iter->second);
1467 for (resolution_set::iterator iter = native_int.begin();
1468 iter != native_int.end(); ++iter)
1469 printf(" %ux%ui\n", iter->first, iter->second);
1470 }
1471
1472 if (dispid.native_width) {
1473 printf("\n----------------\n");
1474 printf("\nNative Video Resolution if the DisplayID Blocks are parsed:\n");
1475 printf(" %ux%u\n", dispid.native_width, dispid.native_height);
1476 }
1477 }
1478
10751479 int edid_state::parse_edid()
10761480 {
10771481 hide_serial_numbers = options[OptHideSerialNumbers];
10921496 printf("edid-decode (hex):\n\n");
10931497 for (unsigned i = 0; i < num_blocks; i++) {
10941498 hex_block("", edid + i * EDID_PAGE_SIZE, EDID_PAGE_SIZE, false);
1499 if (i == num_blocks - 1 && options[OptOnlyHexDump])
1500 return 0;
10951501 printf("\n");
10961502 }
10971503 printf("----------------\n\n");
11131519 if (has_cta)
11141520 cta_resolve_svrs();
11151521
1116 if (options[OptPreferredTimings] && base.preferred_timing.is_valid()) {
1117 printf("\n----------------\n");
1118 printf("\nPreferred Video Timing if only Block 0 is parsed:\n");
1119 print_timings(" ", base.preferred_timing, true);
1120 }
1121
1122 if (options[OptNativeTimings] &&
1123 base.preferred_timing.is_valid() && base.preferred_is_also_native) {
1124 printf("\n----------------\n");
1125 printf("\nNative Video Timing if only Block 0 is parsed:\n");
1126 print_timings(" ", base.preferred_timing, true);
1127 }
1128
1129 if (options[OptPreferredTimings] && !cta.preferred_timings.empty()) {
1130 printf("\n----------------\n");
1131 printf("\nPreferred Video Timing%s if Block 0 and CTA-861 Blocks are parsed:\n",
1132 cta.preferred_timings.size() > 1 ? "s" : "");
1133 for (vec_timings_ext::iterator iter = cta.preferred_timings.begin();
1134 iter != cta.preferred_timings.end(); ++iter)
1135 print_timings(" ", *iter, true);
1136 }
1137
1138 if (options[OptNativeTimings] && !cta.native_timings.empty()) {
1139 printf("\n----------------\n");
1140 printf("\nNative Video Timing%s if Block 0 and CTA-861 Blocks are parsed:\n",
1141 cta.native_timings.size() > 1 ? "s" : "");
1142 for (vec_timings_ext::iterator iter = cta.native_timings.begin();
1143 iter != cta.native_timings.end(); ++iter)
1144 print_timings(" ", *iter, true);
1145 }
1146
1147 if (options[OptPreferredTimings] && !dispid.preferred_timings.empty()) {
1148 printf("\n----------------\n");
1149 printf("\nPreferred Video Timing%s if Block 0 and DisplayID Blocks are parsed:\n",
1150 dispid.preferred_timings.size() > 1 ? "s" : "");
1151 for (vec_timings_ext::iterator iter = dispid.preferred_timings.begin();
1152 iter != dispid.preferred_timings.end(); ++iter)
1153 print_timings(" ", *iter, true);
1154 }
1522 if (options[OptPreferredTimings])
1523 print_preferred_timings();
1524
1525 print_native_res();
11551526
11561527 if (!options[OptCheck] && !options[OptCheckInline])
11571528 return 0;
11781549 return failures ? -2 : 0;
11791550 }
11801551
1552 enum cvt_opts {
1553 CVT_WIDTH = 0,
1554 CVT_HEIGHT,
1555 CVT_FPS,
1556 CVT_INTERLACED,
1557 CVT_OVERSCAN,
1558 CVT_RB,
1559 CVT_ALT,
1560 CVT_RB_H_BLANK,
1561 CVT_RB_V_BLANK,
1562 CVT_EARLY_VSYNC,
1563 };
1564
1565 static int parse_cvt_subopt(char **subopt_str, double *value)
1566 {
1567 int opt;
1568 char *opt_str;
1569
1570 static const char * const subopt_list[] = {
1571 "w",
1572 "h",
1573 "fps",
1574 "interlaced",
1575 "overscan",
1576 "rb",
1577 "alt",
1578 "hblank",
1579 "vblank",
1580 "early-vsync",
1581 nullptr
1582 };
1583
1584 opt = getsubopt(subopt_str, (char* const*) subopt_list, &opt_str);
1585
1586 if (opt == -1) {
1587 fprintf(stderr, "Invalid suboptions specified.\n");
1588 usage();
1589 std::exit(EXIT_FAILURE);
1590 }
1591 if (opt_str == nullptr && opt != CVT_INTERLACED && opt != CVT_ALT &&
1592 opt != CVT_OVERSCAN && opt != CVT_EARLY_VSYNC) {
1593 fprintf(stderr, "No value given to suboption <%s>.\n",
1594 subopt_list[opt]);
1595 usage();
1596 std::exit(EXIT_FAILURE);
1597 }
1598
1599 if (opt_str)
1600 *value = strtod(opt_str, nullptr);
1601 return opt;
1602 }
1603
1604 static void parse_cvt(char *optarg)
1605 {
1606 unsigned w = 0, h = 0;
1607 double fps = 0;
1608 unsigned rb = RB_NONE;
1609 unsigned rb_h_blank = 0;
1610 unsigned rb_v_blank = 460;
1611 bool interlaced = false;
1612 bool alt = false;
1613 bool overscan = false;
1614 bool early_vsync = false;
1615
1616 while (*optarg != '\0') {
1617 int opt;
1618 double opt_val;
1619
1620 opt = parse_cvt_subopt(&optarg, &opt_val);
1621
1622 switch (opt) {
1623 case CVT_WIDTH:
1624 w = round(opt_val);
1625 break;
1626 case CVT_HEIGHT:
1627 h = round(opt_val);
1628 break;
1629 case CVT_FPS:
1630 fps = opt_val;
1631 break;
1632 case CVT_RB:
1633 rb = opt_val;
1634 break;
1635 case CVT_OVERSCAN:
1636 overscan = true;
1637 break;
1638 case CVT_INTERLACED:
1639 interlaced = opt_val;
1640 break;
1641 case CVT_ALT:
1642 alt = opt_val;
1643 break;
1644 case CVT_RB_H_BLANK:
1645 rb_h_blank = opt_val;
1646 break;
1647 case CVT_RB_V_BLANK:
1648 rb_v_blank = opt_val;
1649 if (rb_v_blank < 460) {
1650 fprintf(stderr, "vblank must be >= 460, set to 460.\n");
1651 rb_v_blank = 460;
1652 } else if (rb_v_blank > 705) {
1653 fprintf(stderr, "warning: vblank values > 705 might not be supported by RBv3 compliant sources.\n");
1654 }
1655 break;
1656 case CVT_EARLY_VSYNC:
1657 early_vsync = true;
1658 break;
1659 default:
1660 break;
1661 }
1662 }
1663
1664 if (!w || !h || !fps) {
1665 fprintf(stderr, "Missing width, height and/or fps.\n");
1666 usage();
1667 std::exit(EXIT_FAILURE);
1668 }
1669 if (interlaced)
1670 fps /= 2;
1671 timings t = state.calc_cvt_mode(w, h, fps, rb, interlaced, overscan, alt,
1672 rb_h_blank, rb_v_blank, early_vsync);
1673 state.print_timings("", &t, "CVT", "", true, false);
1674 }
1675
1676 struct gtf_parsed_data {
1677 unsigned w, h;
1678 double freq;
1679 double C, M, K, J;
1680 bool overscan;
1681 bool interlaced;
1682 bool secondary;
1683 bool params_from_edid;
1684 enum gtf_ip_parm ip_parm;
1685 };
1686
1687 enum gtf_opts {
1688 GTF_WIDTH = 0,
1689 GTF_HEIGHT,
1690 GTF_FPS,
1691 GTF_HORFREQ,
1692 GTF_PIXCLK,
1693 GTF_INTERLACED,
1694 GTF_OVERSCAN,
1695 GTF_SECONDARY,
1696 GTF_C2,
1697 GTF_M,
1698 GTF_K,
1699 GTF_J2,
1700 };
1701
1702 static int parse_gtf_subopt(char **subopt_str, double *value)
1703 {
1704 int opt;
1705 char *opt_str;
1706
1707 static const char * const subopt_list[] = {
1708 "w",
1709 "h",
1710 "fps",
1711 "horfreq",
1712 "pixclk",
1713 "interlaced",
1714 "overscan",
1715 "secondary",
1716 "C",
1717 "M",
1718 "K",
1719 "J",
1720 nullptr
1721 };
1722
1723 opt = getsubopt(subopt_str, (char * const *)subopt_list, &opt_str);
1724
1725 if (opt == -1) {
1726 fprintf(stderr, "Invalid suboptions specified.\n");
1727 usage();
1728 std::exit(EXIT_FAILURE);
1729 }
1730 if (opt_str == nullptr && opt != GTF_INTERLACED && opt != GTF_OVERSCAN &&
1731 opt != GTF_SECONDARY) {
1732 fprintf(stderr, "No value given to suboption <%s>.\n",
1733 subopt_list[opt]);
1734 usage();
1735 std::exit(EXIT_FAILURE);
1736 }
1737
1738 if (opt == GTF_C2 || opt == GTF_J2)
1739 *value = round(2.0 * strtod(opt_str, nullptr));
1740 else if (opt_str)
1741 *value = strtod(opt_str, nullptr);
1742 return opt;
1743 }
1744
1745 static void parse_gtf(char *optarg, gtf_parsed_data &data)
1746 {
1747 memset(&data, 0, sizeof(data));
1748 data.params_from_edid = true;
1749 data.C = 40;
1750 data.M = 600;
1751 data.K = 128;
1752 data.J = 20;
1753
1754 while (*optarg != '\0') {
1755 int opt;
1756 double opt_val;
1757
1758 opt = parse_gtf_subopt(&optarg, &opt_val);
1759
1760 switch (opt) {
1761 case GTF_WIDTH:
1762 data.w = round(opt_val);
1763 break;
1764 case GTF_HEIGHT:
1765 data.h = round(opt_val);
1766 break;
1767 case GTF_FPS:
1768 data.freq = opt_val;
1769 data.ip_parm = gtf_ip_vert_freq;
1770 break;
1771 case GTF_HORFREQ:
1772 data.freq = opt_val;
1773 data.ip_parm = gtf_ip_hor_freq;
1774 break;
1775 case GTF_PIXCLK:
1776 data.freq = opt_val;
1777 data.ip_parm = gtf_ip_clk_freq;
1778 break;
1779 case GTF_INTERLACED:
1780 data.interlaced = true;
1781 break;
1782 case GTF_OVERSCAN:
1783 data.overscan = true;
1784 break;
1785 case GTF_SECONDARY:
1786 data.secondary = true;
1787 break;
1788 case GTF_C2:
1789 data.C = opt_val / 2.0;
1790 data.params_from_edid = false;
1791 break;
1792 case GTF_M:
1793 data.M = round(opt_val);
1794 data.params_from_edid = false;
1795 break;
1796 case GTF_K:
1797 data.K = round(opt_val);
1798 data.params_from_edid = false;
1799 break;
1800 case GTF_J2:
1801 data.J = opt_val / 2.0;
1802 data.params_from_edid = false;
1803 break;
1804 default:
1805 break;
1806 }
1807 }
1808
1809 if (!data.w || !data.h) {
1810 fprintf(stderr, "Missing width and/or height.\n");
1811 usage();
1812 std::exit(EXIT_FAILURE);
1813 }
1814 if (!data.freq) {
1815 fprintf(stderr, "One of fps, horfreq or pixclk must be given.\n");
1816 usage();
1817 std::exit(EXIT_FAILURE);
1818 }
1819 if (!data.secondary)
1820 data.params_from_edid = false;
1821 if (data.interlaced && data.ip_parm == gtf_ip_vert_freq)
1822 data.freq /= 2;
1823 }
1824
1825 static void show_gtf(gtf_parsed_data &data)
1826 {
1827 timings t;
1828
1829 t = state.calc_gtf_mode(data.w, data.h, data.freq, data.interlaced,
1830 data.ip_parm, data.overscan, data.secondary,
1831 data.C, data.M, data.K, data.J);
1832 calc_ratio(&t);
1833 state.print_timings("", &t, "GTF", "", true, false);
1834 }
1835
1836 enum ovt_opts {
1837 OVT_RID,
1838 OVT_WIDTH,
1839 OVT_HEIGHT,
1840 OVT_FPS,
1841 };
1842
1843 static int parse_ovt_subopt(char **subopt_str, unsigned *value)
1844 {
1845 int opt;
1846 char *opt_str;
1847
1848 static const char * const subopt_list[] = {
1849 "rid",
1850 "w",
1851 "h",
1852 "fps",
1853 nullptr
1854 };
1855
1856 opt = getsubopt(subopt_str, (char* const*) subopt_list, &opt_str);
1857
1858 if (opt == -1) {
1859 fprintf(stderr, "Invalid suboptions specified.\n");
1860 usage();
1861 std::exit(EXIT_FAILURE);
1862 }
1863 if (opt_str == nullptr) {
1864 fprintf(stderr, "No value given to suboption <%s>.\n",
1865 subopt_list[opt]);
1866 usage();
1867 std::exit(EXIT_FAILURE);
1868 }
1869
1870 if (opt_str)
1871 *value = strtoul(opt_str, NULL, 0);
1872 return opt;
1873 }
1874
1875 static void parse_ovt(char *optarg)
1876 {
1877 unsigned rid = 0;
1878 unsigned w = 0, h = 0;
1879 unsigned fps = 0;
1880
1881 while (*optarg != '\0') {
1882 int opt;
1883 unsigned opt_val;
1884
1885 opt = parse_ovt_subopt(&optarg, &opt_val);
1886
1887 switch (opt) {
1888 case OVT_RID:
1889 rid = opt_val;
1890 break;
1891 case OVT_WIDTH:
1892 w = opt_val;
1893 break;
1894 case OVT_HEIGHT:
1895 h = opt_val;
1896 break;
1897 case OVT_FPS:
1898 fps = opt_val;
1899 break;
1900 default:
1901 break;
1902 }
1903 }
1904
1905 if ((!rid && (!w || !h)) || !fps) {
1906 fprintf(stderr, "Missing rid, width, height and/or fps.\n");
1907 usage();
1908 std::exit(EXIT_FAILURE);
1909 }
1910 unsigned hratio = 0, vratio = 0;
1911 if (rid) {
1912 const cta_rid *r = find_rid(rid);
1913
1914 if (r) {
1915 w = r->hact;
1916 h = r->vact;
1917 hratio = r->hratio;
1918 vratio = r->vratio;
1919 }
1920 }
1921 timings t = state.calc_ovt_mode(w, h, hratio, vratio, fps);
1922 state.print_timings("", &t, "OVT", "", true, false);
1923 }
1924
11811925 int main(int argc, char **argv)
11821926 {
11831927 char short_options[26 * 2 * 2 + 1];
11841928 enum output_format out_fmt = OUT_FMT_DEFAULT;
1929 gtf_parsed_data gtf_data;
1930 unsigned list_rid = 0;
11851931 int ret;
11861932
11871933 while (1) {
11881934 int option_index = 0;
11891935 unsigned idx = 0;
1190 unsigned i;
1936 unsigned i, val;
1937 const timings *t;
1938 char buf[16];
11911939
11921940 for (i = 0; long_options[i].name; i++) {
11931941 if (!isalpha(long_options[i].val))
12211969 exit(1);
12221970 }
12231971 break;
1972 case OptDiag:
1973 state.diagonal = strtod(optarg, NULL);
1974 break;
1975 case OptSTD: {
1976 unsigned char byte1, byte2 = 0;
1977 char *endptr;
1978
1979 byte1 = strtoul(optarg, &endptr, 0);
1980 if (*endptr == ',')
1981 byte2 = strtoul(endptr + 1, NULL, 0);
1982 state.print_standard_timing("", byte1, byte2, false, true);
1983 break;
1984 }
1985 case OptDMT:
1986 val = strtoul(optarg, NULL, 0);
1987 t = find_dmt_id(val);
1988 if (t) {
1989 sprintf(buf, "DMT 0x%02x", val);
1990 state.print_timings("", t, buf, "", true, false);
1991 } else {
1992 fprintf(stderr, "Unknown DMT code 0x%02x.\n", val);
1993 }
1994 break;
1995 case OptVIC:
1996 val = strtoul(optarg, NULL, 0);
1997 t = find_vic_id(val);
1998 if (t) {
1999 sprintf(buf, "VIC %3u", val);
2000 state.print_timings("", t, buf, "", true, false);
2001 } else {
2002 fprintf(stderr, "Unknown VIC code %u.\n", val);
2003 }
2004 break;
2005 case OptHDMIVIC:
2006 val = strtoul(optarg, NULL, 0);
2007 t = find_hdmi_vic_id(val);
2008 if (t) {
2009 sprintf(buf, "HDMI VIC %u", val);
2010 state.print_timings("", t, buf, "", true, false);
2011 } else {
2012 fprintf(stderr, "Unknown HDMI VIC code %u.\n", val);
2013 }
2014 break;
2015 case OptCVT:
2016 parse_cvt(optarg);
2017 break;
2018 case OptGTF:
2019 parse_gtf(optarg, gtf_data);
2020 break;
2021 case OptOVT:
2022 parse_ovt(optarg);
2023 break;
2024 case OptListRIDTimings:
2025 list_rid = strtoul(optarg, NULL, 0);
2026 break;
12242027 case ':':
12252028 fprintf(stderr, "Option '%s' requires a value.\n",
12262029 argv[optind]);
12412044 return 0;
12422045 }
12432046
2047 if (options[OptListEstTimings])
2048 state.list_established_timings();
2049 if (options[OptListDMTs])
2050 state.list_dmts();
2051 if (options[OptListVICs])
2052 state.cta_list_vics();
2053 if (options[OptListHDMIVICs])
2054 state.cta_list_hdmi_vics();
2055 if (options[OptListRIDs])
2056 state.cta_list_rids();
2057 if (options[OptListRIDTimings])
2058 state.cta_list_rid_timings(list_rid);
2059
2060 if (options[OptListEstTimings] || options[OptListDMTs] ||
2061 options[OptListVICs] || options[OptListHDMIVICs] ||
2062 options[OptListRIDs] || options[OptListRIDTimings])
2063 return 0;
2064
2065 if (options[OptCVT] || options[OptDMT] || options[OptVIC] ||
2066 options[OptHDMIVIC] || options[OptSTD] || options[OptOVT])
2067 return 0;
2068
2069 if (options[OptGTF] && (!gtf_data.params_from_edid || optind == argc)) {
2070 show_gtf(gtf_data);
2071 return 0;
2072 }
2073
12442074 if (optind == argc)
12452075 ret = edid_from_file("-", stdout);
12462076 else
12522082 }
12532083 if (optind < argc - 1)
12542084 return ret ? ret : edid_to_file(argv[optind + 1], out_fmt);
2085
2086 if (options[OptGTF]) {
2087 timings t;
2088
2089 // Find the Secondary Curve
2090 state.preparse_detailed_block(edid + 0x36);
2091 state.preparse_detailed_block(edid + 0x48);
2092 state.preparse_detailed_block(edid + 0x5a);
2093 state.preparse_detailed_block(edid + 0x6c);
2094
2095 t = state.calc_gtf_mode(gtf_data.w, gtf_data.h, gtf_data.freq,
2096 gtf_data.interlaced, gtf_data.ip_parm,
2097 gtf_data.overscan);
2098 unsigned hbl = t.hfp + t.hsync + t.hbp;
2099 unsigned htotal = t.hact + hbl;
2100 double hor_freq_khz = htotal ? (double)t.pixclk_khz / htotal : 0;
2101
2102 if (state.base.supports_sec_gtf &&
2103 hor_freq_khz >= state.base.sec_gtf_start_freq) {
2104 t = state.calc_gtf_mode(gtf_data.w, gtf_data.h, gtf_data.freq,
2105 gtf_data.interlaced, gtf_data.ip_parm,
2106 gtf_data.overscan, true,
2107 state.base.C, state.base.M,
2108 state.base.K, state.base.J);
2109 }
2110 calc_ratio(&t);
2111 if (t.hfp <= 0)
2112 state.print_timings("", &t, "GTF", "INVALID: Hfront <= 0", true, false);
2113 else
2114 state.print_timings("", &t, "GTF", "", true, false);
2115 return 0;
2116 }
12552117
12562118 return ret ? ret : state.parse_edid();
12572119 }
12702132 }
12712133 options[OptCheck] = 1;
12722134 options[OptPreferredTimings] = 1;
1273 options[OptNativeTimings] = 1;
2135 options[OptNativeResolution] = 1;
12742136 state = edid_state();
12752137 int ret = edid_from_file(input, stderr);
12762138 return ret ? ret : state.parse_edid();
1111
1212 #include <string>
1313 #include <vector>
14 #include <set>
1415 #include <string.h>
1516
1617 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
2021 #define EDID_PAGE_SIZE 128U
2122 #define EDID_MAX_BLOCKS 256U
2223
23 #define RB_FLAG (1U << 7)
24 #define RB_ALT (1U << 7)
25
26 #define RB_NONE (0U)
27 #define RB_CVT_V1 (1U)
28 #define RB_CVT_V2 (2U)
29 #define RB_CVT_V3 (3U)
30 #define RB_GTF (4U)
2431
2532 // Video Timings
2633 // If interlaced is true, then the vertical blanking
2734 // for each field is (vfp + vsync + vbp + 0.5), except for
2835 // the VIC 39 timings that doesn't have the 0.5 constant.
36 //
37 // The sequence of the various video parameters is as follows:
38 //
39 // border - front porch - sync - back porch - border - active video
40 //
41 // Note: this is slightly different from EDID 1.4 which calls
42 // 'active video' as 'addressable video' and the EDID 1.4 term
43 // 'active video' includes the borders.
44 //
45 // But since borders are rarely used, the term 'active video' will
46 // typically be the same as 'addressable video', and that's how I
47 // use it.
2948 struct timings {
30 // Active horizontal and vertical frame height, including any
49 // Active horizontal and vertical frame height, excluding any
3150 // borders, if present.
3251 // Note: for interlaced formats the active field height is vact / 2
3352 unsigned hact, vact;
3453 unsigned hratio, vratio;
3554 unsigned pixclk_khz;
3655 // 0: no reduced blanking
37 // 1: reduced blanking version 1
38 // 2: reduced blanking version 2
39 // 3: reduced blanking version 3 with a horizontal blank of 80
40 // 3 | RB_FLAG: reduced blanking version 3 with a horizontal blank of 160
56 // 1: CVT reduced blanking version 1
57 // 2: CVT reduced blanking version 2
58 // 2 | RB_ALT: CVT reduced blanking version 2 video-optimized (1000/1001 fps)
59 // 3: CVT reduced blanking version 3
60 // 3 | RB_ALT: v3 with a horizontal blank of 160
61 // 4: GTF Secondary Curve
4162 unsigned rb;
4263 bool interlaced;
4364 // The horizontal frontporch may be negative in GTF calculations,
88109 std::string flags;
89110 };
90111
112 enum gtf_ip_parm {
113 gtf_ip_vert_freq = 1,
114 gtf_ip_hor_freq,
115 gtf_ip_clk_freq,
116 };
117
91118 typedef std::vector<timings_ext> vec_timings_ext;
119
120 struct cta_rid {
121 unsigned hact, vact;
122 unsigned hratio, vratio;
123 };
124
125 struct cta_vfd {
126 unsigned char rid;
127 unsigned char fr_factor;
128 unsigned int bfr50:1;
129 unsigned int fr24:1;
130 unsigned int bfr60:1;
131 unsigned int fr144:1;
132 unsigned int fr48:1;
133 };
92134
93135 struct edid_state {
94136 edid_state()
98140 max_hor_freq_hz = max_vert_freq_hz = max_pixclk_khz = 0;
99141 min_hor_freq_hz = 0xffffff;
100142 min_vert_freq_hz = 0xffffffff;
143 dtd_max_vsize_mm = dtd_max_hsize_mm = 0;
101144 warnings = failures = 0;
102145 has_cta = has_dispid = false;
103146 hide_serial_numbers = false;
147 image_width = image_height = diagonal = 0;
104148
105149 // Base block state
106150 base.edid_minor = 0;
107151 base.has_name_descriptor = base.has_display_range_descriptor =
108152 base.has_serial_number = base.has_serial_string =
109153 base.supports_continuous_freq = base.supports_gtf =
110 base.supports_cvt = base.uses_gtf = base.uses_cvt =
154 base.supports_cvt = base.seen_non_detailed_descriptor =
111155 base.has_640x480p60_est_timing = base.has_spwg =
112 base.seen_non_detailed_descriptor =
113156 base.preferred_is_also_native = false;
157 base.supports_sec_gtf = false;
158 base.sec_gtf_start_freq = 0;
159 base.C = base.M = base.K = base.J = 0;
160 base.max_pos_neg_hor_freq_khz = 0;
114161 base.detailed_block_cnt = base.dtd_cnt = 0;
115162
116163 base.min_display_hor_freq_hz = base.max_display_hor_freq_hz =
119166 base.max_display_height_mm = 0;
120167
121168 // CTA-861 block state
122 cta.has_vic_1 = cta.first_svd_might_be_preferred =
169 cta.has_vic_1 = cta.first_svd_might_be_preferred = cta.has_sldb =
123170 cta.has_hdmi = cta.has_vcdb = cta.has_vfpdb = false;
124 cta.last_block_was_hdmi_vsdb = cta.have_hf_vsdb = cta.have_hf_scdb = false;
125 cta.first_block = cta.first_svd = true;
171 cta.previous_cta_tag = 0xfff;
172 cta.have_hf_vsdb = cta.have_hf_scdb = false;
173 cta.image_width = cta.image_height = 0;
174 cta.block_number = 0;
175 cta.first_svd = true;
126176 cta.supported_hdmi_vic_codes = cta.supported_hdmi_vic_vsb_codes = 0;
127177 memset(cta.vics, 0, sizeof(cta.vics));
128178 memset(cta.preparsed_has_vic, 0, sizeof(cta.preparsed_has_vic));
179 memset(&cta.preparsed_first_vfd, 0, sizeof(cta.preparsed_first_vfd));
129180 cta.preparsed_phys_addr = 0xffff;
130 cta.preparse_total_dtds = 0;
131 cta.preparse_total_vtdbs = 0;
132 cta.preparse_has_t8vtdb = false;
181 cta.preparsed_speaker_count = 0;
182 cta.preparsed_sld = false;
183 cta.preparsed_sld_has_coord = false;
184 cta.preparsed_total_dtds = 0;
185 cta.preparsed_total_vtdbs = 0;
186 cta.preparsed_has_t8vtdb = false;
133187
134188 // DisplayID block state
135189 dispid.version = 0;
136 dispid.preparse_color_ids = dispid.preparse_xfer_ids = 0;
137 dispid.preparse_displayid_blocks = 0;
190 dispid.native_width = dispid.native_height = 0;
191 dispid.preparsed_color_ids = dispid.preparsed_xfer_ids = 0;
192 dispid.preparsed_displayid_blocks = 0;
138193 dispid.is_base_block = true;
139194 dispid.is_display = dispid.has_product_identification =
140195 dispid.has_display_parameters = dispid.has_type_1_7 =
141196 dispid.has_display_interface_features = false;
197 dispid.block_number = 0;
198 dispid.image_width = dispid.image_height = 0;
142199
143200 // Block Map block state
144201 block_map.saw_block_1 = false;
160217 double min_vert_freq_hz;
161218 double max_vert_freq_hz;
162219 unsigned max_pixclk_khz;
220 unsigned dtd_max_hsize_mm;
221 unsigned dtd_max_vsize_mm;
222
223 // in 0.1 mm units
224 unsigned image_width, image_height;
225 // in inches
226 double diagonal;
163227
164228 unsigned warnings;
165229 unsigned failures;
173237 bool has_serial_string;
174238 bool supports_continuous_freq;
175239 bool supports_gtf;
240 bool supports_sec_gtf;
241 unsigned sec_gtf_start_freq;
242 double C, M, K, J;
176243 bool supports_cvt;
177 bool uses_gtf;
178 bool uses_cvt;
179244 bool has_spwg;
180245 unsigned detailed_block_cnt;
181246 unsigned dtd_cnt;
191256 unsigned max_display_pixclk_khz;
192257 unsigned max_display_width_mm;
193258 unsigned max_display_height_mm;
259 unsigned max_pos_neg_hor_freq_khz;
194260 } base;
195261
196262 // CTA-861 block state
197263 struct {
198 unsigned preparse_total_dtds;
264 unsigned preparsed_total_dtds;
199265 vec_timings_ext vec_dtds;
200 unsigned preparse_total_vtdbs;
266 unsigned preparsed_total_vtdbs;
201267 vec_timings_ext vec_vtdbs;
268 cta_vfd preparsed_first_vfd;
202269 vec_timings_ext preferred_timings;
203 bool preparse_has_t8vtdb;
270 bool preparsed_has_t8vtdb;
271 // Keep track of the found Tag/Extended Tag pairs.
272 // The unsigned value is equal to: (tag) | (OUI enum << 12) or (extended tag) | (tag << 8) | (OUI enum << 12)
273 std::vector<unsigned> found_tags;
204274 timings_ext t8vtdb;
205275 vec_timings_ext native_timings;
276 // in 0.1 mm units
277 unsigned image_width, image_height;
206278 bool has_vic_1;
207279 bool first_svd_might_be_preferred;
208280 unsigned char byte3;
209281 bool has_hdmi;
210282 bool has_vcdb;
211283 bool has_vfpdb;
284 unsigned preparsed_speaker_count;
285 bool preparsed_sld_has_coord;
286 bool preparsed_sld;
287 bool has_sldb;
212288 unsigned short preparsed_phys_addr;
213 bool last_block_was_hdmi_vsdb;
289 unsigned previous_cta_tag;
214290 bool have_hf_vsdb, have_hf_scdb;
215 bool first_block;
291 unsigned block_number;
216292 bool first_svd;
217293 unsigned supported_hdmi_vic_codes;
218294 unsigned supported_hdmi_vic_vsb_codes;
224300 // DisplayID block state
225301 struct {
226302 unsigned char version;
227 unsigned short preparse_color_ids;
228 unsigned short preparse_xfer_ids;
229 unsigned preparse_displayid_blocks;
303 unsigned short preparsed_color_ids;
304 unsigned short preparsed_xfer_ids;
305 unsigned preparsed_displayid_blocks;
230306 bool is_base_block;
231307 bool is_display;
232308 bool has_product_identification;
234310 bool has_type_1_7;
235311 bool has_display_interface_features;
236312 vec_timings_ext preferred_timings;
313 unsigned native_width, native_height;
314 // in 0.1 mm units
315 unsigned image_width, image_height;
316 unsigned block_number;
317 // Keep track of the found CTA-861 Tag/Extended Tag pairs.
318 // The unsigned value is equal to: (tag) | (OUI enum << 12) or (extended tag) | (tag << 8) | (OUI enum << 12)
319 std::vector<unsigned> found_tags;
237320 } dispid;
238321
239322 // Block Map block state
246329 std::string dtd_type() { return dtd_type(base.dtd_cnt); }
247330 bool print_timings(const char *prefix, const struct timings *t,
248331 const char *type, const char *flags = "",
249 bool detailed = false);
332 bool detailed = false, bool do_checks = true);
250333 bool print_timings(const char *prefix, const struct timings_ext &t,
251 bool detailed = false)
334 bool detailed = false, bool do_checks = true)
252335 {
253 return print_timings(prefix, &t.t, t.type.c_str(), t.flags.c_str(), detailed);
336 return print_timings(prefix, &t.t, t.type.c_str(), t.flags.c_str(),
337 detailed, do_checks);
254338 };
255339 bool match_timings(const timings &t1, const timings &t2);
340 timings calc_gtf_mode(unsigned h_pixels, unsigned v_lines,
341 double ip_freq_rqd, bool int_rqd = false,
342 enum gtf_ip_parm ip_parm = gtf_ip_vert_freq,
343 bool margins_rqd = false, bool secondary = false,
344 double C = 40, double M = 600, double K = 128, double J = 20);
256345 void edid_gtf_mode(unsigned refresh, struct timings &t);
257 void edid_cvt_mode(unsigned refresh, struct timings &t);
258 timings calc_cvt_mode(unsigned refresh, unsigned hact, unsigned vact, unsigned rb);
346 timings calc_cvt_mode(unsigned h_pixels, unsigned v_lines,
347 double ip_freq_rqd, unsigned rb, bool int_rqd = false,
348 bool margins_rqd = false, bool alt = false,
349 unsigned rb_h_blank = 0, unsigned rb_v_blank = 460,
350 bool early_vsync_rqd = false);
351 void edid_cvt_mode(unsigned refresh, struct timings &t, unsigned rb_h_blank = 0,
352 unsigned rb_v_blank = 460, bool early_vsync_rqd = false);
259353 void detailed_cvt_descriptor(const char *prefix, const unsigned char *x, bool first);
354 timings calc_ovt_mode(unsigned hact, unsigned vact,
355 unsigned hratio, unsigned vratio,
356 unsigned frame_rate);
260357 void print_standard_timing(const char *prefix, unsigned char b1, unsigned char b2,
261 bool gtf_only = false, unsigned vrefresh_offset = 60);
358 bool gtf_only = false, bool show_both = false);
262359 void detailed_display_range_limits(const unsigned char *x);
263360 void detailed_epi(const unsigned char *x);
264361 void detailed_timings(const char *prefix, const unsigned char *x,
265362 bool base_or_cta = true);
363 void preparse_detailed_block(const unsigned char *x);
266364 void detailed_block(const unsigned char *x);
267365 void parse_base_block(const unsigned char *x);
268366 void check_base_block();
367 void list_dmts();
368 void list_established_timings();
369
370 void data_block_oui(std::string block_name, const unsigned char *x, unsigned length, unsigned *ouinum,
371 bool ignorezeros = false, bool do_ascii = false, bool big_endian = false);
269372
270373 void print_vic_index(const char *prefix, unsigned idx, const char *suffix, bool ycbcr420 = false);
374 void hdmi_latency(unsigned char vid_lat, unsigned char aud_lat, bool is_ilaced);
271375 void cta_vcdb(const unsigned char *x, unsigned length);
272376 void cta_svd(const unsigned char *x, unsigned n, bool for_ycbcr420);
377 void cta_vfdb(const unsigned char *x, unsigned n);
273378 void cta_y420cmdb(const unsigned char *x, unsigned length);
379 void cta_print_svr(unsigned char svr, vec_timings_ext &vec_tim);
274380 void cta_vfpdb(const unsigned char *x, unsigned length);
381 void cta_nvrdb(const unsigned char *x, unsigned length);
382 cta_vfd cta_parse_vfd(const unsigned char *x, unsigned lvfd);
383 void cta_rcdb(const unsigned char *x, unsigned length);
384 void cta_sldb(const unsigned char *x, unsigned length);
385 void cta_preparse_sldb(const unsigned char *x, unsigned length);
275386 void cta_hdmi_block(const unsigned char *x, unsigned length);
276387 void cta_displayid_type_7(const unsigned char *x, unsigned length);
277388 void cta_displayid_type_8(const unsigned char *x, unsigned length);
278389 void cta_displayid_type_10(const unsigned char *x, unsigned length);
279 void cta_ext_block(const unsigned char *x, unsigned length);
280 void cta_block(const unsigned char *x);
390 void cta_block(const unsigned char *x, std::vector<unsigned> &found_tags);
281391 void preparse_cta_block(const unsigned char *x);
282392 void parse_cta_block(const unsigned char *x);
283393 void cta_resolve_svr(vec_timings_ext::iterator iter);
284394 void cta_resolve_svrs();
285395 void check_cta_blocks();
286
396 void cta_list_vics();
397 void cta_list_hdmi_vics();
398 void cta_list_rids();
399 void cta_list_rid_timings(unsigned list_rid = 0);
400
401 void set_displayid_native_res(unsigned w, unsigned h);
287402 void parse_digital_interface(const unsigned char *x);
288403 void parse_display_device(const unsigned char *x);
289404 void parse_display_caps(const unsigned char *x);
297412 std::string product_type(unsigned char x, bool heading);
298413 void parse_displayid_interface_features(const unsigned char *x);
299414 void parse_displayid_parameters(const unsigned char *x);
300 void parse_displayid_parameters_v2(const unsigned char *x);
415 void parse_displayid_parameters_v2(const unsigned char *x, unsigned block_rev);
301416 void parse_displayid_display_intf(const unsigned char *x);
302417 void parse_displayid_color_characteristics(const unsigned char *x);
303418 void parse_displayid_transfer_characteristics(const unsigned char *x);
317432 void parse_displayid_type_9_timing(const unsigned char *x);
318433 void parse_displayid_dynamic_video_timings_range_limits(const unsigned char *x);
319434 void parse_displayid_ContainerID(const unsigned char *x);
320 void parse_displayid_type_10_timing(const unsigned char *x, bool is_cta = false);
435 void parse_displayid_adaptive_sync(const unsigned char *x);
436 void parse_displayid_type_10_timing(const unsigned char *x, unsigned sz,
437 bool is_cta = false);
321438 void preparse_displayid_block(const unsigned char *x);
439 unsigned displayid_block(const unsigned version, const unsigned char *x, unsigned length);
322440 void parse_displayid_block(const unsigned char *x);
323441 void parse_displayid_vesa(const unsigned char *x);
442 void parse_displayid_apple(const unsigned char *x);
324443 void parse_displayid_cta_data_block(const unsigned char *x);
325444 void check_displayid_blocks();
326445
333452
334453 void preparse_extension(const unsigned char *x);
335454 void parse_extension(const unsigned char *x);
455 void print_preferred_timings();
456 void print_native_res();
336457 int parse_edid();
337458 };
338459
377498 void do_checksum(const char *prefix, const unsigned char *x, size_t len);
378499 std::string utohex(unsigned char x);
379500 std::string ouitohex(unsigned oui);
501 std::string containerid2s(const unsigned char *x);
380502 bool memchk(const unsigned char *x, unsigned len, unsigned char v = 0);
381503 void hex_block(const char *prefix, const unsigned char *x, unsigned length,
382504 bool show_ascii = true, unsigned step = 16);
383505 std::string block_name(unsigned char block);
384506 void calc_ratio(struct timings *t);
385 const char *oui_name(unsigned oui, bool reverse = false);
386
507 const char *oui_name(unsigned oui, unsigned *ouinum = NULL);
508 unsigned gcd(unsigned a, unsigned b);
509
510 bool timings_close_match(const timings &t1, const timings &t2);
387511 const struct timings *find_dmt_id(unsigned char dmt_id);
512 const struct timings *close_match_to_dmt(const timings &t, unsigned &dmt);
388513 const struct timings *find_vic_id(unsigned char vic);
514 const struct cta_rid *find_rid(unsigned char rid);
389515 const struct timings *find_hdmi_vic_id(unsigned char hdmi_vic);
516 const struct timings *cta_close_match_to_vic(const timings &t, unsigned &vic);
390517 unsigned char hdmi_vic_to_vic(unsigned char hdmi_vic);
391518 char *extract_string(const unsigned char *x, unsigned len);
392519
520 #define oneoui(c,k,n) const unsigned kOUI_##k = __LINE__<<12;
521 #include "oui.h"
522
393523 #endif
0 // http://standards-oui.ieee.org/oui/oui.txt
1 oneoui(0x000c03, HDMI, "HDMI" )
2 oneoui(0xc45dd8, HDMIForum, "HDMI Forum" )
3 oneoui(0x90848b, HDR10, "HDR10+" )
4 oneoui(0x00001a, AMD, "AMD" )
5 oneoui(0x00044b, NVIDIA, "NVIDIA" )
6 oneoui(0x000c6e, ASUS, "ASUS" )
7 oneoui(0x0010fa, Apple, "Apple" )
8 oneoui(0x0014b9, MSTAR, "MSTAR" )
9 oneoui(0x00d046, Dolby, "Dolby" )
10 oneoui(0x00e047, InFocus, "InFocus" )
11 oneoui(0xca125c, Microsoft, "Microsoft" )
12
13 // http://standards-oui.ieee.org/cid/cid.txt
14 oneoui(0x3a0292, VESA, "VESA" )
15
16 // https://uefi.org/pnp_id_list
17 oneoui(0x41505000, asciiApple, "Apple" ) // 'APP\0'
18
19 #undef oneoui
4444 36, 72, 108, false, 1, 3, 42, true } },
4545
4646 { 0x04, 0x3140, 0x000000, { 640, 480, 4, 3, 25175, 0, false,
47 16, 96, 48, false, 10, 2, 33, false, 8, 8 } },
47 8, 96, 40, false, 2, 2, 25, false, 8, 8 } },
4848 { 0x05, 0x314c, 0x000000, { 640, 480, 4, 3, 31500, 0, false,
49 24, 40, 128, false, 9, 3, 28, false, 8, 8 } },
49 16, 40, 120, false, 1, 3, 20, false, 8, 8 } },
5050 { 0x06, 0x314f, 0x000000, { 640, 480, 4, 3, 31500, 0, false,
5151 16, 64, 120, false, 1, 3, 16, false } },
5252 { 0x07, 0x3159, 0x000000, { 640, 480, 4, 3, 36000, 0, false,
353353 return NULL;
354354 }
355355
356 /*
357 * Copied from xserver/hw/xfree86/modes/xf86gtf.c
358 */
359 void edid_state::edid_gtf_mode(unsigned refresh, struct timings &t)
356 void edid_state::list_established_timings()
360357 {
361 #define CELL_GRAN 8.0 /* assumed character cell granularity */
362 #define MIN_PORCH 1 /* minimum front porch */
363 #define V_SYNC_RQD 3 /* width of vsync in lines */
364 #define H_SYNC_PERCENT 8.0 /* width of hsync as % of total line */
365 #define MIN_VSYNC_PLUS_BP 550.0 /* min time of vsync + back porch (microsec) */
366 #define M 600.0 /* blanking formula gradient */
367 #define C 40.0 /* blanking formula offset */
368 #define K 128.0 /* blanking formula scaling factor */
369 #define J 20.0 /* blanking formula scaling factor */
370
371 /* C' and M' are part of the Blanking Duty Cycle computation */
372
373 #define C_PRIME (((C - J) * K/256.0) + J)
374 #define M_PRIME (K/256.0 * M)
375 double h_pixels_rnd;
376 double v_lines_rnd;
377 double v_field_rate_rqd;
378 double h_period_est;
379 double vsync_plus_bp;
380 double total_v_lines;
381 double v_field_rate_est;
382 double h_period;
383 double total_active_pixels;
384 double ideal_duty_cycle;
385 double h_blank;
386 double total_pixels;
387
388 /* 1. In order to give correct results, the number of horizontal
389 * pixels requested is first processed to ensure that it is divisible
390 * by the character size, by rounding it to the nearest character
391 * cell boundary:
392 *
393 * [H PIXELS RND] = ((ROUND([H PIXELS]/[CELL GRAN RND],0))*[CELLGRAN RND])
394 */
395
396 h_pixels_rnd = rint((double)t.hact / CELL_GRAN) * CELL_GRAN;
397
398 /* 2. If interlace is requested, the number of vertical lines assumed
399 * by the calculation must be halved, as the computation calculates
400 * the number of vertical lines per field. In either case, the
401 * number of lines is rounded to the nearest integer.
402 *
403 * [V LINES RND] = IF([INT RQD?]="y", ROUND([V LINES]/2,0),
404 * ROUND([V LINES],0))
405 */
406
407 v_lines_rnd = t.vact;
408
409 /* 3. Find the frame rate required:
410 *
411 * [V FIELD RATE RQD] = IF([INT RQD?]="y", [I/P FREQ RQD]*2,
412 * [I/P FREQ RQD])
413 */
414
415 v_field_rate_rqd = refresh;
416
417 /* 7. Estimate the Horizontal period
418 *
419 * [H PERIOD EST] = ((1/[V FIELD RATE RQD]) - [MIN VSYNC+BP]/1000000) /
420 * ([V LINES RND] +
421 * [MIN PORCH RND]+[INTERLACE]) * 1000000
422 */
423
424 h_period_est = (((1.0/v_field_rate_rqd) - (MIN_VSYNC_PLUS_BP/1000000.0))
425 / (v_lines_rnd + MIN_PORCH)
426 * 1000000.0);
427
428 /* 8. Find the number of lines in V sync + back porch:
429 *
430 * [V SYNC+BP] = ROUND(([MIN VSYNC+BP]/[H PERIOD EST]),0)
431 */
432
433 vsync_plus_bp = rint(MIN_VSYNC_PLUS_BP/h_period_est);
434
435 /* 10. Find the total number of lines in Vertical field period:
436 *
437 * [TOTAL V LINES] = [V LINES RND] +
438 * [V SYNC+BP] + [INTERLACE] +
439 * [MIN PORCH RND]
440 */
441
442 total_v_lines = v_lines_rnd + vsync_plus_bp + MIN_PORCH;
443 t.vbp = vsync_plus_bp - V_SYNC_RQD;
444 t.vsync = V_SYNC_RQD;
445 t.vfp = MIN_PORCH;
446
447 /* 11. Estimate the Vertical field frequency:
448 *
449 * [V FIELD RATE EST] = 1 / [H PERIOD EST] / [TOTAL V LINES] * 1000000
450 */
451
452 v_field_rate_est = 1.0 / h_period_est / total_v_lines * 1000000.0;
453
454 /* 12. Find the actual horizontal period:
455 *
456 * [H PERIOD] = [H PERIOD EST] / ([V FIELD RATE RQD] / [V FIELD RATE EST])
457 */
458
459 h_period = h_period_est / (v_field_rate_rqd / v_field_rate_est);
460
461 /* 17. Find total number of active pixels in image
462 *
463 * [TOTAL ACTIVE PIXELS] = [H PIXELS RND]
464 */
465
466 total_active_pixels = h_pixels_rnd;
467
468 /* 18. Find the ideal blanking duty cycle from the blanking duty cycle
469 * equation:
470 *
471 * [IDEAL DUTY CYCLE] = [C'] - ([M']*[H PERIOD]/1000)
472 */
473
474 ideal_duty_cycle = C_PRIME - (M_PRIME * h_period / 1000.0);
475
476 /* 19. Find the number of pixels in the blanking time to the nearest
477 * double character cell:
478 *
479 * [H BLANK (PIXELS)] = (ROUND(([TOTAL ACTIVE PIXELS] *
480 * [IDEAL DUTY CYCLE] /
481 * (100-[IDEAL DUTY CYCLE]) /
482 * (2*[CELL GRAN RND])), 0))
483 * * (2*[CELL GRAN RND])
484 */
485
486 h_blank = rint(total_active_pixels *
487 ideal_duty_cycle /
488 (100.0 - ideal_duty_cycle) /
489 (2.0 * CELL_GRAN)) * (2.0 * CELL_GRAN);
490
491 /* 20. Find total number of pixels:
492 *
493 * [TOTAL PIXELS] = [TOTAL ACTIVE PIXELS] + [H BLANK (PIXELS)]
494 */
495
496 total_pixels = total_active_pixels + h_blank;
497
498 /* 21. Find pixel clock frequency:
499 *
500 * [PIXEL FREQ] = [TOTAL PIXELS] / [H PERIOD]
501 */
502
503 t.pixclk_khz = (int)(1000.0 * total_pixels / h_period + 0.5);
504
505 /* Stage 1 computations are now complete; I should really pass
506 the results to another function and do the Stage 2
507 computations, but I only need a few more values so I'll just
508 append the computations here for now */
509 /* 17. Find the number of pixels in the horizontal sync period:
510 *
511 * [H SYNC (PIXELS)] =(ROUND(([H SYNC%] / 100 * [TOTAL PIXELS] /
512 * [CELL GRAN RND]),0))*[CELL GRAN RND]
513 */
514 t.hsync = rint(H_SYNC_PERCENT / 100.0 * total_pixels / CELL_GRAN) * CELL_GRAN;
515 /* 18. Find the number of pixels in the horizontal front porch period:
516 *
517 * [H FRONT PORCH (PIXELS)] = ([H BLANK (PIXELS)]/2)-[H SYNC (PIXELS)]
518 */
519 t.hfp = (h_blank / 2.0) - t.hsync;
520 /* 19. Find the number of pixels in the horizontal back porch period:
521 *
522 * [H BACK PORCH (PIXELS)] = [H FRONT PORCH (PIXELS)]+[H SYNC (PIXELS)]
523 */
524 t.hbp = t.hfp + t.hsync;
525 t.pos_pol_hsync = false;
526 t.pos_pol_vsync = true;
527 t.interlaced = false;
528 t.rb = 0;
358 printf("Established Timings I & II, 'Byte' is the EDID address:\n\n");
359 for (unsigned i = 0; i < ARRAY_SIZE(established_timings12); i++) {
360 unsigned char dmt_id = established_timings12[i].dmt_id;
361 const struct timings *t;
362 char type[16];
363
364 if (dmt_id) {
365 sprintf(type, "DMT 0x%02x", dmt_id);
366 t = find_dmt_id(dmt_id);
367 } else {
368 t = &established_timings12[i].t;
369 sprintf(type, "%-8s", established_timings12[i].type);
370 }
371 printf("Byte 0x%02x, Bit %u: ", 0x23 + i / 8, 7 - i % 8);
372 print_timings("", t, type, "", false, false);
373 }
374 printf("\nEstablished timings III, 'Byte' is the offset from the start of the descriptor:\n\n");
375 for (unsigned i = 0; i < ARRAY_SIZE(established_timings3_dmt_ids); i++) {
376 unsigned char dmt_id = established_timings3_dmt_ids[i];
377 char type[16];
378
379 sprintf(type, "DMT 0x%02x", dmt_id);
380 printf("Byte 0x%02x, Bit %u: ", 6 + i / 8, 7 - i % 8);
381 print_timings("", find_dmt_id(dmt_id), type, "", false, false);
382 }
529383 }
530384
531 /*
532 * Copied from xserver/hw/xfree86/modes/xf86cvt.c
533 */
534 void edid_state::edid_cvt_mode(unsigned refresh, struct timings &t)
385 const struct timings *close_match_to_dmt(const timings &t, unsigned &dmt)
535386 {
536 int HDisplay = t.hact;
537 int VDisplay = t.vact;
538
539 /* 2) character cell horizontal granularity (pixels) - default 8 */
540 #define CVT_H_GRANULARITY 8
541
542 /* 4) Minimum vertical porch (lines) - default 3 */
543 #define CVT_MIN_V_PORCH 3
544
545 /* 4) Minimum number of vertical back porch lines - default 6 */
546 #define CVT_MIN_V_BPORCH 6
547
548 /* Pixel Clock step (kHz) */
549 #define CVT_CLOCK_STEP 250
550
551 double HPeriod;
552 int VDisplayRnd, VSync;
553 double VFieldRate = refresh;
554 int HTotal, VTotal, Clock, HSyncStart, HSyncEnd, VSyncStart, VSyncEnd;
555
556 /* 2. Horizontal pixels */
557 HDisplay = HDisplay - (HDisplay % CVT_H_GRANULARITY);
558
559 /* 5. Find number of lines per field */
560 VDisplayRnd = VDisplay;
561
562 /* Determine VSync Width from aspect ratio */
563 if ((VDisplay * 4 / 3) == HDisplay)
564 VSync = 4;
565 else if ((VDisplay * 16 / 9) == HDisplay)
566 VSync = 5;
567 else if ((VDisplay * 16 / 10) == HDisplay)
568 VSync = 6;
569 else if (!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay))
570 VSync = 7;
571 else if ((VDisplay * 15 / 9) == HDisplay)
572 VSync = 7;
573 else /* Custom */
574 VSync = 10;
575
576 if (!t.rb) { /* simplified GTF calculation */
577 /* 4) Minimum time of vertical sync + back porch interval (µs)
578 * default 550.0 */
579 #define CVT_MIN_VSYNC_BP 550.0
580
581 /* 3) Nominal HSync width (% of line period) - default 8 */
582 #define CVT_HSYNC_PERCENTAGE 8
583
584 double HBlankPercentage;
585 int VSyncAndBackPorch;
586 int HBlank;
587
588 /* 8. Estimated Horizontal period */
589 HPeriod = ((double) (1000000.0 / VFieldRate - CVT_MIN_VSYNC_BP)) /
590 (VDisplayRnd + CVT_MIN_V_PORCH);
591
592 /* 9. Find number of lines in sync + backporch */
593 if (((int) (CVT_MIN_VSYNC_BP / HPeriod) + 1) <
594 (VSync + CVT_MIN_V_BPORCH))
595 VSyncAndBackPorch = VSync + CVT_MIN_V_BPORCH;
596 else
597 VSyncAndBackPorch = (int) (CVT_MIN_VSYNC_BP / HPeriod) + 1;
598
599 VTotal = VDisplayRnd + VSyncAndBackPorch + CVT_MIN_V_PORCH;
600
601 /* 5) Definition of Horizontal blanking time limitation */
602 /* Gradient (%/kHz) - default 600 */
603 #define CVT_M_FACTOR 600.0
604
605 /* Offset (%) - default 40 */
606 #define CVT_C_FACTOR 40.0
607
608 /* Blanking time scaling factor - default 128 */
609 #define CVT_K_FACTOR 128.0
610
611 /* Scaling factor weighting - default 20 */
612 #define CVT_J_FACTOR 20.0
613
614 #define CVT_M_PRIME (CVT_M_FACTOR * CVT_K_FACTOR / 256.0)
615 #define CVT_C_PRIME ((CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256.0 + \
616 CVT_J_FACTOR)
617
618 /* 12. Find ideal blanking duty cycle from formula */
619 HBlankPercentage = CVT_C_PRIME - CVT_M_PRIME * HPeriod / 1000.0;
620
621 /* 13. Blanking time */
622 if (HBlankPercentage < 20)
623 HBlankPercentage = 20;
624
625 HBlank = (double)HDisplay * HBlankPercentage / (100.0 - HBlankPercentage) / (2.0 * CVT_H_GRANULARITY);
626 HBlank *= 2 * CVT_H_GRANULARITY;
627
628 /* 14. Find total number of pixels in a line. */
629 HTotal = HDisplay + HBlank;
630
631 int HSync = (HTotal * CVT_HSYNC_PERCENTAGE) / 100.0 + 0.0;
632 //printf("%d %d %d\n", HTotal, HBlank, HSync);
633 HSync -= HSync % CVT_H_GRANULARITY;
634
635 /* Fill in HSync values */
636 HSyncEnd = HTotal - HBlank / 2;
637
638 HSyncStart = HSyncEnd - HSync;
639 VSyncStart = VDisplayRnd + CVT_MIN_V_PORCH;
640 VSyncEnd = VSyncStart + VSync;
641
642 /* 15/13. Find pixel clock frequency (kHz) */
643 Clock = ((double)HTotal / HPeriod) * 1000.0;
644 Clock -= Clock % CVT_CLOCK_STEP;
645 }
646 else { /* Reduced blanking */
647 /* Minimum vertical blanking interval time (µs) - default 460 */
648 #define CVT_RB_MIN_VBLANK 460.0
649
650 /* Fixed number of clocks for horizontal sync */
651 #define CVT_RB_H_SYNC 32.0
652
653 /* Fixed number of clocks for horizontal blanking */
654 #define CVT_RB1_H_BLANK 160.0 // RB1 & RB3 with RB_FLAG set
655 #define CVT_RB2_H_BLANK 80.0 // RB2 & RB3 with RB_FLAG cleared
656
657 /* Fixed number of lines for vertical front porch - default 3 */
658 #define CVT_RB1_V_FPORCH 3
659 #define CVT_RB2_V_FPORCH 1
660 #define CVT_RB3_V_FIELD_RATE_PPM_ADJ 350.0
661 #define CVT_RB2_CLOCK_STEP 1
662
663 int VBILines;
664 double h_blank = (t.rb & ~RB_FLAG) == 1 ? CVT_RB1_H_BLANK : CVT_RB2_H_BLANK;
665 int v_fporch = t.rb == 1 ? CVT_RB1_V_FPORCH : CVT_RB2_V_FPORCH;
666 unsigned clock_step = t.rb == 1 ? CVT_CLOCK_STEP : CVT_RB2_CLOCK_STEP;
667
668 if (t.rb == 3)
669 VFieldRate += VFieldRate * (CVT_RB3_V_FIELD_RATE_PPM_ADJ / 1000000.0);
670
671 /* 8. Estimate Horizontal period. */
672 HPeriod = ((double) (1000000.0 / VFieldRate - CVT_RB_MIN_VBLANK)) / VDisplayRnd;
673
674 /* 9. Find number of lines in vertical blanking */
675 VBILines = ((double) CVT_RB_MIN_VBLANK) / HPeriod;
676 VBILines++;
677
678 /* 10. Check if vertical blanking is sufficient */
679 if (VBILines < (v_fporch + VSync + CVT_MIN_V_BPORCH))
680 VBILines = v_fporch + VSync + CVT_MIN_V_BPORCH;
681
682 /* 11. Find total number of lines in vertical field */
683 VTotal = VDisplayRnd + VBILines;
684
685 /* 12. Find total number of pixels in a line */
686 HTotal = HDisplay + h_blank;
687
688 /* Fill in HSync values */
689 HSyncEnd = HDisplay + h_blank / 2;
690 HSyncStart = HSyncEnd - CVT_RB_H_SYNC;
691
692 /* Fill in VSync values */
693 VSyncStart = VDisplay + v_fporch;
694 VSyncEnd = VSyncStart + VSync;
695
696 /* 15/13. Find pixel clock frequency (kHz) */
697 double clk_khz = ((double)VFieldRate * VTotal * HTotal) / 1000.0;
698 if (t.rb < 3)
699 Clock = clock_step * floor(clk_khz / clock_step);
700 else
701 Clock = clock_step * ceil(clk_khz / clock_step);
702 }
703 t.pixclk_khz = Clock;
704
705 t.pos_pol_hsync = t.rb;
706 t.pos_pol_vsync = !t.rb;
707 t.vfp = VSyncStart - VDisplay;
708 t.vsync = VSyncEnd - VSyncStart;
709 t.vbp = VTotal - VSyncEnd;
710 t.hfp = HSyncStart - HDisplay;
711 t.hsync = HSyncEnd - HSyncStart;
712 t.hbp = HTotal - HSyncEnd;
713 t.interlaced = false;
387 for (unsigned i = 0; i < ARRAY_SIZE(dmt_timings); i++) {
388 if (timings_close_match(t, dmt_timings[i].t)) {
389 dmt = dmt_timings[i].dmt_id;
390 return &dmt_timings[i].t;
391 }
392 }
393 dmt = 0;
394 return NULL;
714395 }
715396
716 timings edid_state::calc_cvt_mode(unsigned refresh, unsigned hact, unsigned vact, unsigned rb)
397 void edid_state::list_dmts()
717398 {
718 timings t = {};
719
720 t.hact = hact;
721 t.vact = vact;
722 t.rb = rb;
723 calc_ratio(&t);
724 edid_cvt_mode(refresh, t);
725 return t;
399 char type[16];
400
401 for (unsigned i = 0; i < ARRAY_SIZE(dmt_timings); i++) {
402 sprintf(type, "DMT 0x%02x", dmt_timings[i].dmt_id);
403 std::string flags;
404 if (dmt_timings[i].std_id)
405 flags += std::string("STD: ") +
406 utohex(dmt_timings[i].std_id >> 8) + " " +
407 utohex(dmt_timings[i].std_id & 0xff);
408 if (dmt_timings[i].cvt_id)
409 add_str(flags, std::string("CVT: ") +
410 utohex(dmt_timings[i].cvt_id >> 16) + " " +
411 utohex((dmt_timings[i].cvt_id >> 8) & 0xff) + " " +
412 utohex(dmt_timings[i].cvt_id & 0xff));
413 print_timings("", &dmt_timings[i].t, type, flags.c_str(), false, false);
414 }
726415 }
727416
728417 void edid_state::detailed_cvt_descriptor(const char *prefix, const unsigned char *x, bool first)
734423 if (!first && !memcmp(x, empty, 3))
735424 return;
736425
737 base.uses_cvt = true;
738426 cvt_t.vact = x[0];
739427 if (!cvt_t.vact)
740428 fail("CVT byte 0 is 0, which is a reserved value.\n");
794482 print_timings(prefix, &cvt_t, "CVT", preferred == 3 ? s_pref : "");
795483 }
796484 if (x[2] & 0x01) {
797 cvt_t.rb = 1;
485 cvt_t.rb = RB_CVT_V1;
798486 edid_cvt_mode(60, cvt_t);
799487 print_timings(prefix, &cvt_t, "CVT", preferred == 4 ? s_pref : "");
800488 }
838526 }
839527
840528 void edid_state::print_standard_timing(const char *prefix, unsigned char b1, unsigned char b2,
841 bool gtf_only, unsigned vrefresh_offset)
529 bool gtf_only, bool show_both)
842530 {
843531 const struct timings *t;
844532 struct timings formula = {};
862550 hact = (b1 + 31) * 8;
863551 switch ((b2 >> 6) & 0x3) {
864552 case 0x00:
865 if (gtf_only || base.edid_minor >= 3) {
553 if (gtf_only || show_both || base.edid_minor >= 3) {
866554 hratio = 16;
867555 vratio = 10;
868556 } else {
884572 break;
885573 }
886574 vact = (double)hact * vratio / hratio;
887 vact = 8 * ((vact + 7) / 8);
888 refresh = vrefresh_offset + (b2 & 0x3f);
575 refresh = (b2 & 0x3f) + 60;
889576
890577 formula.hact = hact;
891578 formula.vact = vact;
892579 formula.hratio = hratio;
893580 formula.vratio = vratio;
894581
895 if (!gtf_only && base.edid_minor >= 4) {
896 base.uses_cvt = true;
897 edid_cvt_mode(refresh, formula);
898 print_timings(prefix, &formula, "CVT ", "EDID 1.4 source");
582 if (!gtf_only && (show_both || base.edid_minor >= 4)) {
583 if (show_both || base.supports_cvt) {
584 edid_cvt_mode(refresh, formula);
585 print_timings(prefix, &formula, "CVT ",
586 show_both ? "" : "EDID 1.4 source");
587 }
899588 /*
900 * A EDID 1.3 source will assume GTF, so both GTF and CVT
589 * An EDID 1.3 source will assume GTF, so both GTF and CVT
901590 * have to be supported.
902591 */
903 base.uses_gtf = true;
904592 edid_gtf_mode(refresh, formula);
905 print_timings(prefix, &formula, "GTF ", "EDID 1.3 source");
593 if (base.supports_cvt)
594 print_timings(prefix, &formula, "GTF ", "EDID 1.3 source");
595 else
596 print_timings(prefix, &formula, "GTF ");
906597 } else if (gtf_only || base.edid_minor >= 2) {
907 base.uses_gtf = true;
908598 edid_gtf_mode(refresh, formula);
909599 print_timings(prefix, &formula, "GTF ");
910600 } else {
913603 min_vert_freq_hz = min(min_vert_freq_hz, refresh);
914604 max_vert_freq_hz = max(max_vert_freq_hz, refresh);
915605 }
606
607 // See Ref. D-8 in the EDID-1.4 spec
608 if (vact & 1)
609 warn("Standard Timing %ux%u has a dubious odd vertical resolution.\n", hact, vact);
916610 }
917611
918612 void edid_state::detailed_display_range_limits(const unsigned char *x)
924618 std::string range_class;
925619
926620 data_block = "Display Range Limits";
927 printf(" %s:\n", data_block.c_str());
621 printf(" %s:\n", data_block.c_str());
928622 base.has_display_range_descriptor = 1;
929623
930624 if (base.edid_minor >= 4) {
950644 range_class = "GTF";
951645 if (base.edid_minor >= 4 && !base.supports_continuous_freq)
952646 fail("GTF can't be combined with non-continuous frequencies.\n");
953 base.supports_gtf = true;
647 if (base.edid_minor >= 4)
648 warn("GTF support is deprecated in EDID 1.4.\n");
954649 break;
955650 case 0x01: /* range limits only */
956651 range_class = "Bare Limits";
961656 range_class = "Secondary GTF";
962657 if (base.edid_minor >= 4 && !base.supports_continuous_freq)
963658 fail("GTF can't be combined with non-continuous frequencies.\n");
964 base.supports_gtf = true;
659 if (base.edid_minor >= 4)
660 warn("GTF support is deprecated in EDID 1.4.\n");
965661 has_sec_gtf = true;
966662 break;
967663 case 0x04: /* cvt */
971667 fail("'%s' is not allowed for EDID < 1.4.\n", range_class.c_str());
972668 else if (!base.supports_continuous_freq)
973669 fail("CVT can't be combined with non-continuous frequencies.\n");
974 if (base.edid_minor >= 4) {
975 /* GTF is implied if CVT is signaled */
976 base.supports_gtf = true;
977 base.supports_cvt = true;
978 }
979670 break;
980671 default: /* invalid */
981672 fail("Unknown range class (0x%02x).\n", x[10]);
991682 fail("Min horizontal freq > max horizontal freq.\n");
992683 base.min_display_hor_freq_hz = (x[7] + h_min_offset) * 1000;
993684 base.max_display_hor_freq_hz = (x[8] + h_max_offset) * 1000;
994 printf(" Monitor ranges (%s): %d-%d Hz V, %d-%d kHz H",
685 printf(" Monitor ranges (%s): %d-%d Hz V, %d-%d kHz H",
995686 range_class.c_str(),
996687 x[5] + v_min_offset, x[6] + v_max_offset,
997688 x[7] + h_min_offset, x[8] + h_max_offset);
1012703 base.max_display_pixclk_khz = x[9] * 10000;
1013704 printf(", max dotclock %d MHz\n", x[9] * 10);
1014705 } else {
706 printf("\n");
1015707 if (base.edid_minor >= 4)
1016708 fail("EDID 1.4 block does not set max dotclock.\n");
1017 printf("\n");
1018709 }
1019710
1020711 if (has_sec_gtf) {
1021712 if (x[11])
1022713 fail("Byte 11 is 0x%02x instead of 0x00.\n", x[11]);
1023 printf(" GTF Secondary Curve Block:\n");
1024 printf(" Start frequency: %u kHz\n", x[12] * 2);
1025 printf(" C: %f\n", x[13] / 2.0);
1026 if (x[13] > 127)
1027 fail("Byte 13 is > 127.\n");
1028 printf(" M: %u\n", (x[15] << 8) | x[14]);
1029 printf(" K: %u\n", x[16]);
1030 printf(" J: %f\n", x[17] / 2.0);
1031 if (x[17] > 127)
1032 fail("Byte 17 is > 127.\n");
714 if (memchk(x + 12, 6)) {
715 fail("Zeroed Secondary Curve Block.\n");
716 } else {
717 printf(" GTF Secondary Curve Block:\n");
718 printf(" Start frequency: %u kHz\n", x[12] * 2);
719 printf(" C: %.1f%%\n", x[13] / 2.0);
720 printf(" M: %u%%/kHz\n", (x[15] << 8) | x[14]);
721 printf(" K: %u\n", x[16]);
722 printf(" J: %.1f%%\n", x[17] / 2.0);
723 }
1033724 } else if (is_cvt) {
1034725 int max_h_pixels = 0;
1035726
1036 printf(" CVT version %d.%d\n", (x[11] & 0xf0) >> 4, x[11] & 0x0f);
727 printf(" CVT version %d.%d\n", (x[11] & 0xf0) >> 4, x[11] & 0x0f);
1037728
1038729 if (x[12] & 0xfc) {
1039730 unsigned raw_offset = (x[12] & 0xfc) >> 2;
1040731
1041 printf(" Real max dotclock: %.2f MHz\n",
732 printf(" Real max dotclock: %.2f MHz\n",
1042733 (x[9] * 10) - (raw_offset * 0.25));
1043734 if (raw_offset >= 40)
1044735 warn("CVT block corrects dotclock by more than 9.75 MHz.\n");
1049740 max_h_pixels |= x[13];
1050741 max_h_pixels *= 8;
1051742 if (max_h_pixels)
1052 printf(" Max active pixels per line: %d\n", max_h_pixels);
1053
1054 printf(" Supported aspect ratios:%s%s%s%s%s\n",
743 printf(" Max active pixels per line: %d\n", max_h_pixels);
744
745 printf(" Supported aspect ratios:%s%s%s%s%s\n",
1055746 x[14] & 0x80 ? " 4:3" : "",
1056747 x[14] & 0x40 ? " 16:9" : "",
1057748 x[14] & 0x20 ? " 16:10" : "",
1060751 if (x[14] & 0x07)
1061752 fail("Reserved bits of byte 14 are non-zero.\n");
1062753
1063 printf(" Preferred aspect ratio: ");
754 printf(" Preferred aspect ratio: ");
1064755 switch ((x[15] & 0xe0) >> 5) {
1065756 case 0x00:
1066757 printf("4:3");
1086777 printf("\n");
1087778
1088779 if (x[15] & 0x08)
1089 printf(" Supports CVT standard blanking\n");
780 printf(" Supports CVT standard blanking\n");
1090781 if (x[15] & 0x10)
1091 printf(" Supports CVT reduced blanking\n");
782 printf(" Supports CVT reduced blanking\n");
1092783
1093784 if (x[15] & 0x07)
1094785 fail("Reserved bits of byte 15 are non-zero.\n");
1095786
1096787 if (x[16] & 0xf0) {
1097 printf(" Supported display scaling:\n");
788 printf(" Supported display scaling:\n");
1098789 if (x[16] & 0x80)
1099 printf(" Horizontal shrink\n");
790 printf(" Horizontal shrink\n");
1100791 if (x[16] & 0x40)
1101 printf(" Horizontal stretch\n");
792 printf(" Horizontal stretch\n");
1102793 if (x[16] & 0x20)
1103 printf(" Vertical shrink\n");
794 printf(" Vertical shrink\n");
1104795 if (x[16] & 0x10)
1105 printf(" Vertical stretch\n");
796 printf(" Vertical stretch\n");
1106797 }
1107798
1108799 if (x[16] & 0x0f)
1109800 fail("Reserved bits of byte 16 are non-zero.\n");
1110801
1111802 if (x[17])
1112 printf(" Preferred vertical refresh: %d Hz\n", x[17]);
803 printf(" Preferred vertical refresh: %d Hz\n", x[17]);
1113804 else
1114805 warn("CVT block does not set preferred refresh rate.\n");
1115806 } else {
1246937 return;
1247938 }
1248939
940 /*
941 * If the borders are non-zero, then it is unclear how to interpret
942 * the DTD blanking parameters.
943 *
944 * According to EDID 1.3 (3.12) the Hor/Vert Blanking includes the
945 * borders, and so does the Hor/Vert Sync Offset.
946 *
947 * According to EDID 1.4 (3.12) the Hor/Vert Blanking excludes the
948 * borders, and they are also excluded from the Hor/Vert Front Porch.
949 *
950 * But looking at what is really done in EDIDs is that the Hor/Vert
951 * Blanking follows EDID 1.3, but the Hor/Vert Front Porch does not
952 * include the border.
953 *
954 * So hbl/vbl includes the borders, so those need to be subtracted,
955 * but hfp/vfp is used as-is.
956 *
957 * In practice you really shouldn't use non-zero borders in DTDs
958 * since clearly nobody knows how to interpret the timing.
959 */
1249960 t.hact = (x[2] + ((x[4] & 0xf0) << 4));
1250 hbl = (x[3] + ((x[4] & 0x0f) << 8));
961 t.hborder = x[15];
962 hbl = (x[3] + ((x[4] & 0x0f) << 8)) - t.hborder * 2;
1251963 t.hfp = (x[8] + ((x[11] & 0xc0) << 2));
1252964 t.hsync = (x[9] + ((x[11] & 0x30) << 4));
1253965 t.hbp = hbl - t.hsync - t.hfp;
1254 t.hborder = x[15];
1255966 t.vact = (x[5] + ((x[7] & 0xf0) << 4));
1256 vbl = (x[6] + ((x[7] & 0x0f) << 8));
967 t.vborder = x[16];
968 vbl = (x[6] + ((x[7] & 0x0f) << 8)) - t.vborder * 2;
1257969 t.vfp = ((x[10] >> 4) + ((x[11] & 0x0c) << 2));
1258970 t.vsync = ((x[10] & 0x0f) + ((x[11] & 0x03) << 4));
1259971 t.vbp = vbl - t.vsync - t.vfp;
1260 t.vborder = x[16];
1261972
1262973 unsigned char flags = x[17];
1263974
13521063 if (block_nr == 0 && base.dtd_cnt == 1) {
13531064 te.type = "DTD 1";
13541065 base.preferred_timing = te;
1355 cta.preferred_timings.push_back(te);
1356 cta.native_timings.push_back(te);
1066 if (has_cta) {
1067 cta.preferred_timings.push_back(te);
1068 cta.native_timings.push_back(te);
1069 }
13571070 }
13581071 if (base_or_cta)
13591072 cta.vec_dtds.push_back(te);
13601073
1074 if (t.hborder || t.vborder)
1075 warn("The use of non-zero borders in a DTD is not recommended.\n");
13611076 if ((base.max_display_width_mm && !t.hsize_mm) ||
13621077 (base.max_display_height_mm && !t.vsize_mm)) {
13631078 fail("Mismatch of image size vs display size: image size is not set, but display size is.\n");
13691084
13701085 s += " ";
13711086 hex_block(s.c_str(), x, 18, true, 18);
1087 }
1088 }
1089
1090 void edid_state::preparse_detailed_block(const unsigned char *x)
1091 {
1092 if (x[0] || x[1])
1093 return;
1094 if (x[3] != 0xfd)
1095 return;
1096
1097 switch (x[10]) {
1098 case 0x00: /* default gtf */
1099 base.supports_gtf = true;
1100 break;
1101 case 0x02: /* secondary gtf curve */
1102 base.supports_gtf = true;
1103 base.supports_sec_gtf = !memchk(x + 12, 6);
1104 base.sec_gtf_start_freq = x[12] * 2;
1105 base.C = x[13] / 2.0;
1106 base.M = (x[15] << 8) | x[14];
1107 base.K = x[16];
1108 base.J = x[17] / 2.0;
1109 break;
1110 case 0x04: /* cvt */
1111 if (base.edid_minor >= 4) {
1112 /* GTF is implied if CVT is signaled */
1113 base.supports_gtf = true;
1114 base.supports_cvt = true;
1115 }
1116 break;
13721117 }
13731118 }
13741119
14251170 case 0xf7:
14261171 data_block = "Established timings III";
14271172 printf(" %s:\n", data_block.c_str());
1428 for (i = 0; i < 44; i++)
1173 for (i = 0; i < ARRAY_SIZE(established_timings3_dmt_ids); i++)
14291174 if (x[6 + i / 8] & (1 << (7 - i % 8))) {
14301175 unsigned char dmt_id = established_timings3_dmt_ids[i];
14311176 char type[16];
14331178 sprintf(type, "DMT 0x%02x", dmt_id);
14341179 print_timings(" ", find_dmt_id(dmt_id), type);
14351180 }
1181 if (base.edid_minor < 4)
1182 fail("Not allowed for EDID < 1.4.\n");
14361183 return;
14371184 case 0xf8:
14381185 data_block = "CVT 3 Byte Timing Codes";
14431190 }
14441191 for (i = 0; i < 4; i++)
14451192 detailed_cvt_descriptor(" ", x + 6 + (i * 3), !i);
1193 if (base.edid_minor < 4)
1194 fail("Not allowed for EDID < 1.4.\n");
14461195 return;
14471196 case 0xf9:
14481197 data_block = "Display Color Management Data";
15541303 }
15551304 }
15561305
1306 /*
1307 * The sRGB chromaticities are (x, y):
1308 * red: 0.640, 0.330
1309 * green: 0.300, 0.600
1310 * blue: 0.150, 0.060
1311 * white: 0.3127, 0.3290
1312 */
1313 static const unsigned char srgb_chromaticity[10] = {
1314 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, 0x0f, 0x50, 0x54
1315 };
1316
15571317 void edid_state::parse_base_block(const unsigned char *x)
15581318 {
15591319 time_t the_time;
15601320 struct tm *ptm;
1561 int analog, i;
1321 int analog;
15621322 unsigned col_x, col_y;
15631323 bool has_preferred_timing = false;
15641324
16531413 fail("Digital Video Interface Standard set to reserved value 0x%02x.\n", x[0x14] & 0x7f);
16541414 }
16551415 } else {
1416 static const char * const voltages[] = {
1417 "0.700 : 0.300 : 1.000 V p-p",
1418 "0.714 : 0.286 : 1.000 V p-p",
1419 "1.000 : 0.400 : 1.400 V p-p",
1420 "0.700 : 0.000 : 0.700 V p-p"
1421 };
16561422 unsigned voltage = (x[0x14] & 0x60) >> 5;
16571423 unsigned sync = (x[0x14] & 0x0f);
16581424
16591425 analog = 1;
16601426 printf(" Analog display\n");
1661 printf(" Input voltage level: %s V\n",
1662 voltage == 3 ? "0.7/0.7" :
1663 voltage == 2 ? "1.0/0.4" :
1664 voltage == 1 ? "0.714/0.286" :
1665 "0.7/0.3");
1427 printf(" Signal Level Standard: %s\n", voltages[voltage]);
16661428
16671429 if (x[0x14] & 0x10)
16681430 printf(" Blank-to-black setup/pedestal\n");
16811443 printf(" Maximum image size: %u cm x %u cm\n", x[0x15], x[0x16]);
16821444 base.max_display_width_mm = x[0x15] * 10;
16831445 base.max_display_height_mm = x[0x16] * 10;
1446 image_width = base.max_display_width_mm * 10;
1447 image_height = base.max_display_height_mm * 10;
16841448 if (x[0x15] < 10 || x[0x16] < 10)
16851449 warn("Dubious maximum image size (%ux%u is smaller than 10x10 cm).\n",
16861450 x[0x15], x[0x16]);
16981462 if (x[0x17] == 0xff)
16991463 printf(" Gamma is defined in an extension block\n");
17001464 else
1701 printf(" Gamma: %.2f\n", ((x[0x17] + 100.0) / 100.0));
1465 printf(" Gamma: %.2f\n", (x[0x17] + 100.0) / 100.0);
17021466
17031467 if (x[0x18] & 0xe0) {
17041468 printf(" DPMS levels:");
17141478 case 0x00: printf("Monochrome or grayscale display\n"); break;
17151479 case 0x08: printf("RGB color display\n"); break;
17161480 case 0x10: printf("Non-RGB color display\n"); break;
1717 case 0x18: printf("Undefined display color type\n");
1481 case 0x18: printf("Undefined display color type\n"); break;
17181482 }
17191483 } else {
17201484 printf(" Supported color formats: RGB 4:4:4");
17261490 }
17271491
17281492 if (x[0x18] & 0x04) {
1729 /*
1730 * The sRGB chromaticities are (x, y):
1731 * red: 0.640, 0.330
1732 * green: 0.300, 0.600
1733 * blue: 0.150, 0.060
1734 * white: 0.3127, 0.3290
1735 */
1736 static const unsigned char srgb_chromaticity[10] = {
1737 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, 0x0f, 0x50, 0x54
1738 };
17391493 printf(" Default (sRGB) color space is primary color space\n");
17401494 if (memcmp(x + 0x19, srgb_chromaticity, sizeof(srgb_chromaticity)))
17411495 fail("sRGB is signaled, but the chromaticities do not match.\n");
1742 }
1496 if (x[0x17] != 120)
1497 warn("sRGB is signaled, but the gamma != 2.2.\n");
1498 } else if (!memcmp(x + 0x19, srgb_chromaticity, sizeof(srgb_chromaticity))) {
1499 fail("The chromaticities match sRGB, but sRGB is not signaled.\n");
1500 }
1501
17431502 if (base.edid_minor >= 4) {
17441503 /* 1.4 always has a preferred timing and this bit means something else. */
17451504 has_preferred_timing = true;
17921551 data_block = "Established Timings I & II";
17931552 if (x[0x23] || x[0x24] || x[0x25]) {
17941553 printf(" %s:\n", data_block.c_str());
1795 for (i = 0; i < 17; i++) {
1554 for (unsigned i = 0; i < ARRAY_SIZE(established_timings12); i++) {
17961555 if (x[0x23 + i / 8] & (1 << (7 - i % 8))) {
17971556 unsigned char dmt_id = established_timings12[i].dmt_id;
17981557 const struct timings *t;
18131572 }
18141573 base.has_640x480p60_est_timing = x[0x23] & 0x20;
18151574
1575 /*
1576 * Need to find the Display Range Limit info before reading
1577 * the standard timings.
1578 */
1579 preparse_detailed_block(x + 0x36);
1580 preparse_detailed_block(x + 0x48);
1581 preparse_detailed_block(x + 0x5a);
1582 preparse_detailed_block(x + 0x6c);
1583
18161584 data_block = "Standard Timings";
18171585 bool found = false;
1818 for (i = 0; i < 8; i++) {
1586 for (unsigned i = 0; i < 8; i++) {
18191587 if (x[0x26 + i * 2] != 0x01 || x[0x26 + i * 2 + 1] != 0x01) {
18201588 found = true;
18211589 break;
18231591 }
18241592 if (found) {
18251593 printf(" %s:\n", data_block.c_str());
1826 for (i = 0; i < 8; i++)
1594 for (unsigned i = 0; i < 8; i++)
18271595 print_standard_timing(" ", x[0x26 + i * 2], x[0x26 + i * 2 + 1]);
18281596 } else {
18291597 printf(" %s: none\n", data_block.c_str());
18431611
18441612 for (unsigned i = 0; i < (base.has_spwg ? 2 : 4); i++)
18451613 if (x[0x36 + i * 18] || x[0x37 + i * 18])
1846 cta.preparse_total_dtds++;
1614 cta.preparsed_total_dtds++;
18471615
18481616 data_block = "Detailed Timing Descriptors";
18491617 printf(" %s:\n", data_block.c_str());
18791647 void edid_state::check_base_block()
18801648 {
18811649 data_block = "Base EDID";
1882 if (base.uses_gtf && !base.supports_gtf)
1883 fail("GTF timings are used, but the EDID does not signal GTF support.\n");
1884 if (base.uses_cvt && !base.supports_cvt)
1885 fail("CVT timings are used, but the EDID does not signal CVT support.\n");
1650
18861651 /*
18871652 * Allow for regular rounding of vertical and horizontal frequencies.
18881653 * The spec says that the pixelclock shall be rounded up, so there is
19391704 */
19401705 msg(!out_of_range || base.edid_minor >= 4, "%s", err.c_str());
19411706 }
1707
1708 if ((image_width && dtd_max_hsize_mm >= 10 + image_width / 10) ||
1709 (image_height && dtd_max_vsize_mm >= 10 + image_height / 10))
1710 fail("The DTD max image size is %ux%umm, which is larger than the display size %.1fx%.1fmm.\n",
1711 dtd_max_hsize_mm, dtd_max_vsize_mm,
1712 image_width / 10.0, image_height / 10.0);
1713 if ((!image_width && dtd_max_hsize_mm) || (!image_height && dtd_max_vsize_mm))
1714 fail("The DTD max image size is %ux%umm, but the display size is not specified anywhere.\n",
1715 dtd_max_hsize_mm, dtd_max_vsize_mm);
1716
1717 // Secondary GTF curves start at a specific frequency. Any legacy timings
1718 // that have a positive hsync and negative vsync must be less than that
1719 // frequency to avoid confusion.
1720 if (base.supports_sec_gtf && base.max_pos_neg_hor_freq_khz >= base.sec_gtf_start_freq)
1721 fail("Second GTF start frequency %u is less than the highest P/N frequency %u.\n",
1722 base.sec_gtf_start_freq, base.max_pos_neg_hor_freq_khz);
19421723 if (base.edid_minor == 3 && num_blocks > 2 && !block_map.saw_block_1)
19431724 fail("EDID 1.3 requires a Block Map Extension in Block 1 if there are more than 2 blocks in the EDID.\n");
19441725 if (base.edid_minor == 3 && num_blocks > 128 && !block_map.saw_block_128)
66 * Maintainer: Hans Verkuil <hverkuil-cisco@xs4all.nl>
77 */
88
9 #include <algorithm>
910 #include <stdio.h>
1011 #include <math.h>
1112
187188 { 4096, 2160, 256, 135, 1188000, 0, false, 88, 88, 128, true, 8, 10, 72, true },
188189 };
189190
191 static const cta_rid rids[] = {
192 /* RID 0-9 */
193 { 0, 0, 0, 0 },
194 { 1280, 720, 16, 9 },
195 { 1280, 720, 64, 27 },
196 { 1680, 720, 64, 27 },
197 { 1920, 1080, 16, 9 },
198 { 1920, 1080, 64, 27 },
199 { 2560, 1080, 64, 27 },
200 { 3840, 1080, 32, 9 },
201 { 2560, 1440, 16, 9 },
202 { 3440, 1440, 64, 27 },
203 /* RID 10-19 */
204 { 5120, 1440, 32, 9 },
205 { 3840, 2160, 16, 9 },
206 { 3840, 2160, 64, 27 },
207 { 5120, 2160, 64, 27 },
208 { 7680, 2160, 32, 9 },
209 { 5120, 2880, 16, 9 },
210 { 5120, 2880, 64, 27 },
211 { 6880, 2880, 64, 27 },
212 { 10240, 2880, 32, 9 },
213 { 7680, 4320, 16, 9 },
214 /* RID 20-28 */
215 { 7680, 4320, 64, 27 },
216 { 10240, 4320, 64, 27 },
217 { 15360, 4320, 32, 9 },
218 { 11520, 6480, 16, 9 },
219 { 11520, 6480, 64, 27 },
220 { 15360, 6480, 64, 27 },
221 { 15360, 8640, 16, 9 },
222 { 15360, 8640, 64, 27 },
223 { 20480, 8640, 64, 27 },
224 };
225
226 static const unsigned char rid2vic[ARRAY_SIZE(rids)][8] = {
227 /* RID 0-9 */
228 {},
229 { 60, 61, 62, 108, 19, 4, 41, 47 },
230 { 65, 66, 67, 109, 68, 69, 70, 71 },
231 { 79, 80, 81, 110, 82, 83, 84, 85 },
232 { 32, 33, 34, 111, 31, 16, 64, 63 },
233 { 72, 73, 74, 112, 75, 76, 77, 78 },
234 { 86, 87, 88, 113, 89, 90, 91, 92 },
235 {},
236 {},
237 {},
238 /* RID 10-19 */
239 {},
240 { 93, 94, 95, 114, 96, 97, 117, 118 },
241 { 103, 104, 105, 116, 106, 107, 119, 120 },
242 { 121, 122, 123, 124, 125, 126, 127, 193 },
243 {},
244 {},
245 {},
246 {},
247 {},
248 { 194, 195, 196, 197, 198, 199, 200, 201 },
249 /* RID 20-28 */
250 { 202, 203, 204, 205, 206, 207, 208, 209 },
251 { 210, 211, 212, 213, 214, 215, 216, 217 },
252 {},
253 {},
254 {},
255 {},
256 {},
257 {},
258 {},
259 };
260
261 static const unsigned vf_rate_values[] = {
262 /* Rate Index 0-7 */
263 0, 24, 25, 30, 48, 50, 60, 100,
264 /* Rate Index 8-15 */
265 120, 144, 200, 240, 300, 360, 400, 480,
266 };
267
190268 static const unsigned char edid_hdmi_mode_map[] = { 95, 94, 93, 98 };
191269
192270 unsigned char hdmi_vic_to_vic(unsigned char hdmi_vic)
200278 {
201279 if (vic > 0 && vic <= ARRAY_SIZE(edid_cta_modes1))
202280 return edid_cta_modes1 + vic - 1;
203 if (vic >= 193 && vic <= ARRAY_SIZE(edid_cta_modes2) + 193)
281 if (vic >= 193 && vic < ARRAY_SIZE(edid_cta_modes2) + 193)
204282 return edid_cta_modes2 + vic - 193;
205283 return NULL;
206284 }
210288 if (hdmi_vic > 0 && hdmi_vic <= ARRAY_SIZE(edid_hdmi_mode_map))
211289 return find_vic_id(edid_hdmi_mode_map[hdmi_vic - 1]);
212290 return NULL;
291 }
292
293 const struct cta_rid *find_rid(unsigned char rid)
294 {
295 if (rid > 0 && rid < ARRAY_SIZE(rids))
296 return &rids[rid];
297 return NULL;
298 }
299
300 static unsigned char rid_to_vic(unsigned char rid, unsigned char rate_index)
301 {
302 if (vf_rate_values[rate_index] > 120)
303 return 0;
304 return rid2vic[rid][rate_index - 1];
305 }
306
307 const struct timings *cta_close_match_to_vic(const timings &t, unsigned &vic)
308 {
309 for (vic = 1; vic <= ARRAY_SIZE(edid_cta_modes1); vic++) {
310 if (timings_close_match(t, edid_cta_modes1[vic - 1]))
311 return &edid_cta_modes1[vic - 1];
312 }
313 for (vic = 193; vic < ARRAY_SIZE(edid_cta_modes2) + 193; vic++) {
314 if (timings_close_match(t, edid_cta_modes1[vic - 193]))
315 return &edid_cta_modes1[vic - 193];
316 }
317 vic = 0;
318 return NULL;
319 }
320
321 void edid_state::cta_list_vics()
322 {
323 char type[16];
324 for (unsigned vic = 1; vic <= ARRAY_SIZE(edid_cta_modes1); vic++) {
325 sprintf(type, "VIC %3u", vic);
326 print_timings("", &edid_cta_modes1[vic - 1], type, "", false, false);
327 }
328 for (unsigned vic = 193; vic < ARRAY_SIZE(edid_cta_modes2) + 193; vic++) {
329 sprintf(type, "VIC %3u", vic);
330 print_timings("", &edid_cta_modes2[vic - 193], type, "", false, false);
331 }
332 }
333
334 void edid_state::cta_list_hdmi_vics()
335 {
336 for (unsigned i = 0; i < ARRAY_SIZE(edid_hdmi_mode_map); i++) {
337 unsigned vic = edid_hdmi_mode_map[i];
338 char type[16];
339
340 sprintf(type, "HDMI VIC %u", i + 1);
341 print_timings("", find_vic_id(vic), type, "", false, false);
342 }
343 }
344
345 void edid_state::cta_list_rids()
346 {
347 for (unsigned i = 1; i < ARRAY_SIZE(rids); i++) {
348 printf("RID %2u: %5ux%-4u %2u:%-2u\n", i,
349 rids[i].hact, rids[i].vact,
350 rids[i].hratio, rids[i].vratio);
351 }
352 }
353
354 void edid_state::cta_list_rid_timings(unsigned list_rid)
355 {
356 for (unsigned rid = 1; rid < ARRAY_SIZE(rids); rid++) {
357 char type[16];
358
359 if (list_rid && rid != list_rid)
360 continue;
361
362 sprintf(type, "RID %u", rid);
363 for (unsigned i = 1; i < ARRAY_SIZE(vf_rate_values); i++) {
364 unsigned fps = vf_rate_values[i];
365
366 if (rid_to_vic(rid, i)) {
367 printf("%s: %5ux%-4u %7.3f Hz %3u:%-2u maps to VIC %u\n", type,
368 rids[rid].hact, rids[rid].vact, (double)fps,
369 rids[rid].hratio, rids[rid].vratio,
370 rid_to_vic(rid, i));
371 continue;
372 }
373 timings t = calc_ovt_mode(rids[rid].hact, rids[rid].vact,
374 rids[rid].hratio, rids[rid].vratio, fps);
375 print_timings("", &t, type, "", false, false);
376 }
377 }
213378 }
214379
215380 static std::string audio_ext_format(unsigned char x)
229394 case 11: return "MPEG-H 3D Audio";
230395 case 12: return "AC-4";
231396 case 13: return "L-PCM 3D Audio";
397 case 14: return "Auro-Cx";
398 case 15: return "MPEG-D USAC";
232399 default: break;
233400 }
234401 fail("Unknown Audio Ext Format 0x%02x.\n", x);
305472 printf(" Max channels: %u\n",
306473 (((x[i + 1] & 0x80) >> 3) | ((x[i] & 0x80) >> 4) |
307474 (x[i] & 0x07))+1);
475 else if ((ext_format == 12 || ext_format == 14) && (x[i] & 0x07))
476 fail("Bits F10-F12 must be 0.\n");
308477 else
309478 printf(" Max channels: %u\n", (x[i] & 0x07)+1);
479
480 if ((format == 1 || format == 14) && (x[i + 2] & 0xf8))
481 fail("Bits F33-F37 must be 0.\n");
482 if (ext_format != 13 && (x[i+1] & 0x80))
483 fail("Bit F27 must be 0.\n");
484
485 // Several sample rates are not supported in certain formats
486 if (ext_format == 12 && (x[i+1] & 0x29))
487 fail("Bits F20, F23 and F25 must be 0.\n");
488 if (ext_format >= 4 && ext_format <= 6 && (x[i+1] & 0x60))
489 fail("Bits F25 and F26 must be 0.\n");
490 if ((ext_format == 8 || ext_format == 10 || ext_format == 15) && (x[i+1] & 0x60))
491 fail("Bits F25 and F26 must be 0.\n");
310492
311493 printf(" Supported sample rates (kHz):%s%s%s%s%s%s%s\n",
312494 (x[i+1] & 0x40) ? " 192" : "",
354536 (x[i+2] & 1) ? "implicitly and explicitly" : "only implicitly");
355537 if (ext_format == 6 && (x[i+2] & 1))
356538 printf(" Supports 22.2ch System H\n");
539 } else if (ext_format == 12 || ext_format == 14) {
540 printf(" Audio Format Code dependent value: %u\n", x[i+2] & 7);
357541 }
358542 }
359543 }
410594 print_timings(" ", t, type, flags);
411595 }
412596 if (override_pref) {
597 if (!cta.preferred_timings.empty()) {
598 if (match_timings(cta.preferred_timings[0].t, *t))
599 warn("For improved preferred timing interoperability, set 'Native detailed modes' to 1.\n");
600 else
601 warn("VIC %u is the preferred timing, overriding the first detailed timings. Is this intended?\n", vic);
602 }
413603 cta.preferred_timings.insert(cta.preferred_timings.begin(),
414604 timings_ext(*t, type, flags));
415 warn("VIC %u is the preferred timing, overriding the first detailed timings. Is this intended?\n", vic);
416605 } else if (first_svd) {
417606 cta.preferred_timings.push_back(timings_ext(*t, type, flags));
418607 }
436625 }
437626 }
438627
628 cta_vfd edid_state::cta_parse_vfd(const unsigned char *x, unsigned lvfd)
629 {
630 cta_vfd vfd = {};
631
632 vfd.rid = x[0] & 0x3f;
633 if (vfd.rid >= ARRAY_SIZE(rids)) {
634 vfd.rid = 0;
635 return vfd;
636 }
637 vfd.bfr50 = !!(x[0] & 0x80);
638 vfd.fr24 = !!(x[0] & 0x40);
639 vfd.bfr60 = lvfd > 1 ? !!(x[1] & 0x80) : 1;
640 vfd.fr144 = lvfd > 1 ? !!(x[1] & 0x40) : 0;
641 vfd.fr_factor = lvfd > 1 ? (x[1] & 0x3f) : 3;
642 vfd.fr48 = lvfd > 2 ? !!(x[2] & 0x01) : 0;
643 return vfd;
644 }
645
646 static bool vfd_has_rate(cta_vfd &vfd, unsigned rate_index)
647 {
648 static const unsigned factors[6] = {
649 1, 2, 4, 8, 12, 16
650 };
651 unsigned rate = vf_rate_values[rate_index];
652 unsigned factor = 0;
653
654 if (!vfd.rid)
655 return false;
656 if (rate == 24)
657 return vfd.fr24;
658 if (rate == 48)
659 return vfd.fr48;
660 if (rate == 144)
661 return vfd.fr144;
662
663 if (!(rate % 30)) {
664 if (!vfd.bfr60)
665 return false;
666 factor = rate / 30;
667 }
668 if (!(rate % 25)) {
669 if (!vfd.bfr50)
670 return false;
671 factor = rate / 25;
672 }
673
674 for (unsigned i = 0; i < ARRAY_SIZE(factors); i++)
675 if (factors[i] == factor && (vfd.fr_factor & (1 << i)))
676 return true;
677 return false;
678 }
679
680 void edid_state::cta_vfdb(const unsigned char *x, unsigned n)
681 {
682 if (n-- == 0) {
683 fail("Length is 0.\n");
684 return;
685 }
686 unsigned char flags = *x++;
687 unsigned lvfd = (flags & 3) + 1;
688
689 if (n % lvfd) {
690 fail("Length - 1 is not a multiple of Lvfd (%u).\n", lvfd);
691 return;
692 }
693 if (flags & 0x80)
694 printf(" Supports YCbCr 4:2:0\n");
695 if (flags & 0x40)
696 printf(" NTSC fractional frame rates are preferred\n");
697 for (unsigned i = 0; i < n; i += lvfd, x += lvfd) {
698 unsigned char rid = x[0] & 0x3f;
699 cta_vfd vfd = cta_parse_vfd(x, lvfd);
700
701 if (lvfd > 2 && (x[2] & 0xfe))
702 fail("Bits F31-F37 must be 0.\n");
703 if (lvfd > 3 && x[3])
704 fail("Bits F40-F47 must be 0.\n");
705 if (rid == 0 || rid >= ARRAY_SIZE(rids)) {
706 fail("Unknown RID %u.\n", rid);
707 continue;
708 }
709 for (unsigned rate_index = 1; rate_index < ARRAY_SIZE(vf_rate_values); rate_index++) {
710 if (!vfd_has_rate(vfd, rate_index))
711 continue;
712 struct timings t = calc_ovt_mode(rids[vfd.rid].hact,
713 rids[vfd.rid].vact,
714 rids[vfd.rid].hratio,
715 rids[vfd.rid].vratio,
716 vf_rate_values[i]);
717 char type[16];
718 sprintf(type, "RID %u@%up", rid, vf_rate_values[rate_index]);
719 print_timings(" ", &t, type);
720 if (rid_to_vic(vfd.rid, i))
721 fail("%s not allowed since it maps to VIC %u.\n",
722 rid_to_vic(vfd.rid, i));
723 }
724 }
725 }
726
439727 void edid_state::print_vic_index(const char *prefix, unsigned idx, const char *suffix, bool ycbcr420)
440728 {
441729 if (!suffix)
502790 max_idx + 1, cta.preparsed_svds[0].size());
503791 }
504792
793 void edid_state::cta_print_svr(unsigned char svr, vec_timings_ext &vec_tim)
794 {
795 char suffix[16];
796
797 if ((svr > 0 && svr < 128) || (svr > 192 && svr < 254)) {
798 const struct timings *t;
799 unsigned char vic = svr;
800
801 sprintf(suffix, "VIC %3u", vic);
802
803 t = find_vic_id(vic);
804 if (t) {
805 print_timings(" ", t, suffix);
806 vec_tim.push_back(timings_ext(*t, suffix, ""));
807 } else {
808 printf(" %s: Unknown\n", suffix);
809 fail("Unknown VIC %u.\n", vic);
810 }
811
812 } else if (svr >= 129 && svr <= 144) {
813 sprintf(suffix, "DTD %3u", svr - 128);
814 if (svr >= cta.preparsed_total_dtds + 129) {
815 printf(" %s: Invalid\n", suffix);
816 fail("Invalid DTD %u.\n", svr - 128);
817 } else {
818 printf(" %s\n", suffix);
819 vec_tim.push_back(timings_ext(svr, suffix));
820 }
821 } else if (svr >= 145 && svr <= 160) {
822 sprintf(suffix, "VTDB %3u", svr - 144);
823 if (svr >= cta.preparsed_total_vtdbs + 145) {
824 printf(" %s: Invalid\n", suffix);
825 fail("Invalid VTDB %u.\n", svr - 144);
826 } else {
827 printf(" %s\n", suffix);
828 vec_tim.push_back(timings_ext(svr, suffix));
829 }
830 } else if (svr >= 161 && svr <= 175) {
831 sprintf(suffix, "RID %u@%up",
832 cta.preparsed_first_vfd.rid, vf_rate_values[svr - 160]);
833 if (!vfd_has_rate(cta.preparsed_first_vfd, svr - 160)) {
834 printf(" %s: Invalid\n", suffix);
835 fail("Invalid %s.\n", suffix);
836 } else {
837 printf(" %s\n", suffix);
838 vec_tim.push_back(timings_ext(svr, suffix));
839 }
840 } else if (svr == 254) {
841 sprintf(suffix, "T8VTDB");
842 if (!cta.preparsed_has_t8vtdb) {
843 printf(" %s: Invalid\n", suffix);
844 fail("Invalid T8VTDB.\n");
845 } else {
846 printf(" %s\n", suffix);
847 vec_tim.push_back(timings_ext(svr, suffix));
848 }
849 }
850 }
851
505852 void edid_state::cta_vfpdb(const unsigned char *x, unsigned length)
506853 {
507854 unsigned i;
511858 return;
512859 }
513860 cta.preferred_timings.clear();
514 for (i = 0; i < length; i++) {
515 unsigned char svr = x[i];
516 char suffix[16];
517
518 if ((svr > 0 && svr < 128) || (svr > 192 && svr < 254)) {
519 const struct timings *t;
520 unsigned char vic = svr;
521
522 sprintf(suffix, "VIC %3u", vic);
523
524 t = find_vic_id(vic);
525 if (t) {
526 print_timings(" ", t, suffix);
527 cta.preferred_timings.push_back(timings_ext(*t, suffix, ""));
528 } else {
529 printf(" %s: Unknown\n", suffix);
530 fail("Unknown VIC %u.\n", vic);
531 }
532
533 } else if (svr >= 129 && svr <= 144) {
534 sprintf(suffix, "DTD %3u", svr - 128);
535 if (svr >= cta.preparse_total_dtds + 129) {
536 printf(" %s: Invalid\n", suffix);
537 fail("Invalid DTD %u.\n", svr - 128);
538 } else {
539 printf(" %s\n", suffix);
540 cta.preferred_timings.push_back(timings_ext(svr, suffix));
541 }
542 } else if (svr >= 145 && svr <= 160) {
543 sprintf(suffix, "VTDB %3u", svr - 144);
544 if (svr >= cta.preparse_total_vtdbs + 145) {
545 printf(" %s: Invalid\n", suffix);
546 fail("Invalid VTDB %u.\n", svr - 144);
547 } else {
548 printf(" %s\n", suffix);
549 cta.preferred_timings.push_back(timings_ext(svr, suffix));
550 }
551 } else if (svr == 254) {
552 sprintf(suffix, "T8VTDB");
553 if (!cta.preparse_has_t8vtdb) {
554 printf(" %s: Invalid\n", suffix);
555 fail("Invalid T8VTDB.\n");
556 } else {
557 printf(" %s\n", suffix);
558 cta.preferred_timings.push_back(timings_ext(svr, suffix));
559 }
560 }
561 }
562 }
563
564 static std::string hdmi_latency(unsigned char l, bool is_video)
861 for (i = 0; i < length; i++)
862 cta_print_svr(x[i], cta.preferred_timings);
863 }
864
865 void edid_state::cta_nvrdb(const unsigned char *x, unsigned length)
866 {
867 if (length == 0) {
868 fail("Empty Data Block with length %u.\n", length);
869 return;
870 }
871
872 unsigned char flags = length == 1 ? 0 : x[1];
873
874 cta.native_timings.clear();
875 cta_print_svr(x[0], cta.native_timings);
876 if ((flags & 1) && length < 6) {
877 fail("Data Block too short for Image Size (length = %u).\n", length);
878 return;
879 }
880 if (flags & 0x7e)
881 fail("Bits F41-F46 must be 0.\n");
882 if (!(flags & 1))
883 return;
884
885 unsigned w = (x[3] << 8) | x[2];
886 unsigned h = (x[5] << 8) | x[4];
887
888 if (!w || !h)
889 fail("Image Size has a zero width and/or height.\n");
890
891 if (flags & 0x80)
892 printf(" Image Size: %ux%u mm\n", w, h);
893 else
894 printf(" Image Size: %.1fx%.1f mm\n", w / 10.0, h / 10.0);
895 }
896
897 static std::string hdmi_latency2s(unsigned char l, bool is_video)
565898 {
566899 if (!l)
567900 return "Unknown";
570903 return std::to_string(1 + 2 * l) + " ms";
571904 }
572905
906 void edid_state::hdmi_latency(unsigned char vid_lat, unsigned char aud_lat,
907 bool is_ilaced)
908 {
909 const char *vid = is_ilaced ? "Interlaced video" : "Video";
910 const char *aud = is_ilaced ? "Interlaced audio" : "Audio";
911
912 printf(" %s latency: %s\n", vid, hdmi_latency2s(vid_lat, true).c_str());
913 printf(" %s latency: %s\n", aud, hdmi_latency2s(aud_lat, false).c_str());
914
915 if (vid_lat > 251 && vid_lat != 0xff)
916 fail("Invalid %s latency value %u.\n", vid, vid_lat);
917 if (aud_lat > 251 && aud_lat != 0xff)
918 fail("Invalid %s latency value %u.\n", aud, aud_lat);
919
920 if (!vid_lat || vid_lat > 251)
921 return;
922 if (!aud_lat || aud_lat > 251)
923 return;
924
925 unsigned vid_ms = 1 + 2 * vid_lat;
926 unsigned aud_ms = 1 + 2 * aud_lat;
927
928 // HDMI 2.0 latency checks for devices without HDMI output
929 if (aud_ms < vid_ms)
930 warn("%s latency < %s latency (%u ms < %u ms). This is discouraged for devices without HDMI output.\n",
931 aud, vid, aud_ms, vid_ms);
932 else if (vid_ms + 20 < aud_ms)
933 warn("%s latency + 20 < %s latency (%u + 20 ms < %u ms). This is forbidden for devices without HDMI output.\n",
934 vid, aud, vid_ms, aud_ms);
935 else if (vid_ms < aud_ms)
936 warn("%s latency < %s latency (%u ms < %u ms). This is discouraged for devices without HDMI output.\n",
937 vid, aud, vid_ms, aud_ms);
938 }
939
573940 void edid_state::cta_hdmi_block(const unsigned char *x, unsigned length)
574941 {
575942 unsigned len_vic, len_3d;
576943
577 if (length < 4) {
944 if (length < 1) {
578945 fail("Empty Data Block with length %u.\n", length);
579946 return;
580947 }
581 printf(" Source physical address: %u.%u.%u.%u\n", x[3] >> 4, x[3] & 0x0f,
582 x[4] >> 4, x[4] & 0x0f);
583
584 if (length < 6)
585 return;
586
587 if (x[5] & 0x80)
948 printf(" Source physical address: %x.%x.%x.%x\n", x[0] >> 4, x[0] & 0x0f,
949 x[1] >> 4, x[1] & 0x0f);
950
951 if (length < 3)
952 return;
953
954 if (x[2] & 0x80)
588955 printf(" Supports_AI\n");
589 if (x[5] & 0x40)
956 if (x[2] & 0x40)
590957 printf(" DC_48bit\n");
591 if (x[5] & 0x20)
958 if (x[2] & 0x20)
592959 printf(" DC_36bit\n");
593 if (x[5] & 0x10)
960 if (x[2] & 0x10)
594961 printf(" DC_30bit\n");
595 if (x[5] & 0x08)
962 if (x[2] & 0x08)
596963 printf(" DC_Y444\n");
597964 /* two reserved bits */
598 if (x[5] & 0x01)
965 if (x[2] & 0x01)
599966 printf(" DVI_Dual\n");
600967
601 if (length < 7)
602 return;
603
604 printf(" Maximum TMDS clock: %u MHz\n", x[6] * 5);
605 if (x[6] * 5 > 340)
968 if (length < 4)
969 return;
970
971 printf(" Maximum TMDS clock: %u MHz\n", x[3] * 5);
972 if (x[3] * 5 > 340)
606973 fail("HDMI VSDB Max TMDS rate is > 340.\n");
607974
608 if (length < 8)
609 return;
610
611 if (x[7] & 0x0f) {
975 if (length < 5)
976 return;
977
978 if (x[4] & 0x0f) {
612979 printf(" Supported Content Types:\n");
613 if (x[7] & 0x01)
980 if (x[4] & 0x01)
614981 printf(" Graphics\n");
615 if (x[7] & 0x02)
982 if (x[4] & 0x02)
616983 printf(" Photo\n");
617 if (x[7] & 0x04)
984 if (x[4] & 0x04)
618985 printf(" Cinema\n");
619 if (x[7] & 0x08)
986 if (x[4] & 0x08)
620987 printf(" Game\n");
621988 }
622989
623 unsigned b = 8;
624 if (x[7] & 0x80) {
625 printf(" Video latency: %s\n", hdmi_latency(x[b], true).c_str());
626 printf(" Audio latency: %s\n", hdmi_latency(x[b + 1], false).c_str());
990 unsigned b = 5;
991 if (x[4] & 0x80) {
992 hdmi_latency(x[b], x[b + 1], false);
993
994 if (x[4] & 0x40) {
995 if (x[b] == x[b + 2] &&
996 x[b + 1] == x[b + 3])
997 warn("Progressive and Interlaced latency values are identical, no need for both.\n");
998 b += 2;
999 hdmi_latency(x[b], x[b + 1], true);
1000 }
6271001 b += 2;
628
629 if (x[7] & 0x40) {
630 printf(" Interlaced video latency: %s\n", hdmi_latency(x[b], true).c_str());
631 printf(" Interlaced audio latency: %s\n", hdmi_latency(x[b + 1], false).c_str());
632 b += 2;
633 }
634 }
635
636 if (!(x[7] & 0x20))
1002 }
1003
1004 if (!(x[4] & 0x20))
6371005 return;
6381006
6391007 bool mask = false;
8421210 static void cta_hf_scdb(const unsigned char *x, unsigned length)
8431211 {
8441212 unsigned rate = x[1] * 5;
1213 unsigned v;
8451214
8461215 printf(" Version: %u\n", x[0]);
8471216 if (rate) {
8531222 printf(" SCDC Present\n");
8541223 if (x[2] & 0x40)
8551224 printf(" SCDC Read Request Capable\n");
1225 if (x[2] & 0x20)
1226 printf(" Supports Cable Status\n");
8561227 if (x[2] & 0x10)
8571228 printf(" Supports Color Content Bits Per Component Indication\n");
8581229 if (x[2] & 0x08)
9061277 if (length <= 5)
9071278 return;
9081279
909 printf(" VRRmin: %d Hz\n", x[5] & 0x3f);
910 printf(" VRRmax: %d Hz\n", (x[5] & 0xc0) << 2 | x[6]);
1280 v = x[5] & 0x3f;
1281 if (v) {
1282 printf(" VRRmin: %u Hz\n", v);
1283 if (v > 48)
1284 fail("VRRmin > 48.\n");
1285 }
1286 v = (x[5] & 0xc0) << 2 | x[6];
1287 if (v) {
1288 printf(" VRRmax: %u Hz\n", v);
1289 if (!(x[5] & 0x3f))
1290 fail("VRRmin == 0, but VRRmax isn't.\n");
1291 else if (v < 100)
1292 fail("VRRmax < 100.\n");
1293 }
9111294
9121295 if (length <= 7)
9131296 return;
9511334 1024 * (1 + (x[9] & 0x3f)));
9521335 }
9531336
1337 static void cta_amd(const unsigned char *x, unsigned length)
1338 {
1339 // These Freesync values are reversed engineered by looking
1340 // at existing EDIDs.
1341 printf(" Version: %u.%u\n", x[0], x[1]);
1342 printf(" Minimum Refresh Rate: %u Hz\n", x[2]);
1343 printf(" Maximum Refresh Rate: %u Hz\n", x[3]);
1344 // Freesync 1.x flags
1345 // One or more of the 0xe6 bits signal that the VESA MCCS
1346 // protocol is used to switch the Freesync range
1347 printf(" Flags 1.x: 0x%02x%s\n", x[4],
1348 (x[4] & 0xe6) ? " (MCCS)" : "");
1349 if (length >= 10) {
1350 // Freesync 2.x flags
1351 // Bit 2 no doubt indicates if the monitor supports Local Dimming
1352 // There are probably also bits to signal support of the
1353 // FreeSync2_scRGB and FreeSync2_Gamma22 HDR display modes.
1354 // I suspect bits 0 and 1.
1355 printf(" Flags 2.x: 0x%02x\n", x[5]);
1356 // The AMD tone mapping tutorial referred to in the URL below
1357 // mentions that the Freesync HDR info reports max/min
1358 // luminance of the monitor with and without local dimming.
1359 //
1360 // https://gpuopen.com/learn/using-amd-freesync-premium-pro-hdr-code-samples/
1361 //
1362 // So I assume that the first two luminance values are
1363 // the max/min luminance of the display and the next two
1364 // luminance values are the max/min luminance values when
1365 // local dimming is disabled. The values I get seem to
1366 // support that.
1367 printf(" Maximum luminance: %u (%.3f cd/m^2)\n",
1368 x[6], 50.0 * pow(2, x[6] / 32.0));
1369 printf(" Minimum luminance: %u (%.3f cd/m^2)\n",
1370 x[7], (50.0 * pow(2, x[6] / 32.0)) * pow(x[7] / 255.0, 2) / 100.0);
1371 if (x[5] & 4) {
1372 // One or both bytes can be 0. The meaning of that
1373 // is unknown.
1374 printf(" Maximum luminance (without local dimming): %u (%.3f cd/m^2)\n",
1375 x[8], 50.0 * pow(2, x[8] / 32.0));
1376 printf(" Minimum luminance (without local dimming): %u (%.3f cd/m^2)\n",
1377 x[9], (50.0 * pow(2, x[8] / 32.0)) * pow(x[9] / 255.0, 2) / 100.0);
1378 } else {
1379 // These bytes are always 0x08 0x2f. If these values
1380 // represent max/min luminance as well, then these
1381 // would map to 59.460 and 0.020 cd/m^2 respectively.
1382 // I wonder if this somehow relates to SDR.
1383 printf(" Unknown: 0x%02x 0x%02x\n", x[8], x[9]);
1384 }
1385 }
1386 }
1387
1388 static std::string display_use_case(unsigned char x)
1389 {
1390 switch (x) {
1391 case 1: return "Test equipment";
1392 case 2: return "Generic display";
1393 case 3: return "Television display";
1394 case 4: return "Desktop productivity display";
1395 case 5: return "Desktop gaming display";
1396 case 6: return "Presentation display";
1397 case 7: return "Virtual reality headset";
1398 case 8: return "Augmented reality";
1399 case 16: return "Video wall display";
1400 case 17: return "Medical imaging display";
1401 case 18: return "Dedicated gaming display";
1402 case 19: return "Dedicated video monitor display";
1403 case 20: return "Accessory display";
1404 default: break;
1405 }
1406 fail("Unknown Display product primary use case 0x%02x.\n", x);
1407 return std::string("Unknown display use case (") + utohex(x) + ")";
1408 }
1409
1410 static void cta_microsoft(const unsigned char *x, unsigned length)
1411 {
1412 // This VSDB is documented at:
1413 // https://docs.microsoft.com/en-us/windows-hardware/drivers/display/specialized-monitors-edid-extension
1414 printf(" Version: %u\n", x[0]);
1415 if (x[0] > 2) {
1416 // In version 1 and 2 these bits should always be set to 0.
1417 printf(" Desktop Usage: %u\n", (x[1] >> 6) & 1);
1418 printf(" Third-Party Usage: %u\n", (x[1] >> 5) & 1);
1419 }
1420 printf(" Display Product Primary Use Case: %u (%s)\n", x[1] & 0x1f,
1421 display_use_case(x[1] & 0x1f).c_str());
1422 printf(" Container ID: %s\n", containerid2s(x + 2).c_str());
1423 }
1424
9541425 static void cta_hdr10plus(const unsigned char *x, unsigned length)
9551426 {
956 printf(" Application Version: %u", x[0]);
957 if (length > 1)
958 hex_block(" ", x + 1, length - 1);
959 else
960 printf("\n");
1427 if (length == 0) {
1428 fail("Empty Data Block with length %u.\n", length);
1429 return;
1430 }
1431 printf(" Application Version: %u\n", x[0]);
1432 hex_block(" ", x + 1, length - 1);
1433 }
1434
1435 // Convert a PQ value (0-1) to cd/m^2 aka nits (0-10000)
1436 static double pq2nits(double pq)
1437 {
1438 const double m1 = 2610.0 / 16384.0;
1439 const double m2 = 128.0 * (2523.0 / 4096.0);
1440 const double c1 = 3424.0 / 4096.0;
1441 const double c2 = 32.0 * (2413.0 / 4096.0);
1442 const double c3 = 32.0 * (2392.0 / 4096.0);
1443 double e = pow(pq, 1.0 / m2);
1444 double v = e - c1;
1445
1446 if (v < 0)
1447 v = 0;
1448 v /= c2 - c3 * e;
1449 v = pow(v, 1.0 / m1);
1450 return v * 10000.0;
9611451 }
9621452
9631453 static void cta_dolby_video(const unsigned char *x, unsigned length)
9751465 printf(" Supports global dimming\n");
9761466 unsigned char dm_version = x[16];
9771467 printf(" DM Version: %u.%u\n", dm_version >> 4, dm_version & 0xf);
978 printf(" Target Min PQ: %u\n", (x[14] << 4) | (x[13] >> 4));
979 printf(" Target Max PQ: %u\n", (x[15] << 4) | (x[13] & 0xf));
1468 unsigned pq = (x[14] << 4) | (x[13] >> 4);
1469 printf(" Target Min PQ: %u (%.8f cd/m^2)\n", pq, pq2nits(pq / 4095.0));
1470 pq = (x[15] << 4) | (x[13] & 0xf);
1471 printf(" Target Max PQ: %u (%u cd/m^2)\n", pq, (unsigned)pq2nits(pq / 4095.0));
9801472 printf(" Rx, Ry: %.8f, %.8f\n",
9811473 ((x[1] >> 4) | (x[2] << 4)) / 4096.0,
9821474 ((x[1] & 0xf) | (x[3] << 4)) / 4096.0);
10011493 printf(" DM Version: %u.x\n", dm_version + 2);
10021494 printf(" Colorimetry: %s\n", (x[2] & 0x01) ? "P3-D65" : "ITU-R BT.709");
10031495 printf(" Low Latency: %s\n", (x[3] & 0x01) ? "Standard + Low Latency" : "Only Standard");
1004 printf(" Target Max Luminance: %u cd/m^2\n", 100 + (x[1] >> 1) * 50);
10051496 double lm = (x[2] >> 1) / 127.0;
10061497 printf(" Target Min Luminance: %.8f cd/m^2\n", lm * lm);
1498 printf(" Target Max Luminance: %u cd/m^2\n", 100 + (x[1] >> 1) * 50);
10071499 if (length == 10) {
10081500 printf(" Rx, Ry: %.8f, %.8f\n", x[4] / 256.0, x[5] / 256.0);
10091501 printf(" Gx, Gy: %.8f, %.8f\n", x[6] / 256.0, x[7] / 256.0);
10551547 case 2: printf("12 bit\n"); break;
10561548 case 3: printf("Reserved\n"); break;
10571549 }
1058 printf(" Target Min PQ v2: %u\n", 20 * (x[1] >> 3));
1059 printf(" Target Max PQ v2: %u\n", 2055 + 65 * (x[2] >> 3));
1550
1551 // This divider constant is a guess. According to what I read
1552 // when googling for how to interpret these values, the Min PQ
1553 // maps to a range of 0-1 cd/m^2, and the Max PQ maps to a
1554 // range of 100-10000 cd/m^2. Since the maximum value for the Max PQ
1555 // is 2055 + 65 * 31 = 4070, I am guessing that that is the correct
1556 // divider, but it might well be 4095 or 4096 instead.
1557 //
1558 // I'm also not sure if the divider for Min PQ is the same as for
1559 // Max PQ. To map the max value of 20 * 31 to 1 cd/m^2 you would
1560 // need a divider of 4134 or 4135, but I suspect the same divider
1561 // is used.
1562 const double dv_pq_div = 2055 + 31 * 65;
1563
1564 unsigned pq = 20 * (x[1] >> 3);
1565 printf(" Target Min PQ v2: %u (%.8f cd/m^2)\n", pq, pq2nits(pq / dv_pq_div));
1566 pq = 2055 + 65 * (x[2] >> 3);
1567 printf(" Target Max PQ v2: %u (%u cd/m^2)\n", pq, (unsigned)pq2nits(pq / dv_pq_div));
10601568
10611569 double xmin = 0.625;
10621570 double xstep = (0.74609375 - xmin) / 31.0;
13311839 return s / 64.0;
13321840 }
13331841
1334 static void cta_rcdb(const unsigned char *x, unsigned length)
1842 void edid_state::cta_rcdb(const unsigned char *x, unsigned length)
13351843 {
13361844 unsigned spm = ((x[3] << 16) | (x[2] << 8) | x[1]);
13371845 unsigned i;
13411849 return;
13421850 }
13431851
1344 if (x[0] & 0x40)
1852 if ((x[0] & 0x20) && !cta.has_sldb)
1853 fail("'SLD' flag is 1, but no Speaker Location Data Block is found.\n");
1854 else if (!(x[0] & 0x20) && cta.has_sldb)
1855 fail("'SLD' flag is 0, but a Speaker Location Data Block is present.\n");
1856
1857 if (x[0] & 0x40) {
13451858 printf(" Speaker count: %u\n", (x[0] & 0x1f) + 1);
1859 } else {
1860 if (x[0] & 0x1f)
1861 fail("'Speaker' flag is 0, but 'Speaker Count' is != 0.\n");
1862 if (x[0] & 0x20)
1863 fail("'SLD' flag is 1, but 'Speaker' is 0.\n");
1864 }
13461865
13471866 printf(" Speaker Presence Mask:\n");
13481867 for (i = 0; i < ARRAY_SIZE(speaker_map); i++) {
13491868 if ((spm >> i) & 1)
13501869 printf(" %s\n", speaker_map[i]);
13511870 }
1871
13521872 if ((x[0] & 0xa0) == 0x80)
13531873 fail("'Display' flag set, but not the 'SLD' flag.\n");
1354 if ((x[0] & 0x20) && length >= 7) {
1874
1875 bool valid_max = cta.preparsed_sld_has_coord || (x[0] & 0x80);
1876
1877 if (valid_max && length >= 7) {
13551878 printf(" Xmax: %u dm\n", x[4]);
13561879 printf(" Ymax: %u dm\n", x[5]);
13571880 printf(" Zmax: %u dm\n", x[6]);
1881 } else if (!valid_max && length >= 7) {
1882 // The RCDB should have been truncated.
1883 warn("'Display' flag is 0 and 'Coord' is 0 for all SLDs, but the Max coordinates are still present.\n");
13581884 }
13591885 if ((x[0] & 0x80) && length >= 10) {
13601886 printf(" DisplayX: %.3f * Xmax\n", decode_uchar_as_double(x[7]));
13611887 printf(" DisplayY: %.3f * Ymax\n", decode_uchar_as_double(x[8]));
13621888 printf(" DisplayZ: %.3f * Zmax\n", decode_uchar_as_double(x[9]));
1889 } else if (!(x[0] & 0x80) && length >= 10) {
1890 // The RCDB should have been truncated.
1891 warn("'Display' flag is 0, but the Display coordinates are still present.\n");
13631892 }
13641893 }
13651894
13941923 "RS - Right Surround",
13951924 };
13961925
1397 static void cta_sldb(const unsigned char *x, unsigned length)
1926 void edid_state::cta_sldb(const unsigned char *x, unsigned length)
13981927 {
13991928 if (length < 2) {
14001929 fail("Empty Data Block with length %u.\n", length);
14011930 return;
14021931 }
1932
1933 unsigned active_cnt = 0;
1934 unsigned channel_is_active = 0;
1935
14031936 while (length >= 2) {
14041937 printf(" Channel: %u (%sactive)\n", x[0] & 0x1f,
14051938 (x[0] & 0x20) ? "" : "not ");
1939 if (x[0] & 0x20) {
1940 if (channel_is_active & (1U << (x[0] & 0x1f)))
1941 fail("Channel Index %u was already marked 'Active'.\n",
1942 x[0] & 0x1f);
1943 channel_is_active |= 1U << (x[0] & 0x1f);
1944 active_cnt++;
1945 }
14061946 if ((x[1] & 0x1f) < ARRAY_SIZE(speaker_location))
14071947 printf(" Speaker: %s\n", speaker_location[x[1] & 0x1f]);
14081948 if (length >= 5 && (x[0] & 0x40)) {
14131953 x += 3;
14141954 }
14151955
1956 length -= 2;
1957 x += 2;
1958 }
1959 if (active_cnt != cta.preparsed_speaker_count)
1960 fail("There are %u active speakers, but 'Speaker Count' is %u.\n",
1961 active_cnt, cta.preparsed_speaker_count);
1962 }
1963
1964 void edid_state::cta_preparse_sldb(const unsigned char *x, unsigned length)
1965 {
1966 cta.has_sldb = true;
1967 while (length >= 2) {
1968 if (length >= 5 && (x[0] & 0x40)) {
1969 cta.preparsed_sld_has_coord = true;
1970 return;
1971 }
14161972 length -= 2;
14171973 x += 2;
14181974 }
14371993 * follow the default rules with respect to RGB Quantization Range
14381994 * handling.
14391995 *
1440 * The HDMI 2.0 spec recommends that this is set, but it is a good
1441 * recommendation in general, not just for HDMI.
1996 * Starting with the CTA-861-H spec this bit is now required to be
1997 * 1 for new designs.
14421998 */
14431999 if (!(d & 0x40))
1444 warn("Set Selectable RGB Quantization to avoid interop issues.\n");
2000 fail("Set Selectable RGB Quantization to avoid interop issues.\n");
14452001 /*
1446 * HDMI 2.0 recommends that the Selectable YCbCr Quantization bit is set
1447 * as well, but in practice this is less of an interop issue.
2002 * Since most YCbCr formats use limited range, the interop issues are
2003 * less noticable than for RGB formats.
14482004 *
1449 * I decided to not warn about this (for now).
1450 *
1451 * if (!(d & 0x80))
1452 * warn("Set Selectable YCbCr Quantization to avoid interop issues.\n");
2005 * Starting with the CTA-861-H spec this bit is now required to be
2006 * 1 for new designs, but just warn about it (for now).
14532007 */
2008 if ((cta.byte3 & 0x30) && !(d & 0x80))
2009 warn("Set Selectable YCbCr Quantization to avoid interop issues.\n");
2010
2011 unsigned char s_pt = (d >> 4) & 0x03;
2012 unsigned char s_it = (d >> 2) & 0x03;
2013 unsigned char s_ce = d & 0x03;
2014
14542015 printf(" PT scan behavior: ");
1455 switch ((d >> 4) & 0x03) {
2016 switch (s_pt) {
14562017 case 0: printf("No Data\n"); break;
14572018 case 1: printf("Always Overscanned\n"); break;
14582019 case 2: printf("Always Underscanned\n"); break;
14592020 case 3: printf("Supports both over- and underscan\n"); break;
14602021 }
14612022 printf(" IT scan behavior: ");
1462 switch ((d >> 2) & 0x03) {
2023 switch (s_it) {
14632024 case 0: printf("IT video formats not supported\n"); break;
14642025 case 1:
14652026 printf("Always Overscanned\n");
14752036 break;
14762037 case 3: printf("Supports both over- and underscan\n"); break;
14772038 }
1478 if (((d >> 2) & 0x03) < 2)
2039 if (s_it < 2)
14792040 warn("IT scan behavior is expected to support underscanned.\n");
14802041 printf(" CE scan behavior: ");
1481 switch (d & 0x03) {
2042 switch (s_ce) {
14822043 case 0: printf("CE video formats not supported\n"); break;
14832044 case 1: printf("Always Overscanned\n"); break;
14842045 case 2: printf("Always Underscanned\n"); break;
14852046 case 3: printf("Supports both over- and underscan\n"); break;
14862047 }
1487 if ((d & 0x03) == 0)
2048 if (s_ce == 0)
14882049 warn("'CE video formats not supported' makes no sense.\n");
1489 }
1490
1491 static const char *colorimetry_map[] = {
2050 else if (s_pt == s_it && s_pt == s_ce)
2051 warn("S_PT is equal to S_IT and S_CE, so should be set to 0 instead.\n");
2052 }
2053
2054 static const char *colorimetry1_map[] = {
14922055 "xvYCC601",
14932056 "xvYCC709",
14942057 "sYCC601",
14992062 "BT2020RGB",
15002063 };
15012064
2065 static const char *colorimetry2_map[] = {
2066 "Reserved MD0",
2067 "Reserved MD1",
2068 "Reserved MD2",
2069 "Reserved MD3",
2070 "Default",
2071 "sRGB",
2072 "ICtCp",
2073 "ST2113RGB",
2074 };
2075
15022076 static void cta_colorimetry_block(const unsigned char *x, unsigned length)
15032077 {
15042078 unsigned i;
15072081 fail("Empty Data Block with length %u.\n", length);
15082082 return;
15092083 }
1510 for (i = 0; i < ARRAY_SIZE(colorimetry_map); i++) {
2084 for (i = 0; i < ARRAY_SIZE(colorimetry1_map); i++)
15112085 if (x[0] & (1 << i))
1512 printf(" %s\n", colorimetry_map[i]);
1513 }
1514 if (x[1] & 0x80)
1515 printf(" DCI-P3\n");
1516 if (x[1] & 0x40)
1517 printf(" ICtCp\n");
2086 printf(" %s\n", colorimetry1_map[i]);
2087 if (x[1] & 0xf)
2088 fail("Reserved bits MD0-MD3 must be 0.\n");
2089 for (i = 0; i < ARRAY_SIZE(colorimetry2_map); i++)
2090 if (x[1] & (1 << i))
2091 printf(" %s\n", colorimetry2_map[i]);
15182092 }
15192093
15202094 static const char *eotf_map[] = {
16862260 x++;
16872261 length--;
16882262 for (unsigned i = 0; i < length / sz; i++)
1689 parse_displayid_type_10_timing(x + i * sz, true);
2263 parse_displayid_type_10_timing(x + i * sz, sz, true);
16902264 }
16912265
16922266 static void cta_hdmi_audio_block(const unsigned char *x, unsigned length)
17552329 }
17562330 }
17572331
1758 void edid_state::cta_ext_block(const unsigned char *x, unsigned length)
1759 {
1760 const char *name;
1761 unsigned oui;
1762 bool reverse = false;
2332 void edid_state::cta_block(const unsigned char *x, std::vector<unsigned> &found_tags)
2333 {
2334 unsigned length = x[0] & 0x1f;
2335 unsigned tag = (x[0] & 0xe0) >> 5;
2336 unsigned extended = (tag == 0x07) ? 1 : 0;
2337
2338 x++;
2339 if (extended && length) {
2340 tag <<= 8;
2341 tag |= x[0];
2342 length--;
2343 x++;
2344 }
2345
2346 bool dooutputname = true;
17632347 bool audio_block = false;
1764
1765 switch (x[0]) {
1766 case 0x00: data_block = "Video Capability Data Block"; break;
1767 case 0x01: data_block.clear(); break;
1768 case 0x02: data_block = "VESA Video Display Device Data Block"; break;
1769 case 0x03: data_block = "VESA Video Timing Block Extension"; break;
1770 case 0x04: data_block = "Reserved for HDMI Video Data Block"; break;
1771 case 0x05: data_block = "Colorimetry Data Block"; break;
1772 case 0x06: data_block = "HDR Static Metadata Data Block"; break;
1773 case 0x07: data_block = "HDR Dynamic Metadata Data Block"; break;
1774
1775 case 0x0d: data_block = "Video Format Preference Data Block"; break;
1776 case 0x0e: data_block = "YCbCr 4:2:0 Video Data Block"; break;
1777 case 0x0f: data_block = "YCbCr 4:2:0 Capability Map Data Block"; break;
1778 case 0x10: data_block = "Reserved for CTA-861 Miscellaneous Audio Fields"; break;
1779 case 0x11: data_block.clear(); audio_block = true; break;
1780 case 0x12: data_block = "HDMI Audio Data Block"; audio_block = true; break;
1781 case 0x13: data_block = "Room Configuration Data Block"; audio_block = true; break;
1782 case 0x14: data_block = "Speaker Location Data Block"; audio_block = true; break;
1783
1784 case 0x20: data_block = "InfoFrame Data Block"; break;
1785
1786 case 0x34: data_block = "DisplayID Type VII Video Timing Data Block"; break;
1787 case 0x35: data_block = "DisplayID Type VIII Video Timing Data Block"; break;
1788 case 0x42: data_block = "DisplayID Type X Video Timing Data Block"; break;
1789
1790 case 0x78: data_block = "HDMI Forum EDID Extension Override Data Block"; break;
1791 case 0x79: data_block = "HDMI Forum Sink Capability Data Block"; break;
2348 data_block.clear();
2349
2350 switch (tag) {
2351 case 0x01: data_block = "Audio Data Block"; audio_block = true; break;
2352 case 0x02: data_block = "Video Data Block"; break;
2353 case 0x03: data_block = "Vendor-Specific Data Block"; break;
2354 case 0x04: data_block = "Speaker Allocation Data Block"; audio_block = true; break;
2355 case 0x05: data_block = "VESA Display Transfer Characteristics Data Block"; break;
2356 case 0x06: data_block = "Video Format Data Block"; break;
2357 case 0x07: data_block = "Unknown CTA-861 Data Block (extended tag truncated)"; break;
2358
2359 case 0x700: data_block = "Video Capability Data Block"; break;
2360 case 0x701: data_block = "Vendor-Specific Video Data Block"; break;
2361 case 0x702: data_block = "VESA Video Display Device Data Block"; break;
2362 case 0x703: data_block = "VESA Video Timing Block Extension"; break;
2363 case 0x704: data_block = "Reserved for HDMI Video Data Block"; break;
2364 case 0x705: data_block = "Colorimetry Data Block"; break;
2365 case 0x706: data_block = "HDR Static Metadata Data Block"; break;
2366 case 0x707: data_block = "HDR Dynamic Metadata Data Block"; break;
2367 case 0x708: data_block = "Native Video Resolution Data Block"; break;
2368
2369 case 0x70d: data_block = "Video Format Preference Data Block"; break;
2370 case 0x70e: data_block = "YCbCr 4:2:0 Video Data Block"; break;
2371 case 0x70f: data_block = "YCbCr 4:2:0 Capability Map Data Block"; break;
2372 case 0x710: data_block = "Reserved for CTA-861 Miscellaneous Audio Fields"; break;
2373 case 0x711: data_block = "Vendor-Specific Audio Data Block"; audio_block = true; break;
2374 case 0x712: data_block = "HDMI Audio Data Block"; audio_block = true; break;
2375 case 0x713: data_block = "Room Configuration Data Block"; audio_block = true; break;
2376 case 0x714: data_block = "Speaker Location Data Block"; audio_block = true; break;
2377
2378 case 0x720: data_block = "InfoFrame Data Block"; break;
2379
2380 case 0x722: data_block = "DisplayID Type VII Video Timing Data Block"; break;
2381 case 0x723: data_block = "DisplayID Type VIII Video Timing Data Block"; break;
2382 case 0x72a: data_block = "DisplayID Type X Video Timing Data Block"; break;
2383
2384 case 0x778: data_block = "HDMI Forum EDID Extension Override Data Block"; break;
2385 case 0x779: data_block = "HDMI Forum Sink Capability Data Block"; break;
2386
17922387 default:
1793 if (x[0] <= 12)
1794 printf(" Unknown CTA-861 Video-Related");
1795 else if (x[0] <= 31)
1796 printf(" Unknown CTA-861 Audio-Related");
1797 else if (x[0] >= 120 && x[0] <= 127)
1798 printf(" Unknown CTA-861 HDMI-Related");
1799 else
1800 printf(" Unknown CTA-861");
1801 printf(" Data Block (extended tag 0x%02x, length %u)\n", x[0], length);
1802 hex_block(" ", x + 1, length);
1803 data_block.clear();
1804 warn("Unknown Extended CTA-861 Data Block 0x%02x.\n", x[0]);
1805 return;
2388 std::string unknown_name;
2389 if (tag < 0x700) unknown_name = "Unknown CTA-861 Data Block";
2390 else if (tag < 0x70d) unknown_name = "Unknown CTA-861 Video-Related Data Block";
2391 else if (tag < 0x720) unknown_name = "Unknown CTA-861 Audio-Related Data Block";
2392 else if (tag < 0x778) unknown_name = "Unknown CTA-861 Data Block";
2393 else if (tag < 0x780) unknown_name = "Unknown CTA-861 HDMI-Related Data Block";
2394 else unknown_name = "Unknown CTA-861 Data Block";
2395 unknown_name += std::string(" (") + (extended ? "extended " : "") + "tag " + utohex(tag & 0xff) + ", length " + std::to_string(length) + ")";
2396 printf(" %s:\n", unknown_name.c_str());
2397 warn("%s.\n", unknown_name.c_str());
2398 break;
2399 }
2400
2401 switch (tag) {
2402 case 0x03:
2403 case 0x701:
2404 case 0x711: {
2405 unsigned ouinum;
2406
2407 data_block_oui(data_block, x, length, &ouinum);
2408 x += (length < 3) ? length : 3;
2409 length -= (length < 3) ? length : 3;
2410 dooutputname = false;
2411 tag |= ouinum;
2412 break;
2413 }
2414 }
2415
2416 if (dooutputname && data_block.length())
2417 printf(" %s:\n", data_block.c_str());
2418
2419 switch (tag) {
2420 case 0x04:
2421 case 0x05:
2422 case 0x700:
2423 case 0x702:
2424 case 0x705:
2425 case 0x706:
2426 case 0x708:
2427 case 0x70d:
2428 case 0x70f:
2429 case 0x712:
2430 case 0x713:
2431 case 0x778:
2432 case 0x779:
2433 if (std::find(found_tags.begin(), found_tags.end(), tag) != found_tags.end())
2434 fail("Only one instance of this Data Block is allowed.\n");
2435 break;
18062436 }
18072437
18082438 // See Table 52 of CTA-861-G for a description of Byte 3
18092439 if (audio_block && !(cta.byte3 & 0x40))
1810 fail("audio information is present, but bit 6 of Byte 3 of the CTA-861 Extension header indicates no Basic Audio support.\n");
1811
1812 if (data_block.length())
1813 printf(" %s:\n", data_block.c_str());
1814
1815 switch (x[0]) {
1816 case 0x00: cta_vcdb(x + 1, length); return;
1817 case 0x01:
1818 if (length < 3) {
1819 data_block = std::string("Vendor-Specific Video Data Block");
1820 fail("Invalid length %u < 3.\n", length);
1821 return;
1822 }
1823 oui = (x[3] << 16) + (x[2] << 8) + x[1];
1824 name = oui_name(oui);
1825 if (!name) {
1826 name = oui_name(oui, true);
1827 if (name)
1828 reverse = true;
1829 }
1830 if (!name) {
1831 printf(" Vendor-Specific Video Data Block, OUI %s:\n",
1832 ouitohex(oui).c_str());
1833 hex_block(" ", x + 4, length - 3);
1834 data_block.clear();
1835 warn("Unknown Extended Vendor-Specific Video Data Block, OUI %s.\n",
1836 ouitohex(oui).c_str());
1837 return;
1838 }
1839 data_block = std::string("Vendor-Specific Video Data Block (") + name + ")";
1840 if (reverse)
1841 fail((std::string("OUI ") + ouitohex(oui) + " is in the wrong byte order\n").c_str());
1842 printf(" %s, OUI %s:\n", data_block.c_str(), ouitohex(oui).c_str());
1843 if (oui == 0x90848b)
1844 cta_hdr10plus(x + 4, length - 3);
1845 else if (oui == 0x00d046)
1846 cta_dolby_video(x + 4, length - 3);
1847 else
1848 hex_block(" ", x + 4, length - 3);
1849 return;
1850 case 0x02: cta_vesa_vdddb(x + 1, length); return;
1851 case 0x05: cta_colorimetry_block(x + 1, length); return;
1852 case 0x06: cta_hdr_static_metadata_block(x + 1, length); return;
1853 case 0x07: cta_hdr_dyn_metadata_block(x + 1, length); return;
1854 case 0x0d: cta_vfpdb(x + 1, length); return;
1855 case 0x0e: cta_svd(x + 1, length, true); return;
1856 case 0x0f: cta_y420cmdb(x + 1, length); return;
1857 case 0x11:
1858 if (length < 3) {
1859 data_block = std::string("Vendor-Specific Audio Data Block");
1860 fail("Invalid length %u < 3.\n", length);
1861 return;
1862 }
1863 oui = (x[3] << 16) + (x[2] << 8) + x[1];
1864 name = oui_name(oui);
1865 if (!name) {
1866 name = oui_name(oui, true);
1867 if (name)
1868 reverse = true;
1869 }
1870 if (!name) {
1871 printf(" Vendor-Specific Audio Data Block, OUI %s:\n",
1872 ouitohex(oui).c_str());
1873 hex_block(" ", x + 4, length - 3);
1874 data_block.clear();
1875 warn("Unknown Extended Vendor-Specific Audio Data Block, OUI %s.\n",
1876 ouitohex(oui).c_str());
1877 return;
1878 }
1879 data_block = std::string("Vendor-Specific Audio Data Block (") + name + ")";
1880 if (reverse)
1881 fail((std::string("OUI ") + ouitohex(oui) + " is in the wrong byte order\n").c_str());
1882 printf(" %s, OUI %s:\n", data_block.c_str(), ouitohex(oui).c_str());
1883 if (oui == 0x00d046)
1884 cta_dolby_audio(x + 4, length - 3);
1885 else
1886 hex_block(" ", x + 4, length - 3);
1887 return;
1888 case 0x12: cta_hdmi_audio_block(x + 1, length); return;
1889 case 0x13: cta_rcdb(x + 1, length); return;
1890 case 0x14: cta_sldb(x + 1, length); return;
1891 case 0x20: cta_ifdb(x + 1, length); return;
1892 case 0x34: cta_displayid_type_7(x + 1, length); return;
1893 case 0x35: cta_displayid_type_8(x + 1, length); return;
1894 case 0x42: cta_displayid_type_10(x + 1, length); return;
1895 case 0x78:
1896 cta_hf_eeodb(x + 1, length);
2440 fail("Audio information is present, but bit 6 of Byte 3 of the CTA-861 Extension header indicates no Basic Audio support.\n");
2441
2442 switch (tag) {
2443 case 0x01: cta_audio_block(x, length); break;
2444 case 0x02: cta_svd(x, length, false); break;
2445 case 0x03|kOUI_HDMI:
2446 cta_hdmi_block(x, length);
2447 // The HDMI OUI is present, so this EDID represents an HDMI
2448 // interface. And HDMI interfaces must use EDID version 1.3
2449 // according to the HDMI Specification, so check for this.
2450 if (base.edid_minor != 3)
2451 fail("The HDMI Specification requires EDID 1.3 instead of 1.%u.\n",
2452 base.edid_minor);
2453 break;
2454 case 0x03|kOUI_HDMIForum:
2455 if (cta.previous_cta_tag != (0x03|kOUI_HDMI))
2456 fail("HDMI Forum VSDB did not immediately follow the HDMI VSDB.\n");
2457 if (cta.have_hf_scdb || cta.have_hf_vsdb)
2458 fail("Duplicate HDMI Forum VSDB/SCDB.\n");
2459 cta_hf_scdb(x, length);
2460 cta.have_hf_vsdb = true;
2461 break;
2462 case 0x03|kOUI_AMD: cta_amd(x, length); break;
2463 case 0x03|kOUI_Microsoft: if (length != 0x12) goto dodefault; cta_microsoft(x, length); break;
2464 case 0x04: cta_sadb(x, length); break;
2465 case 0x05: cta_vesa_dtcdb(x, length); break;
2466 case 0x06: cta_vfdb(x, length); break;
2467 case 0x07: fail("Extended tag cannot have zero length.\n"); break;
2468 case 0x700: cta_vcdb(x, length); break;
2469 case 0x701|kOUI_HDR10: cta_hdr10plus(x, length); break;
2470 case 0x701|kOUI_Dolby: cta_dolby_video(x, length); break;
2471 // 0x701|kOUI_Apple: this almost certainly contains 'BLC Info/Corrections',
2472 // since the data (spread out over two VSDBs) is very similar to what is seen
2473 // in DisplayID blocks. Since I don't know how to parse this data, we still
2474 // default to a hex dump, but I mention this here in case data on how to
2475 // parse this becomes available.
2476 case 0x702: cta_vesa_vdddb(x, length); break;
2477 case 0x705: cta_colorimetry_block(x, length); break;
2478 case 0x706: cta_hdr_static_metadata_block(x, length); break;
2479 case 0x707: cta_hdr_dyn_metadata_block(x, length); break;
2480 case 0x708: cta_nvrdb(x, length); return;
2481 case 0x70d: cta_vfpdb(x, length); break;
2482 case 0x70e: cta_svd(x, length, true); break;
2483 case 0x70f: cta_y420cmdb(x, length); break;
2484 case 0x711|kOUI_Dolby: cta_dolby_audio(x, length); break;
2485 case 0x712: cta_hdmi_audio_block(x, length); break;
2486 case 0x713: cta_rcdb(x, length); break;
2487 case 0x714: cta_sldb(x, length); break;
2488 case 0x720: cta_ifdb(x, length); break;
2489 case 0x722: cta_displayid_type_7(x, length); break;
2490 case 0x723: cta_displayid_type_8(x, length); break;
2491 case 0x72a: cta_displayid_type_10(x, length); break;
2492 case 0x778:
2493 cta_hf_eeodb(x, length);
18972494 // This must be the first CTA-861 block
1898 if (!cta.first_block)
2495 if (cta.block_number > 0)
18992496 fail("Block starts at a wrong offset.\n");
1900 return;
1901 case 0x79:
1902 if (!cta.last_block_was_hdmi_vsdb)
2497 break;
2498 case 0x779:
2499 if (cta.previous_cta_tag != (0x03|kOUI_HDMI))
19032500 fail("HDMI Forum SCDB did not immediately follow the HDMI VSDB.\n");
19042501 if (cta.have_hf_scdb || cta.have_hf_vsdb)
19052502 fail("Duplicate HDMI Forum VSDB/SCDB.\n");
19062503 if (length < 2) {
19072504 data_block = std::string("HDMI Forum SCDB");
19082505 fail("Invalid length %u < 2.\n", length);
1909 return;
1910 }
1911 if (x[1] || x[2])
2506 break;
2507 }
2508 if (x[0] || x[1])
19122509 printf(" Non-zero SCDB reserved fields!\n");
1913 cta_hf_scdb(x + 3, length - 2);
1914 cta.have_hf_scdb = 1;
1915 return;
1916 }
1917
1918 hex_block(" ", x + 1, length);
1919 }
1920
1921 void edid_state::cta_block(const unsigned char *x)
1922 {
1923 unsigned length = x[0] & 0x1f;
1924 const char *name;
1925 unsigned oui;
1926 bool reverse = false;
1927 bool audio_block = false;
1928
1929 switch ((x[0] & 0xe0) >> 5) {
1930 case 0x01:
1931 data_block = "Audio Data Block";
1932 printf(" %s:\n", data_block.c_str());
1933 cta_audio_block(x + 1, length);
1934 audio_block = true;
2510 cta_hf_scdb(x + 2, length - 2);
2511 cta.have_hf_scdb = true;
19352512 break;
1936 case 0x02:
1937 data_block = "Video Data Block";
1938 printf(" %s:\n", data_block.c_str());
1939 cta_svd(x + 1, length, false);
2513 dodefault:
2514 default:
2515 hex_block(" ", x, length);
19402516 break;
1941 case 0x03:
1942 oui = (x[3] << 16) + (x[2] << 8) + x[1];
1943 name = oui_name(oui);
1944 if (!name) {
1945 name = oui_name(oui, true);
1946 if (name)
1947 reverse = true;
1948 }
1949 if (!name) {
1950 printf(" Vendor-Specific Data Block, OUI %s:\n", ouitohex(oui).c_str());
1951 hex_block(" ", x + 4, length - 3);
1952 data_block.clear();
1953 warn("Unknown Vendor-Specific Data Block, OUI %s.\n",
1954 ouitohex(oui).c_str());
1955 return;
1956 }
1957 data_block = std::string("Vendor-Specific Data Block (") + name + ")";
1958 if (reverse)
1959 fail((std::string("OUI ") + ouitohex(oui) + " is in the wrong byte order\n").c_str());
1960 printf(" %s, OUI %s:\n", data_block.c_str(), ouitohex(oui).c_str());
1961 if (oui == 0x000c03) {
1962 cta_hdmi_block(x + 1, length);
1963 cta.last_block_was_hdmi_vsdb = 1;
1964 cta.first_block = 0;
1965 // The HDMI OUI is present, so this EDID represents an HDMI
1966 // interface. And HDMI interfaces must use EDID version 1.3
1967 // according to the HDMI Specification, so check for this.
1968 if (base.edid_minor != 3)
1969 fail("The HDMI Specification requires EDID 1.3 instead of 1.%u.\n",
1970 base.edid_minor);
1971 return;
1972 }
1973 if (oui == 0xc45dd8) {
1974 if (!cta.last_block_was_hdmi_vsdb)
1975 fail("HDMI Forum VSDB did not immediately follow the HDMI VSDB.\n");
1976 if (cta.have_hf_scdb || cta.have_hf_vsdb)
1977 fail("Duplicate HDMI Forum VSDB/SCDB.\n");
1978 cta_hf_scdb(x + 4, length - 3);
1979 cta.have_hf_vsdb = 1;
1980 break;
1981 }
1982 hex_block(" ", x + 4, length - 3);
1983 break;
1984 case 0x04:
1985 data_block = "Speaker Allocation Data Block";
1986 printf(" %s:\n", data_block.c_str());
1987 cta_sadb(x + 1, length);
1988 audio_block = true;
1989 break;
1990 case 0x05:
1991 data_block = "VESA Display Transfer Characteristics Data Block";
1992 printf(" %s:\n", data_block.c_str());
1993 cta_vesa_dtcdb(x + 1, length);
1994 break;
1995 case 0x07:
1996 cta_ext_block(x + 1, length - 1);
1997 break;
1998 default: {
1999 unsigned tag = (*x & 0xe0) >> 5;
2000 unsigned length = *x & 0x1f;
2001
2002 printf(" Unknown CTA-861 tag 0x%02x, length %u\n", tag, length);
2003 hex_block(" ", x + 1, length);
2004 data_block.clear();
2005 warn("Unknown CTA-861 Data Block %u.\n", tag);
2006 break;
2007 }
2008 }
2009
2010 // See Table 52 of CTA-861-G for a description of Byte 3
2011 if (audio_block && !(cta.byte3 & 0x40))
2012 fail("audio information is present, but bit 6 of Byte 3 of the CTA-861 Extension header indicates no Basic Audio support.\n");
2013 cta.first_block = 0;
2014 cta.last_block_was_hdmi_vsdb = 0;
2517 }
2518
2519 cta.block_number++;
2520 cta.previous_cta_tag = tag;
2521 found_tags.push_back(tag);
20152522 }
20162523
20172524 void edid_state::preparse_cta_block(const unsigned char *x)
20262533 if (memchk(detailed, 18))
20272534 break;
20282535 if (detailed[0] || detailed[1])
2029 cta.preparse_total_dtds++;
2536 cta.preparsed_total_dtds++;
20302537 }
20312538 }
20322539
20452552 cta.preparsed_phys_addr = (x[i + 4] << 8) | x[i + 5];
20462553 }
20472554 break;
2555 case 0x06:
2556 if (!(x[i] & 0x1f) || cta.preparsed_first_vfd.rid)
2557 break;
2558 cta.preparsed_first_vfd = cta_parse_vfd(x + 2, (x[i + 1] & 3) + 1);
2559 break;
20482560 case 0x07:
20492561 if (x[i + 1] == 0x0d)
20502562 cta.has_vfpdb = true;
2563 if (x[i + 1] == 0x13 && (x[i + 2] & 0x40)) {
2564 cta.preparsed_speaker_count = 1 + (x[i + 2] & 0x1f);
2565 cta.preparsed_sld = x[i + 2] & 0x20;
2566 }
2567 if (x[i + 1] == 0x14)
2568 cta_preparse_sldb(x + i + 2, (x[i] & 0x1f) - 1);
20512569 if (x[i + 1] == 0x22)
2052 cta.preparse_total_vtdbs++;
2570 cta.preparsed_total_vtdbs++;
20532571 if (x[i + 1] == 0x23)
2054 cta.preparse_has_t8vtdb = true;
2055 if (x[i + 1] == 0x32)
2056 cta.preparse_total_vtdbs +=
2572 cta.preparsed_has_t8vtdb = true;
2573 if (x[i + 1] == 0x2a)
2574 cta.preparsed_total_vtdbs +=
20572575 ((x[i] & 0x1f) - 2) / (6 + ((x[i + 2] & 0x70) >> 4));
20582576 if (x[i + 1] != 0x0e)
20592577 continue;
21212639 // msg(!cta.has_hdmi, "If YCbCr support is indicated, then both 4:2:2 and 4:4:4 %s be supported.\n",
21222640 // cta.has_hdmi ? "shall" : "should");
21232641 printf(" Native detailed modes: %u\n", x[3] & 0x0f);
2124 if (cta.first_block)
2642 if (cta.block_number == 0)
21252643 cta.byte3 = x[3];
21262644 else if (x[3] != cta.byte3)
21272645 fail("Byte 3 must be the same for all CTA-861 Extension Blocks.\n");
2128 if (cta.first_block) {
2646 if (cta.block_number == 0) {
21292647 unsigned native_dtds = x[3] & 0x0f;
21302648
21312649 cta.native_timings.clear();
21322650 if (!native_dtds && !cta.has_vfpdb) {
21332651 cta.first_svd_might_be_preferred = true;
2134 } else if (native_dtds > cta.preparse_total_dtds) {
2652 } else if (native_dtds > cta.preparsed_total_dtds) {
21352653 fail("There are more Native DTDs (%u) than DTDs (%u).\n",
2136 native_dtds, cta.preparse_total_dtds);
2654 native_dtds, cta.preparsed_total_dtds);
21372655 }
2138 if (native_dtds > cta.preparse_total_dtds)
2139 native_dtds = cta.preparse_total_dtds;
2656 if (native_dtds > cta.preparsed_total_dtds)
2657 native_dtds = cta.preparsed_total_dtds;
21402658 for (unsigned i = 0; i < native_dtds; i++) {
21412659 char type[16];
21422660
21502668 if (version >= 3) {
21512669 unsigned i;
21522670
2153 for (i = 4; i < offset; i += (x[i] & 0x1f) + 1)
2154 cta_block(x + i);
2671 for (i = 4; i < offset; i += (x[i] & 0x1f) + 1) {
2672 cta_block(x + i, cta.found_tags);
2673 }
21552674
21562675 data_block.clear();
21572676 if (i != offset)
21862705 cta.supported_hdmi_vic_codes)
21872706 fail("HDMI VIC Codes must have their CTA-861 VIC equivalents in the VSB.\n");
21882707 if (!cta.has_vcdb)
2189 warn("Missing VCDB, needed for Set Selectable RGB Quantization to avoid interop issues.\n");
2708 fail("Missing VCDB, needed for Set Selectable RGB Quantization to avoid interop issues.\n");
21902709 }
21912710
21922711 void edid_state::cta_resolve_svr(vec_timings_ext::iterator iter)
21972716 } else if (iter->svr() <= 144) {
21982717 iter->flags = cta.vec_dtds[iter->svr() - 129].flags;
21992718 iter->t = cta.vec_dtds[iter->svr() - 129].t;
2200 } else {
2719 } else if (iter->svr() <= 160) {
22012720 iter->flags = cta.vec_vtdbs[iter->svr() - 145].flags;
22022721 iter->t = cta.vec_vtdbs[iter->svr() - 145].t;
2722 } else if (iter->svr() <= 175) {
2723 iter->flags.clear();
2724 unsigned char rid = cta.preparsed_first_vfd.rid;
2725 iter->t = calc_ovt_mode(rids[rid].hact, rids[rid].vact,
2726 rids[rid].hratio, rids[rid].vratio,
2727 vf_rate_values[iter->svr() - 160]);
22032728 }
22042729 }
22052730
22972822 warn("Native interlaced resolution of %ux%u is smaller than the max preferred interlaced resolution %ux%u.\n",
22982823 native_ilace_hact, native_ilace_vact,
22992824 max_pref_ilace_hact, max_pref_ilace_vact);
2300 }
2825
2826 if (dispid.native_width && native_prog_hact &&
2827 !native_prog_mixed_resolutions) {
2828 if (dispid.native_width != native_prog_hact ||
2829 dispid.native_height != native_prog_vact)
2830 fail("Mismatch between CTA-861 and DisplayID native progressive resolution.\n");
2831 }
2832 }
8080 check_displayid_datablock_revision(x[1]);
8181
8282 dispid.has_product_identification = true;
83 if (dispid.version >= 0x20) {
84 unsigned oui = (x[3] << 16) | (x[4] << 8) | x[5];
85 printf(" Vendor OUI %s\n", ouitohex(oui).c_str());
86 } else {
87 printf(" Vendor ID: %c%c%c\n", x[3], x[4], x[5]);
88 }
8983 printf(" Product Code: %u\n", x[6] | (x[7] << 8));
9084 unsigned sn = x[8] | (x[9] << 8) | (x[10] << 16) | (x[11] << 24);
9185 if (sn) {
135129 }
136130 }
137131
132 void edid_state::set_displayid_native_res(unsigned w, unsigned h)
133 {
134 if (dispid.native_width &&
135 (dispid.native_width != w || dispid.native_height != h)) {
136 fail("Native resolution mismatch: %ux%u -> %ux%u.\n",
137 dispid.native_width, dispid.native_height, w, h);
138 return;
139 }
140
141 if (!w && !h)
142 return;
143
144 if (!w ^ !h) {
145 fail("Invalid Native Pixel Format %ux%u.\n", w, h);
146 } else {
147 dispid.native_width = w;
148 dispid.native_height = h;
149 }
150 }
151
138152 void edid_state::parse_displayid_parameters(const unsigned char *x)
139153 {
140154 check_displayid_datablock_revision(x[1]);
142156 if (!check_displayid_datablock_length(x, 12, 12))
143157 return;
144158
159 if (dispid.has_display_parameters)
160 fail("Duplicate Display Parameters Data Block.\n");
145161 dispid.has_display_parameters = true;
162 dispid.image_width = (x[4] << 8) + x[3];
163 dispid.image_height = (x[6] << 8) + x[5];
164 if (dispid.image_width > image_width ||
165 dispid.image_height > image_height) {
166 image_width = dispid.image_width;
167 image_height = dispid.image_height;
168 }
146169 printf(" Image size: %.1f mm x %.1f mm\n",
147 ((x[4] << 8) + x[3]) / 10.0,
148 ((x[6] << 8) + x[5]) / 10.0);
149 printf(" Pixels: %d x %d\n",
150 (x[8] << 8) + x[7], (x[10] << 8) + x[9]);
170 dispid.image_width / 10.0, dispid.image_height / 10.0);
171 unsigned w = (x[8] << 8) + x[7];
172 unsigned h = (x[10] << 8) + x[9];
173 printf(" Display native pixel format: %ux%u\n", w, h);
174 set_displayid_native_res(w, h);
151175 print_flag_lines(" ", " Feature support flags:",
152176 x[11], feature_support_flags);
153177
192216 printf(" Uses %u CIE (x, y) coordinates\n", cie_year);
193217 if (xfer_id) {
194218 printf(" Associated with Transfer Characteristics Data Block with Identifier %u\n", xfer_id);
195 if (!(dispid.preparse_xfer_ids & (1 << xfer_id)))
219 if (!(dispid.preparsed_xfer_ids & (1 << xfer_id)))
196220 fail("Missing Transfer Characteristics Data Block with Identifier %u.\n", xfer_id);
197221 }
198222 if (!num_primaries) {
204228 for (unsigned i = 0; i < num_primaries; i++) {
205229 unsigned idx = offset + 3 * i;
206230
207 printf(" Primary #%u: (%.6f, %.6f)\n", i,
231 printf(" Primary #%u: (%.4f, %.4f)\n", i,
208232 fp2d(x[idx] | ((x[idx + 1] & 0x0f) << 8)),
209233 fp2d(((x[idx + 1] & 0xf0) >> 4) | (x[idx + 2] << 4)));
210234 }
212236 for (unsigned i = 0; i < num_whitepoints; i++) {
213237 unsigned idx = offset + 3 * i;
214238
215 printf(" White point #%u: (%.6f, %.6f)\n", i,
239 printf(" White point #%u: (%.4f, %.4f)\n", i,
216240 fp2d(x[idx] | ((x[idx + 1] & 0x0f) << 8)),
217241 fp2d(((x[idx + 1] & 0xf0) >> 4) | (x[idx + 2] << 4)));
218242 }
225249 {
226250 struct timings t = {};
227251 unsigned hbl, vbl;
252 std::string name = is_cta ? std::string("VTDB ") + std::to_string(cta.vec_vtdbs.size() + 1) : "DTD";
228253 std::string s("aspect ");
229254
230255 dispid.has_type_1_7 = true;
269294 t.hratio = 256;
270295 t.vratio = 135;
271296 break;
297 case 8:
298 s += "undefined";
299 break;
272300 default:
273 s += "undefined";
274 if ((x[3] & 0xf) > (dispid.version <= 0x12 ? 7 : 8))
275 fail("Unknown aspect 0x%02x.\n", x[3] & 0xf);
301 s += "reserved";
302 fail("Unknown aspect 0x%02x.\n", x[3] & 0xf);
276303 break;
277304 }
278305 switch ((x[3] >> 5) & 0x3) {
319346 dispid.preferred_timings.push_back(timings_ext(t, "DTD", s));
320347 }
321348
322 print_timings(" ", &t, "DTD", s.c_str(), true);
349 print_timings(" ", &t, name.c_str(), s.c_str(), true);
323350 if (is_cta) {
324 timings_ext te(t, "DTD", s);
351 timings_ext te(t, name.c_str(), s);
325352 cta.vec_vtdbs.push_back(te);
326353
327354 // Only use a T7VTDB if is cannot be expressed by a
335362 unsigned vtot = t.vact + t.vfp + t.vsync + t.vbp;
336363 unsigned refresh = (t.pixclk_khz * 1000ULL) / (htot * vtot);
337364
338 for (unsigned rb = 0; rb <= 3; rb++) {
339 timings cvt_t = calc_cvt_mode(refresh, t.hact, t.vact, rb);
365 for (unsigned rb = RB_NONE; rb <= RB_CVT_V3; rb++) {
366 timings cvt_t = calc_cvt_mode(t.hact, t.vact, refresh, rb);
340367 if (match_timings(t, cvt_t)) {
341368 fail("This T7VTDB can be represented as a T10VTDB.\n");
342369 return;
343370 }
344371 }
345 timings cvt_t = calc_cvt_mode(refresh, t.hact, t.vact, 3 | RB_FLAG);
372 timings cvt_t = calc_cvt_mode(t.hact, t.vact, refresh, RB_CVT_V3,
373 false, false, true);
346374 if (match_timings(t, cvt_t))
347375 fail("This T7VTDB can be represented as a T10VTDB.\n");
348376 }
453481 t.hratio = 256;
454482 t.vratio = 135;
455483 break;
484 case 8:
485 s += "undefined";
486 break;
456487 default:
457 s += "undefined";
458 if ((x[3] & 0xf) > (dispid.version <= 0x12 ? 7 : 8))
459 fail("Unknown aspect 0x%02x.\n", x[3] & 0xf);
460 break;
461 }
462
463 t.rb = ((x[0] & 0x70) >> 4) == 1;
488 s += "reserved";
489 fail("Unknown aspect 0x%02x.\n", x[0] & 0xf);
490 break;
491 }
492
493 t.rb = ((x[0] & 0x70) >> 4) == 1 ? RB_CVT_V1 : RB_NONE;
464494 t.hact = 8 + 8 * x[1];
465495 t.vact = t.hact * t.vratio / t.hratio;
466496
504534 if (!check_displayid_datablock_length(x, 15, 15))
505535 return;
506536 printf(" Pixel Clock: %.3f-%.3f MHz\n",
507 (double)(x[3] | (x[4] << 8) | (x[5] << 16)) / 100.0,
508 (double)(x[6] | (x[7] << 8) | (x[8] << 16)) / 100.0);
537 (double)((x[3] | (x[4] << 8) | (x[5] << 16)) + 1) / 100.0,
538 (double)((x[6] | (x[7] << 8) | (x[8] << 16)) + 1) / 100.0);
509539 printf(" Horizontal Frequency: %u-%u kHz\n", x[9], x[10]);
510540 printf(" Minimum Horizontal Blanking: %u pixels\n", x[11] | (x[12] << 8));
511541 printf(" Vertical Refresh: %u-%u Hz\n", x[13], x[14]);
589619 printf(" The backlight may be switched on and off\n");
590620 if (x[4] & 0x04)
591621 printf(" The backlight's intensity can be controlled\n");
592 printf(" Display native pixel format: %ux%u\n",
593 x[5] | (x[6] << 8), x[7] | (x[8] << 8));
622 unsigned w = x[5] | (x[6] << 8);
623 unsigned h = x[7] | (x[8] << 8);
624
625 if (w) w++;
626 if (h) h++;
627
628 printf(" Display native pixel format: %ux%u\n", w, h);
629 set_displayid_native_res(w, h);
594630 printf(" Aspect ratio and orientation:\n");
595631 printf(" Aspect Ratio: %.2f\n", (100 + x[9]) / 100.0);
596632 unsigned char v = x[0x0a];
658694 if (!check_displayid_datablock_length(x, 6, 6))
659695 return;
660696
661 printf(" Power Sequence T1: %.1f-%u.0 ms\n", (x[3] >> 4) / 10.0, (x[3] & 0xf) * 2);
662 printf(" Power Sequence T2: 0.0-%u.0 ms\n", (x[4] & 0x3f) * 2);
663 printf(" Power Sequence T3: 0.0-%u.0 ms\n", (x[5] & 0x3f) * 2);
664 printf(" Power Sequence T4: 0.0-%u.0 ms\n", (x[6] & 0x7f) * 10);
665 printf(" Power Sequence T5: 0.0-%u.0 ms\n", (x[7] & 0x3f) * 10);
666 printf(" Power Sequence T6: 0.0-%u.0 ms\n", (x[8] & 0x3f) * 10);
697 printf(" Power Sequence T1 Range: %.1f-%u.0 ms\n", (x[3] >> 4) / 10.0, (x[3] & 0xf) * 2);
698 printf(" Power Sequence T2 Range: 0.0-%u.0 ms\n", (x[4] & 0x3f) * 2);
699 printf(" Power Sequence T3 Range: 0.0-%u.0 ms\n", (x[5] & 0x3f) * 2);
700 printf(" Power Sequence T4 Min: %u.0 ms\n", (x[6] & 0x7f) * 10);
701 printf(" Power Sequence T5 Min: %u.0 ms\n", (x[7] & 0x3f) * 10);
702 printf(" Power Sequence T6 Min: %u.0 ms\n", (x[8] & 0x3f) * 10);
667703 }
668704
669705 // tag 0x0e
678714
679715 if (xfer_id) {
680716 printf(" Transfer Characteristics Data Block Identifier: %u\n", xfer_id);
681 if (!(dispid.preparse_color_ids & (1 << xfer_id)))
717 if (!(dispid.preparsed_color_ids & (1 << xfer_id)))
682718 fail("Missing Color Characteristics Data Block using Identifier %u.\n", xfer_id);
683719 }
684720 if (first_is_white)
697733 i - first_is_white);
698734 unsigned samples = x[offset];
699735 if (four_param) {
736 if (samples != 5)
737 fail("Expected 5 samples.\n");
700738 printf(" A0=%u A1=%u A2=%u A3=%u Gamma=%.2f\n",
701739 x[offset + 1], x[offset + 2], x[offset + 3], x[offset + 4],
702740 (double)(x[offset + 5] + 100.0) / 100.0);
703741 samples++;
704742 } else {
705 for (unsigned j = offset + 1; j < offset + samples; j++)
706 printf(" %3u", x[j]);
707 printf(" 255\n");
743 double sum = 0;
744
745 // The spec is not very clear about the number of samples:
746 // should this be interpreted as the actual number of
747 // samples stored in this Data Block, or as the number of
748 // samples in the curve, but where the last sample is not
749 // actually stored since it is always 0x3ff.
750 //
751 // The ATP Manager interprets this as the latter, so that's
752 // what we implement here.
753 for (unsigned j = offset + 1; j < offset + samples; j++) {
754 sum += x[j];
755 printf(" %.2f", sum * 100.0 / 1023.0);
756 }
757 printf(" 100.00\n");
708758 }
709759 offset += samples;
710760 len -= samples;
917967 if (x[0] & 0x10)
918968 s += ", refresh rate * (1000/1001) supported";
919969
920 t.rb = 2;
970 t.rb = RB_CVT_V2;
921971 if ((x[0] & 0x03) == 1)
922972 warn("Unexpected use of 'custom reduced blanking'.\n");
923973 else if ((x[0] & 0x03) > 1)
10831133
10841134 // tag 0x21
10851135
1086 void edid_state::parse_displayid_parameters_v2(const unsigned char *x)
1087 {
1088 check_displayid_datablock_revision(x[1]);
1089
1136 void edid_state::parse_displayid_parameters_v2(const unsigned char *x,
1137 unsigned block_rev)
1138 {
10901139 if (!check_displayid_datablock_length(x, 29, 29))
10911140 return;
1141 if (dispid.has_display_parameters)
1142 fail("Duplicate Display Parameters Data Block.\n");
1143 dispid.has_display_parameters = true;
10921144
10931145 unsigned hor_size = (x[4] << 8) + x[3];
10941146 unsigned vert_size = (x[6] << 8) + x[5];
10951147
1096 dispid.has_display_parameters = true;
1097 if (x[1] & 0x80)
1098 printf(" Image size: %u mm x %u mm\n",
1099 hor_size, vert_size);
1100 else
1148 dispid.image_width = hor_size;
1149 dispid.image_height = vert_size;
1150 if (x[1] & 0x80) {
1151 printf(" Image size: %u mm x %u mm\n", hor_size, vert_size);
1152 dispid.image_width *= 10;
1153 dispid.image_height *= 10;
1154 } else {
11011155 printf(" Image size: %.1f mm x %.1f mm\n",
11021156 hor_size / 10.0, vert_size / 10.0);
1103 printf(" Pixels: %d x %d\n",
1104 (x[8] << 8) + x[7], (x[10] << 8) + x[9]);
1157 }
1158 if (dispid.image_width > image_width ||
1159 dispid.image_height > image_height) {
1160 image_width = dispid.image_width;
1161 image_height = dispid.image_height;
1162 }
1163
1164 unsigned w = (x[8] << 8) + x[7];
1165 unsigned h = (x[10] << 8) + x[9];
1166
1167 printf(" Display native pixel format: %ux%u\n", w, h);
1168 set_displayid_native_res(w, h);
1169
11051170 unsigned char v = x[11];
11061171 printf(" Scan Orientation: ");
11071172 switch (v & 0x07) {
11441209 printf(" Native Minimum Luminance: %s\n",
11451210 ieee7542d(x[0x1c] | (x[0x1d] << 8)).c_str());
11461211 printf(" Native Color Depth: ");
1147 if (bpc444[x[0x1e] & 0x07])
1212 if (!(x[0x1e] & 0x07))
1213 printf("Not defined\n");
1214 else if (bpc444[x[0x1e] & 0x07])
11481215 printf("%s bpc\n", bpc444[x[0x1e] & 0x07]);
11491216 else
11501217 printf("Reserved\n");
11551222 case 0x02: printf("Organic LED\n"); break;
11561223 default: printf("Reserved\n"); break;
11571224 }
1225 if (block_rev)
1226 printf(" Display Device Theme Preference: %s\n",
1227 (x[0x1e] & 0x80) ? "Dark Theme Preferred" : "No Preference");
11581228 if (x[0x1f] != 0xff)
11591229 printf(" Native Gamma EOTF: %.2f\n",
11601230 (100 + x[0x1f]) / 100.0);
11901260 s += ", refresh rate * (1000/1001) supported";
11911261
11921262 switch (x[0] & 0x07) {
1193 case 1: t.rb = 1; break;
1194 case 2: t.rb = 2; break;
1263 case 1: t.rb = RB_CVT_V1; break;
1264 case 2: t.rb = RB_CVT_V2; break;
11951265 default: break;
11961266 }
11971267
13261396
13271397 if (check_displayid_datablock_length(x, 16, 16)) {
13281398 x += 3;
1329 printf(" %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
1330 x[0], x[1], x[2], x[3],
1331 x[4], x[5],
1332 x[6], x[7],
1333 x[8], x[9],
1334 x[10], x[11], x[12], x[13], x[14], x[15]);
1399 printf(" Container ID: %s\n", containerid2s(x).c_str());
1400 }
1401 }
1402
1403 // tag 0x2b
1404
1405 void edid_state::parse_displayid_adaptive_sync(const unsigned char *x)
1406 {
1407 check_displayid_datablock_revision(x[1], 0x70);
1408
1409 unsigned size = 6 + ((x[1] >> 4) & 0x7);
1410 unsigned len = x[2];
1411 unsigned descriptor = 1;
1412
1413 x += 3;
1414 if (len % size)
1415 fail("DisplayID payload length %u is not a multiple of %u.\n", len, size);
1416 while (len >= size) {
1417 printf(" Descriptor #%u:\n", descriptor++);
1418
1419 printf(" %sNative Panel Range\n", (x[0] & 1) ? "" : "Non-");
1420 unsigned v = (x[0] >> 2) & 3;
1421 switch (v) {
1422 case 0: printf(" Fixed Average V-Total\n"); break;
1423 case 1: printf(" Fixed Average V-Total and Adaptive V-Total\n"); break;
1424 default:
1425 printf(" Reserved %u\n", v);
1426 fail("Use of reserved value %u.\n", v);
1427 break;
1428 }
1429 if (x[0] & 0x10)
1430 printf(" Supports Seamless Transition\n");
1431 if (x[0] & 0x02)
1432 printf(" 'Max Single Frame Duration Increase' field value without jitter impact\n");
1433 if (x[0] & 0x20)
1434 printf(" 'Max Single Frame Duration Decrease' field value without jitter impact\n");
1435 printf(" Max Duration Increase: %.2f ms\n", x[1] / 4.0);
1436 printf(" Max Duration Decrease: %.2f ms\n", x[5] / 4.0);
1437 printf(" Min Refresh Rate: %u Hz\n", x[2]);
1438 printf(" Max Refresh Rate: %u Hz\n", 1 + x[3] + (x[4] & 3) * 256);
1439
1440 len -= size;
1441 x += size;
13351442 }
13361443 }
13371444
13381445 // tag 0x32
13391446
1340 void edid_state::parse_displayid_type_10_timing(const unsigned char *x, bool is_cta)
1447 void edid_state::parse_displayid_type_10_timing(const unsigned char *x,
1448 unsigned sz, bool is_cta)
13411449 {
13421450 struct timings t = {};
1451 std::string name = is_cta ? std::string("VTDB ") + std::to_string(cta.vec_vtdbs.size() + 1) : "CVT";
13431452 std::string s("aspect ");
13441453
13451454 t.hact = 1 + (x[1] | (x[2] << 8));
13641473 }
13651474
13661475 switch (x[0] & 0x07) {
1367 case 1: t.rb = 1; break;
1368 case 2: t.rb = 2; break;
1369 case 3: t.rb = 3; break;
1476 case 1: t.rb = RB_CVT_V1; break;
1477 case 2: t.rb = RB_CVT_V2; break;
1478 case 3: t.rb = RB_CVT_V3; break;
13701479 default: break;
13711480 }
13721481
1482 unsigned rb = t.rb;
1483 unsigned rb_h_blank = rb == RB_CVT_V3 ? 80 : 0;
1484 unsigned rb_v_blank = 460;
1485 bool early_vsync_rqd = false;
1486
13731487 if (x[0] & 0x10) {
1374 if (t.rb == 2) {
1488 if (rb == RB_CVT_V2) {
13751489 s += ", refresh rate * (1000/1001) supported";
1376 } else if (t.rb == 3) {
1490 t.rb |= RB_ALT;
1491 } else if (rb == RB_CVT_V3) {
13771492 s += ", hblank is 160 pixels";
1378 t.rb |= RB_FLAG;
1493 t.rb |= RB_ALT;
1494 rb_h_blank = 160;
13791495 } else {
13801496 fail("VR_HB must be 0.\n");
13811497 }
13831499 if (x[0] & 0x80)
13841500 s += ", YCbCr 4:2:0";
13851501
1386 edid_cvt_mode(1 + x[5], t);
1387
1388 print_timings(" ", &t, "CVT", s.c_str());
1502 if (x[0] & 0x08) {
1503 if (rb == RB_CVT_V3) {
1504 early_vsync_rqd = true;
1505 s += ", early-vsync";
1506 } else {
1507 fail("EVS must be 0.\n");
1508 }
1509 }
1510
1511 unsigned refresh = 1 + x[5] + (sz == 6 ? 0 : ((x[6] & 3) << 8));
1512
1513 if (sz > 6) {
1514 if (rb == RB_CVT_V3) {
1515 unsigned delta_hblank = (x[6] >> 2) & 7;
1516
1517 if (rb_h_blank == 80)
1518 rb_h_blank = 80 + 8 * delta_hblank;
1519 else if (delta_hblank <= 5)
1520 rb_h_blank = 160 + 8 * delta_hblank;
1521 else
1522 rb_h_blank = 160 - (delta_hblank - 5) * 8;
1523 if (delta_hblank)
1524 s += ", delta-hblank=" + std::to_string(delta_hblank);
1525
1526 rb_v_blank += ((x[6] >> 5) & 7) * 35;
1527 if (rb_v_blank > 460)
1528 s += ", add-vblank=" + std::to_string(rb_v_blank - 460);
1529 } else {
1530 if (x[6] & 0xe0)
1531 fail("Additional_Vertical_Blank_Time must be 0.\n");
1532 if (x[6] & 0x1c)
1533 fail("Delta_Horizontal_Blank must be 0.\n");
1534 }
1535 }
1536
1537 edid_cvt_mode(refresh, t, rb_h_blank, rb_v_blank, early_vsync_rqd);
1538
1539 print_timings(" ", &t, name.c_str(), s.c_str());
13891540 if (is_cta) {
1390 timings_ext te(t, "CVT", s);
1541 timings_ext te(t, name.c_str(), s);
13911542 cta.vec_vtdbs.push_back(te);
13921543 }
13931544 }
14041555 unsigned len = x[2];
14051556 x += 6;
14061557 printf(" Data Structure Type: ");
1407 switch (x[0] & 0x07) {
1408 case 0x00: printf("eDP\n"); break;
1409 case 0x01: printf("DP\n"); break;
1410 default: printf("Reserved\n"); break;
1411 }
1558 switch (x[0] & 7) {
1559 case 0: printf("eDP\n"); break;
1560 case 1: printf("DP\n"); break;
1561 default: printf("Reserved (%d)\n", x[0] & 7); break;
1562 }
1563
1564 if ((x[0] >> 3) & 15)
1565 warn("Reserved bits 6:3 (%d) are not 0.\n", (x[0] >> 3) & 15);
1566
14121567 printf(" Default Colorspace and EOTF Handling: %s\n",
14131568 (x[0] & 0x80) ? "Native as specified in the Display Parameters DB" : "sRGB");
1569
14141570 printf(" Number of Pixels in Hor Pix Cnt Overlapping an Adjacent Panel: %u\n",
14151571 x[1] & 0xf);
1572 if ((x[1] & 0xf) > 8)
1573 warn("Number of Pixels in Hor Pix Cnt Overlapping an Adjacent Panel exceeds 8.\n");
1574
1575 if ((x[1] >> 4) & 1)
1576 warn("Reserved bit 4 is not 0.\n");
1577
14161578 printf(" Multi-SST Operation: ");
1417 switch ((x[1] >> 5) & 0x03) {
1418 case 0x00: printf("Not Supported\n"); break;
1419 case 0x01: printf("Two Streams (number of links shall be 2 or 4)\n"); break;
1420 case 0x02: printf("Four Streams (number of links shall be 4)\n"); break;
1421 case 0x03: printf("Reserved\n"); break;
1422 }
1579 switch ((x[1] >> 5) & 3) {
1580 case 0: printf("Not Supported\n"); break;
1581 case 1: printf("Two Streams (number of links shall be 2 or 4)\n"); break;
1582 case 2: printf("Four Streams (number of links shall be 4)\n"); break;
1583 case 3: printf("Reserved\n"); warn("Invalid option for Multi-SST Operation.\n"); break;
1584 }
1585
1586 if ((x[1] >> 7) & 1)
1587 warn("Reserved bit 7 is not 0.\n");
1588
14231589 if (len >= 7) {
14241590 double bpp = (x[2] & 0x3f) + (x[3] & 0x0f) / 16.0;
14251591 printf(" Pass through timing's target DSC bits per pixel: %.4f\n", bpp);
14261592 }
14271593 }
14281594
1595 // tag 0x7f, OUI 00-10-FA (Apple)
1596
1597 void edid_state::parse_displayid_apple(const unsigned char *x)
1598 {
1599 int length = x[2] - 3;
1600
1601 x += 6;
1602
1603 // Based on the very limited information I found here:
1604 // https://opensource.apple.com/source/IOKitUser/IOKitUser-1445.40.1/graphics.subproj/IODisplayLib.c
1605 switch (x[0]) {
1606 case 1:
1607 printf(" Type: BLC Info/Corrections, Version: %u\n", x[1]);
1608 break;
1609 default:
1610 printf(" Type: %u, Version: %u\n", x[0], x[1]);
1611 break;
1612 }
1613 hex_block(" ", x + 2, length - 2);
1614 }
1615
14291616 // tag 0x81
14301617
14311618 void edid_state::parse_displayid_cta_data_block(const unsigned char *x)
14411628 }
14421629 x += 3;
14431630
1444 for (i = 0; i < len; i += (x[i] & 0x1f) + 1)
1445 cta_block(x + i);
1631 for (i = 0; i < len; i += (x[i] & 0x1f) + 1) {
1632 cta_block(x + i, dispid.found_tags);
1633 }
14461634
14471635 if (i != len)
14481636 fail("Length is %u instead of %u.\n", len, i);
14981686
14991687 unsigned offset = 5;
15001688
1501 dispid.preparse_displayid_blocks++;
1689 dispid.preparsed_displayid_blocks++;
15021690 while (length > 0) {
15031691 unsigned tag = x[offset];
15041692 unsigned len = x[offset + 2];
15051693
15061694 switch (tag) {
15071695 case 0x02:
1508 dispid.preparse_color_ids |= 1 << ((x[offset + 1] >> 3) & 0x0f);
1696 dispid.preparsed_color_ids |= 1 << ((x[offset + 1] >> 3) & 0x0f);
15091697 break;
15101698 case 0x0e:
1511 dispid.preparse_xfer_ids |= 1 << ((x[offset + 1] >> 4) & 0x0f);
1699 dispid.preparsed_xfer_ids |= 1 << ((x[offset + 1] >> 4) & 0x0f);
15121700 break;
15131701 default:
15141702 break;
15281716 }
15291717 }
15301718
1719 unsigned edid_state::displayid_block(const unsigned version, const unsigned char *x, unsigned length)
1720 {
1721 unsigned i;
1722 unsigned tag = x[0];
1723 unsigned tag_version = (tag < 0x20) ? 1 : (tag < 0x7f) ? 2 : (tag < 0x80) ? 1 : 0;
1724 bool dooutputname = true;
1725 unsigned len = (length < 3) ? 0 : x[2];
1726 bool hasoui = false;
1727 unsigned ouinum;
1728
1729 switch (tag) {
1730 // DisplayID 1.3:
1731 case 0x00:
1732 data_block_oui("Product Identification Data Block (" + utohex(tag) + ")",
1733 x + 3, len, &ouinum, true, true, true);
1734 dooutputname = false;
1735 hasoui = true;
1736 break;
1737 case 0x01: data_block = "Display Parameters Data Block (" + utohex(tag) + ")"; break;
1738 case 0x02: data_block = "Color Characteristics Data Block"; break;
1739 case 0x03: data_block = "Video Timing Modes Type 1 - Detailed Timings Data Block"; break;
1740 case 0x04: data_block = "Video Timing Modes Type 2 - Detailed Timings Data Block"; break;
1741 case 0x05: data_block = "Video Timing Modes Type 3 - Short Timings Data Block"; break;
1742 case 0x06: data_block = "Video Timing Modes Type 4 - DMT Timings Data Block"; break;
1743 case 0x07: data_block = "Supported Timing Modes Type 1 - VESA DMT Timings Data Block"; break;
1744 case 0x08: data_block = "Supported Timing Modes Type 2 - CTA-861 Timings Data Block"; break;
1745 case 0x09: data_block = "Video Timing Range Data Block"; break;
1746 case 0x0a: data_block = "Product Serial Number Data Block"; break;
1747 case 0x0b: data_block = "GP ASCII String Data Block"; break;
1748 case 0x0c: data_block = "Display Device Data Data Block"; break;
1749 case 0x0d: data_block = "Interface Power Sequencing Data Block"; break;
1750 case 0x0e: data_block = "Transfer Characteristics Data Block"; break;
1751 case 0x0f: data_block = "Display Interface Data Block"; break;
1752 case 0x10: data_block = "Stereo Display Interface Data Block (" + utohex(tag) + ")"; break;
1753 case 0x11: data_block = "Video Timing Modes Type 5 - Short Timings Data Block"; break;
1754 case 0x12: data_block = "Tiled Display Topology Data Block (" + utohex(tag) + ")"; break;
1755 case 0x13: data_block = "Video Timing Modes Type 6 - Detailed Timings Data Block"; break;
1756 // 0x14 .. 0x7e RESERVED for Additional VESA-defined Data Blocks
1757 // DisplayID 2.0
1758 case 0x20:
1759 data_block_oui("Product Identification Data Block (" + utohex(tag) + ")",
1760 x + 3, len, &ouinum, false, false, true);
1761 dooutputname = false;
1762 hasoui = true;
1763 break;
1764 case 0x21: data_block = "Display Parameters Data Block (" + utohex(tag) + ")"; break;
1765 case 0x22: data_block = "Video Timing Modes Type 7 - Detailed Timings Data Block"; break;
1766 case 0x23: data_block = "Video Timing Modes Type 8 - Enumerated Timing Codes Data Block"; break;
1767 case 0x24: data_block = "Video Timing Modes Type 9 - Formula-based Timings Data Block"; break;
1768 case 0x25: data_block = "Dynamic Video Timing Range Limits Data Block"; break;
1769 case 0x26: data_block = "Display Interface Features Data Block"; break;
1770 case 0x27: data_block = "Stereo Display Interface Data Block (" + utohex(tag) + ")"; break;
1771 case 0x28: data_block = "Tiled Display Topology Data Block (" + utohex(tag) + ")"; break;
1772 case 0x29: data_block = "ContainerID Data Block"; break;
1773 case 0x2b: data_block = "Adaptive Sync Data Block"; break;
1774 case 0x32: data_block = "Video Timing Modes Type 10 - Formula-based Timings Data Block"; break;
1775 // 0x2a .. 0x7d RESERVED for Additional VESA-defined Data Blocks
1776 case 0x7e: // DisplayID 2.0
1777 data_block_oui("Vendor-Specific Data Block (" + utohex(tag) + ")",
1778 x + 3, len, &ouinum, false, false, true);
1779 dooutputname = false;
1780 hasoui = true;
1781 tag |= ouinum;
1782 break;
1783 case 0x7f: // DisplayID 1.3
1784 data_block_oui("Vendor-Specific Data Block (" + utohex(tag) + ")",
1785 x + 3, len, &ouinum, false, true, true);
1786 dooutputname = false;
1787 hasoui = true;
1788 tag |= ouinum;
1789 break;
1790 // 0x80 RESERVED
1791 case 0x81: data_block = "CTA-861 DisplayID Data Block"; break;
1792 // 0x82 .. 0xff RESERVED
1793 default: data_block = "Unknown DisplayID Data Block (" + utohex(tag) + ", length " + std::to_string(len) + ")"; break;
1794 }
1795
1796 if (length < 3) {
1797 // Report a problem when the remaining bytes are not 0.
1798 data_block.clear(); // Probably not a Data Block so clear this.
1799 if (tag || (length > 1 && x[1])) {
1800 printf(" Filler:\n");
1801 fail("Not enough bytes remain (%d) for a DisplayID data block and the DisplayID filler is non-0.\n", length);
1802 hex_block(" ", x, length);
1803 }
1804 return length;
1805 }
1806
1807 if (length < len + 3) {
1808 data_block.clear(); // Probably not a Data Block so clear this.
1809 printf(" Filler:\n");
1810 fail("The length of this DisplayID data block (%d) exceeds the number of bytes remaining (%d).\n", len + 3, length);
1811 hex_block(" ", x, length);
1812 return length;
1813 }
1814
1815 if (!tag && !len) {
1816 // A Product Identification Data Block with no payload bytes is not valid - assume this is the end.
1817 data_block.clear(); // Probably not a Product Identification Data Block so clear this.
1818 if (!memchk(x, length)) {
1819 printf(" Filler:\n");
1820 fail("Non-0 filler bytes in the DisplayID block.\n");
1821 hex_block(" ", x, length);
1822 }
1823 return length;
1824 }
1825
1826 if (dooutputname && data_block.length())
1827 printf(" %s:\n", data_block.c_str());
1828
1829 if (version >= 0x20 && tag_version == 1)
1830 fail("Use of DisplayID v1.x tag for DisplayID v%u.%u.\n",
1831 version >> 4, version & 0xf);
1832 if (version < 0x20 && tag_version == 2)
1833 fail("Use of DisplayID v2.0 tag for DisplayID v%u.%u.\n",
1834 version >> 4, version & 0xf);
1835
1836 unsigned block_rev = x[1] & 0x07;
1837
1838 switch (tag) {
1839 case 0x00: parse_displayid_product_id(x); break;
1840 case 0x01: parse_displayid_parameters(x); break;
1841 case 0x02: parse_displayid_color_characteristics(x); break;
1842 case 0x03:
1843 check_displayid_datablock_revision(x[1], 0, block_rev & 1);
1844 for (i = 0; i < len / 20; i++)
1845 parse_displayid_type_1_7_timing(&x[3 + (i * 20)], false, block_rev);
1846 break;
1847 case 0x04:
1848 check_displayid_datablock_revision(x[1]);
1849 for (i = 0; i < len / 11; i++)
1850 parse_displayid_type_2_timing(&x[3 + (i * 11)]);
1851 break;
1852 case 0x05:
1853 check_displayid_datablock_revision(x[1], 0, block_rev & 1);
1854 for (i = 0; i < len / 3; i++)
1855 parse_displayid_type_3_timing(&x[3 + (i * 3)]);
1856 break;
1857 case 0x06:
1858 check_displayid_datablock_revision(x[1], 0xc0, 1);
1859 for (i = 0; i < len; i++)
1860 parse_displayid_type_4_8_timing((x[1] & 0xc0) >> 6, x[3 + i]);
1861 break;
1862 case 0x07:
1863 check_displayid_datablock_revision(x[1]);
1864 for (i = 0; i < min(len, 10) * 8; i++)
1865 if (x[3 + i / 8] & (1 << (i % 8))) {
1866 char type[16];
1867 sprintf(type, "DMT 0x%02x", i + 1);
1868 print_timings(" ", find_dmt_id(i + 1), type);
1869 }
1870 break;
1871 case 0x08:
1872 check_displayid_datablock_revision(x[1]);
1873 for (i = 0; i < min(len, 8) * 8; i++)
1874 if (x[3 + i / 8] & (1 << (i % 8))) {
1875 char type[16];
1876 sprintf(type, "VIC %3u", i + 1);
1877 print_timings(" ", find_vic_id(i + 1), type);
1878 }
1879 break;
1880 case 0x09: parse_displayid_video_timing_range_limits(x); break;
1881 case 0x0a:
1882 case 0x0b: parse_displayid_string(x); break;
1883 case 0x0c: parse_displayid_display_device(x); break;
1884 case 0x0d: parse_displayid_intf_power_sequencing(x); break;
1885 case 0x0e: parse_displayid_transfer_characteristics(x); break;
1886 case 0x0f: parse_displayid_display_intf(x); break;
1887 case 0x10: parse_displayid_stereo_display_intf(x); break;
1888 case 0x11:
1889 check_displayid_datablock_revision(x[1]);
1890 for (i = 0; i < len / 7; i++)
1891 parse_displayid_type_5_timing(&x[3 + (i * 7)]);
1892 break;
1893 case 0x12: parse_displayid_tiled_display_topology(x, false); break;
1894 case 0x13:
1895 check_displayid_datablock_revision(x[1]);
1896 for (i = 0; i < len; i += (x[3 + i + 2] & 0x40) ? 17 : 14)
1897 parse_displayid_type_6_timing(&x[3 + i]);
1898 break;
1899 case 0x20: parse_displayid_product_id(x); break;
1900 case 0x21:
1901 if (block_rev >= 1)
1902 check_displayid_datablock_revision(x[1], 0x80, 1);
1903 else
1904 check_displayid_datablock_revision(x[1], 0x80, 0);
1905 parse_displayid_parameters_v2(x, block_rev);
1906 break;
1907 case 0x22: {
1908 unsigned sz = 20;
1909
1910 if (block_rev >= 2)
1911 check_displayid_datablock_revision(x[1], 0x08, 2);
1912 else if (block_rev == 1)
1913 check_displayid_datablock_revision(x[1], 0x08, 1);
1914 else
1915 check_displayid_datablock_revision(x[1]);
1916 sz += (x[1] & 0x70) >> 4;
1917 if (block_rev >= 1 && (x[1] & 0x08))
1918 printf(" These timings support DSC pass-through\n");
1919 for (i = 0; i < len / sz; i++)
1920 parse_displayid_type_1_7_timing(&x[3 + i * sz], true, block_rev);
1921 break;
1922 }
1923 case 0x23:
1924 if (block_rev)
1925 check_displayid_datablock_revision(x[1], 0xe8, 1);
1926 else
1927 check_displayid_datablock_revision(x[1], 0xc8);
1928 if (x[1] & 0x08) {
1929 for (i = 0; i < len / 2; i++)
1930 parse_displayid_type_4_8_timing((x[1] & 0xc0) >> 6,
1931 x[3 + i * 2] |
1932 (x[4 + i * 2] << 8));
1933 } else {
1934 for (i = 0; i < len; i++)
1935 parse_displayid_type_4_8_timing((x[1] & 0xc0) >> 6,
1936 x[3 + i]);
1937 }
1938 break;
1939 case 0x24:
1940 check_displayid_datablock_revision(x[1]);
1941 for (i = 0; i < len / 6; i++)
1942 parse_displayid_type_9_timing(&x[3 + i * 6]);
1943 break;
1944 case 0x25: parse_displayid_dynamic_video_timings_range_limits(x); break;
1945 case 0x26: parse_displayid_interface_features(x); break;
1946 case 0x27: parse_displayid_stereo_display_intf(x); break;
1947 case 0x28: parse_displayid_tiled_display_topology(x, true); break;
1948 case 0x29: parse_displayid_ContainerID(x); break;
1949 case 0x2b: parse_displayid_adaptive_sync(x); break;
1950 case 0x32: {
1951 unsigned sz = 6 + ((x[1] & 0x70) >> 4);
1952
1953 check_displayid_datablock_revision(x[1], 0x70);
1954 for (i = 0; i < len / sz; i++)
1955 parse_displayid_type_10_timing(&x[3 + i * sz], sz);
1956 break;
1957 }
1958 case 0x7e|kOUI_VESA: parse_displayid_vesa(x); break;
1959 case 0x7f|kOUI_Apple: parse_displayid_apple(x); break;
1960 case 0x81: parse_displayid_cta_data_block(x); break;
1961 default: hex_block(" ", x + 3 + (hasoui ? 3 : 0), (len > (hasoui ? 3 : 0)) ? len - (hasoui ? 3 : 0) : 0); break;
1962 }
1963
1964 if ((tag == 0x00 || tag == 0x20) &&
1965 (!dispid.is_base_block || dispid.block_number > 0))
1966 fail("%s is required to be the first DisplayID Data Block.\n",
1967 data_block.c_str());
1968
1969 dispid.block_number++;
1970 return len + 3;
1971 }
1972
15311973 void edid_state::parse_displayid_block(const unsigned char *x)
15321974 {
15331975 unsigned version = x[1];
15341976 unsigned length = x[2];
15351977 unsigned prod_type = x[3]; // future check: based on type, check for required data blocks
15361978 unsigned ext_count = x[4];
1537 unsigned i;
15381979
15391980 printf(" Version: %u.%u\n Extension Count: %u\n",
15401981 version >> 4, version & 0xf, ext_count);
15451986 product_type(prod_type, false).c_str());
15461987 if (!prod_type)
15471988 fail("DisplayID Base Block has no product type.\n");
1548 if (ext_count != dispid.preparse_displayid_blocks - 1)
1989 if (ext_count != dispid.preparsed_displayid_blocks - 1)
15491990 fail("Expected %u DisplayID Extension Block%s, but got %u.\n",
15501991 ext_count,
15511992 ext_count > 1 ? "s" : "",
1552 dispid.preparse_displayid_blocks - 1);
1993 dispid.preparsed_displayid_blocks - 1);
15531994 } else {
15541995 if (prod_type)
15551996 fail("Product Type should be 0 in extension block.\n");
15662007 length = 121;
15672008 }
15682009
1569 unsigned offset = 5;
1570 bool first_data_block = true;
1571 while (length > 0) {
1572 unsigned tag = x[offset];
1573 unsigned oui = 0;
1574
1575 switch (tag) {
1576 // DisplayID 1.3:
1577 case 0x00: data_block = "Product Identification Data Block (" + utohex(tag) + ")"; break;
1578 case 0x01: data_block = "Display Parameters Data Block (" + utohex(tag) + ")"; break;
1579 case 0x02: data_block = "Color Characteristics Data Block"; break;
1580 case 0x03: data_block = "Video Timing Modes Type 1 - Detailed Timings Data Block"; break;
1581 case 0x04: data_block = "Video Timing Modes Type 2 - Detailed Timings Data Block"; break;
1582 case 0x05: data_block = "Video Timing Modes Type 3 - Short Timings Data Block"; break;
1583 case 0x06: data_block = "Video Timing Modes Type 4 - DMT Timings Data Block"; break;
1584 case 0x07: data_block = "Supported Timing Modes Type 1 - VESA DMT Timings Data Block"; break;
1585 case 0x08: data_block = "Supported Timing Modes Type 2 - CTA-861 Timings Data Block"; break;
1586 case 0x09: data_block = "Video Timing Range Data Block"; break;
1587 case 0x0a: data_block = "Product Serial Number Data Block"; break;
1588 case 0x0b: data_block = "GP ASCII String Data Block"; break;
1589 case 0x0c: data_block = "Display Device Data Data Block"; break;
1590 case 0x0d: data_block = "Interface Power Sequencing Data Block"; break;
1591 case 0x0e: data_block = "Transfer Characteristics Data Block"; break;
1592 case 0x0f: data_block = "Display Interface Data Block"; break;
1593 case 0x10: data_block = "Stereo Display Interface Data Block (" + utohex(tag) + ")"; break;
1594 case 0x11: data_block = "Video Timing Modes Type 5 - Short Timings Data Block"; break;
1595 case 0x12: data_block = "Tiled Display Topology Data Block (" + utohex(tag) + ")"; break;
1596 case 0x13: data_block = "Video Timing Modes Type 6 - Detailed Timings Data Block"; break;
1597 // 0x14 .. 0x7e RESERVED for Additional VESA-defined Data Blocks
1598 // DisplayID 2.0
1599 case 0x20: data_block = "Product Identification Data Block (" + utohex(tag) + ")"; break;
1600 case 0x21: data_block = "Display Parameters Data Block (" + utohex(tag) + ")"; break;
1601 case 0x22: data_block = "Video Timing Modes Type 7 - Detailed Timings Data Block"; break;
1602 case 0x23: data_block = "Video Timing Modes Type 8 - Enumerated Timing Codes Data Block"; break;
1603 case 0x24: data_block = "Video Timing Modes Type 9 - Formula-based Timings Data Block"; break;
1604 case 0x25: data_block = "Dynamic Video Timing Range Limits Data Block"; break;
1605 case 0x26: data_block = "Display Interface Features Data Block"; break;
1606 case 0x27: data_block = "Stereo Display Interface Data Block (" + utohex(tag) + ")"; break;
1607 case 0x28: data_block = "Tiled Display Topology Data Block (" + utohex(tag) + ")"; break;
1608 case 0x29: data_block = "ContainerID Data Block"; break;
1609 case 0x32: data_block = "Video Timing Modes Type 10 - Formula-based Timings Data Block"; break;
1610 // 0x2a .. 0x7d RESERVED for Additional VESA-defined Data Blocks
1611 case 0x7e: // DisplayID 2.0
1612 case 0x7f: // DisplayID 1.3
1613 if ((tag == 0x7e && version >= 0x20) ||
1614 (tag == 0x7f && version < 0x20)) {
1615 oui = (x[offset + 3] << 16) + (x[offset + 4] << 8) + x[offset + 5];
1616 const char *name = oui_name(oui);
1617 bool reversed = false;
1618
1619 if (!name) {
1620 name = oui_name(oui, true);
1621 if (name)
1622 reversed = true;
1623 }
1624 if (name)
1625 data_block = std::string("Vendor-Specific Data Block (") + name + ")";
1626 else
1627 data_block = "Vendor-Specific Data Block, OUI " + ouitohex(oui);
1628 if (reversed)
1629 fail((std::string("OUI ") + ouitohex(oui) + " is in the wrong byte order.\n").c_str());
1630 } else {
1631 data_block = "Unknown DisplayID Data Block (" + utohex(tag) + ")";
1632 }
1633 break;
1634 // 0x80 RESERVED
1635 case 0x81: data_block = "CTA-861 DisplayID Data Block (" + utohex(tag) + ")"; break;
1636 // 0x82 .. 0xff RESERVED
1637 default: data_block = "Unknown DisplayID Data Block (" + utohex(tag) + ")"; break;
1638 }
1639
1640 if (version >= 0x20 && (tag < 0x20 || tag == 0x7f))
1641 fail("Use of DisplayID v1.x tag for DisplayID v%u.%u.\n",
1642 version >> 4, version & 0xf);
1643 if (version < 0x20 && tag >= 0x20 && tag <= 0x7e)
1644 fail("Use of DisplayID v2.0 tag for DisplayID v%u.%u.\n",
1645 version >> 4, version & 0xf);
1646
1647 if (length < 3) {
1648 // report a problem when the remaining bytes are not 0.
1649 if (tag || x[offset + 1]) {
1650 fail("Not enough bytes remain (%d) for a DisplayID data block or the DisplayID filler is non-0.\n", length);
1651 }
1652 break;
1653 }
1654
1655 unsigned block_rev = x[offset + 1] & 0x07;
1656 unsigned len = x[offset + 2];
1657
1658 if (length < len + 3) {
1659 fail("The length of this DisplayID data block (%d) exceeds the number of bytes remaining (%d).\n", len + 3, length);
1660 break;
1661 }
1662
1663 if (!tag && !len) {
1664 // A Product Identification Data Block with no payload bytes is not valid - assume this is the end.
1665 if (!memchk(x + offset, length)) {
1666 fail("Non-0 filler bytes in the DisplayID block.\n");
1667 }
1668 break;
1669 }
1670
1671 printf(" %s:\n", data_block.c_str());
1672
1673 switch (tag) {
1674 case 0x00: parse_displayid_product_id(x + offset); break;
1675 case 0x01: parse_displayid_parameters(x + offset); break;
1676 case 0x02: parse_displayid_color_characteristics(x + offset); break;
1677 case 0x03:
1678 check_displayid_datablock_revision(x[offset + 1], 0, block_rev & 1);
1679 for (i = 0; i < len / 20; i++)
1680 parse_displayid_type_1_7_timing(&x[offset + 3 + (i * 20)], false, block_rev);
1681 break;
1682 case 0x04:
1683 check_displayid_datablock_revision(x[offset + 1]);
1684 for (i = 0; i < len / 11; i++)
1685 parse_displayid_type_2_timing(&x[offset + 3 + (i * 11)]);
1686 break;
1687 case 0x05:
1688 check_displayid_datablock_revision(x[offset + 1], 0, block_rev & 1);
1689 for (i = 0; i < len / 3; i++)
1690 parse_displayid_type_3_timing(&x[offset + 3 + (i * 3)]);
1691 break;
1692 case 0x06:
1693 check_displayid_datablock_revision(x[offset + 1], 0xc0, 1);
1694 for (i = 0; i < len; i++)
1695 parse_displayid_type_4_8_timing((x[offset + 1] & 0xc0) >> 6, x[offset + 3 + i]);
1696 break;
1697 case 0x07:
1698 check_displayid_datablock_revision(x[offset + 1]);
1699 for (i = 0; i < min(len, 10) * 8; i++)
1700 if (x[offset + 3 + i / 8] & (1 << (i % 8))) {
1701 char type[16];
1702 sprintf(type, "DMT 0x%02x", i + 1);
1703 print_timings(" ", find_dmt_id(i + 1), type);
1704 }
1705 break;
1706 case 0x08:
1707 check_displayid_datablock_revision(x[offset + 1]);
1708 for (i = 0; i < min(len, 8) * 8; i++)
1709 if (x[offset + 3 + i / 8] & (1 << (i % 8))) {
1710 char type[16];
1711 sprintf(type, "VIC %3u", i + 1);
1712 print_timings(" ", find_vic_id(i + 1), type);
1713 }
1714 break;
1715 case 0x09: parse_displayid_video_timing_range_limits(x + offset); break;
1716 case 0x0a:
1717 case 0x0b: parse_displayid_string(x + offset); break;
1718 case 0x0c: parse_displayid_display_device(x + offset); break;
1719 case 0x0d: parse_displayid_intf_power_sequencing(x + offset); break;
1720 case 0x0e: parse_displayid_transfer_characteristics(x + offset); break;
1721 case 0x0f: parse_displayid_display_intf(x + offset); break;
1722 case 0x10: parse_displayid_stereo_display_intf(x + offset); break;
1723 case 0x11:
1724 check_displayid_datablock_revision(x[offset + 1]);
1725 for (i = 0; i < len / 7; i++)
1726 parse_displayid_type_5_timing(&x[offset + 3 + (i * 7)]);
1727 break;
1728 case 0x12: parse_displayid_tiled_display_topology(x + offset, false); break;
1729 case 0x13:
1730 check_displayid_datablock_revision(x[offset + 1]);
1731 for (i = 0; i < len; i += (x[offset + 3 + i + 2] & 0x40) ? 17 : 14)
1732 parse_displayid_type_6_timing(&x[offset + 3 + i]);
1733 break;
1734 case 0x20: parse_displayid_product_id(x + offset); break;
1735 case 0x21: parse_displayid_parameters_v2(x + offset); break;
1736 case 0x22: {
1737 unsigned sz = 20;
1738
1739 if (block_rev >= 2)
1740 check_displayid_datablock_revision(x[offset + 1], 0x08, 2);
1741 else if (block_rev == 1)
1742 check_displayid_datablock_revision(x[offset + 1], 0x08, 1);
1743 else
1744 check_displayid_datablock_revision(x[offset + 1]);
1745 sz += (x[offset + 1] & 0x70) >> 4;
1746 if (block_rev >= 1 && (x[offset + 1] & 0x08))
1747 printf(" These timings support DSC pass-through\n");
1748 for (i = 0; i < len / sz; i++)
1749 parse_displayid_type_1_7_timing(&x[offset + 3 + i * sz], true, block_rev);
1750 break;
1751 }
1752 case 0x23:
1753 if (block_rev)
1754 check_displayid_datablock_revision(x[offset + 1], 0xe8, 1);
1755 else
1756 check_displayid_datablock_revision(x[offset + 1], 0xc8);
1757 if (x[offset + 1] & 0x08) {
1758 for (i = 0; i < len / 2; i++)
1759 parse_displayid_type_4_8_timing((x[offset + 1] & 0xc0) >> 6,
1760 x[offset + 3 + i * 2] |
1761 (x[offset + 4 + i * 2] << 8));
1762 } else {
1763 for (i = 0; i < len; i++)
1764 parse_displayid_type_4_8_timing((x[offset + 1] & 0xc0) >> 6,
1765 x[offset + 3 + i]);
1766 }
1767 break;
1768 case 0x24:
1769 check_displayid_datablock_revision(x[offset + 1]);
1770 for (i = 0; i < len / 6; i++)
1771 parse_displayid_type_9_timing(&x[offset + 3 + i * 6]);
1772 break;
1773 case 0x25: parse_displayid_dynamic_video_timings_range_limits(x + offset); break;
1774 case 0x26: parse_displayid_interface_features(x + offset); break;
1775 case 0x27: parse_displayid_stereo_display_intf(x + offset); break;
1776 case 0x28: parse_displayid_tiled_display_topology(x + offset, true); break;
1777 case 0x29: parse_displayid_ContainerID(x + offset); break;
1778 case 0x32: {
1779 unsigned sz = 6 + ((x[offset + 1] & 0x70) >> 4);
1780
1781 check_displayid_datablock_revision(x[offset + 1], 0x10);
1782 for (i = 0; i < len / sz; i++)
1783 parse_displayid_type_10_timing(&x[offset + 3 + i * sz]);
1784 break;
1785 }
1786 case 0x81: parse_displayid_cta_data_block(x + offset); break;
1787 case 0x7e:
1788 if (oui == 0x3a0292) {
1789 parse_displayid_vesa(x + offset);
1790 break;
1791 }
1792 // fall-through
1793 default: hex_block(" ", x + offset + 3, len); break;
1794 }
1795
1796 if ((tag == 0x00 || tag == 0x20) &&
1797 (!dispid.is_base_block || !first_data_block))
1798 fail("%s is required to be the first DisplayID Data Block.\n",
1799 data_block.c_str());
1800 length -= len + 3;
1801 offset += len + 3;
1802 first_data_block = false;
2010 unsigned len;
2011 for (const unsigned char *y = x + 5; length > 0; y += len) {
2012 len = displayid_block(version, y, length);
2013 length -= len;
18032014 }
18042015
18052016 /*
18312042 dispid.version >= 0x20 ? "VII" : "I");
18322043 if (dispid.preferred_timings.empty())
18332044 fail("DisplayID expects at least one preferred timing.\n");
1834 }
2045 if (cta.image_width && dispid.image_width &&
2046 (cta.image_width != dispid.image_width ||
2047 cta.image_height != dispid.image_height))
2048 fail("Image size mismatch: CTA-861: %.1fx%.1fmm DisplayID: %.1fx%.1fmm.\n",
2049 cta.image_width / 10.0, cta.image_height / 10.0,
2050 dispid.image_width / 10.0, dispid.image_height / 10.0);
2051 if (dispid.image_width && dispid.image_width < 25600 && dispid.image_height < 25600 &&
2052 (abs((int)dispid.image_width - (int)base.max_display_width_mm * 10) >= 100 ||
2053 abs((int)dispid.image_height - (int)base.max_display_height_mm * 10) >= 100))
2054 fail("Image size mismatch: DisplayID: %.1fx%.1fmm Base EDID: %u.0x%u.0mm.\n",
2055 dispid.image_width / 10.0, dispid.image_height / 10.0,
2056 base.max_display_width_mm, base.max_display_height_mm);
2057 }
1616 unsigned num_cvt = x[3];
1717 unsigned num_st = x[4];
1818
19 const unsigned char *y = x + 0x7f;
1920 x += 5;
2021 if (num_dtd) {
2122 printf(" Detailed Timing Descriptors:\n");
22 for (unsigned i = 0; i < num_dtd; i++, x += 18)
23 for (unsigned i = 0; i < num_dtd; i++, x += 18) {
24 if (x + 18 > y) {
25 fail("Not enough bytes remain for more DTDs in the VTB-EXT.\n");
26 return;
27 }
2328 detailed_timings(" ", x, false);
29 }
2430 }
2531 if (num_cvt) {
2632 printf(" Coordinated Video Timings:\n");
27 for (unsigned i = 0; i < num_cvt; i++, x += 3)
33 for (unsigned i = 0; i < num_cvt; i++, x += 3) {
34 if (x + 3 > y) {
35 fail("Not enough bytes remain for more CVTs in the VTB-EXT.\n");
36 return;
37 }
2838 detailed_cvt_descriptor(" ", x, false);
39 }
2940 }
3041 if (num_st) {
42 // Note: the VTB-EXT standard has a mistake in the example EDID
43 // that it provides: there the refresh rate (bits 5-0 of the
44 // second byte) is set to 60 for 60 Hz, but this should be 0
45 // since the actual refresh rate is the value + 60.
46 //
47 // The documentation itself is correct, though.
3148 printf(" Standard Timings:\n");
3249 for (unsigned i = 0; i < num_st; i++, x += 2) {
33 if ((x[1] & 0x3f) >= 60)
34 print_standard_timing(" ", x[0], x[1] - 60, true);
35 else
36 print_standard_timing(" ", x[0], x[1], true, 0);
50 if (x + 2 > y) {
51 fail("Not enough bytes remain for more STs in the VTB-EXT.\n");
52 return;
53 }
54 print_standard_timing(" ", x[0], x[1], true);
3755 }
3856 }
3957 }
1717 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70
1818 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 5e
1919
20 02 03 24 f0 51 61 60 5f 5e 5d 10 1f 04 13 22 21
21 20 05 14 02 11 01 23 09 07 07 e2 00 ea e6 0d 61
20 02 03 24 f1 51 61 60 5f 5e 5d 10 1f 04 13 22 21
21 20 05 14 02 11 01 23 09 07 07 e2 00 ca e6 0d 61
2222 81 82 6a 84 4d d0 00 a0 f0 70 3e 80 30 20 35 00
2323 c0 1c 32 00 00 1e 1a 36 80 a0 70 38 1f 40 30 20
2424 35 00 c0 1c 32 00 00 1a 1a 1d 00 80 51 d0 1c 20
2525 40 80 35 00 c0 1c 32 00 00 1c 00 00 00 00 00 00
2626 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b7
28
29 70 20 5f 02 7c 20 00 10 00 00 00 01 00 01 00 00
27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d6
28
29 70 20 5f 02 7c 20 00 10 12 34 56 01 00 01 00 00
3030 00 00 00 04 54 65 73 74 21 00 1d 80 3e 28 23 00
3131 0f 70 08 00 3c 8a 54 cc 84 99 68 42 0f 00 45 54
32 00 00 00 00 00 00 00 ff 22 00 14 4f 10 09 80 ff
33 0e 2f 02 27 81 57 00 6f 08 59 00 47 80 09 00 24
32 00 00 00 00 00 00 00 ff 22 00 14 4f 10 09 84 ff
33 0e 2f 02 af 80 57 00 6f 08 59 00 07 80 09 00 24
3434 00 06 12 7f 07 37 04 3b 26 00 09 02 02 01 01 00
35 e0 07 00 00 bc 00 00 00 00 00 00 00 00 00 00 00
36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
37
38 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
39 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
42 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
43 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
45 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
46
47 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
49 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
51 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
52 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
53 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
55
56 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
57 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
58 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
62 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
63 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
64
65 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
66 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
67 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
68 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
69 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
71 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
72 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
73
74 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
75 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
76 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
77 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
78 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
79 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
81 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
82
83 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
84 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
85 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
86 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
87 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
88 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
89 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
91
92 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
93 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
94 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
95 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
96 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
97 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
98 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
99 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
100
101 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
102 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
103 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
104 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
105 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
106 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
107 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
108 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
109
110 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
111 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
112 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
113 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
114 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
115 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
116 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
117 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
118
119 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
121 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
122 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
123 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
124 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
125 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
126 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
127
128 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
129 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
131 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
132 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
133 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
134 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
135 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
136
137 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
138 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
139 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
141 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
142 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
143 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
144 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
145
146 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
147 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
148 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
149 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
151 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
152 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
153 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
154
155 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
156 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
157 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
158 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
159 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
161 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
162 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
163
164 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
165 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
166 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
167 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
168 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
169 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
171 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
172
173 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
174 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
175 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
176 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
177 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
178 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
179 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
181
182 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
183 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
184 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
185 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
186 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
187 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
188 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
189 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
190
191 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
192 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
193 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
194 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
195 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
196 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
197 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
198 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
199
200 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
201 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
202 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
203 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
204 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
205 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
206 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
207 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
208
209 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
211 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
212 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
213 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
214 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
215 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
216 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
217
218 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
219 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
221 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
222 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
223 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
224 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
225 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
226
227 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
228 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
229 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
231 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
232 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
233 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
234 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
235
236 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
237 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
238 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
239 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
241 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
242 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
243 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
244
245 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
246 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
247 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
248 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
249 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
250 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
251 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
252 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
253
254 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
255 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
256 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
257 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
258 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
259 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
261 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
262
263 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
264 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
265 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
266 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
267 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
268 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
269 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
271
272 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
273 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
274 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
275 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
276 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
277 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
278 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
279 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
280
281 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
282 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
283 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
284 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
285 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
286 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
287 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
288 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
289
290 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
291 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
292 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
293 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
294 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
295 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
296 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
297 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
298
299 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
300 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
301 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
302 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
303 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
304 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
305 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
306 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
307
308 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
309 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
310 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
311 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
312 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
313 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
314 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
315 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
316
317 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
318 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
319 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
320 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
321 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
322 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
323 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
324 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
325
326 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
327 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
328 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
329 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
331 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
332 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
333 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
334
335 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
336 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
337 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
338 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
339 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
340 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
341 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
342 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
343
344 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
345 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
346 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
347 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
348 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
349 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
351 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
352
353 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
354 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
355 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
356 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
357 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
358 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
359 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
360 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
361
362 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
363 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
364 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
365 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
366 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
367 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
368 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
369 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
370
371 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
372 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
373 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
374 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
375 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
376 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
377 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
378 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
379
380 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
381 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
382 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
383 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
384 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
385 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
386 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
387 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
388
389 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
390 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
391 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
392 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
393 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
394 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
395 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
396 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
397
398 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
399 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
400 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
401 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
402 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
403 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
404 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
405 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
406
407 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
408 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
409 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
410 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
411 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
412 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
413 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
414 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
415
416 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
417 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
418 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
419 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
420 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
421 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
422 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
423 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
424
425 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
426 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
427 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
428 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
429 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
430 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
431 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
432 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
433
434 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
435 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
436 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
437 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
438 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
439 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
440 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
441 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
442
443 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
444 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
445 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
446 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
447 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
448 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
449 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
451
452 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
453 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
454 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
455 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
456 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
457 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
458 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
459 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
460
461 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
462 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
463 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
464 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
465 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
466 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
467 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
468 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
469
470 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
471 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
472 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
473 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
474 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
475 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
476 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
477 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
478
479 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
480 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
481 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
482 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
483 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
484 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
485 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
486 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
487
488 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
489 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
491 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
492 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
493 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
494 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
495 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
496
497 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
498 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
499 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
500 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
501 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
502 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
503 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
504 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
505
506 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
507 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
508 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
509 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
511 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
512 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
513 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
514
515 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
516 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
517 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
518 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
519 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
521 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
522 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
523
524 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
525 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
526 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
527 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
528 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
529 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
531 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
532
533 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
534 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
535 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
536 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
537 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
538 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
539 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
541
542 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
543 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
544 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
545 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
546 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
547 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
548 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
549 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
550
551 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
552 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
553 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
554 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
555 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
556 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
557 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
558 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
559
560 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
561 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
562 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
563 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
564 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
565 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
566 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
567 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
568
569 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
570 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
571 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
572 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
573 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
574 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
575 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
576 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
577
578 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
579 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
580 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
581 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
582 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
583 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
584 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
585 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
586
587 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
588 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
589 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
590 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
591 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
592 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
593 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
594 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
595
596 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
597 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
598 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
599 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
600 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
601 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
602 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
603 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
604
605 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
606 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
607 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
608 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
609 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
610 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
611 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
612 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
613
614 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
615 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
616 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
617 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
618 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
619 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
621 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
622
623 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
624 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
625 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
626 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
627 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
628 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
629 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
630 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
631
632 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
633 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
634 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
635 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
636 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
637 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
638 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
639 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
640
641 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
642 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
643 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
644 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
645 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
646 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
647 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
648 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
649
650 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
651 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
652 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
653 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
654 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
655 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
656 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
657 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
658
659 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
660 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
661 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
662 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
663 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
664 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
665 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
666 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
667
668 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
669 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
670 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
671 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
672 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
673 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
674 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
675 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
676
677 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
678 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
679 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
680 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
681 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
682 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
683 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
684 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
685
686 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
687 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
688 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
689 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
690 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
691 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
692 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
693 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
694
695 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
696 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
697 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
698 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
699 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
700 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
701 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
702 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
703
704 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
705 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
706 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
707 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
708 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
709 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
710 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
711 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
712
713 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
714 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
715 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
716 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
717 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
718 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
719 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
720 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
721
722 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
723 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
724 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
725 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
726 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
727 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
728 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
729 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
730
731 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
732 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
733 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
734 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
735 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
736 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
737 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
738 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
739
740 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
741 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
742 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
743 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
744 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
745 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
746 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
747 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
748
749 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
750 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
751 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
752 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
753 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
754 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
755 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
756 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
757
758 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
759 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
760 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
761 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
762 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
763 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
764 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
765 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
766
767 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
768 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
769 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
770 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
771 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
772 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
773 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
774 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
775
776 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
777 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
778 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
779 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
780 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
781 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
782 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
783 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
784
785 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
786 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
787 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
788 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
789 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
790 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
791 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
792 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
793
794 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
795 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
796 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
797 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
798 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
799 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
800 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
801 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
802
803 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
804 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
805 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
806 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
807 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
808 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
809 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
810 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
811
812 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
813 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
814 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
815 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
816 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
817 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
818 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
819 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
820
821 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
822 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
823 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
824 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
825 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
826 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
827 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
828 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
829
830 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
831 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
832 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
833 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
834 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
835 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
836 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
837 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
838
839 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
840 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
841 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
842 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
843 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
844 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
845 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
846 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
847
848 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
849 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
850 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
851 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
852 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
853 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
854 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
855 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
856
857 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
858 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
859 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
860 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
861 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
862 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
863 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
864 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
865
866 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
867 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
868 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
869 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
870 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
871 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
872 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
873 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
874
875 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
876 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
877 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
878 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
879 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
880 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
881 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
882 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
883
884 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
885 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
886 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
887 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
888 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
889 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
890 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
891 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
892
893 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
894 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
895 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
896 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
897 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
898 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
899 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
900 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
901
902 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
903 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
904 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
905 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
906 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
907 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
908 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
909 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
910
911 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
912 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
913 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
914 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
915 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
916 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
917 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
918 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
919
920 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
921 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
922 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
923 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
924 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
925 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
926 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
927 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
928
929 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
930 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
931 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
932 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
933 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
934 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
935 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
936 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
937
938 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
939 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
940 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
941 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
942 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
943 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
944 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
945 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
946
947 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
948 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
949 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
950 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
951 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
952 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
953 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
954 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
955
956 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
957 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
958 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
959 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
960 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
961 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
962 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
963 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
964
965 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
966 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
967 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
968 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
969 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
970 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
971 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
972 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
973
974 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
975 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
976 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
977 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
978 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
979 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
980 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
981 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
982
983 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
984 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
985 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
986 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
987 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
988 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
989 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
990 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
991
992 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
993 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
994 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
995 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
996 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
997 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
998 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
999 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1000
1001 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1002 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1003 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1004 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1005 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1006 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1007 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1008 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1009
1010 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1011 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1012 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1013 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1014 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1015 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1016 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1017 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1018
1019 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1021 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1022 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1023 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1024 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1025 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1026 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1027
1028 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1029 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1031 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1032 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1033 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1034 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1035 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1036
1037 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1038 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1039 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1041 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1042 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1043 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1044 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1045
1046 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1047 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1048 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1049 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1051 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1052 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1053 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1054
1055 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1056 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1057 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1058 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1059 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1061 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1062 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1063
1064 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1065 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1066 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1067 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1068 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1069 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1071 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1072
1073 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1074 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1075 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1076 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1077 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1078 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1079 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1081
1082 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1083 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1084 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1085 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1086 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1087 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1088 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1089 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1090
1091 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1092 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1093 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1094 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1095 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1096 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1097 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1098 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1099
1100 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1101 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1102 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1103 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1104 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1105 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1106 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1107 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1108
1109 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1111 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1112 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1113 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1114 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1115 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1116 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1117
1118 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1119 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1121 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1122 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1123 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1124 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1125 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1126
1127 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1128 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1129 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1131 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1132 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1133 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1134 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1135
1136 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1137 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1138 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1139 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1141 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1142 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1143 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1144
1145 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1146 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1147 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1148 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1149 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1151 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1152 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
35 e0 07 00 00 d5 00 00 00 00 00 00 00 00 00 00 00
36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
37
38 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
39 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
42 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
43 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
45 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
46
47 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
49 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
51 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
52 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
53 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
55
56 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
57 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
58 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
62 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
63 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
64
65 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
66 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
67 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
68 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
69 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
71 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
72 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
73
74 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
75 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
76 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
77 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
78 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
79 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
81 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
82
83 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
84 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
85 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
86 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
87 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
88 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
89 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
91
92 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
93 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
94 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
95 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
96 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
97 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
98 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
99 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
100
101 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
102 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
103 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
104 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
105 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
106 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
107 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
108 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
109
110 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
111 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
112 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
113 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
114 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
115 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
116 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
117 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
118
119 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
121 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
122 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
123 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
124 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
125 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
126 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
127
128 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
129 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
131 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
132 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
133 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
134 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
135 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
136
137 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
138 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
139 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
141 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
142 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
143 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
144 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
145
146 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
147 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
148 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
149 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
151 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
152 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
153 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
154
155 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
156 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
157 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
158 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
159 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
161 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
162 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
163
164 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
165 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
166 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
167 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
168 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
169 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
171 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
172
173 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
174 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
175 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
176 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
177 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
178 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
179 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
181
182 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
183 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
184 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
185 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
186 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
187 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
188 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
189 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
190
191 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
192 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
193 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
194 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
195 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
196 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
197 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
198 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
199
200 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
201 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
202 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
203 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
204 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
205 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
206 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
207 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
208
209 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
211 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
212 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
213 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
214 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
215 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
216 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
217
218 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
219 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
221 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
222 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
223 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
224 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
225 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
226
227 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
228 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
229 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
231 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
232 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
233 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
234 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
235
236 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
237 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
238 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
239 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
241 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
242 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
243 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
244
245 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
246 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
247 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
248 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
249 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
250 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
251 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
252 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
253
254 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
255 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
256 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
257 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
258 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
259 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
261 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
262
263 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
264 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
265 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
266 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
267 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
268 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
269 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
271
272 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
273 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
274 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
275 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
276 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
277 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
278 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
279 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
280
281 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
282 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
283 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
284 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
285 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
286 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
287 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
288 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
289
290 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
291 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
292 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
293 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
294 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
295 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
296 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
297 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
298
299 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
300 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
301 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
302 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
303 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
304 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
305 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
306 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
307
308 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
309 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
310 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
311 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
312 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
313 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
314 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
315 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
316
317 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
318 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
319 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
320 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
321 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
322 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
323 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
324 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
325
326 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
327 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
328 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
329 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
331 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
332 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
333 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
334
335 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
336 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
337 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
338 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
339 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
340 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
341 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
342 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
343
344 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
345 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
346 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
347 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
348 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
349 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
351 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
352
353 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
354 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
355 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
356 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
357 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
358 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
359 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
360 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
361
362 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
363 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
364 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
365 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
366 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
367 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
368 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
369 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
370
371 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
372 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
373 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
374 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
375 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
376 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
377 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
378 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
379
380 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
381 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
382 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
383 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
384 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
385 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
386 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
387 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
388
389 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
390 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
391 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
392 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
393 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
394 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
395 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
396 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
397
398 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
399 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
400 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
401 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
402 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
403 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
404 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
405 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
406
407 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
408 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
409 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
410 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
411 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
412 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
413 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
414 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
415
416 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
417 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
418 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
419 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
420 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
421 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
422 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
423 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
424
425 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
426 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
427 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
428 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
429 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
430 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
431 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
432 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
433
434 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
435 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
436 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
437 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
438 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
439 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
440 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
441 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
442
443 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
444 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
445 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
446 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
447 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
448 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
449 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
451
452 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
453 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
454 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
455 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
456 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
457 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
458 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
459 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
460
461 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
462 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
463 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
464 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
465 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
466 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
467 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
468 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
469
470 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
471 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
472 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
473 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
474 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
475 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
476 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
477 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
478
479 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
480 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
481 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
482 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
483 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
484 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
485 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
486 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
487
488 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
489 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
491 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
492 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
493 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
494 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
495 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
496
497 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
498 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
499 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
500 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
501 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
502 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
503 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
504 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
505
506 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
507 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
508 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
509 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
511 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
512 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
513 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
514
515 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
516 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
517 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
518 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
519 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
521 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
522 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
523
524 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
525 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
526 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
527 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
528 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
529 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
531 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
532
533 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
534 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
535 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
536 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
537 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
538 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
539 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
541
542 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
543 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
544 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
545 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
546 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
547 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
548 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
549 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
550
551 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
552 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
553 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
554 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
555 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
556 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
557 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
558 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
559
560 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
561 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
562 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
563 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
564 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
565 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
566 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
567 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
568
569 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
570 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
571 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
572 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
573 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
574 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
575 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
576 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
577
578 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
579 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
580 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
581 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
582 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
583 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
584 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
585 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
586
587 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
588 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
589 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
590 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
591 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
592 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
593 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
594 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
595
596 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
597 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
598 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
599 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
600 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
601 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
602 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
603 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
604
605 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
606 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
607 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
608 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
609 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
610 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
611 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
612 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
613
614 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
615 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
616 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
617 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
618 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
619 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
621 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
622
623 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
624 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
625 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
626 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
627 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
628 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
629 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
630 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
631
632 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
633 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
634 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
635 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
636 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
637 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
638 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
639 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
640
641 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
642 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
643 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
644 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
645 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
646 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
647 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
648 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
649
650 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
651 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
652 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
653 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
654 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
655 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
656 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
657 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
658
659 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
660 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
661 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
662 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
663 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
664 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
665 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
666 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
667
668 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
669 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
670 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
671 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
672 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
673 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
674 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
675 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
676
677 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
678 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
679 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
680 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
681 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
682 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
683 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
684 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
685
686 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
687 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
688 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
689 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
690 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
691 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
692 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
693 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
694
695 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
696 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
697 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
698 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
699 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
700 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
701 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
702 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
703
704 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
705 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
706 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
707 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
708 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
709 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
710 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
711 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
712
713 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
714 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
715 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
716 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
717 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
718 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
719 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
720 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
721
722 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
723 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
724 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
725 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
726 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
727 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
728 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
729 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
730
731 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
732 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
733 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
734 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
735 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
736 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
737 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
738 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
739
740 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
741 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
742 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
743 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
744 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
745 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
746 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
747 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
748
749 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
750 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
751 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
752 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
753 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
754 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
755 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
756 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
757
758 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
759 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
760 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
761 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
762 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
763 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
764 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
765 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
766
767 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
768 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
769 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
770 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
771 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
772 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
773 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
774 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
775
776 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
777 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
778 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
779 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
780 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
781 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
782 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
783 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
784
785 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
786 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
787 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
788 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
789 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
790 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
791 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
792 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
793
794 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
795 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
796 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
797 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
798 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
799 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
800 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
801 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
802
803 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
804 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
805 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
806 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
807 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
808 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
809 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
810 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
811
812 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
813 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
814 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
815 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
816 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
817 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
818 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
819 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
820
821 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
822 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
823 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
824 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
825 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
826 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
827 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
828 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
829
830 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
831 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
832 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
833 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
834 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
835 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
836 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
837 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
838
839 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
840 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
841 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
842 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
843 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
844 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
845 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
846 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
847
848 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
849 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
850 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
851 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
852 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
853 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
854 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
855 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
856
857 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
858 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
859 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
860 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
861 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
862 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
863 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
864 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
865
866 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
867 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
868 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
869 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
870 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
871 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
872 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
873 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
874
875 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
876 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
877 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
878 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
879 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
880 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
881 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
882 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
883
884 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
885 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
886 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
887 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
888 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
889 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
890 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
891 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
892
893 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
894 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
895 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
896 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
897 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
898 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
899 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
900 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
901
902 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
903 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
904 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
905 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
906 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
907 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
908 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
909 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
910
911 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
912 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
913 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
914 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
915 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
916 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
917 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
918 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
919
920 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
921 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
922 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
923 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
924 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
925 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
926 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
927 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
928
929 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
930 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
931 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
932 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
933 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
934 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
935 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
936 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
937
938 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
939 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
940 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
941 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
942 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
943 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
944 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
945 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
946
947 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
948 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
949 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
950 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
951 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
952 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
953 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
954 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
955
956 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
957 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
958 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
959 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
960 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
961 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
962 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
963 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
964
965 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
966 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
967 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
968 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
969 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
970 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
971 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
972 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
973
974 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
975 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
976 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
977 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
978 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
979 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
980 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
981 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
982
983 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
984 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
985 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
986 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
987 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
988 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
989 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
990 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
991
992 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
993 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
994 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
995 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
996 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
997 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
998 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
999 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1000
1001 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1002 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1003 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1004 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1005 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1006 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1007 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1008 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1009
1010 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1011 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1012 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1013 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1014 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1015 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1016 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1017 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1018
1019 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1021 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1022 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1023 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1024 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1025 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1026 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1027
1028 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1029 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1031 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1032 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1033 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1034 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1035 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1036
1037 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1038 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1039 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1041 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1042 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1043 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1044 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1045
1046 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1047 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1048 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1049 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1051 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1052 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1053 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1054
1055 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1056 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1057 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1058 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1059 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1061 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1062 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1063
1064 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1065 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1066 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1067 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1068 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1069 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1071 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1072
1073 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1074 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1075 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1076 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1077 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1078 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1079 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1081
1082 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1083 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1084 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1085 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1086 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1087 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1088 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1089 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1090
1091 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1092 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1093 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1094 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1095 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1096 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1097 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1098 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1099
1100 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1101 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1102 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1103 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1104 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1105 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1106 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1107 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1108
1109 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1111 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1112 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1113 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1114 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1115 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1116 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1117
1118 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1119 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1121 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1122 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1123 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1124 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1125 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1126
1127 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1128 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1129 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1131 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1132 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1133 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1134 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1135
1136 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1137 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1138 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1139 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1141 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1142 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1143 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1144
1145 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00
1146 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1147 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1148 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1149 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1151 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1152 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
1717 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70
1818 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 5e
1919
20 02 03 24 f0 51 61 60 5f 5e 5d 10 1f 04 13 22 21
21 20 05 14 02 11 01 23 09 07 07 e2 00 ea e6 0d 61
20 02 03 24 f1 51 61 60 5f 5e 5d 10 1f 04 13 22 21
21 20 05 14 02 11 01 23 09 07 07 e2 00 ca e6 0d 61
2222 81 82 6a 84 4d d0 00 a0 f0 70 3e 80 30 20 35 00
2323 c0 1c 32 00 00 1e 1a 36 80 a0 70 38 1f 40 30 20
2424 35 00 c0 1c 32 00 00 1a 1a 1d 00 80 51 d0 1c 20
2525 40 80 35 00 c0 1c 32 00 00 1c 00 00 00 00 00 00
2626 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b7
28
29 70 20 5f 02 fa 20 00 10 00 00 00 01 00 01 00 00
27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d6
28
29 70 20 5f 02 fa 20 00 10 12 34 56 01 00 01 00 00
3030 00 00 00 04 54 65 73 74 21 00 1d 80 3e 28 23 00
3131 0f 70 08 00 3c 8a 54 cc 84 99 68 42 0f 00 45 54
32 00 00 00 00 00 00 00 ff 22 00 14 4f 10 09 80 ff
33 0e 2f 02 27 81 57 00 6f 08 59 00 47 80 09 00 24
32 00 00 00 00 00 00 00 ff 22 00 14 4f 10 09 84 ff
33 0e 2f 02 af 80 57 00 6f 08 59 00 07 80 09 00 24
3434 00 06 12 7f 07 37 04 3b 26 00 09 02 02 01 01 00
35 e0 07 00 00 3e 00 00 00 00 00 00 00 00 00 00 00
35 e0 07 00 00 57 00 00 00 00 00 00 00 00 00 00 00
3636 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90
3737
3838 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00