// File: rpavlik[P]edid-decode/parse-cta-block.cpp
// Function: edid_state::cta_block(unsigned char const*, bool)
void edid_state::cta_block(const unsigned char *x, bool duplicate)
{
	unsigned length = x[0] & 0x1f;
	const char *name;
	unsigned oui;
	bool reverse = false;
	bool audio_block = false;

	switch ((x[0] & 0xe0) >> 5) {
	case 0x01:
		data_block = "Audio Data Block";
		printf("  %s:\n", data_block.c_str());
		cta_audio_block(x + 1, length);
		audio_block = true;
		break;
	case 0x02:
		data_block = "Video Data Block";
		printf("  %s:\n", data_block.c_str());
		cta_svd(x + 1, length, false);
		break;
	case 0x03:
		oui = (x[3] << 16) + (x[2] << 8) + x[1];
		name = oui_name(oui);
		if (!name) {
			name = oui_name(oui, true);
			if (name)
				reverse = true;
		}
		if (!name) {
			printf("  Vendor-Specific Data Block, OUI %s:\n", ouitohex(oui).c_str());
			hex_block("    ", x + 4, length - 3);
			data_block.clear();
			warn("Unknown Vendor-Specific Data Block, OUI %s.\n",
			     ouitohex(oui).c_str());
			return;
		}
		data_block = std::string("Vendor-Specific Data Block (") + name + ")";
		if (reverse)
			fail((std::string("OUI ") + ouitohex(oui) + " is in the wrong byte order\n").c_str());
		printf("  %s, OUI %s:\n", data_block.c_str(), ouitohex(oui).c_str());
		if (oui == 0x000c03) {
			cta_hdmi_block(x + 1, length);
			cta.last_block_was_hdmi_vsdb = 1;
			cta.first_block = 0;
			// The HDMI OUI is present, so this EDID represents an HDMI
			// interface. And HDMI interfaces must use EDID version 1.3
			// according to the HDMI Specification, so check for this.
			if (base.edid_minor != 3)
				fail("The HDMI Specification requires EDID 1.3 instead of 1.%u.\n",
				     base.edid_minor);
			return;
		}
		if (oui == 0xc45dd8) {
			if (!cta.last_block_was_hdmi_vsdb)
				fail("HDMI Forum VSDB did not immediately follow the HDMI VSDB.\n");
			if (cta.have_hf_scdb || cta.have_hf_vsdb)
				fail("Duplicate HDMI Forum VSDB/SCDB.\n");
			cta_hf_scdb(x + 4, length - 3);
			cta.have_hf_vsdb = 1;
			break;
		}
		if (oui == 0x00001a) {
			cta_amd(x + 4, length - 3);
			break;
		}
		if (oui == 0xca125c && length == 0x15) {
			cta_microsoft(x + 4, length - 3);
			break;
		}
		hex_block("    ", x + 4, length - 3);
		break;
	case 0x04:
		data_block = "Speaker Allocation Data Block";
		printf("  %s:\n", data_block.c_str());
		cta_sadb(x + 1, length);
		audio_block = true;
		if (duplicate)
			fail("Only one instance of this Data Block is allowed.\n");
		break;
	case 0x05:
		data_block = "VESA Display Transfer Characteristics Data Block";
		printf("  %s:\n", data_block.c_str());
		cta_vesa_dtcdb(x + 1, length);
		if (duplicate)
			fail("Only one instance of this Data Block is allowed.\n");
		break;
	case 0x07:
		cta_ext_block(x + 1, length - 1, duplicate);
		break;
	default: {
		unsigned tag = (*x & 0xe0) >> 5;
		unsigned length = *x & 0x1f;

		printf("  Unknown CTA-861 tag 0x%02x, length %u\n", tag, length);
		hex_block("    ", x + 1, length);
		data_block.clear();
		warn("Unknown CTA-861 Data Block %u.\n", tag);
		break;
	}
	}

	// See Table 52 of CTA-861-G for a description of Byte 3
	if (audio_block && !(cta.byte3 & 0x40))
		fail("audio information is present, but bit 6 of Byte 3 of the CTA-861 Extension header indicates no Basic Audio support.\n");
	cta.first_block = 0;
	cta.last_block_was_hdmi_vsdb = 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1e0, %rsp            # imm = 0x1E0
movb %dl, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
andb $0x1, %al
movb %al, -0x11(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x1a0(%rbp)
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
andl $0x1f, %eax
movl %eax, -0x18(%rbp)
movb $0x0, -0x25(%rbp)
movb $0x0, -0x26(%rbp)
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
shrl $0x5, %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x198(%rbp)
subl $0x6, %eax
ja 0x1c9b5
movq -0x198(%rbp), %rax
leaq 0x19cfe(%rip), %rcx     # 0x35f94
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x1a0(%rbp), %rdi
addq $0x30, %rdi
leaq 0x1e36b(%rip), %rsi     # 0x3a61c
callq 0x4420
movq -0x1a0(%rbp), %rdi
addq $0x30, %rdi
callq 0x4150
movq %rax, %rsi
leaq 0x17e21(%rip), %rdi     # 0x340f1
movb $0x0, %al
callq 0x4050
movq -0x10(%rbp), %rdi
addq $0x1, %rdi
movl -0x18(%rbp), %esi
callq 0x1caa0
movb $0x1, -0x26(%rbp)
jmp 0x1ca42
movq -0x1a0(%rbp), %rdi
addq $0x30, %rdi
leaq 0x1e2ae(%rip), %rsi     # 0x3a5b0
callq 0x4420
movq -0x1a0(%rbp), %rdi
addq $0x30, %rdi
callq 0x4150
movq %rax, %rsi
leaq 0x17dd0(%rip), %rdi     # 0x340f1
movb $0x0, %al
callq 0x4050
movq -0x1a0(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x1, %rsi
movl -0x18(%rbp), %edx
xorl %ecx, %ecx
callq 0x15860
jmp 0x1ca42
movq -0x10(%rbp), %rax
movzbl 0x3(%rax), %eax
shll $0x10, %eax
movq -0x10(%rbp), %rcx
movzbl 0x2(%rcx), %ecx
shll $0x8, %ecx
addl %ecx, %eax
movq -0x10(%rbp), %rcx
movzbl 0x1(%rcx), %ecx
addl %ecx, %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %edi
xorl %esi, %esi
callq 0x75c0
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0x1c39e
movl -0x24(%rbp), %edi
movl $0x1, %esi
callq 0x75c0
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x1c39c
movb $0x1, -0x25(%rbp)
jmp 0x1c39e
cmpq $0x0, -0x20(%rbp)
jne 0x1c499
movl -0x24(%rbp), %esi
leaq -0x48(%rbp), %rdi
movq %rdi, -0x1a8(%rbp)
callq 0x7770
movq -0x1a8(%rbp), %rdi
callq 0x4150
movq %rax, %rsi
leaq 0x1e756(%rip), %rdi     # 0x3ab28
xorl %eax, %eax
callq 0x4050
jmp 0x1c3db
leaq -0x48(%rbp), %rdi
callq 0x41f0
movq -0x10(%rbp), %rsi
addq $0x4, %rsi
movl -0x18(%rbp), %edx
addl $-0x3, %edx
leaq 0x183e6(%rip), %rdi     # 0x347df
movl $0x1, %ecx
movl %ecx, -0x1ac(%rbp)
movl $0x10, %r8d
callq 0x7860
movq -0x1a0(%rbp), %rdi
addq $0x30, %rdi
callq 0x4400
movl -0x24(%rbp), %esi
leaq -0x78(%rbp), %rdi
movq %rdi, -0x1b8(%rbp)
callq 0x7770
movq -0x1b8(%rbp), %rdi
callq 0x4150
movl -0x1ac(%rbp), %edi
movq %rax, %rdx
leaq 0x1e701(%rip), %rsi     # 0x3ab4f
xorl %eax, %eax
callq 0x47d0
jmp 0x1c457
leaq -0x78(%rbp), %rdi
callq 0x41f0
jmp 0x1ca83
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x41f0
jmp 0x1ca8c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x41f0
jmp 0x1ca8c
leaq -0xd9(%rbp), %rdi
movq %rdi, -0x1c0(%rbp)
callq 0x4560
movq -0x1c0(%rbp), %rdx
leaq 0x1e6c2(%rip), %rsi     # 0x3ab7c
leaq -0xd8(%rbp), %rdi
callq 0xb510
jmp 0x1c4c8
movq -0x20(%rbp), %rdx
leaq -0xb8(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0xb4c0
jmp 0x1c4e1
leaq 0x2042d(%rip), %rdx     # 0x3c915
leaq -0x98(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0xb4c0
jmp 0x1c4fd
movq -0x1a0(%rbp), %rdi
addq $0x30, %rdi
leaq -0x98(%rbp), %rsi
callq 0x43d0
leaq -0x98(%rbp), %rdi
callq 0x41f0
leaq -0xb8(%rbp), %rdi
callq 0x41f0
leaq -0xd8(%rbp), %rdi
callq 0x41f0
leaq -0xd9(%rbp), %rdi
callq 0x4370
testb $0x1, -0x25(%rbp)
je 0x1c6f8
leaq -0x141(%rbp), %rdi
movq %rdi, -0x1c8(%rbp)
callq 0x4560
movq -0x1c8(%rbp), %rdx
leaq 0x24554(%rip), %rsi     # 0x40ac3
leaq -0x140(%rbp), %rdi
callq 0xb510
jmp 0x1c57d
movl -0x24(%rbp), %esi
leaq -0x168(%rbp), %rdi
callq 0x7770
jmp 0x1c58e
leaq -0x120(%rbp), %rdi
leaq -0x140(%rbp), %rsi
leaq -0x168(%rbp), %rdx
callq 0xb7b0
jmp 0x1c5aa
leaq 0x1e3d7(%rip), %rdx     # 0x3a988
leaq -0x100(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0xb4c0
jmp 0x1c5c6
leaq -0x100(%rbp), %rdi
callq 0x4150
movq %rax, %rsi
xorl %edi, %edi
movb %dil, %al
callq 0x47d0
jmp 0x1c5e1
leaq -0x100(%rbp), %rdi
callq 0x41f0
leaq -0x120(%rbp), %rdi
callq 0x41f0
leaq -0x168(%rbp), %rdi
callq 0x41f0
leaq -0x140(%rbp), %rdi
callq 0x41f0
leaq -0x141(%rbp), %rdi
callq 0x4370
jmp 0x1c6f8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x1c662
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x1c656
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x41f0
leaq -0xd8(%rbp), %rdi
callq 0x41f0
leaq -0xd9(%rbp), %rdi
callq 0x4370
jmp 0x1ca8c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x1c6e7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x1c6db
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x1c6cf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x1c6c3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x41f0
leaq -0x120(%rbp), %rdi
callq 0x41f0
leaq -0x168(%rbp), %rdi
callq 0x41f0
leaq -0x140(%rbp), %rdi
callq 0x41f0
leaq -0x141(%rbp), %rdi
callq 0x4370
jmp 0x1ca8c
movq -0x1a0(%rbp), %rdi
addq $0x30, %rdi
callq 0x4150
movq %rax, -0x1d0(%rbp)
movl -0x24(%rbp), %esi
leaq -0x188(%rbp), %rdi
movq %rdi, -0x1d8(%rbp)
callq 0x7770
movq -0x1d8(%rbp), %rdi
callq 0x4150
movq -0x1d0(%rbp), %rsi
movq %rax, %rdx
leaq 0x1e263(%rip), %rdi     # 0x3a9a5
xorl %eax, %eax
callq 0x4050
jmp 0x1c74b
leaq -0x188(%rbp), %rdi
callq 0x41f0
cmpl $0xc03, -0x24(%rbp)     # imm = 0xC03
jne 0x1c7d6
movq -0x1a0(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x1, %rsi
movl -0x18(%rbp), %edx
callq 0x17060
movq -0x1a0(%rbp), %rax
movb $0x1, 0x2d2(%rax)
movb $0x0, 0x2d5(%rax)
cmpl $0x3, 0x88(%rax)
je 0x1c7d1
movq -0x1a0(%rbp), %rax
movl 0x88(%rax), %edx
xorl %edi, %edi
leaq 0x1e3ee(%rip), %rsi     # 0x3ab99
movb $0x0, %al
callq 0x47d0
jmp 0x1c7d1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x188(%rbp), %rdi
callq 0x41f0
jmp 0x1ca8c
jmp 0x1ca83
cmpl $0xc45dd8, -0x24(%rbp)  # imm = 0xC45DD8
jne 0x1c855
movq -0x1a0(%rbp), %rax
testb $0x1, 0x2d2(%rax)
jne 0x1c7ff
xorl %edi, %edi
leaq 0x1e3dc(%rip), %rsi     # 0x3abd4
movb $0x0, %al
callq 0x47d0
movq -0x1a0(%rbp), %rax
testb $0x1, 0x2d4(%rax)
jne 0x1c81f
movq -0x1a0(%rbp), %rax
testb $0x1, 0x2d3(%rax)
je 0x1c82f
xorl %edi, %edi
leaq 0x1e295(%rip), %rsi     # 0x3aabd
movb $0x0, %al
callq 0x47d0
movq -0x10(%rbp), %rdi
addq $0x4, %rdi
movl -0x18(%rbp), %esi
subl $0x3, %esi
callq 0x1bcb0
movq -0x1a0(%rbp), %rax
movb $0x1, 0x2d3(%rax)
jmp 0x1ca42
cmpl $0x1a, -0x24(%rbp)
jne 0x1c873
movq -0x10(%rbp), %rdi
addq $0x4, %rdi
movl -0x18(%rbp), %esi
subl $0x3, %esi
callq 0x1d1a0
jmp 0x1ca42
cmpl $0xca125c, -0x24(%rbp)  # imm = 0xCA125C
jne 0x1c89a
cmpl $0x15, -0x18(%rbp)
jne 0x1c89a
movq -0x10(%rbp), %rdi
addq $0x4, %rdi
movl -0x18(%rbp), %esi
subl $0x3, %esi
callq 0x1d440
jmp 0x1ca42
movq -0x10(%rbp), %rsi
addq $0x4, %rsi
movl -0x18(%rbp), %edx
subl $0x3, %edx
leaq 0x17f30(%rip), %rdi     # 0x347df
movl $0x1, %ecx
movl $0x10, %r8d
callq 0x7860
jmp 0x1ca42
movq -0x1a0(%rbp), %rdi
addq $0x30, %rdi
leaq 0x1e339(%rip), %rsi     # 0x3ac0f
callq 0x4420
movq -0x1a0(%rbp), %rdi
addq $0x30, %rdi
callq 0x4150
movq %rax, %rsi
leaq 0x177fc(%rip), %rdi     # 0x340f1
movb $0x0, %al
callq 0x4050
movq -0x10(%rbp), %rdi
addq $0x1, %rdi
movl -0x18(%rbp), %esi
callq 0x1d570
movb $0x1, -0x26(%rbp)
testb $0x1, -0x11(%rbp)
je 0x1c926
xorl %edi, %edi
leaq 0x1defd(%rip), %rsi     # 0x3a81c
movb $0x0, %al
callq 0x47d0
jmp 0x1ca42
movq -0x1a0(%rbp), %rdi
addq $0x30, %rdi
leaq 0x1e2f0(%rip), %rsi     # 0x3ac2d
callq 0x4420
movq -0x1a0(%rbp), %rdi
addq $0x30, %rdi
callq 0x4150
movq %rax, %rsi
leaq 0x17795(%rip), %rdi     # 0x340f1
movb $0x0, %al
callq 0x4050
movq -0x10(%rbp), %rdi
addq $0x1, %rdi
movl -0x18(%rbp), %esi
callq 0x1d610
testb $0x1, -0x11(%rbp)
je 0x1c989
xorl %edi, %edi
leaq 0x1de9a(%rip), %rsi     # 0x3a81c
movb $0x0, %al
callq 0x47d0
jmp 0x1ca42
movq -0x1a0(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x1, %rsi
movl -0x18(%rbp), %edx
subl $0x1, %edx
movb -0x11(%rbp), %al
andb $0x1, %al
movzbl %al, %ecx
callq 0x189c0
jmp 0x1ca42
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
andl $0xe0, %eax
sarl $0x5, %eax
movl %eax, -0x18c(%rbp)
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
andl $0x1f, %eax
movl %eax, -0x190(%rbp)
movl -0x18c(%rbp), %esi
movl -0x190(%rbp), %edx
leaq 0x1e271(%rip), %rdi     # 0x3ac5e
movb $0x0, %al
callq 0x4050
movq -0x10(%rbp), %rsi
addq $0x1, %rsi
movl -0x190(%rbp), %edx
leaq 0x17dd6(%rip), %rdi     # 0x347df
movl $0x1, %ecx
movl $0x10, %r8d
callq 0x7860
movq -0x1a0(%rbp), %rdi
addq $0x30, %rdi
callq 0x4400
movl -0x18c(%rbp), %edx
movl $0x1, %edi
leaq 0x1e24c(%rip), %rsi     # 0x3ac87
movb $0x0, %al
callq 0x47d0
testb $0x1, -0x26(%rbp)
je 0x1ca6e
movq -0x1a0(%rbp), %rax
movzbl 0x2c2(%rax), %eax
andl $0x40, %eax
cmpl $0x0, %eax
jne 0x1ca6e
xorl %edi, %edi
leaq 0x1dde7(%rip), %rsi     # 0x3a84e
movb $0x0, %al
callq 0x47d0
movq -0x1a0(%rbp), %rax
movb $0x0, 0x2d5(%rax)
movb $0x0, 0x2d2(%rax)
addq $0x1e0, %rsp            # imm = 0x1E0
popq %rbp
retq
movq -0x50(%rbp), %rdi
callq 0x4550
nopw %cs:(%rax,%rax)