New upstream version 0.1~git20220315.cb74358c2896
Andrej Shadura
2 years ago
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 | |
2 | 13 | |
3 | 14 | EMXX ?= em++ |
4 | 15 | |
5 | 16 | SOURCES = edid-decode.cpp parse-base-block.cpp parse-cta-block.cpp \ |
6 | 17 | 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 | |
9 | 21 | |
10 | 22 | all: edid-decode |
11 | 23 | |
12 | 24 | 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) | |
14 | 26 | |
15 | edid-decode: $(SOURCES) edid-decode.h Makefile | |
27 | edid-decode: $(SOURCES) edid-decode.h oui.h Makefile | |
16 | 28 | $(CXX) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(WARN_FLAGS) -g $(sha) $(date) -o $@ $(SOURCES) -lm |
17 | 29 | |
18 | edid-decode.js: $(SOURCES) edid-decode.h Makefile | |
30 | edid-decode.js: $(SOURCES) edid-decode.h oui.h Makefile | |
19 | 31 | $(EMXX) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(WARN_FLAGS) $(sha) $(date) -s EXPORTED_FUNCTIONS='["_parse_edid"]' -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -o $@ $(SOURCES) -lm |
20 | 32 | |
21 | 33 | 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
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
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
87 | 87 | is the actual HDMI VIC code. |
88 | 88 | .TP |
89 | 89 | 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). | |
92 | 98 | .RE |
93 | 99 | |
94 | 100 | By default DTDs are shown in the long format while others are just shown in |
110 | 116 | .TP |
111 | 117 | DisplayID 1.3: VESA Display Identification Data (DisplayID) Standard, Version 1.3 |
112 | 118 | .TP |
113 | DisplayID 2.0: VESA DisplayID Standard, Version 2.0 | |
119 | DisplayID 2.1: VESA DisplayID Standard, Version 2.1 | |
114 | 120 | .TP |
115 | 121 | DI-EXT: VESA Display Information Extension Block Standard, Release A |
116 | 122 | .TP |
130 | 136 | .TP |
131 | 137 | CTA-861-H: A DTV Profile for Uncompressed High Speed Digital Interfaces |
132 | 138 | .TP |
139 | CTA-861.6: Improvements on Audio and Video Signaling | |
140 | .TP | |
133 | 141 | SPWG Notebook Panel Specification, Version 3.5 |
134 | 142 | .TP |
135 | 143 | EPI Embedded Panel Interface, Revision 1.0 |
144 | .TP | |
145 | Microsoft EDID extension for head-mounted and specialized monitors, Version 3 | |
136 | 146 | .RE |
137 | 147 | |
138 | 148 | .TP |
141 | 151 | .TP |
142 | 152 | DMT 1.3: VESA and Industry Standards and Guidelines for Computer Display Monitor Timing (DMT), Version 1.0, Rev. 13 |
143 | 153 | .TP |
154 | CVT 2.0: VESA Coordinated Video Timings (CVT) Standard, Version 2.0 | |
155 | .TP | |
144 | 156 | CVT 1.2: VESA Coordinated Video Timings (CVT) Standard, Version 1.2 |
157 | .TP | |
158 | CVT 1.2: VESA CVT v1.2 Errata E2 | |
145 | 159 | .TP |
146 | 160 | GTF 1.1: VESA Generalized Timing Formula Standard, Version: 1.1 |
147 | 161 | .RE |
151 | 165 | \fB\-h\fR, \fB\-\-help\fR |
152 | 166 | Prints the help message. |
153 | 167 | .TP |
154 | \fB\-o\fR, \fB\-\-output\-format\fR=\fI<fmt>\fR | |
168 | \fB\-o\fR, \fB\-\-output\-format\fR \fI<fmt>\fR | |
155 | 169 | If [out] is specified, then write the EDID in format \fI<fmt>\fR. |
156 | .br | |
170 | ||
157 | 171 | The output format can be one of: |
158 | 172 | .br |
159 | 173 | hex: hex numbers in ascii text (default for stdout) |
172 | 186 | Check if the EDID conforms to the standards. Warnings and failures are |
173 | 187 | reported as they happen. |
174 | 188 | .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 | |
177 | 191 | 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. | |
179 | 196 | .TP |
180 | 197 | \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 | |
182 | 199 | depending on whether the Source only parses Block 0 (e.g. DVI outputs), or Block 0 |
183 | 200 | and the CTA-861 Extension Blocks (HDMI), or Block 0 and the DisplayID Extension Blocks |
184 | 201 | (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. | |
185 | 207 | .TP |
186 | 208 | \fB\-P\fR, \fB\-\-physical\-address\fR |
187 | 209 | Just report the HDMI Source Physical Address and nothing else. Reports f.f.f.f |
196 | 218 | \fB\-L\fR, \fB\-\-long\-timings\fR |
197 | 219 | Report all video timings in a long format. |
198 | 220 | .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 | |
199 | 226 | \fB\-X\fR, \fB\-\-xmodeline\fR |
200 | 227 | Report all long video timings in the ModeLine format as defined in xorg.conf(5). |
201 | 228 | This ModeLine can be used in the xorg.conf file or passed to xrandr(1) with the |
210 | 237 | .TP |
211 | 238 | \fB\-s\fR, \fB\-\-skip\-hex\-dump\fR |
212 | 239 | 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. | |
213 | 243 | .TP |
214 | 244 | \fB\-\-skip\-sha\fR |
215 | 245 | Don't show the SHA hash. Normally edid-decode will show the SHA, i.e. the |
227 | 257 | \fB\-\-version\fR |
228 | 258 | Show the SHA hash and the last commit date. |
229 | 259 | |
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 | ||
230 | 359 | .PP |
231 | 360 | .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. | |
235 | 362 | .B edid-decode |
236 | 363 | does attempt to validate its input against the relevant standards, but its |
237 | 364 | opinions have not been double-checked with the relevant standards bodies, |
41 | 41 | enum Option { |
42 | 42 | OptCheck = 'c', |
43 | 43 | OptCheckInline = 'C', |
44 | OptFBModeTimings = 'F', | |
44 | 45 | OptHelp = 'h', |
45 | OptNativeTimings = 'n', | |
46 | OptOnlyHexDump = 'H', | |
47 | OptLongTimings = 'L', | |
48 | OptNativeResolution = 'n', | |
49 | OptNTSC = 'N', | |
46 | 50 | OptOutputFormat = 'o', |
47 | 51 | OptPreferredTimings = 'p', |
48 | 52 | OptPhysicalAddress = 'P', |
49 | OptLongTimings = 'L', | |
53 | OptSkipHexDump = 's', | |
50 | 54 | OptShortTimings = 'S', |
51 | OptFBModeTimings = 'F', | |
55 | OptV4L2Timings = 'V', | |
52 | 56 | OptXModeLineTimings = 'X', |
53 | OptV4L2Timings = 'V', | |
54 | OptSkipHexDump = 's', | |
55 | 57 | OptSkipSHA = 128, |
56 | 58 | OptHideSerialNumbers, |
57 | 59 | 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, | |
58 | 74 | OptLast = 256 |
59 | 75 | }; |
60 | 76 | |
63 | 79 | static struct option long_options[] = { |
64 | 80 | { "help", no_argument, 0, OptHelp }, |
65 | 81 | { "output-format", required_argument, 0, OptOutputFormat }, |
66 | { "native-timings", no_argument, 0, OptNativeTimings }, | |
82 | { "native-resolution", no_argument, 0, OptNativeResolution }, | |
67 | 83 | { "preferred-timings", no_argument, 0, OptPreferredTimings }, |
68 | 84 | { "physical-address", no_argument, 0, OptPhysicalAddress }, |
69 | 85 | { "skip-hex-dump", no_argument, 0, OptSkipHexDump }, |
86 | { "only-hex-dump", no_argument, 0, OptOnlyHexDump }, | |
70 | 87 | { "skip-sha", no_argument, 0, OptSkipSHA }, |
71 | 88 | { "hide-serial-numbers", no_argument, 0, OptHideSerialNumbers }, |
72 | 89 | { "version", no_argument, 0, OptVersion }, |
74 | 91 | { "check", no_argument, 0, OptCheck }, |
75 | 92 | { "short-timings", no_argument, 0, OptShortTimings }, |
76 | 93 | { "long-timings", no_argument, 0, OptLongTimings }, |
94 | { "ntsc", no_argument, 0, OptNTSC }, | |
77 | 95 | { "xmodeline", no_argument, 0, OptXModeLineTimings }, |
78 | 96 | { "fbmode", no_argument, 0, OptFBModeTimings }, |
79 | 97 | { "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 }, | |
80 | 112 | { 0, 0, 0, 0 } |
81 | 113 | }; |
82 | 114 | |
89 | 121 | " if the output filename is '-'.\n" |
90 | 122 | "\nOptions:\n" |
91 | 123 | " -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" | |
93 | 125 | " <fmt> is one of:\n" |
94 | 126 | " hex: hex numbers in ascii text (default for stdout)\n" |
95 | 127 | " raw: binary data (default unless writing to stdout)\n" |
96 | 128 | " carray: c-program struct\n" |
97 | 129 | " 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" | |
99 | 131 | " 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" | |
101 | 133 | " 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"); | |
115 | 193 | } |
116 | 194 | |
117 | 195 | static std::string s_msgs[EDID_MAX_BLOCKS + 1][2]; |
175 | 253 | printf("\n"); |
176 | 254 | } |
177 | 255 | |
178 | static unsigned gcd(unsigned a, unsigned b) | |
256 | unsigned gcd(unsigned a, unsigned b) | |
179 | 257 | { |
180 | 258 | while (b) { |
181 | 259 | unsigned t = b; |
200 | 278 | |
201 | 279 | std::string edid_state::dtd_type(unsigned cnt) |
202 | 280 | { |
203 | unsigned len = std::to_string(cta.preparse_total_dtds).length(); | |
281 | unsigned len = std::to_string(cta.preparsed_total_dtds).length(); | |
204 | 282 | char buf[16]; |
205 | 283 | sprintf(buf, "DTD %*u", len, cnt); |
206 | 284 | return buf; |
238 | 316 | num_flags++; |
239 | 317 | } |
240 | 318 | |
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 | ||
241 | 350 | static void print_modeline(unsigned indent, const struct timings *t, double refresh) |
242 | 351 | { |
243 | 352 | 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; | |
244 | 357 | |
245 | 358 | printf("%*sModeline \"%ux%u_%.2f%s\" %.3f %u %u %u %u %u %u %u %u %cHSync", |
246 | 359 | indent, "", |
247 | 360 | t->hact, t->vact, refresh, |
248 | 361 | 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, | |
253 | 366 | t->pos_pol_hsync ? '+' : '-'); |
254 | 367 | if (!t->no_pol_vsync) |
255 | 368 | printf(" %cVSync", t->pos_pol_vsync ? '+' : '-'); |
274 | 387 | t->hact, t->vact, t->hact, t->vact); |
275 | 388 | unsigned mult = t->interlaced ? 2 : 1; |
276 | 389 | 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; | |
277 | 394 | printf("%*stimings %llu %d %d %d %u %u %u\n", |
278 | 395 | indent + 8, "", |
279 | 396 | (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); | |
281 | 398 | if (t->interlaced) |
282 | 399 | printf("%*slaced true\n", indent + 8, ""); |
283 | 400 | if (t->pos_pol_hsync) |
304 | 421 | printf("V4L2_DV_HSYNC_POS_POL, \\\n"); |
305 | 422 | else |
306 | 423 | 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; | |
307 | 428 | 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, | |
311 | 432 | t->interlaced ? t->vsync : 0, |
312 | t->interlaced ? t->vbp + !t->even_vtotal : 0); | |
433 | t->interlaced ? vbp + !t->even_vtotal : 0); | |
313 | 434 | |
314 | 435 | std::string flags; |
315 | 436 | unsigned num_flags = 0; |
356 | 477 | |
357 | 478 | static void print_detailed_timing(unsigned indent, const struct timings *t) |
358 | 479 | { |
359 | printf("%*sHfront %4d Hsync %3u Hback %3d Hpol %s", | |
480 | printf("%*sHfront %4d Hsync %3u Hback %4d Hpol %s", | |
360 | 481 | indent, "", |
361 | 482 | t->hfp, t->hsync, t->hbp, t->pos_pol_hsync ? "P" : "N"); |
362 | 483 | if (t->hborder) |
363 | 484 | printf(" Hborder %u", t->hborder); |
364 | 485 | printf("\n"); |
365 | 486 | |
366 | printf("%*sVfront %4u Vsync %3u Vback %3d", | |
487 | printf("%*sVfront %4u Vsync %3u Vback %4d", | |
367 | 488 | indent, "", t->vfp, t->vsync, t->vbp); |
368 | 489 | if (!t->no_pol_vsync) |
369 | 490 | printf(" Vpol %s", t->pos_pol_vsync ? "P" : "N"); |
373 | 494 | printf(" Both Fields"); |
374 | 495 | } else if (t->interlaced) { |
375 | 496 | printf(" Vfront +0.5 Odd Field\n"); |
376 | printf("%*sVfront %4d Vsync %3u Vback %3d", | |
497 | printf("%*sVfront %4d Vsync %3u Vback %4d", | |
377 | 498 | indent, "", t->vfp, t->vsync, t->vbp); |
378 | 499 | if (!t->no_pol_vsync) |
379 | 500 | printf(" Vpol %s", t->pos_pol_vsync ? "P" : "N"); |
386 | 507 | |
387 | 508 | bool edid_state::print_timings(const char *prefix, const struct timings *t, |
388 | 509 | const char *type, const char *flags, |
389 | bool detailed) | |
510 | bool detailed, bool do_checks) | |
390 | 511 | { |
391 | 512 | if (!t) { |
392 | 513 | // Should not happen |
393 | fail("Unknown video timings.\n"); | |
514 | if (do_checks) | |
515 | fail("Unknown video timings.\n"); | |
394 | 516 | return false; |
395 | 517 | } |
396 | 518 | |
400 | 522 | detailed = true; |
401 | 523 | |
402 | 524 | 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; | |
405 | 527 | unsigned htotal = t->hact + hbl; |
406 | 528 | double hor_freq_khz = htotal ? (double)t->pixclk_khz / htotal : 0; |
407 | 529 | |
408 | 530 | if (t->interlaced) |
409 | 531 | vact /= 2; |
410 | 532 | |
533 | double out_hor_freq_khz = hor_freq_khz; | |
411 | 534 | if (t->ycbcr420) |
412 | 535 | hor_freq_khz /= 2; |
413 | 536 | |
417 | 540 | |
418 | 541 | if (!t->hact || !hbl || !t->hfp || !t->hsync || |
419 | 542 | !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); | |
426 | 550 | ok = false; |
427 | 551 | } |
428 | 552 | |
431 | 555 | else if (t->interlaced) |
432 | 556 | vtotal = vact + t->vfp + t->vsync + t->vbp + 0.5; |
433 | 557 | |
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 | } | |
435 | 566 | |
436 | 567 | std::string s; |
437 | if (t->rb) { | |
568 | unsigned rb = t->rb & ~RB_ALT; | |
569 | if (rb) { | |
570 | bool alt = t->rb & RB_ALT; | |
438 | 571 | 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" : ""); | |
443 | 576 | } |
444 | 577 | add_str(s, flags); |
445 | 578 | if (t->hsize_mm || t->vsize_mm) |
446 | 579 | 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; | |
447 | 584 | if (!s.empty()) |
448 | 585 | s = " (" + s + ")"; |
449 | 586 | unsigned pixclk_khz = t->pixclk_khz / (t->ycbcr420 ? 2 : 1); |
451 | 588 | char buf[10]; |
452 | 589 | |
453 | 590 | 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", | |
455 | 592 | prefix, type, |
456 | 593 | t->hact, buf, |
457 | 594 | refresh, |
458 | 595 | t->hratio, t->vratio, |
459 | hor_freq_khz, | |
460 | pixclk_khz / 1000.0, | |
596 | out_hor_freq_khz, | |
597 | pixclk / 1000000.0, | |
461 | 598 | s.c_str()); |
462 | 599 | |
463 | 600 | unsigned len = strlen(prefix) + 2; |
471 | 608 | else if (detailed) |
472 | 609 | print_detailed_timing(len + strlen(type) + 6, t); |
473 | 610 | |
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 | ||
474 | 638 | 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"); | |
476 | 640 | if (t->hfp <= 0) |
477 | 641 | fail("0 or negative horizontal front porch.\n"); |
478 | 642 | if (t->hbp <= 0) |
479 | 643 | fail("0 or negative horizontal back porch.\n"); |
480 | 644 | if (t->vbp <= 0) |
481 | 645 | 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 */ | |
485 | 648 | } else if (!t->hsize_mm && !t->vsize_mm) { |
486 | 649 | /* this is valid */ |
487 | 650 | } else if (t->hsize_mm > base.max_display_width_mm + 9 || |
493 | 656 | fail("Mismatch of image size %ux%u mm vs display size %ux%u mm.\n", |
494 | 657 | t->hsize_mm, t->vsize_mm, base.max_display_width_mm, base.max_display_height_mm); |
495 | 658 | } |
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 | } | |
505 | 659 | 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; | |
506 | 673 | } |
507 | 674 | |
508 | 675 | std::string utohex(unsigned char x) |
513 | 680 | return buf; |
514 | 681 | } |
515 | 682 | |
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; | |
521 | 688 | 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 | } | |
535 | 769 | } |
536 | 770 | } |
537 | 771 | |
555 | 789 | unsigned length, bool show_ascii, unsigned step) |
556 | 790 | { |
557 | 791 | unsigned i, j; |
558 | ||
559 | if (!length) | |
560 | return; | |
561 | 792 | |
562 | 793 | for (i = 0; i < length; i += step) { |
563 | 794 | unsigned len = min(step, length - i); |
733 | 964 | edid_data.insert(edid_data.end(), buf, buf + i); |
734 | 965 | } |
735 | 966 | |
736 | if (edid_data.empty()) | |
967 | if (edid_data.empty()) { | |
968 | state.edid_size = 0; | |
737 | 969 | return false; |
970 | } | |
738 | 971 | |
739 | 972 | const char *data = &edid_data[0]; |
740 | 973 | const char *start; |
926 | 1159 | |
927 | 1160 | odd_hex_digits = false; |
928 | 1161 | 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 | } | |
929 | 1166 | fprintf(error, "EDID extract of '%s' failed: ", from_file); |
930 | 1167 | if (odd_hex_digits) |
931 | 1168 | fprintf(error, "odd number of hexadecimal digits.\n"); |
1072 | 1309 | do_checksum("", x, EDID_PAGE_SIZE); |
1073 | 1310 | } |
1074 | 1311 | |
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 | ||
1075 | 1479 | int edid_state::parse_edid() |
1076 | 1480 | { |
1077 | 1481 | hide_serial_numbers = options[OptHideSerialNumbers]; |
1092 | 1496 | printf("edid-decode (hex):\n\n"); |
1093 | 1497 | for (unsigned i = 0; i < num_blocks; i++) { |
1094 | 1498 | hex_block("", edid + i * EDID_PAGE_SIZE, EDID_PAGE_SIZE, false); |
1499 | if (i == num_blocks - 1 && options[OptOnlyHexDump]) | |
1500 | return 0; | |
1095 | 1501 | printf("\n"); |
1096 | 1502 | } |
1097 | 1503 | printf("----------------\n\n"); |
1113 | 1519 | if (has_cta) |
1114 | 1520 | cta_resolve_svrs(); |
1115 | 1521 | |
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(); | |
1155 | 1526 | |
1156 | 1527 | if (!options[OptCheck] && !options[OptCheckInline]) |
1157 | 1528 | return 0; |
1178 | 1549 | return failures ? -2 : 0; |
1179 | 1550 | } |
1180 | 1551 | |
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 | ||
1181 | 1925 | int main(int argc, char **argv) |
1182 | 1926 | { |
1183 | 1927 | char short_options[26 * 2 * 2 + 1]; |
1184 | 1928 | enum output_format out_fmt = OUT_FMT_DEFAULT; |
1929 | gtf_parsed_data gtf_data; | |
1930 | unsigned list_rid = 0; | |
1185 | 1931 | int ret; |
1186 | 1932 | |
1187 | 1933 | while (1) { |
1188 | 1934 | int option_index = 0; |
1189 | 1935 | unsigned idx = 0; |
1190 | unsigned i; | |
1936 | unsigned i, val; | |
1937 | const timings *t; | |
1938 | char buf[16]; | |
1191 | 1939 | |
1192 | 1940 | for (i = 0; long_options[i].name; i++) { |
1193 | 1941 | if (!isalpha(long_options[i].val)) |
1221 | 1969 | exit(1); |
1222 | 1970 | } |
1223 | 1971 | 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; | |
1224 | 2027 | case ':': |
1225 | 2028 | fprintf(stderr, "Option '%s' requires a value.\n", |
1226 | 2029 | argv[optind]); |
1241 | 2044 | return 0; |
1242 | 2045 | } |
1243 | 2046 | |
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 | ||
1244 | 2074 | if (optind == argc) |
1245 | 2075 | ret = edid_from_file("-", stdout); |
1246 | 2076 | else |
1252 | 2082 | } |
1253 | 2083 | if (optind < argc - 1) |
1254 | 2084 | 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 | } | |
1255 | 2117 | |
1256 | 2118 | return ret ? ret : state.parse_edid(); |
1257 | 2119 | } |
1270 | 2132 | } |
1271 | 2133 | options[OptCheck] = 1; |
1272 | 2134 | options[OptPreferredTimings] = 1; |
1273 | options[OptNativeTimings] = 1; | |
2135 | options[OptNativeResolution] = 1; | |
1274 | 2136 | state = edid_state(); |
1275 | 2137 | int ret = edid_from_file(input, stderr); |
1276 | 2138 | return ret ? ret : state.parse_edid(); |
11 | 11 | |
12 | 12 | #include <string> |
13 | 13 | #include <vector> |
14 | #include <set> | |
14 | 15 | #include <string.h> |
15 | 16 | |
16 | 17 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) |
20 | 21 | #define EDID_PAGE_SIZE 128U |
21 | 22 | #define EDID_MAX_BLOCKS 256U |
22 | 23 | |
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) | |
24 | 31 | |
25 | 32 | // Video Timings |
26 | 33 | // If interlaced is true, then the vertical blanking |
27 | 34 | // for each field is (vfp + vsync + vbp + 0.5), except for |
28 | 35 | // 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. | |
29 | 48 | struct timings { |
30 | // Active horizontal and vertical frame height, including any | |
49 | // Active horizontal and vertical frame height, excluding any | |
31 | 50 | // borders, if present. |
32 | 51 | // Note: for interlaced formats the active field height is vact / 2 |
33 | 52 | unsigned hact, vact; |
34 | 53 | unsigned hratio, vratio; |
35 | 54 | unsigned pixclk_khz; |
36 | 55 | // 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 | |
41 | 62 | unsigned rb; |
42 | 63 | bool interlaced; |
43 | 64 | // The horizontal frontporch may be negative in GTF calculations, |
88 | 109 | std::string flags; |
89 | 110 | }; |
90 | 111 | |
112 | enum gtf_ip_parm { | |
113 | gtf_ip_vert_freq = 1, | |
114 | gtf_ip_hor_freq, | |
115 | gtf_ip_clk_freq, | |
116 | }; | |
117 | ||
91 | 118 | 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 | }; | |
92 | 134 | |
93 | 135 | struct edid_state { |
94 | 136 | edid_state() |
98 | 140 | max_hor_freq_hz = max_vert_freq_hz = max_pixclk_khz = 0; |
99 | 141 | min_hor_freq_hz = 0xffffff; |
100 | 142 | min_vert_freq_hz = 0xffffffff; |
143 | dtd_max_vsize_mm = dtd_max_hsize_mm = 0; | |
101 | 144 | warnings = failures = 0; |
102 | 145 | has_cta = has_dispid = false; |
103 | 146 | hide_serial_numbers = false; |
147 | image_width = image_height = diagonal = 0; | |
104 | 148 | |
105 | 149 | // Base block state |
106 | 150 | base.edid_minor = 0; |
107 | 151 | base.has_name_descriptor = base.has_display_range_descriptor = |
108 | 152 | base.has_serial_number = base.has_serial_string = |
109 | 153 | 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 = | |
111 | 155 | base.has_640x480p60_est_timing = base.has_spwg = |
112 | base.seen_non_detailed_descriptor = | |
113 | 156 | 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; | |
114 | 161 | base.detailed_block_cnt = base.dtd_cnt = 0; |
115 | 162 | |
116 | 163 | base.min_display_hor_freq_hz = base.max_display_hor_freq_hz = |
119 | 166 | base.max_display_height_mm = 0; |
120 | 167 | |
121 | 168 | // 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 = | |
123 | 170 | 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; | |
126 | 176 | cta.supported_hdmi_vic_codes = cta.supported_hdmi_vic_vsb_codes = 0; |
127 | 177 | memset(cta.vics, 0, sizeof(cta.vics)); |
128 | 178 | memset(cta.preparsed_has_vic, 0, sizeof(cta.preparsed_has_vic)); |
179 | memset(&cta.preparsed_first_vfd, 0, sizeof(cta.preparsed_first_vfd)); | |
129 | 180 | 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; | |
133 | 187 | |
134 | 188 | // DisplayID block state |
135 | 189 | 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; | |
138 | 193 | dispid.is_base_block = true; |
139 | 194 | dispid.is_display = dispid.has_product_identification = |
140 | 195 | dispid.has_display_parameters = dispid.has_type_1_7 = |
141 | 196 | dispid.has_display_interface_features = false; |
197 | dispid.block_number = 0; | |
198 | dispid.image_width = dispid.image_height = 0; | |
142 | 199 | |
143 | 200 | // Block Map block state |
144 | 201 | block_map.saw_block_1 = false; |
160 | 217 | double min_vert_freq_hz; |
161 | 218 | double max_vert_freq_hz; |
162 | 219 | 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; | |
163 | 227 | |
164 | 228 | unsigned warnings; |
165 | 229 | unsigned failures; |
173 | 237 | bool has_serial_string; |
174 | 238 | bool supports_continuous_freq; |
175 | 239 | bool supports_gtf; |
240 | bool supports_sec_gtf; | |
241 | unsigned sec_gtf_start_freq; | |
242 | double C, M, K, J; | |
176 | 243 | bool supports_cvt; |
177 | bool uses_gtf; | |
178 | bool uses_cvt; | |
179 | 244 | bool has_spwg; |
180 | 245 | unsigned detailed_block_cnt; |
181 | 246 | unsigned dtd_cnt; |
191 | 256 | unsigned max_display_pixclk_khz; |
192 | 257 | unsigned max_display_width_mm; |
193 | 258 | unsigned max_display_height_mm; |
259 | unsigned max_pos_neg_hor_freq_khz; | |
194 | 260 | } base; |
195 | 261 | |
196 | 262 | // CTA-861 block state |
197 | 263 | struct { |
198 | unsigned preparse_total_dtds; | |
264 | unsigned preparsed_total_dtds; | |
199 | 265 | vec_timings_ext vec_dtds; |
200 | unsigned preparse_total_vtdbs; | |
266 | unsigned preparsed_total_vtdbs; | |
201 | 267 | vec_timings_ext vec_vtdbs; |
268 | cta_vfd preparsed_first_vfd; | |
202 | 269 | 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; | |
204 | 274 | timings_ext t8vtdb; |
205 | 275 | vec_timings_ext native_timings; |
276 | // in 0.1 mm units | |
277 | unsigned image_width, image_height; | |
206 | 278 | bool has_vic_1; |
207 | 279 | bool first_svd_might_be_preferred; |
208 | 280 | unsigned char byte3; |
209 | 281 | bool has_hdmi; |
210 | 282 | bool has_vcdb; |
211 | 283 | bool has_vfpdb; |
284 | unsigned preparsed_speaker_count; | |
285 | bool preparsed_sld_has_coord; | |
286 | bool preparsed_sld; | |
287 | bool has_sldb; | |
212 | 288 | unsigned short preparsed_phys_addr; |
213 | bool last_block_was_hdmi_vsdb; | |
289 | unsigned previous_cta_tag; | |
214 | 290 | bool have_hf_vsdb, have_hf_scdb; |
215 | bool first_block; | |
291 | unsigned block_number; | |
216 | 292 | bool first_svd; |
217 | 293 | unsigned supported_hdmi_vic_codes; |
218 | 294 | unsigned supported_hdmi_vic_vsb_codes; |
224 | 300 | // DisplayID block state |
225 | 301 | struct { |
226 | 302 | 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; | |
230 | 306 | bool is_base_block; |
231 | 307 | bool is_display; |
232 | 308 | bool has_product_identification; |
234 | 310 | bool has_type_1_7; |
235 | 311 | bool has_display_interface_features; |
236 | 312 | 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; | |
237 | 320 | } dispid; |
238 | 321 | |
239 | 322 | // Block Map block state |
246 | 329 | std::string dtd_type() { return dtd_type(base.dtd_cnt); } |
247 | 330 | bool print_timings(const char *prefix, const struct timings *t, |
248 | 331 | const char *type, const char *flags = "", |
249 | bool detailed = false); | |
332 | bool detailed = false, bool do_checks = true); | |
250 | 333 | bool print_timings(const char *prefix, const struct timings_ext &t, |
251 | bool detailed = false) | |
334 | bool detailed = false, bool do_checks = true) | |
252 | 335 | { |
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); | |
254 | 338 | }; |
255 | 339 | 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); | |
256 | 345 | 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); | |
259 | 353 | 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); | |
260 | 357 | 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); | |
262 | 359 | void detailed_display_range_limits(const unsigned char *x); |
263 | 360 | void detailed_epi(const unsigned char *x); |
264 | 361 | void detailed_timings(const char *prefix, const unsigned char *x, |
265 | 362 | bool base_or_cta = true); |
363 | void preparse_detailed_block(const unsigned char *x); | |
266 | 364 | void detailed_block(const unsigned char *x); |
267 | 365 | void parse_base_block(const unsigned char *x); |
268 | 366 | 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); | |
269 | 372 | |
270 | 373 | 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); | |
271 | 375 | void cta_vcdb(const unsigned char *x, unsigned length); |
272 | 376 | void cta_svd(const unsigned char *x, unsigned n, bool for_ycbcr420); |
377 | void cta_vfdb(const unsigned char *x, unsigned n); | |
273 | 378 | void cta_y420cmdb(const unsigned char *x, unsigned length); |
379 | void cta_print_svr(unsigned char svr, vec_timings_ext &vec_tim); | |
274 | 380 | 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); | |
275 | 386 | void cta_hdmi_block(const unsigned char *x, unsigned length); |
276 | 387 | void cta_displayid_type_7(const unsigned char *x, unsigned length); |
277 | 388 | void cta_displayid_type_8(const unsigned char *x, unsigned length); |
278 | 389 | 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); | |
281 | 391 | void preparse_cta_block(const unsigned char *x); |
282 | 392 | void parse_cta_block(const unsigned char *x); |
283 | 393 | void cta_resolve_svr(vec_timings_ext::iterator iter); |
284 | 394 | void cta_resolve_svrs(); |
285 | 395 | 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); | |
287 | 402 | void parse_digital_interface(const unsigned char *x); |
288 | 403 | void parse_display_device(const unsigned char *x); |
289 | 404 | void parse_display_caps(const unsigned char *x); |
297 | 412 | std::string product_type(unsigned char x, bool heading); |
298 | 413 | void parse_displayid_interface_features(const unsigned char *x); |
299 | 414 | 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); | |
301 | 416 | void parse_displayid_display_intf(const unsigned char *x); |
302 | 417 | void parse_displayid_color_characteristics(const unsigned char *x); |
303 | 418 | void parse_displayid_transfer_characteristics(const unsigned char *x); |
317 | 432 | void parse_displayid_type_9_timing(const unsigned char *x); |
318 | 433 | void parse_displayid_dynamic_video_timings_range_limits(const unsigned char *x); |
319 | 434 | 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); | |
321 | 438 | void preparse_displayid_block(const unsigned char *x); |
439 | unsigned displayid_block(const unsigned version, const unsigned char *x, unsigned length); | |
322 | 440 | void parse_displayid_block(const unsigned char *x); |
323 | 441 | void parse_displayid_vesa(const unsigned char *x); |
442 | void parse_displayid_apple(const unsigned char *x); | |
324 | 443 | void parse_displayid_cta_data_block(const unsigned char *x); |
325 | 444 | void check_displayid_blocks(); |
326 | 445 | |
333 | 452 | |
334 | 453 | void preparse_extension(const unsigned char *x); |
335 | 454 | void parse_extension(const unsigned char *x); |
455 | void print_preferred_timings(); | |
456 | void print_native_res(); | |
336 | 457 | int parse_edid(); |
337 | 458 | }; |
338 | 459 | |
377 | 498 | void do_checksum(const char *prefix, const unsigned char *x, size_t len); |
378 | 499 | std::string utohex(unsigned char x); |
379 | 500 | std::string ouitohex(unsigned oui); |
501 | std::string containerid2s(const unsigned char *x); | |
380 | 502 | bool memchk(const unsigned char *x, unsigned len, unsigned char v = 0); |
381 | 503 | void hex_block(const char *prefix, const unsigned char *x, unsigned length, |
382 | 504 | bool show_ascii = true, unsigned step = 16); |
383 | 505 | std::string block_name(unsigned char block); |
384 | 506 | 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); | |
387 | 511 | const struct timings *find_dmt_id(unsigned char dmt_id); |
512 | const struct timings *close_match_to_dmt(const timings &t, unsigned &dmt); | |
388 | 513 | const struct timings *find_vic_id(unsigned char vic); |
514 | const struct cta_rid *find_rid(unsigned char rid); | |
389 | 515 | 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); | |
390 | 517 | unsigned char hdmi_vic_to_vic(unsigned char hdmi_vic); |
391 | 518 | char *extract_string(const unsigned char *x, unsigned len); |
392 | 519 | |
520 | #define oneoui(c,k,n) const unsigned kOUI_##k = __LINE__<<12; | |
521 | #include "oui.h" | |
522 | ||
393 | 523 | #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 |
44 | 44 | 36, 72, 108, false, 1, 3, 42, true } }, |
45 | 45 | |
46 | 46 | { 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 } }, | |
48 | 48 | { 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 } }, | |
50 | 50 | { 0x06, 0x314f, 0x000000, { 640, 480, 4, 3, 31500, 0, false, |
51 | 51 | 16, 64, 120, false, 1, 3, 16, false } }, |
52 | 52 | { 0x07, 0x3159, 0x000000, { 640, 480, 4, 3, 36000, 0, false, |
353 | 353 | return NULL; |
354 | 354 | } |
355 | 355 | |
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() | |
360 | 357 | { |
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 | } | |
529 | 383 | } |
530 | 384 | |
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) | |
535 | 386 | { |
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; | |
714 | 395 | } |
715 | 396 | |
716 | timings edid_state::calc_cvt_mode(unsigned refresh, unsigned hact, unsigned vact, unsigned rb) | |
397 | void edid_state::list_dmts() | |
717 | 398 | { |
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 | } | |
726 | 415 | } |
727 | 416 | |
728 | 417 | void edid_state::detailed_cvt_descriptor(const char *prefix, const unsigned char *x, bool first) |
734 | 423 | if (!first && !memcmp(x, empty, 3)) |
735 | 424 | return; |
736 | 425 | |
737 | base.uses_cvt = true; | |
738 | 426 | cvt_t.vact = x[0]; |
739 | 427 | if (!cvt_t.vact) |
740 | 428 | fail("CVT byte 0 is 0, which is a reserved value.\n"); |
794 | 482 | print_timings(prefix, &cvt_t, "CVT", preferred == 3 ? s_pref : ""); |
795 | 483 | } |
796 | 484 | if (x[2] & 0x01) { |
797 | cvt_t.rb = 1; | |
485 | cvt_t.rb = RB_CVT_V1; | |
798 | 486 | edid_cvt_mode(60, cvt_t); |
799 | 487 | print_timings(prefix, &cvt_t, "CVT", preferred == 4 ? s_pref : ""); |
800 | 488 | } |
838 | 526 | } |
839 | 527 | |
840 | 528 | 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) | |
842 | 530 | { |
843 | 531 | const struct timings *t; |
844 | 532 | struct timings formula = {}; |
862 | 550 | hact = (b1 + 31) * 8; |
863 | 551 | switch ((b2 >> 6) & 0x3) { |
864 | 552 | case 0x00: |
865 | if (gtf_only || base.edid_minor >= 3) { | |
553 | if (gtf_only || show_both || base.edid_minor >= 3) { | |
866 | 554 | hratio = 16; |
867 | 555 | vratio = 10; |
868 | 556 | } else { |
884 | 572 | break; |
885 | 573 | } |
886 | 574 | vact = (double)hact * vratio / hratio; |
887 | vact = 8 * ((vact + 7) / 8); | |
888 | refresh = vrefresh_offset + (b2 & 0x3f); | |
575 | refresh = (b2 & 0x3f) + 60; | |
889 | 576 | |
890 | 577 | formula.hact = hact; |
891 | 578 | formula.vact = vact; |
892 | 579 | formula.hratio = hratio; |
893 | 580 | formula.vratio = vratio; |
894 | 581 | |
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 | } | |
899 | 588 | /* |
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 | |
901 | 590 | * have to be supported. |
902 | 591 | */ |
903 | base.uses_gtf = true; | |
904 | 592 | 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 "); | |
906 | 597 | } else if (gtf_only || base.edid_minor >= 2) { |
907 | base.uses_gtf = true; | |
908 | 598 | edid_gtf_mode(refresh, formula); |
909 | 599 | print_timings(prefix, &formula, "GTF "); |
910 | 600 | } else { |
913 | 603 | min_vert_freq_hz = min(min_vert_freq_hz, refresh); |
914 | 604 | max_vert_freq_hz = max(max_vert_freq_hz, refresh); |
915 | 605 | } |
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); | |
916 | 610 | } |
917 | 611 | |
918 | 612 | void edid_state::detailed_display_range_limits(const unsigned char *x) |
924 | 618 | std::string range_class; |
925 | 619 | |
926 | 620 | data_block = "Display Range Limits"; |
927 | printf(" %s:\n", data_block.c_str()); | |
621 | printf(" %s:\n", data_block.c_str()); | |
928 | 622 | base.has_display_range_descriptor = 1; |
929 | 623 | |
930 | 624 | if (base.edid_minor >= 4) { |
950 | 644 | range_class = "GTF"; |
951 | 645 | if (base.edid_minor >= 4 && !base.supports_continuous_freq) |
952 | 646 | 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"); | |
954 | 649 | break; |
955 | 650 | case 0x01: /* range limits only */ |
956 | 651 | range_class = "Bare Limits"; |
961 | 656 | range_class = "Secondary GTF"; |
962 | 657 | if (base.edid_minor >= 4 && !base.supports_continuous_freq) |
963 | 658 | 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"); | |
965 | 661 | has_sec_gtf = true; |
966 | 662 | break; |
967 | 663 | case 0x04: /* cvt */ |
971 | 667 | fail("'%s' is not allowed for EDID < 1.4.\n", range_class.c_str()); |
972 | 668 | else if (!base.supports_continuous_freq) |
973 | 669 | 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 | } | |
979 | 670 | break; |
980 | 671 | default: /* invalid */ |
981 | 672 | fail("Unknown range class (0x%02x).\n", x[10]); |
991 | 682 | fail("Min horizontal freq > max horizontal freq.\n"); |
992 | 683 | base.min_display_hor_freq_hz = (x[7] + h_min_offset) * 1000; |
993 | 684 | 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", | |
995 | 686 | range_class.c_str(), |
996 | 687 | x[5] + v_min_offset, x[6] + v_max_offset, |
997 | 688 | x[7] + h_min_offset, x[8] + h_max_offset); |
1012 | 703 | base.max_display_pixclk_khz = x[9] * 10000; |
1013 | 704 | printf(", max dotclock %d MHz\n", x[9] * 10); |
1014 | 705 | } else { |
706 | printf("\n"); | |
1015 | 707 | if (base.edid_minor >= 4) |
1016 | 708 | fail("EDID 1.4 block does not set max dotclock.\n"); |
1017 | printf("\n"); | |
1018 | 709 | } |
1019 | 710 | |
1020 | 711 | if (has_sec_gtf) { |
1021 | 712 | if (x[11]) |
1022 | 713 | 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 | } | |
1033 | 724 | } else if (is_cvt) { |
1034 | 725 | int max_h_pixels = 0; |
1035 | 726 | |
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); | |
1037 | 728 | |
1038 | 729 | if (x[12] & 0xfc) { |
1039 | 730 | unsigned raw_offset = (x[12] & 0xfc) >> 2; |
1040 | 731 | |
1041 | printf(" Real max dotclock: %.2f MHz\n", | |
732 | printf(" Real max dotclock: %.2f MHz\n", | |
1042 | 733 | (x[9] * 10) - (raw_offset * 0.25)); |
1043 | 734 | if (raw_offset >= 40) |
1044 | 735 | warn("CVT block corrects dotclock by more than 9.75 MHz.\n"); |
1049 | 740 | max_h_pixels |= x[13]; |
1050 | 741 | max_h_pixels *= 8; |
1051 | 742 | 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", | |
1055 | 746 | x[14] & 0x80 ? " 4:3" : "", |
1056 | 747 | x[14] & 0x40 ? " 16:9" : "", |
1057 | 748 | x[14] & 0x20 ? " 16:10" : "", |
1060 | 751 | if (x[14] & 0x07) |
1061 | 752 | fail("Reserved bits of byte 14 are non-zero.\n"); |
1062 | 753 | |
1063 | printf(" Preferred aspect ratio: "); | |
754 | printf(" Preferred aspect ratio: "); | |
1064 | 755 | switch ((x[15] & 0xe0) >> 5) { |
1065 | 756 | case 0x00: |
1066 | 757 | printf("4:3"); |
1086 | 777 | printf("\n"); |
1087 | 778 | |
1088 | 779 | if (x[15] & 0x08) |
1089 | printf(" Supports CVT standard blanking\n"); | |
780 | printf(" Supports CVT standard blanking\n"); | |
1090 | 781 | if (x[15] & 0x10) |
1091 | printf(" Supports CVT reduced blanking\n"); | |
782 | printf(" Supports CVT reduced blanking\n"); | |
1092 | 783 | |
1093 | 784 | if (x[15] & 0x07) |
1094 | 785 | fail("Reserved bits of byte 15 are non-zero.\n"); |
1095 | 786 | |
1096 | 787 | if (x[16] & 0xf0) { |
1097 | printf(" Supported display scaling:\n"); | |
788 | printf(" Supported display scaling:\n"); | |
1098 | 789 | if (x[16] & 0x80) |
1099 | printf(" Horizontal shrink\n"); | |
790 | printf(" Horizontal shrink\n"); | |
1100 | 791 | if (x[16] & 0x40) |
1101 | printf(" Horizontal stretch\n"); | |
792 | printf(" Horizontal stretch\n"); | |
1102 | 793 | if (x[16] & 0x20) |
1103 | printf(" Vertical shrink\n"); | |
794 | printf(" Vertical shrink\n"); | |
1104 | 795 | if (x[16] & 0x10) |
1105 | printf(" Vertical stretch\n"); | |
796 | printf(" Vertical stretch\n"); | |
1106 | 797 | } |
1107 | 798 | |
1108 | 799 | if (x[16] & 0x0f) |
1109 | 800 | fail("Reserved bits of byte 16 are non-zero.\n"); |
1110 | 801 | |
1111 | 802 | if (x[17]) |
1112 | printf(" Preferred vertical refresh: %d Hz\n", x[17]); | |
803 | printf(" Preferred vertical refresh: %d Hz\n", x[17]); | |
1113 | 804 | else |
1114 | 805 | warn("CVT block does not set preferred refresh rate.\n"); |
1115 | 806 | } else { |
1246 | 937 | return; |
1247 | 938 | } |
1248 | 939 | |
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 | */ | |
1249 | 960 | 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; | |
1251 | 963 | t.hfp = (x[8] + ((x[11] & 0xc0) << 2)); |
1252 | 964 | t.hsync = (x[9] + ((x[11] & 0x30) << 4)); |
1253 | 965 | t.hbp = hbl - t.hsync - t.hfp; |
1254 | t.hborder = x[15]; | |
1255 | 966 | 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; | |
1257 | 969 | t.vfp = ((x[10] >> 4) + ((x[11] & 0x0c) << 2)); |
1258 | 970 | t.vsync = ((x[10] & 0x0f) + ((x[11] & 0x03) << 4)); |
1259 | 971 | t.vbp = vbl - t.vsync - t.vfp; |
1260 | t.vborder = x[16]; | |
1261 | 972 | |
1262 | 973 | unsigned char flags = x[17]; |
1263 | 974 | |
1352 | 1063 | if (block_nr == 0 && base.dtd_cnt == 1) { |
1353 | 1064 | te.type = "DTD 1"; |
1354 | 1065 | 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 | } | |
1357 | 1070 | } |
1358 | 1071 | if (base_or_cta) |
1359 | 1072 | cta.vec_dtds.push_back(te); |
1360 | 1073 | |
1074 | if (t.hborder || t.vborder) | |
1075 | warn("The use of non-zero borders in a DTD is not recommended.\n"); | |
1361 | 1076 | if ((base.max_display_width_mm && !t.hsize_mm) || |
1362 | 1077 | (base.max_display_height_mm && !t.vsize_mm)) { |
1363 | 1078 | fail("Mismatch of image size vs display size: image size is not set, but display size is.\n"); |
1369 | 1084 | |
1370 | 1085 | s += " "; |
1371 | 1086 | 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; | |
1372 | 1117 | } |
1373 | 1118 | } |
1374 | 1119 | |
1425 | 1170 | case 0xf7: |
1426 | 1171 | data_block = "Established timings III"; |
1427 | 1172 | 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++) | |
1429 | 1174 | if (x[6 + i / 8] & (1 << (7 - i % 8))) { |
1430 | 1175 | unsigned char dmt_id = established_timings3_dmt_ids[i]; |
1431 | 1176 | char type[16]; |
1433 | 1178 | sprintf(type, "DMT 0x%02x", dmt_id); |
1434 | 1179 | print_timings(" ", find_dmt_id(dmt_id), type); |
1435 | 1180 | } |
1181 | if (base.edid_minor < 4) | |
1182 | fail("Not allowed for EDID < 1.4.\n"); | |
1436 | 1183 | return; |
1437 | 1184 | case 0xf8: |
1438 | 1185 | data_block = "CVT 3 Byte Timing Codes"; |
1443 | 1190 | } |
1444 | 1191 | for (i = 0; i < 4; i++) |
1445 | 1192 | detailed_cvt_descriptor(" ", x + 6 + (i * 3), !i); |
1193 | if (base.edid_minor < 4) | |
1194 | fail("Not allowed for EDID < 1.4.\n"); | |
1446 | 1195 | return; |
1447 | 1196 | case 0xf9: |
1448 | 1197 | data_block = "Display Color Management Data"; |
1554 | 1303 | } |
1555 | 1304 | } |
1556 | 1305 | |
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 | ||
1557 | 1317 | void edid_state::parse_base_block(const unsigned char *x) |
1558 | 1318 | { |
1559 | 1319 | time_t the_time; |
1560 | 1320 | struct tm *ptm; |
1561 | int analog, i; | |
1321 | int analog; | |
1562 | 1322 | unsigned col_x, col_y; |
1563 | 1323 | bool has_preferred_timing = false; |
1564 | 1324 | |
1653 | 1413 | fail("Digital Video Interface Standard set to reserved value 0x%02x.\n", x[0x14] & 0x7f); |
1654 | 1414 | } |
1655 | 1415 | } 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 | }; | |
1656 | 1422 | unsigned voltage = (x[0x14] & 0x60) >> 5; |
1657 | 1423 | unsigned sync = (x[0x14] & 0x0f); |
1658 | 1424 | |
1659 | 1425 | analog = 1; |
1660 | 1426 | 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]); | |
1666 | 1428 | |
1667 | 1429 | if (x[0x14] & 0x10) |
1668 | 1430 | printf(" Blank-to-black setup/pedestal\n"); |
1681 | 1443 | printf(" Maximum image size: %u cm x %u cm\n", x[0x15], x[0x16]); |
1682 | 1444 | base.max_display_width_mm = x[0x15] * 10; |
1683 | 1445 | 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; | |
1684 | 1448 | if (x[0x15] < 10 || x[0x16] < 10) |
1685 | 1449 | warn("Dubious maximum image size (%ux%u is smaller than 10x10 cm).\n", |
1686 | 1450 | x[0x15], x[0x16]); |
1698 | 1462 | if (x[0x17] == 0xff) |
1699 | 1463 | printf(" Gamma is defined in an extension block\n"); |
1700 | 1464 | else |
1701 | printf(" Gamma: %.2f\n", ((x[0x17] + 100.0) / 100.0)); | |
1465 | printf(" Gamma: %.2f\n", (x[0x17] + 100.0) / 100.0); | |
1702 | 1466 | |
1703 | 1467 | if (x[0x18] & 0xe0) { |
1704 | 1468 | printf(" DPMS levels:"); |
1714 | 1478 | case 0x00: printf("Monochrome or grayscale display\n"); break; |
1715 | 1479 | case 0x08: printf("RGB color display\n"); break; |
1716 | 1480 | 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; | |
1718 | 1482 | } |
1719 | 1483 | } else { |
1720 | 1484 | printf(" Supported color formats: RGB 4:4:4"); |
1726 | 1490 | } |
1727 | 1491 | |
1728 | 1492 | 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 | }; | |
1739 | 1493 | printf(" Default (sRGB) color space is primary color space\n"); |
1740 | 1494 | if (memcmp(x + 0x19, srgb_chromaticity, sizeof(srgb_chromaticity))) |
1741 | 1495 | 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 | ||
1743 | 1502 | if (base.edid_minor >= 4) { |
1744 | 1503 | /* 1.4 always has a preferred timing and this bit means something else. */ |
1745 | 1504 | has_preferred_timing = true; |
1792 | 1551 | data_block = "Established Timings I & II"; |
1793 | 1552 | if (x[0x23] || x[0x24] || x[0x25]) { |
1794 | 1553 | 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++) { | |
1796 | 1555 | if (x[0x23 + i / 8] & (1 << (7 - i % 8))) { |
1797 | 1556 | unsigned char dmt_id = established_timings12[i].dmt_id; |
1798 | 1557 | const struct timings *t; |
1813 | 1572 | } |
1814 | 1573 | base.has_640x480p60_est_timing = x[0x23] & 0x20; |
1815 | 1574 | |
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 | ||
1816 | 1584 | data_block = "Standard Timings"; |
1817 | 1585 | bool found = false; |
1818 | for (i = 0; i < 8; i++) { | |
1586 | for (unsigned i = 0; i < 8; i++) { | |
1819 | 1587 | if (x[0x26 + i * 2] != 0x01 || x[0x26 + i * 2 + 1] != 0x01) { |
1820 | 1588 | found = true; |
1821 | 1589 | break; |
1823 | 1591 | } |
1824 | 1592 | if (found) { |
1825 | 1593 | printf(" %s:\n", data_block.c_str()); |
1826 | for (i = 0; i < 8; i++) | |
1594 | for (unsigned i = 0; i < 8; i++) | |
1827 | 1595 | print_standard_timing(" ", x[0x26 + i * 2], x[0x26 + i * 2 + 1]); |
1828 | 1596 | } else { |
1829 | 1597 | printf(" %s: none\n", data_block.c_str()); |
1843 | 1611 | |
1844 | 1612 | for (unsigned i = 0; i < (base.has_spwg ? 2 : 4); i++) |
1845 | 1613 | if (x[0x36 + i * 18] || x[0x37 + i * 18]) |
1846 | cta.preparse_total_dtds++; | |
1614 | cta.preparsed_total_dtds++; | |
1847 | 1615 | |
1848 | 1616 | data_block = "Detailed Timing Descriptors"; |
1849 | 1617 | printf(" %s:\n", data_block.c_str()); |
1879 | 1647 | void edid_state::check_base_block() |
1880 | 1648 | { |
1881 | 1649 | 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 | ||
1886 | 1651 | /* |
1887 | 1652 | * Allow for regular rounding of vertical and horizontal frequencies. |
1888 | 1653 | * The spec says that the pixelclock shall be rounded up, so there is |
1939 | 1704 | */ |
1940 | 1705 | msg(!out_of_range || base.edid_minor >= 4, "%s", err.c_str()); |
1941 | 1706 | } |
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); | |
1942 | 1723 | if (base.edid_minor == 3 && num_blocks > 2 && !block_map.saw_block_1) |
1943 | 1724 | fail("EDID 1.3 requires a Block Map Extension in Block 1 if there are more than 2 blocks in the EDID.\n"); |
1944 | 1725 | if (base.edid_minor == 3 && num_blocks > 128 && !block_map.saw_block_128) |
6 | 6 | * Maintainer: Hans Verkuil <hverkuil-cisco@xs4all.nl> |
7 | 7 | */ |
8 | 8 | |
9 | #include <algorithm> | |
9 | 10 | #include <stdio.h> |
10 | 11 | #include <math.h> |
11 | 12 | |
187 | 188 | { 4096, 2160, 256, 135, 1188000, 0, false, 88, 88, 128, true, 8, 10, 72, true }, |
188 | 189 | }; |
189 | 190 | |
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 | ||
190 | 268 | static const unsigned char edid_hdmi_mode_map[] = { 95, 94, 93, 98 }; |
191 | 269 | |
192 | 270 | unsigned char hdmi_vic_to_vic(unsigned char hdmi_vic) |
200 | 278 | { |
201 | 279 | if (vic > 0 && vic <= ARRAY_SIZE(edid_cta_modes1)) |
202 | 280 | 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) | |
204 | 282 | return edid_cta_modes2 + vic - 193; |
205 | 283 | return NULL; |
206 | 284 | } |
210 | 288 | if (hdmi_vic > 0 && hdmi_vic <= ARRAY_SIZE(edid_hdmi_mode_map)) |
211 | 289 | return find_vic_id(edid_hdmi_mode_map[hdmi_vic - 1]); |
212 | 290 | 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 | } | |
213 | 378 | } |
214 | 379 | |
215 | 380 | static std::string audio_ext_format(unsigned char x) |
229 | 394 | case 11: return "MPEG-H 3D Audio"; |
230 | 395 | case 12: return "AC-4"; |
231 | 396 | case 13: return "L-PCM 3D Audio"; |
397 | case 14: return "Auro-Cx"; | |
398 | case 15: return "MPEG-D USAC"; | |
232 | 399 | default: break; |
233 | 400 | } |
234 | 401 | fail("Unknown Audio Ext Format 0x%02x.\n", x); |
305 | 472 | printf(" Max channels: %u\n", |
306 | 473 | (((x[i + 1] & 0x80) >> 3) | ((x[i] & 0x80) >> 4) | |
307 | 474 | (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"); | |
308 | 477 | else |
309 | 478 | 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"); | |
310 | 492 | |
311 | 493 | printf(" Supported sample rates (kHz):%s%s%s%s%s%s%s\n", |
312 | 494 | (x[i+1] & 0x40) ? " 192" : "", |
354 | 536 | (x[i+2] & 1) ? "implicitly and explicitly" : "only implicitly"); |
355 | 537 | if (ext_format == 6 && (x[i+2] & 1)) |
356 | 538 | 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); | |
357 | 541 | } |
358 | 542 | } |
359 | 543 | } |
410 | 594 | print_timings(" ", t, type, flags); |
411 | 595 | } |
412 | 596 | 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 | } | |
413 | 603 | cta.preferred_timings.insert(cta.preferred_timings.begin(), |
414 | 604 | timings_ext(*t, type, flags)); |
415 | warn("VIC %u is the preferred timing, overriding the first detailed timings. Is this intended?\n", vic); | |
416 | 605 | } else if (first_svd) { |
417 | 606 | cta.preferred_timings.push_back(timings_ext(*t, type, flags)); |
418 | 607 | } |
436 | 625 | } |
437 | 626 | } |
438 | 627 | |
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 | ||
439 | 727 | void edid_state::print_vic_index(const char *prefix, unsigned idx, const char *suffix, bool ycbcr420) |
440 | 728 | { |
441 | 729 | if (!suffix) |
502 | 790 | max_idx + 1, cta.preparsed_svds[0].size()); |
503 | 791 | } |
504 | 792 | |
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 | ||
505 | 852 | void edid_state::cta_vfpdb(const unsigned char *x, unsigned length) |
506 | 853 | { |
507 | 854 | unsigned i; |
511 | 858 | return; |
512 | 859 | } |
513 | 860 | 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) | |
565 | 898 | { |
566 | 899 | if (!l) |
567 | 900 | return "Unknown"; |
570 | 903 | return std::to_string(1 + 2 * l) + " ms"; |
571 | 904 | } |
572 | 905 | |
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 | ||
573 | 940 | void edid_state::cta_hdmi_block(const unsigned char *x, unsigned length) |
574 | 941 | { |
575 | 942 | unsigned len_vic, len_3d; |
576 | 943 | |
577 | if (length < 4) { | |
944 | if (length < 1) { | |
578 | 945 | fail("Empty Data Block with length %u.\n", length); |
579 | 946 | return; |
580 | 947 | } |
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) | |
588 | 955 | printf(" Supports_AI\n"); |
589 | if (x[5] & 0x40) | |
956 | if (x[2] & 0x40) | |
590 | 957 | printf(" DC_48bit\n"); |
591 | if (x[5] & 0x20) | |
958 | if (x[2] & 0x20) | |
592 | 959 | printf(" DC_36bit\n"); |
593 | if (x[5] & 0x10) | |
960 | if (x[2] & 0x10) | |
594 | 961 | printf(" DC_30bit\n"); |
595 | if (x[5] & 0x08) | |
962 | if (x[2] & 0x08) | |
596 | 963 | printf(" DC_Y444\n"); |
597 | 964 | /* two reserved bits */ |
598 | if (x[5] & 0x01) | |
965 | if (x[2] & 0x01) | |
599 | 966 | printf(" DVI_Dual\n"); |
600 | 967 | |
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) | |
606 | 973 | fail("HDMI VSDB Max TMDS rate is > 340.\n"); |
607 | 974 | |
608 | if (length < 8) | |
609 | return; | |
610 | ||
611 | if (x[7] & 0x0f) { | |
975 | if (length < 5) | |
976 | return; | |
977 | ||
978 | if (x[4] & 0x0f) { | |
612 | 979 | printf(" Supported Content Types:\n"); |
613 | if (x[7] & 0x01) | |
980 | if (x[4] & 0x01) | |
614 | 981 | printf(" Graphics\n"); |
615 | if (x[7] & 0x02) | |
982 | if (x[4] & 0x02) | |
616 | 983 | printf(" Photo\n"); |
617 | if (x[7] & 0x04) | |
984 | if (x[4] & 0x04) | |
618 | 985 | printf(" Cinema\n"); |
619 | if (x[7] & 0x08) | |
986 | if (x[4] & 0x08) | |
620 | 987 | printf(" Game\n"); |
621 | 988 | } |
622 | 989 | |
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 | } | |
627 | 1001 | 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)) | |
637 | 1005 | return; |
638 | 1006 | |
639 | 1007 | bool mask = false; |
842 | 1210 | static void cta_hf_scdb(const unsigned char *x, unsigned length) |
843 | 1211 | { |
844 | 1212 | unsigned rate = x[1] * 5; |
1213 | unsigned v; | |
845 | 1214 | |
846 | 1215 | printf(" Version: %u\n", x[0]); |
847 | 1216 | if (rate) { |
853 | 1222 | printf(" SCDC Present\n"); |
854 | 1223 | if (x[2] & 0x40) |
855 | 1224 | printf(" SCDC Read Request Capable\n"); |
1225 | if (x[2] & 0x20) | |
1226 | printf(" Supports Cable Status\n"); | |
856 | 1227 | if (x[2] & 0x10) |
857 | 1228 | printf(" Supports Color Content Bits Per Component Indication\n"); |
858 | 1229 | if (x[2] & 0x08) |
906 | 1277 | if (length <= 5) |
907 | 1278 | return; |
908 | 1279 | |
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 | } | |
911 | 1294 | |
912 | 1295 | if (length <= 7) |
913 | 1296 | return; |
951 | 1334 | 1024 * (1 + (x[9] & 0x3f))); |
952 | 1335 | } |
953 | 1336 | |
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 | ||
954 | 1425 | static void cta_hdr10plus(const unsigned char *x, unsigned length) |
955 | 1426 | { |
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; | |
961 | 1451 | } |
962 | 1452 | |
963 | 1453 | static void cta_dolby_video(const unsigned char *x, unsigned length) |
975 | 1465 | printf(" Supports global dimming\n"); |
976 | 1466 | unsigned char dm_version = x[16]; |
977 | 1467 | 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)); | |
980 | 1472 | printf(" Rx, Ry: %.8f, %.8f\n", |
981 | 1473 | ((x[1] >> 4) | (x[2] << 4)) / 4096.0, |
982 | 1474 | ((x[1] & 0xf) | (x[3] << 4)) / 4096.0); |
1001 | 1493 | printf(" DM Version: %u.x\n", dm_version + 2); |
1002 | 1494 | printf(" Colorimetry: %s\n", (x[2] & 0x01) ? "P3-D65" : "ITU-R BT.709"); |
1003 | 1495 | 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); | |
1005 | 1496 | double lm = (x[2] >> 1) / 127.0; |
1006 | 1497 | 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); | |
1007 | 1499 | if (length == 10) { |
1008 | 1500 | printf(" Rx, Ry: %.8f, %.8f\n", x[4] / 256.0, x[5] / 256.0); |
1009 | 1501 | printf(" Gx, Gy: %.8f, %.8f\n", x[6] / 256.0, x[7] / 256.0); |
1055 | 1547 | case 2: printf("12 bit\n"); break; |
1056 | 1548 | case 3: printf("Reserved\n"); break; |
1057 | 1549 | } |
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)); | |
1060 | 1568 | |
1061 | 1569 | double xmin = 0.625; |
1062 | 1570 | double xstep = (0.74609375 - xmin) / 31.0; |
1331 | 1839 | return s / 64.0; |
1332 | 1840 | } |
1333 | 1841 | |
1334 | static void cta_rcdb(const unsigned char *x, unsigned length) | |
1842 | void edid_state::cta_rcdb(const unsigned char *x, unsigned length) | |
1335 | 1843 | { |
1336 | 1844 | unsigned spm = ((x[3] << 16) | (x[2] << 8) | x[1]); |
1337 | 1845 | unsigned i; |
1341 | 1849 | return; |
1342 | 1850 | } |
1343 | 1851 | |
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) { | |
1345 | 1858 | 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 | } | |
1346 | 1865 | |
1347 | 1866 | printf(" Speaker Presence Mask:\n"); |
1348 | 1867 | for (i = 0; i < ARRAY_SIZE(speaker_map); i++) { |
1349 | 1868 | if ((spm >> i) & 1) |
1350 | 1869 | printf(" %s\n", speaker_map[i]); |
1351 | 1870 | } |
1871 | ||
1352 | 1872 | if ((x[0] & 0xa0) == 0x80) |
1353 | 1873 | 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) { | |
1355 | 1878 | printf(" Xmax: %u dm\n", x[4]); |
1356 | 1879 | printf(" Ymax: %u dm\n", x[5]); |
1357 | 1880 | 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"); | |
1358 | 1884 | } |
1359 | 1885 | if ((x[0] & 0x80) && length >= 10) { |
1360 | 1886 | printf(" DisplayX: %.3f * Xmax\n", decode_uchar_as_double(x[7])); |
1361 | 1887 | printf(" DisplayY: %.3f * Ymax\n", decode_uchar_as_double(x[8])); |
1362 | 1888 | 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"); | |
1363 | 1892 | } |
1364 | 1893 | } |
1365 | 1894 | |
1394 | 1923 | "RS - Right Surround", |
1395 | 1924 | }; |
1396 | 1925 | |
1397 | static void cta_sldb(const unsigned char *x, unsigned length) | |
1926 | void edid_state::cta_sldb(const unsigned char *x, unsigned length) | |
1398 | 1927 | { |
1399 | 1928 | if (length < 2) { |
1400 | 1929 | fail("Empty Data Block with length %u.\n", length); |
1401 | 1930 | return; |
1402 | 1931 | } |
1932 | ||
1933 | unsigned active_cnt = 0; | |
1934 | unsigned channel_is_active = 0; | |
1935 | ||
1403 | 1936 | while (length >= 2) { |
1404 | 1937 | printf(" Channel: %u (%sactive)\n", x[0] & 0x1f, |
1405 | 1938 | (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 | } | |
1406 | 1946 | if ((x[1] & 0x1f) < ARRAY_SIZE(speaker_location)) |
1407 | 1947 | printf(" Speaker: %s\n", speaker_location[x[1] & 0x1f]); |
1408 | 1948 | if (length >= 5 && (x[0] & 0x40)) { |
1413 | 1953 | x += 3; |
1414 | 1954 | } |
1415 | 1955 | |
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 | } | |
1416 | 1972 | length -= 2; |
1417 | 1973 | x += 2; |
1418 | 1974 | } |
1437 | 1993 | * follow the default rules with respect to RGB Quantization Range |
1438 | 1994 | * handling. |
1439 | 1995 | * |
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. | |
1442 | 1998 | */ |
1443 | 1999 | 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"); | |
1445 | 2001 | /* |
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. | |
1448 | 2004 | * |
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). | |
1453 | 2007 | */ |
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 | ||
1454 | 2015 | printf(" PT scan behavior: "); |
1455 | switch ((d >> 4) & 0x03) { | |
2016 | switch (s_pt) { | |
1456 | 2017 | case 0: printf("No Data\n"); break; |
1457 | 2018 | case 1: printf("Always Overscanned\n"); break; |
1458 | 2019 | case 2: printf("Always Underscanned\n"); break; |
1459 | 2020 | case 3: printf("Supports both over- and underscan\n"); break; |
1460 | 2021 | } |
1461 | 2022 | printf(" IT scan behavior: "); |
1462 | switch ((d >> 2) & 0x03) { | |
2023 | switch (s_it) { | |
1463 | 2024 | case 0: printf("IT video formats not supported\n"); break; |
1464 | 2025 | case 1: |
1465 | 2026 | printf("Always Overscanned\n"); |
1475 | 2036 | break; |
1476 | 2037 | case 3: printf("Supports both over- and underscan\n"); break; |
1477 | 2038 | } |
1478 | if (((d >> 2) & 0x03) < 2) | |
2039 | if (s_it < 2) | |
1479 | 2040 | warn("IT scan behavior is expected to support underscanned.\n"); |
1480 | 2041 | printf(" CE scan behavior: "); |
1481 | switch (d & 0x03) { | |
2042 | switch (s_ce) { | |
1482 | 2043 | case 0: printf("CE video formats not supported\n"); break; |
1483 | 2044 | case 1: printf("Always Overscanned\n"); break; |
1484 | 2045 | case 2: printf("Always Underscanned\n"); break; |
1485 | 2046 | case 3: printf("Supports both over- and underscan\n"); break; |
1486 | 2047 | } |
1487 | if ((d & 0x03) == 0) | |
2048 | if (s_ce == 0) | |
1488 | 2049 | 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[] = { | |
1492 | 2055 | "xvYCC601", |
1493 | 2056 | "xvYCC709", |
1494 | 2057 | "sYCC601", |
1499 | 2062 | "BT2020RGB", |
1500 | 2063 | }; |
1501 | 2064 | |
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 | ||
1502 | 2076 | static void cta_colorimetry_block(const unsigned char *x, unsigned length) |
1503 | 2077 | { |
1504 | 2078 | unsigned i; |
1507 | 2081 | fail("Empty Data Block with length %u.\n", length); |
1508 | 2082 | return; |
1509 | 2083 | } |
1510 | for (i = 0; i < ARRAY_SIZE(colorimetry_map); i++) { | |
2084 | for (i = 0; i < ARRAY_SIZE(colorimetry1_map); i++) | |
1511 | 2085 | 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]); | |
1518 | 2092 | } |
1519 | 2093 | |
1520 | 2094 | static const char *eotf_map[] = { |
1686 | 2260 | x++; |
1687 | 2261 | length--; |
1688 | 2262 | 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); | |
1690 | 2264 | } |
1691 | 2265 | |
1692 | 2266 | static void cta_hdmi_audio_block(const unsigned char *x, unsigned length) |
1755 | 2329 | } |
1756 | 2330 | } |
1757 | 2331 | |
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; | |
1763 | 2347 | 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 | ||
1792 | 2387 | 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; | |
1806 | 2436 | } |
1807 | 2437 | |
1808 | 2438 | // See Table 52 of CTA-861-G for a description of Byte 3 |
1809 | 2439 | 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); | |
1897 | 2494 | // This must be the first CTA-861 block |
1898 | if (!cta.first_block) | |
2495 | if (cta.block_number > 0) | |
1899 | 2496 | 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)) | |
1903 | 2500 | fail("HDMI Forum SCDB did not immediately follow the HDMI VSDB.\n"); |
1904 | 2501 | if (cta.have_hf_scdb || cta.have_hf_vsdb) |
1905 | 2502 | fail("Duplicate HDMI Forum VSDB/SCDB.\n"); |
1906 | 2503 | if (length < 2) { |
1907 | 2504 | data_block = std::string("HDMI Forum SCDB"); |
1908 | 2505 | 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]) | |
1912 | 2509 | 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; | |
1935 | 2512 | 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); | |
1940 | 2516 | 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); | |
2015 | 2522 | } |
2016 | 2523 | |
2017 | 2524 | void edid_state::preparse_cta_block(const unsigned char *x) |
2026 | 2533 | if (memchk(detailed, 18)) |
2027 | 2534 | break; |
2028 | 2535 | if (detailed[0] || detailed[1]) |
2029 | cta.preparse_total_dtds++; | |
2536 | cta.preparsed_total_dtds++; | |
2030 | 2537 | } |
2031 | 2538 | } |
2032 | 2539 | |
2045 | 2552 | cta.preparsed_phys_addr = (x[i + 4] << 8) | x[i + 5]; |
2046 | 2553 | } |
2047 | 2554 | 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; | |
2048 | 2560 | case 0x07: |
2049 | 2561 | if (x[i + 1] == 0x0d) |
2050 | 2562 | 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); | |
2051 | 2569 | if (x[i + 1] == 0x22) |
2052 | cta.preparse_total_vtdbs++; | |
2570 | cta.preparsed_total_vtdbs++; | |
2053 | 2571 | 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 += | |
2057 | 2575 | ((x[i] & 0x1f) - 2) / (6 + ((x[i + 2] & 0x70) >> 4)); |
2058 | 2576 | if (x[i + 1] != 0x0e) |
2059 | 2577 | continue; |
2121 | 2639 | // msg(!cta.has_hdmi, "If YCbCr support is indicated, then both 4:2:2 and 4:4:4 %s be supported.\n", |
2122 | 2640 | // cta.has_hdmi ? "shall" : "should"); |
2123 | 2641 | printf(" Native detailed modes: %u\n", x[3] & 0x0f); |
2124 | if (cta.first_block) | |
2642 | if (cta.block_number == 0) | |
2125 | 2643 | cta.byte3 = x[3]; |
2126 | 2644 | else if (x[3] != cta.byte3) |
2127 | 2645 | 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) { | |
2129 | 2647 | unsigned native_dtds = x[3] & 0x0f; |
2130 | 2648 | |
2131 | 2649 | cta.native_timings.clear(); |
2132 | 2650 | if (!native_dtds && !cta.has_vfpdb) { |
2133 | 2651 | 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) { | |
2135 | 2653 | 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); | |
2137 | 2655 | } |
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; | |
2140 | 2658 | for (unsigned i = 0; i < native_dtds; i++) { |
2141 | 2659 | char type[16]; |
2142 | 2660 | |
2150 | 2668 | if (version >= 3) { |
2151 | 2669 | unsigned i; |
2152 | 2670 | |
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 | } | |
2155 | 2674 | |
2156 | 2675 | data_block.clear(); |
2157 | 2676 | if (i != offset) |
2186 | 2705 | cta.supported_hdmi_vic_codes) |
2187 | 2706 | fail("HDMI VIC Codes must have their CTA-861 VIC equivalents in the VSB.\n"); |
2188 | 2707 | 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"); | |
2190 | 2709 | } |
2191 | 2710 | |
2192 | 2711 | void edid_state::cta_resolve_svr(vec_timings_ext::iterator iter) |
2197 | 2716 | } else if (iter->svr() <= 144) { |
2198 | 2717 | iter->flags = cta.vec_dtds[iter->svr() - 129].flags; |
2199 | 2718 | iter->t = cta.vec_dtds[iter->svr() - 129].t; |
2200 | } else { | |
2719 | } else if (iter->svr() <= 160) { | |
2201 | 2720 | iter->flags = cta.vec_vtdbs[iter->svr() - 145].flags; |
2202 | 2721 | 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]); | |
2203 | 2728 | } |
2204 | 2729 | } |
2205 | 2730 | |
2297 | 2822 | warn("Native interlaced resolution of %ux%u is smaller than the max preferred interlaced resolution %ux%u.\n", |
2298 | 2823 | native_ilace_hact, native_ilace_vact, |
2299 | 2824 | 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 | } |
80 | 80 | check_displayid_datablock_revision(x[1]); |
81 | 81 | |
82 | 82 | 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 | } | |
89 | 83 | printf(" Product Code: %u\n", x[6] | (x[7] << 8)); |
90 | 84 | unsigned sn = x[8] | (x[9] << 8) | (x[10] << 16) | (x[11] << 24); |
91 | 85 | if (sn) { |
135 | 129 | } |
136 | 130 | } |
137 | 131 | |
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 | ||
138 | 152 | void edid_state::parse_displayid_parameters(const unsigned char *x) |
139 | 153 | { |
140 | 154 | check_displayid_datablock_revision(x[1]); |
142 | 156 | if (!check_displayid_datablock_length(x, 12, 12)) |
143 | 157 | return; |
144 | 158 | |
159 | if (dispid.has_display_parameters) | |
160 | fail("Duplicate Display Parameters Data Block.\n"); | |
145 | 161 | 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 | } | |
146 | 169 | 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); | |
151 | 175 | print_flag_lines(" ", " Feature support flags:", |
152 | 176 | x[11], feature_support_flags); |
153 | 177 | |
192 | 216 | printf(" Uses %u CIE (x, y) coordinates\n", cie_year); |
193 | 217 | if (xfer_id) { |
194 | 218 | 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))) | |
196 | 220 | fail("Missing Transfer Characteristics Data Block with Identifier %u.\n", xfer_id); |
197 | 221 | } |
198 | 222 | if (!num_primaries) { |
204 | 228 | for (unsigned i = 0; i < num_primaries; i++) { |
205 | 229 | unsigned idx = offset + 3 * i; |
206 | 230 | |
207 | printf(" Primary #%u: (%.6f, %.6f)\n", i, | |
231 | printf(" Primary #%u: (%.4f, %.4f)\n", i, | |
208 | 232 | fp2d(x[idx] | ((x[idx + 1] & 0x0f) << 8)), |
209 | 233 | fp2d(((x[idx + 1] & 0xf0) >> 4) | (x[idx + 2] << 4))); |
210 | 234 | } |
212 | 236 | for (unsigned i = 0; i < num_whitepoints; i++) { |
213 | 237 | unsigned idx = offset + 3 * i; |
214 | 238 | |
215 | printf(" White point #%u: (%.6f, %.6f)\n", i, | |
239 | printf(" White point #%u: (%.4f, %.4f)\n", i, | |
216 | 240 | fp2d(x[idx] | ((x[idx + 1] & 0x0f) << 8)), |
217 | 241 | fp2d(((x[idx + 1] & 0xf0) >> 4) | (x[idx + 2] << 4))); |
218 | 242 | } |
225 | 249 | { |
226 | 250 | struct timings t = {}; |
227 | 251 | unsigned hbl, vbl; |
252 | std::string name = is_cta ? std::string("VTDB ") + std::to_string(cta.vec_vtdbs.size() + 1) : "DTD"; | |
228 | 253 | std::string s("aspect "); |
229 | 254 | |
230 | 255 | dispid.has_type_1_7 = true; |
269 | 294 | t.hratio = 256; |
270 | 295 | t.vratio = 135; |
271 | 296 | break; |
297 | case 8: | |
298 | s += "undefined"; | |
299 | break; | |
272 | 300 | 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); | |
276 | 303 | break; |
277 | 304 | } |
278 | 305 | switch ((x[3] >> 5) & 0x3) { |
319 | 346 | dispid.preferred_timings.push_back(timings_ext(t, "DTD", s)); |
320 | 347 | } |
321 | 348 | |
322 | print_timings(" ", &t, "DTD", s.c_str(), true); | |
349 | print_timings(" ", &t, name.c_str(), s.c_str(), true); | |
323 | 350 | if (is_cta) { |
324 | timings_ext te(t, "DTD", s); | |
351 | timings_ext te(t, name.c_str(), s); | |
325 | 352 | cta.vec_vtdbs.push_back(te); |
326 | 353 | |
327 | 354 | // Only use a T7VTDB if is cannot be expressed by a |
335 | 362 | unsigned vtot = t.vact + t.vfp + t.vsync + t.vbp; |
336 | 363 | unsigned refresh = (t.pixclk_khz * 1000ULL) / (htot * vtot); |
337 | 364 | |
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); | |
340 | 367 | if (match_timings(t, cvt_t)) { |
341 | 368 | fail("This T7VTDB can be represented as a T10VTDB.\n"); |
342 | 369 | return; |
343 | 370 | } |
344 | 371 | } |
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); | |
346 | 374 | if (match_timings(t, cvt_t)) |
347 | 375 | fail("This T7VTDB can be represented as a T10VTDB.\n"); |
348 | 376 | } |
453 | 481 | t.hratio = 256; |
454 | 482 | t.vratio = 135; |
455 | 483 | break; |
484 | case 8: | |
485 | s += "undefined"; | |
486 | break; | |
456 | 487 | 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; | |
464 | 494 | t.hact = 8 + 8 * x[1]; |
465 | 495 | t.vact = t.hact * t.vratio / t.hratio; |
466 | 496 | |
504 | 534 | if (!check_displayid_datablock_length(x, 15, 15)) |
505 | 535 | return; |
506 | 536 | 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); | |
509 | 539 | printf(" Horizontal Frequency: %u-%u kHz\n", x[9], x[10]); |
510 | 540 | printf(" Minimum Horizontal Blanking: %u pixels\n", x[11] | (x[12] << 8)); |
511 | 541 | printf(" Vertical Refresh: %u-%u Hz\n", x[13], x[14]); |
589 | 619 | printf(" The backlight may be switched on and off\n"); |
590 | 620 | if (x[4] & 0x04) |
591 | 621 | 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); | |
594 | 630 | printf(" Aspect ratio and orientation:\n"); |
595 | 631 | printf(" Aspect Ratio: %.2f\n", (100 + x[9]) / 100.0); |
596 | 632 | unsigned char v = x[0x0a]; |
658 | 694 | if (!check_displayid_datablock_length(x, 6, 6)) |
659 | 695 | return; |
660 | 696 | |
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); | |
667 | 703 | } |
668 | 704 | |
669 | 705 | // tag 0x0e |
678 | 714 | |
679 | 715 | if (xfer_id) { |
680 | 716 | 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))) | |
682 | 718 | fail("Missing Color Characteristics Data Block using Identifier %u.\n", xfer_id); |
683 | 719 | } |
684 | 720 | if (first_is_white) |
697 | 733 | i - first_is_white); |
698 | 734 | unsigned samples = x[offset]; |
699 | 735 | if (four_param) { |
736 | if (samples != 5) | |
737 | fail("Expected 5 samples.\n"); | |
700 | 738 | printf(" A0=%u A1=%u A2=%u A3=%u Gamma=%.2f\n", |
701 | 739 | x[offset + 1], x[offset + 2], x[offset + 3], x[offset + 4], |
702 | 740 | (double)(x[offset + 5] + 100.0) / 100.0); |
703 | 741 | samples++; |
704 | 742 | } 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"); | |
708 | 758 | } |
709 | 759 | offset += samples; |
710 | 760 | len -= samples; |
917 | 967 | if (x[0] & 0x10) |
918 | 968 | s += ", refresh rate * (1000/1001) supported"; |
919 | 969 | |
920 | t.rb = 2; | |
970 | t.rb = RB_CVT_V2; | |
921 | 971 | if ((x[0] & 0x03) == 1) |
922 | 972 | warn("Unexpected use of 'custom reduced blanking'.\n"); |
923 | 973 | else if ((x[0] & 0x03) > 1) |
1083 | 1133 | |
1084 | 1134 | // tag 0x21 |
1085 | 1135 | |
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 | { | |
1090 | 1139 | if (!check_displayid_datablock_length(x, 29, 29)) |
1091 | 1140 | return; |
1141 | if (dispid.has_display_parameters) | |
1142 | fail("Duplicate Display Parameters Data Block.\n"); | |
1143 | dispid.has_display_parameters = true; | |
1092 | 1144 | |
1093 | 1145 | unsigned hor_size = (x[4] << 8) + x[3]; |
1094 | 1146 | unsigned vert_size = (x[6] << 8) + x[5]; |
1095 | 1147 | |
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 { | |
1101 | 1155 | printf(" Image size: %.1f mm x %.1f mm\n", |
1102 | 1156 | 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 | ||
1105 | 1170 | unsigned char v = x[11]; |
1106 | 1171 | printf(" Scan Orientation: "); |
1107 | 1172 | switch (v & 0x07) { |
1144 | 1209 | printf(" Native Minimum Luminance: %s\n", |
1145 | 1210 | ieee7542d(x[0x1c] | (x[0x1d] << 8)).c_str()); |
1146 | 1211 | 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]) | |
1148 | 1215 | printf("%s bpc\n", bpc444[x[0x1e] & 0x07]); |
1149 | 1216 | else |
1150 | 1217 | printf("Reserved\n"); |
1155 | 1222 | case 0x02: printf("Organic LED\n"); break; |
1156 | 1223 | default: printf("Reserved\n"); break; |
1157 | 1224 | } |
1225 | if (block_rev) | |
1226 | printf(" Display Device Theme Preference: %s\n", | |
1227 | (x[0x1e] & 0x80) ? "Dark Theme Preferred" : "No Preference"); | |
1158 | 1228 | if (x[0x1f] != 0xff) |
1159 | 1229 | printf(" Native Gamma EOTF: %.2f\n", |
1160 | 1230 | (100 + x[0x1f]) / 100.0); |
1190 | 1260 | s += ", refresh rate * (1000/1001) supported"; |
1191 | 1261 | |
1192 | 1262 | 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; | |
1195 | 1265 | default: break; |
1196 | 1266 | } |
1197 | 1267 | |
1326 | 1396 | |
1327 | 1397 | if (check_displayid_datablock_length(x, 16, 16)) { |
1328 | 1398 | 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; | |
1335 | 1442 | } |
1336 | 1443 | } |
1337 | 1444 | |
1338 | 1445 | // tag 0x32 |
1339 | 1446 | |
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) | |
1341 | 1449 | { |
1342 | 1450 | struct timings t = {}; |
1451 | std::string name = is_cta ? std::string("VTDB ") + std::to_string(cta.vec_vtdbs.size() + 1) : "CVT"; | |
1343 | 1452 | std::string s("aspect "); |
1344 | 1453 | |
1345 | 1454 | t.hact = 1 + (x[1] | (x[2] << 8)); |
1364 | 1473 | } |
1365 | 1474 | |
1366 | 1475 | 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; | |
1370 | 1479 | default: break; |
1371 | 1480 | } |
1372 | 1481 | |
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 | ||
1373 | 1487 | if (x[0] & 0x10) { |
1374 | if (t.rb == 2) { | |
1488 | if (rb == RB_CVT_V2) { | |
1375 | 1489 | s += ", refresh rate * (1000/1001) supported"; |
1376 | } else if (t.rb == 3) { | |
1490 | t.rb |= RB_ALT; | |
1491 | } else if (rb == RB_CVT_V3) { | |
1377 | 1492 | s += ", hblank is 160 pixels"; |
1378 | t.rb |= RB_FLAG; | |
1493 | t.rb |= RB_ALT; | |
1494 | rb_h_blank = 160; | |
1379 | 1495 | } else { |
1380 | 1496 | fail("VR_HB must be 0.\n"); |
1381 | 1497 | } |
1383 | 1499 | if (x[0] & 0x80) |
1384 | 1500 | s += ", YCbCr 4:2:0"; |
1385 | 1501 | |
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()); | |
1389 | 1540 | if (is_cta) { |
1390 | timings_ext te(t, "CVT", s); | |
1541 | timings_ext te(t, name.c_str(), s); | |
1391 | 1542 | cta.vec_vtdbs.push_back(te); |
1392 | 1543 | } |
1393 | 1544 | } |
1404 | 1555 | unsigned len = x[2]; |
1405 | 1556 | x += 6; |
1406 | 1557 | 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 | ||
1412 | 1567 | printf(" Default Colorspace and EOTF Handling: %s\n", |
1413 | 1568 | (x[0] & 0x80) ? "Native as specified in the Display Parameters DB" : "sRGB"); |
1569 | ||
1414 | 1570 | printf(" Number of Pixels in Hor Pix Cnt Overlapping an Adjacent Panel: %u\n", |
1415 | 1571 | 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 | ||
1416 | 1578 | 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 | ||
1423 | 1589 | if (len >= 7) { |
1424 | 1590 | double bpp = (x[2] & 0x3f) + (x[3] & 0x0f) / 16.0; |
1425 | 1591 | printf(" Pass through timing's target DSC bits per pixel: %.4f\n", bpp); |
1426 | 1592 | } |
1427 | 1593 | } |
1428 | 1594 | |
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 | ||
1429 | 1616 | // tag 0x81 |
1430 | 1617 | |
1431 | 1618 | void edid_state::parse_displayid_cta_data_block(const unsigned char *x) |
1441 | 1628 | } |
1442 | 1629 | x += 3; |
1443 | 1630 | |
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 | } | |
1446 | 1634 | |
1447 | 1635 | if (i != len) |
1448 | 1636 | fail("Length is %u instead of %u.\n", len, i); |
1498 | 1686 | |
1499 | 1687 | unsigned offset = 5; |
1500 | 1688 | |
1501 | dispid.preparse_displayid_blocks++; | |
1689 | dispid.preparsed_displayid_blocks++; | |
1502 | 1690 | while (length > 0) { |
1503 | 1691 | unsigned tag = x[offset]; |
1504 | 1692 | unsigned len = x[offset + 2]; |
1505 | 1693 | |
1506 | 1694 | switch (tag) { |
1507 | 1695 | case 0x02: |
1508 | dispid.preparse_color_ids |= 1 << ((x[offset + 1] >> 3) & 0x0f); | |
1696 | dispid.preparsed_color_ids |= 1 << ((x[offset + 1] >> 3) & 0x0f); | |
1509 | 1697 | break; |
1510 | 1698 | case 0x0e: |
1511 | dispid.preparse_xfer_ids |= 1 << ((x[offset + 1] >> 4) & 0x0f); | |
1699 | dispid.preparsed_xfer_ids |= 1 << ((x[offset + 1] >> 4) & 0x0f); | |
1512 | 1700 | break; |
1513 | 1701 | default: |
1514 | 1702 | break; |
1528 | 1716 | } |
1529 | 1717 | } |
1530 | 1718 | |
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 | ||
1531 | 1973 | void edid_state::parse_displayid_block(const unsigned char *x) |
1532 | 1974 | { |
1533 | 1975 | unsigned version = x[1]; |
1534 | 1976 | unsigned length = x[2]; |
1535 | 1977 | unsigned prod_type = x[3]; // future check: based on type, check for required data blocks |
1536 | 1978 | unsigned ext_count = x[4]; |
1537 | unsigned i; | |
1538 | 1979 | |
1539 | 1980 | printf(" Version: %u.%u\n Extension Count: %u\n", |
1540 | 1981 | version >> 4, version & 0xf, ext_count); |
1545 | 1986 | product_type(prod_type, false).c_str()); |
1546 | 1987 | if (!prod_type) |
1547 | 1988 | 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) | |
1549 | 1990 | fail("Expected %u DisplayID Extension Block%s, but got %u.\n", |
1550 | 1991 | ext_count, |
1551 | 1992 | ext_count > 1 ? "s" : "", |
1552 | dispid.preparse_displayid_blocks - 1); | |
1993 | dispid.preparsed_displayid_blocks - 1); | |
1553 | 1994 | } else { |
1554 | 1995 | if (prod_type) |
1555 | 1996 | fail("Product Type should be 0 in extension block.\n"); |
1566 | 2007 | length = 121; |
1567 | 2008 | } |
1568 | 2009 | |
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; | |
1803 | 2014 | } |
1804 | 2015 | |
1805 | 2016 | /* |
1831 | 2042 | dispid.version >= 0x20 ? "VII" : "I"); |
1832 | 2043 | if (dispid.preferred_timings.empty()) |
1833 | 2044 | 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 | } |
16 | 16 | unsigned num_cvt = x[3]; |
17 | 17 | unsigned num_st = x[4]; |
18 | 18 | |
19 | const unsigned char *y = x + 0x7f; | |
19 | 20 | x += 5; |
20 | 21 | if (num_dtd) { |
21 | 22 | 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 | } | |
23 | 28 | detailed_timings(" ", x, false); |
29 | } | |
24 | 30 | } |
25 | 31 | if (num_cvt) { |
26 | 32 | 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 | } | |
28 | 38 | detailed_cvt_descriptor(" ", x, false); |
39 | } | |
29 | 40 | } |
30 | 41 | 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. | |
31 | 48 | printf(" Standard Timings:\n"); |
32 | 49 | 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); | |
37 | 55 | } |
38 | 56 | } |
39 | 57 | } |
17 | 17 | 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 |
18 | 18 | 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 5e |
19 | 19 | |
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 | |
22 | 22 | 81 82 6a 84 4d d0 00 a0 f0 70 3e 80 30 20 35 00 |
23 | 23 | c0 1c 32 00 00 1e 1a 36 80 a0 70 38 1f 40 30 20 |
24 | 24 | 35 00 c0 1c 32 00 00 1a 1a 1d 00 80 51 d0 1c 20 |
25 | 25 | 40 80 35 00 c0 1c 32 00 00 1c 00 00 00 00 00 00 |
26 | 26 | 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 | |
30 | 30 | 00 00 00 04 54 65 73 74 21 00 1d 80 3e 28 23 00 |
31 | 31 | 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 | |
34 | 34 | 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 |
17 | 17 | 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 |
18 | 18 | 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 5e |
19 | 19 | |
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 | |
22 | 22 | 81 82 6a 84 4d d0 00 a0 f0 70 3e 80 30 20 35 00 |
23 | 23 | c0 1c 32 00 00 1e 1a 36 80 a0 70 38 1f 40 30 20 |
24 | 24 | 35 00 c0 1c 32 00 00 1a 1a 1d 00 80 51 d0 1c 20 |
25 | 25 | 40 80 35 00 c0 1c 32 00 00 1c 00 00 00 00 00 00 |
26 | 26 | 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 | |
30 | 30 | 00 00 00 04 54 65 73 74 21 00 1d 80 3e 28 23 00 |
31 | 31 | 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 | |
34 | 34 | 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 | |
36 | 36 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90 |
37 | 37 | |
38 | 38 | 70 20 04 00 00 23 00 01 02 b6 00 00 00 00 00 00 |