// File: rpavlik[P]edid-decode/parse-cta-block.cpp
// Function: edid_state::cta_sldb(unsigned char const*, unsigned int)
void edid_state::cta_sldb(const unsigned char *x, unsigned length)
{
	if (length < 2) {
		fail("Empty Data Block with length %u.\n", length);
		return;
	}

	unsigned active_cnt = 0;
	unsigned channel_is_active = 0;

	while (length >= 2) {
		printf("    Channel: %u (%sactive)\n", x[0] & 0x1f,
		       (x[0] & 0x20) ? "" : "not ");
		if (x[0] & 0x20) {
			if (channel_is_active & (1U << (x[0] & 0x1f)))
				fail("Channel Index %u was already marked 'Active'.\n",
				     x[0] & 0x1f);
			channel_is_active |= 1U << (x[0] & 0x1f);
			active_cnt++;
		}
		if ((x[1] & 0x1f) < ARRAY_SIZE(speaker_location))
			printf("      Speaker: %s\n", speaker_location[x[1] & 0x1f]);
		if (length >= 5 && (x[0] & 0x40)) {
			printf("      X: %.3f * Xmax\n", decode_uchar_as_double(x[2]));
			printf("      Y: %.3f * Ymax\n", decode_uchar_as_double(x[3]));
			printf("      Z: %.3f * Zmax\n", decode_uchar_as_double(x[4]));
			length -= 3;
			x += 3;
		}

		length -= 2;
		x += 2;
	}
	if (active_cnt != cta.preparsed_speaker_count)
		fail("There are %u active speakers, but 'Speaker Count' is %u.\n",
		     active_cnt, cta.preparsed_speaker_count);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x28(%rbp)
cmpl $0x2, -0x14(%rbp)
jae 0x181c9
movl -0x14(%rbp), %edx
xorl %edi, %edi
leaq 0x213f2(%rip), %rsi     # 0x395af
movb $0x0, %al
callq 0x47d0
jmp 0x18379
movl $0x0, -0x18(%rbp)
movl $0x0, -0x1c(%rbp)
cmpl $0x2, -0x14(%rbp)
jb 0x1834d
movq -0x10(%rbp), %rax
movzbl (%rax), %esi
andl $0x1f, %esi
movq -0x10(%rbp), %rax
movzbl (%rax), %ecx
andl $0x20, %ecx
leaq 0x29448(%rip), %rdx     # 0x41644
leaq 0x17cb6(%rip), %rax     # 0x2feb9
cmpl $0x0, %ecx
cmovneq %rax, %rdx
leaq 0x21e63(%rip), %rdi     # 0x3a074
movb $0x0, %al
callq 0x4050
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0x1827e
movl -0x1c(%rbp), %eax
movq -0x10(%rbp), %rcx
movzbl (%rcx), %ecx
andl $0x1f, %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x1825e
movq -0x10(%rbp), %rax
movzbl (%rax), %edx
andl $0x1f, %edx
xorl %edi, %edi
leaq 0x21e39(%rip), %rsi     # 0x3a090
movb $0x0, %al
callq 0x47d0
movq -0x10(%rbp), %rax
movzbl (%rax), %ecx
andl $0x1f, %ecx
movl $0x1, %eax
shll %cl, %eax
orl -0x1c(%rbp), %eax
movl %eax, -0x1c(%rbp)
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movzbl 0x1(%rax), %eax
andl $0x1f, %eax
cltq
cmpq $0x1c, %rax
jae 0x182b8
movq -0x10(%rbp), %rax
movzbl 0x1(%rax), %eax
andl $0x1f, %eax
movslq %eax, %rcx
leaq 0x334aa(%rip), %rax     # 0x4b750
movq (%rax,%rcx,8), %rsi
leaq 0x21e0e(%rip), %rdi     # 0x3a0bf
movb $0x0, %al
callq 0x4050
cmpl $0x5, -0x14(%rbp)
jb 0x18333
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
andl $0x40, %eax
cmpl $0x0, %eax
je 0x18333
movq -0x10(%rbp), %rax
movzbl 0x2(%rax), %edi
callq 0x18160
leaq 0x21df1(%rip), %rdi     # 0x3a0d2
movb $0x1, %al
callq 0x4050
movq -0x10(%rbp), %rax
movzbl 0x3(%rax), %edi
callq 0x18160
leaq 0x21dec(%rip), %rdi     # 0x3a0e8
movb $0x1, %al
callq 0x4050
movq -0x10(%rbp), %rax
movzbl 0x4(%rax), %edi
callq 0x18160
leaq 0x21de7(%rip), %rdi     # 0x3a0fe
movb $0x1, %al
callq 0x4050
movl -0x14(%rbp), %eax
subl $0x3, %eax
movl %eax, -0x14(%rbp)
movq -0x10(%rbp), %rax
addq $0x3, %rax
movq %rax, -0x10(%rbp)
movl -0x14(%rbp), %eax
subl $0x2, %eax
movl %eax, -0x14(%rbp)
movq -0x10(%rbp), %rax
addq $0x2, %rax
movq %rax, -0x10(%rbp)
jmp 0x181d7
movq -0x28(%rbp), %rcx
movl -0x18(%rbp), %eax
cmpl 0x2c8(%rcx), %eax
je 0x18379
movq -0x28(%rbp), %rax
movl -0x18(%rbp), %edx
movl 0x2c8(%rax), %ecx
xorl %edi, %edi
leaq 0x21da2(%rip), %rsi     # 0x3a114
movb $0x0, %al
callq 0x47d0
addq $0x30, %rsp
popq %rbp
retq
nop