// File: /workspace/github_cpp_makefile_star2_O1/rpavlik[P]edid-decode/parse-cta-block.cpp
// Function: edid_state::parse_cta_block(unsigned char const*)
void edid_state::parse_cta_block(const unsigned char *x)
{
	unsigned version = x[1];
	unsigned offset = x[2];
	const unsigned char *detailed;

	// See Table 52 of CTA-861-G for a description of Byte 3

	printf("  Revision: %u\n", version);
	if (version == 0)
		fail("Invalid CTA-861 Extension revision 0.\n");
	if (version == 2)
		fail("Deprecated CTA-861 Extension revision 2.\n");
	if (cta.has_hdmi && version != 3)
		fail("The HDMI Specification requires CTA Extension revision 3.\n");
	if (version > 3)
		warn("Unknown CTA-861 Extension revision %u.\n", version);

	if (version >= 1) do {
		if (version == 1 && x[3] != 0)
			fail("Non-zero byte 3.\n");

		if (offset < 4)
			break;

		if (version < 3 && ((offset - 4) / 8)) {
			printf("  8-byte timing descriptors: %u\n", (offset - 4) / 8);
			fail("8-byte descriptors were never used.\n");
		}

		if (version >= 2) {
			if (x[3] & 0x80)
				printf("  Underscans IT Video Formats by default\n");
			else
				warn("IT Video Formats are overscanned by default, but normally this should be underscanned.\n");
			if (x[3] & 0x40)
				printf("  Basic audio support\n");
			if (x[3] & 0x20)
				printf("  Supports YCbCr 4:4:4\n");
			if (x[3] & 0x10)
				printf("  Supports YCbCr 4:2:2\n");
			// Disable this test: this fails a lot of EDIDs, and there are
			// also some corner cases where you only want to receive 4:4:4
			// and refuse a fallback to 4:2:2.
//			if ((x[3] & 0x30) && (x[3] & 0x30) != 0x30)
//				msg(!cta.has_hdmi, "If YCbCr support is indicated, then both 4:2:2 and 4:4:4 %s be supported.\n",
//				    cta.has_hdmi ? "shall" : "should");
			printf("  Native detailed modes: %u\n", x[3] & 0x0f);
			if (cta.first_block)
				cta.byte3 = x[3];
			else if (x[3] != cta.byte3)
				fail("Byte 3 must be the same for all CTA-861 Extension Blocks.\n");
			if (cta.first_block) {
				unsigned native_dtds = x[3] & 0x0f;

				cta.native_timings.clear();
				if (!native_dtds && !cta.has_vfpdb) {
					cta.first_svd_might_be_preferred = true;
				} else if (native_dtds > cta.preparsed_total_dtds) {
					fail("There are more Native DTDs (%u) than DTDs (%u).\n",
					     native_dtds, cta.preparsed_total_dtds);
				}
				if (native_dtds > cta.preparsed_total_dtds)
					native_dtds = cta.preparsed_total_dtds;
				for (unsigned i = 0; i < native_dtds; i++) {
					char type[16];

					sprintf(type, "DTD %3u", i + 1);
					cta.native_timings.push_back(timings_ext(i + 129, type));
				}
				if (cta.has_hdmi && block_nr != (block_map.saw_block_1 ? 2 : 1))
					fail("The HDMI Specification requires that the first Extension Block (that is not a Block Map) is an CTA-861 Extension Block.\n");
			}
		}
		if (version >= 3) {
			unsigned i;

			for (i = 4; i < offset; i += (x[i] & 0x1f) + 1) {
				unsigned tag = (x[i] & 0xe0) << 3;

				if (tag == 0x700)
					tag |= x[i + 1];
				bool duplicate = cta.found_tags.find(tag) != cta.found_tags.end();

				cta_block(x + i, duplicate);
				if (!duplicate)
					cta.found_tags.insert(tag);
			}

			data_block.clear();
			if (i != offset)
				fail("Offset is %u, but should be %u.\n", offset, i);
		}

		data_block = "Detailed Timing Descriptors";
		base.seen_non_detailed_descriptor = false;
		bool first = true;
		for (detailed = x + offset; detailed + 17 < x + 127; detailed += 18) {
			if (memchk(detailed, 18))
				break;
			if (first) {
				first = false;
				printf("  %s:\n", data_block.c_str());
			}
			detailed_block(detailed);
		}
		if (!memchk(detailed, x + 127 - detailed)) {
			data_block = "Padding";
			fail("CTA-861 padding contains non-zero bytes.\n");
		}
	} while (0);

	data_block.clear();
	if (base.has_serial_number && base.has_serial_string)
		warn("Display Product Serial Number is set, so the Serial Number in the Base EDID should be 0.\n");
	if (!cta.has_vic_1 && !base.has_640x480p60_est_timing)
		fail("Required 640x480p60 timings are missing in the established timings"
		     " and the SVD list (VIC 1).\n");
	if ((cta.supported_hdmi_vic_vsb_codes & cta.supported_hdmi_vic_codes) !=
	    cta.supported_hdmi_vic_codes)
		fail("HDMI VIC Codes must have their CTA-861 VIC equivalents in the VSB.\n");
	if (!cta.has_vcdb)
		fail("Missing VCDB, needed for Set Selectable RGB Quantization to avoid interop issues.\n");
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movq %rsi, %r15
movq %rdi, %rbx
movzbl 0x1(%rsi), %ebp
movzbl 0x2(%rsi), %r14d
leaq 0x164b2(%rip), %rdi     # 0x2b3b1
movl %ebp, %esi
xorl %eax, %eax
callq 0x3030
testl %ebp, %ebp
je 0x14f1a
cmpl $0x2, %ebp
jne 0x14f2a
leaq 0x164d0(%rip), %rsi     # 0x2b3e8
jmp 0x14f21
leaq 0x164a0(%rip), %rsi     # 0x2b3c1
xorl %edi, %edi
xorl %eax, %eax
callq 0x37ec
cmpl $0x3, %ebp
je 0x14f48
cmpb $0x0, 0x2c3(%rbx)
je 0x14f48
leaq 0x164d3(%rip), %rsi     # 0x2b412
xorl %edi, %edi
xorl %eax, %eax
callq 0x37ec
cmpb $0x4, %bpl
jb 0x14f63
leaq 0x164f8(%rip), %rsi     # 0x2b44d
movl $0x1, %edi
movl %ebp, %edx
xorl %eax, %eax
callq 0x37ec
testl %ebp, %ebp
je 0x153f3
cmpl $0x1, %ebp
jne 0x14f87
cmpb $0x0, 0x3(%r15)
je 0x14f87
leaq 0x164f7(%rip), %rsi     # 0x2b475
xorl %edi, %edi
xorl %eax, %eax
callq 0x37ec
cmpb $0x4, %r14b
jb 0x153f3
cmpb $0x2, %bpl
ja 0x14fc1
leal -0x4(%r14), %esi
cmpl $0x8, %esi
jb 0x14fc1
shrl $0x3, %esi
leaq 0x164dd(%rip), %rdi     # 0x2b487
xorl %eax, %eax
callq 0x3030
leaq 0x164f0(%rip), %rsi     # 0x2b4a8
xorl %edi, %edi
xorl %eax, %eax
callq 0x37ec
cmpl $0x1, %ebp
je 0x15217
cmpb $0x0, 0x3(%r15)
js 0x14fe6
leaq 0x164f5(%rip), %rsi     # 0x2b4cd
movl $0x1, %edi
xorl %eax, %eax
callq 0x37ec
jmp 0x14ff2
leaq 0x195a3(%rip), %rdi     # 0x2e590
callq 0x3380
testb $0x40, 0x3(%r15)
je 0x15005
leaq 0x195b9(%rip), %rdi     # 0x2e5b9
callq 0x3380
testb $0x20, 0x3(%r15)
je 0x15018
leaq 0x195bc(%rip), %rdi     # 0x2e5cf
callq 0x3380
testb $0x10, 0x3(%r15)
je 0x1502b
leaq 0x195c0(%rip), %rdi     # 0x2e5e6
callq 0x3380
movzbl 0x3(%r15), %esi
andl $0xf, %esi
leaq 0x164eb(%rip), %rdi     # 0x2b525
xorl %eax, %eax
callq 0x3030
movb 0x3(%r15), %al
cmpb $0x1, 0x2d5(%rbx)
jne 0x15056
movb %al, 0x2c2(%rbx)
jmp 0x1506e
cmpb 0x2c2(%rbx), %al
je 0x1506e
leaq 0x164dd(%rip), %rsi     # 0x2b542
xorl %edi, %edi
xorl %eax, %eax
callq 0x37ec
cmpb $0x1, 0x2d5(%rbx)
jne 0x15217
movzbl 0x3(%r15), %r12d
leaq 0x2a8(%rbx), %rdi
movq 0x2a8(%rbx), %rsi
movq %rdi, 0x10(%rsp)
callq 0xe144
andl $0xf, %r12d
movl %ebp, 0x1c(%rsp)
jne 0x150ab
cmpb $0x0, 0x2c5(%rbx)
je 0x150cb
movl 0x180(%rbx), %ecx
cmpl %r12d, %ecx
jae 0x150d2
leaq 0x164c0(%rip), %rsi     # 0x2b57d
xorl %edi, %edi
movl %r12d, %edx
xorl %eax, %eax
callq 0x37ec
jmp 0x150d2
movb $0x1, 0x2c1(%rbx)
movl 0x180(%rbx), %eax
cmpl %r12d, %eax
cmovbl %eax, %r12d
movq %r12, 0x8(%rsp)
testl %r12d, %r12d
je 0x151ec
movq 0x8(%rsp), %rax
negl %eax
movq %rax, 0x8(%rsp)
movl $0x81, %r13d
movq %r15, %r12
leal -0x80(%r13), %edx
leaq 0x40(%rsp), %rbp
movq %rbp, %rdi
leaq 0x15045(%rip), %rsi     # 0x2a15a
xorl %eax, %eax
callq 0x3070
leaq 0x30(%rsp), %rax
movq %rax, 0x20(%rsp)
movq %rbp, %rdi
callq 0x3110
leaq (%rsp,%rax), %rdx
addq $0x40, %rdx
leaq 0x20(%rsp), %r15
movq %r15, %rdi
movq %rbp, %rsi
leaq 0x50(%rsp), %rbp
callq 0x8f6e
movq %rbp, %rdi
movl %r13d, %esi
movq %r15, %rdx
callq 0x15c9c
movq 0x10(%rsp), %rdi
movq %rbp, %rsi
callq 0x16042
movq 0xc8(%rsp), %rdi
leaq 0xd8(%rsp), %rax
cmpq %rax, %rdi
movq %r12, %r15
je 0x1518e
movq 0xd8(%rsp), %rsi
incq %rsi
callq 0x3260
movq 0xa8(%rsp), %rdi
leaq 0xb8(%rsp), %rax
cmpq %rax, %rdi
je 0x151b3
movq 0xb8(%rsp), %rsi
incq %rsi
callq 0x3260
movq 0x20(%rsp), %rdi
leaq 0x30(%rsp), %rax
cmpq %rax, %rdi
je 0x151cf
movq 0x30(%rsp), %rsi
incq %rsi
callq 0x3260
movq 0x8(%rsp), %rax
addl %r13d, %eax
incl %eax
movl %r13d, %ecx
incl %ecx
movl %ecx, %r13d
cmpl $0x81, %eax
jne 0x150ff
cmpb $0x0, 0x2c3(%rbx)
movl 0x1c(%rsp), %ebp
je 0x15217
movzbl 0x978(%rbx), %eax
incl %eax
cmpl %eax, 0x8(%rbx)
je 0x15217
leaq 0x163a0(%rip), %rsi     # 0x2b5ae
xorl %edi, %edi
xorl %eax, %eax
callq 0x37ec
cmpb $0x3, %bpl
jb 0x1532b
movq %r15, 0x8(%rsp)
movl $0x4, %r12d
cmpl $0x4, %r14d
je 0x152fc
leaq 0x1e0(%rbx), %rax
movq %rax, 0x10(%rsp)
leaq 0x1e8(%rbx), %r15
movl $0x4, %r12d
movl %r12d, %eax
movq 0x8(%rsp), %rcx
leaq (%rcx,%rax), %rbp
movzbl (%rcx,%rax), %eax
movl %eax, %ecx
andl $-0x20, %ecx
shll $0x3, %ecx
movl %ecx, 0x50(%rsp)
cmpb $-0x20, %al
jb 0x1527c
movzbl 0x1(%rbp), %eax
orl $0x700, %eax            # imm = 0x700
movl %eax, 0x50(%rsp)
movq 0x1f0(%rbx), %rcx
movq %r15, %rax
testq %rcx, %rcx
je 0x152a9
movl 0x50(%rsp), %edx
movq %r15, %rax
xorl %esi, %esi
cmpl %edx, 0x20(%rcx)
setb %sil
cmovaeq %rcx, %rax
movq 0x10(%rcx,%rsi,8), %rcx
testq %rcx, %rcx
jne 0x15292
movq %r15, %r13
cmpq %r15, %rax
je 0x152bf
movl 0x50(%rsp), %ecx
cmpl 0x20(%rax), %ecx
cmovbq %r15, %rax
movq %rax, %r13
xorl %edx, %edx
cmpq %r15, %r13
setne %dl
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x12e60
cmpq %r15, %r13
jne 0x152e6
movq 0x10(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x1616c
movzbl (%rbp), %eax
andl $0x1f, %eax
addl %eax, %r12d
incl %r12d
cmpl %r14d, %r12d
jb 0x1524f
movq $0x0, 0x38(%rbx)
movq 0x30(%rbx), %rax
movb $0x0, (%rax)
cmpl %r14d, %r12d
movq 0x8(%rsp), %r15
je 0x1532b
leaq 0x1630b(%rip), %rsi     # 0x2b627
xorl %edi, %edi
movl %r14d, %edx
movl %r12d, %ecx
xorl %eax, %eax
callq 0x37ec
leaq 0x30(%rbx), %r12
movq 0x38(%rbx), %rdx
leaq 0x10c62(%rip), %rcx     # 0x25f9c
movl $0x1b, %r8d
movq %r12, %rdi
xorl %esi, %esi
callq 0x3390
movb $0x0, 0xc4(%rbx)
cmpb $0x6d, %r14b
ja 0x153ac
movb $0x1, %r13b
leaq (%r15,%r14), %rbp
movq %rbp, %rdi
movl $0x12, %esi
xorl %edx, %edx
callq 0x5b92
testb %al, %al
jne 0x153b2
testb $0x1, %r13b
je 0x1538c
movq (%r12), %rsi
xorl %r13d, %r13d
leaq 0xfa36(%rip), %rdi      # 0x24dbb
xorl %eax, %eax
callq 0x3030
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xc056
leaq 0x12(%r14), %rax
cmpq $0x5c, %r14
movq %rax, %r14
jb 0x1535a
addq %rax, %r15
movq %rax, %r14
jmp 0x153af
addq %r14, %r15
movq %r15, %rbp
movl $0x7f, %esi
subl %r14d, %esi
movq %rbp, %rdi
xorl %edx, %edx
callq 0x5b92
testb %al, %al
jne 0x153f3
movq 0x38(%rbx), %rdx
leaq 0x16275(%rip), %rcx     # 0x2b648
movl $0x7, %r8d
movq %r12, %rdi
xorl %esi, %esi
callq 0x3390
leaq 0x16266(%rip), %rsi     # 0x2b650
xorl %edi, %edi
xorl %eax, %eax
callq 0x37ec
movq $0x0, 0x38(%rbx)
movq 0x30(%rbx), %rax
movb $0x0, (%rax)
cmpb $0x1, 0x8e(%rbx)
jne 0x15427
cmpb $0x1, 0x8f(%rbx)
jne 0x15427
leaq 0x1625f(%rip), %rsi     # 0x2b67a
movl $0x1, %edi
xorl %eax, %eax
callq 0x37ec
cmpb $0x0, 0x2c0(%rbx)
jne 0x15449
cmpb $0x0, 0xc5(%rbx)
jne 0x15449
leaq 0x16294(%rip), %rsi     # 0x2b6d4
xorl %edi, %edi
xorl %eax, %eax
callq 0x37ec
movl 0x2dc(%rbx), %eax
notl %eax
testl %eax, 0x2d8(%rbx)
je 0x15469
leaq 0x162d2(%rip), %rsi     # 0x2b732
xorl %edi, %edi
xorl %eax, %eax
callq 0x37ec
cmpb $0x0, 0x2c4(%rbx)
jne 0x15482
leaq 0x162fd(%rip), %rsi     # 0x2b776
xorl %edi, %edi
xorl %eax, %eax
callq 0x37ec
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x154a6
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0xdd9e
movq 0x20(%rsp), %rdi
leaq 0x30(%rsp), %rax
cmpq %rax, %rdi
je 0x154c2
movq 0x30(%rsp), %rsi
incq %rsi
callq 0x3260
movq %rbx, %rdi
callq 0x3400