// File: /workspace/github_cpp_makefile_star2_O3/rpavlik[P]edid-decode/parse-displayid-block.cpp
// Function: edid_state::parse_displayid_transfer_characteristics(unsigned char const*)
void edid_state::parse_displayid_transfer_characteristics(const unsigned char *x)
{
	check_displayid_datablock_revision(x[1], 0xf0, 1);

	unsigned xfer_id = x[1] >> 4;
	bool first_is_white = x[3] & 0x80;
	bool four_param = x[3] & 0x20;

	if (xfer_id) {
		printf("    Transfer Characteristics Data Block Identifier: %u\n", xfer_id);
		if (!(dispid.preparsed_color_ids & (1 << xfer_id)))
			fail("Missing Color Characteristics Data Block using Identifier %u.\n", xfer_id);
	}
	if (first_is_white)
		printf("    The first curve is the 'white' transfer characteristic\n");
	if (x[3] & 0x40)
		printf("    Individual response curves\n");

	unsigned offset = 4;
	unsigned len = x[2] - 1;

	for (unsigned i = 0; len; i++) {
		if ((x[3] & 0x80) && !i)
			printf("    White curve:      ");
		else
			printf("    Response curve #%u:",
			       i - first_is_white);
		unsigned samples = x[offset];
		if (four_param) {
			if (samples != 5)
				fail("Expected 5 samples.\n");
			printf(" A0=%u A1=%u A2=%u A3=%u Gamma=%.2f\n",
			       x[offset + 1], x[offset + 2], x[offset + 3], x[offset + 4],
			       (double)(x[offset + 5] + 100.0) / 100.0);
			samples++;
		} else {
			double sum = 0;

			// The spec is not very clear about the number of samples:
			// should this be interpreted as the actual number of
			// samples stored in this Data Block, or as the number of
			// samples in the curve, but where the last sample is not
			// actually stored since it is always 0x3ff.
			//
			// The ATP Manager interprets this as the latter, so that's
			// what we implement here.
			for (unsigned j = offset + 1; j < offset + samples; j++) {
				sum += x[j];
				printf(" %.2f", sum * 100.0 / 1023.0);
			}
			printf(" 100.00\n");
		}
		offset += samples;
		len -= samples;
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movzbl 0x1(%rsi), %esi
movl $0xf0, %edx
movl $0x1, %ecx
callq 0x1611c
movzbl 0x1(%rbx), %ebp
movzbl 0x3(%rbx), %r15d
cmpl $0x10, %ebp
jb 0x17fb7
shrl $0x4, %ebp
leaq 0x17348(%rip), %rdi     # 0x2f2d7
movl %ebp, %esi
xorl %eax, %eax
callq 0x3030
movzwl 0x912(%r14), %eax
btl %ebp, %eax
jb 0x17fb7
leaq 0x17363(%rip), %rsi     # 0x2f30f
xorl %edi, %edi
movl %ebp, %edx
xorl %eax, %eax
callq 0x37cc
testb %r15b, %r15b
jns 0x17fc8
leaq 0x1935d(%rip), %rdi     # 0x31320
callq 0x3380
testb $0x40, 0x3(%rbx)
je 0x17fda
leaq 0x19386(%rip), %rdi     # 0x3135b
callq 0x3380
movzbl 0x2(%rbx), %r14d
decl %r14d
je 0x1817a
movl %r15d, %eax
shrl $0x7, %eax
movl %eax, 0x8(%rsp)
movl $0x4, %r12d
xorl %ebp, %ebp
movq %rbx, 0x18(%rsp)
movl %r15d, 0xc(%rsp)
cmpb $0x0, 0x3(%rbx)
setns %al
testl %ebp, %ebp
setne %cl
orb %al, %cl
je 0x1802a
movl %ebp, %esi
subl 0x8(%rsp), %esi
leaq 0x17344(%rip), %rdi     # 0x2f365
xorl %eax, %eax
callq 0x3030
jmp 0x18038
leaq 0x1731d(%rip), %rdi     # 0x2f34e
xorl %eax, %eax
callq 0x3030
movl %r12d, %eax
movzbl (%rbx,%rax), %r13d
testb $0x20, %r15b
jne 0x180f5
movl %r14d, 0x14(%rsp)
leal (%r12,%r13), %eax
incl %r12d
movl %eax, 0x10(%rsp)
cmpl %eax, %r12d
movsd 0x7fbb(%rip), %xmm1     # 0x20020
movsd 0x165c3(%rip), %xmm2    # 0x2e630
leaq 0xd726(%rip), %r14      # 0x2579a
jae 0x180d4
movl %r12d, %r12d
addq 0x18(%rsp), %r12
movl %r13d, %r15d
decq %r15
xorpd %xmm3, %xmm3
xorl %ebx, %ebx
movzbl (%r12,%rbx), %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
addsd %xmm0, %xmm3
movsd %xmm3, 0x20(%rsp)
movapd %xmm3, %xmm0
mulsd %xmm1, %xmm0
divsd %xmm2, %xmm0
movq %r14, %rdi
movb $0x1, %al
callq 0x3030
movsd 0x20(%rsp), %xmm3
movsd 0x1656c(%rip), %xmm2    # 0x2e630
movsd 0x7f54(%rip), %xmm1     # 0x20020
incq %rbx
cmpl %ebx, %r15d
jne 0x1808a
leaq 0x1929f(%rip), %rdi     # 0x3137a
callq 0x3380
movq 0x18(%rsp), %rbx
movl 0xc(%rsp), %r15d
movl 0x14(%rsp), %r14d
movl 0x10(%rsp), %ecx
jmp 0x1816c
cmpl $0x5, %r13d
je 0x1810b
xorl %edi, %edi
leaq 0x17279(%rip), %rsi     # 0x2f37d
xorl %eax, %eax
callq 0x37cc
leal 0x1(%r12), %eax
movzbl (%rbx,%rax), %esi
leal 0x2(%r12), %eax
movzbl (%rbx,%rax), %edx
leal 0x3(%r12), %eax
movzbl (%rbx,%rax), %ecx
leal 0x4(%r12), %eax
movzbl (%rbx,%rax), %r8d
leal 0x5(%r12), %eax
movzbl (%rbx,%rax), %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movsd 0x7ed8(%rip), %xmm1     # 0x20020
addsd %xmm1, %xmm0
divsd %xmm1, %xmm0
leaq 0x1723b(%rip), %rdi     # 0x2f392
movb $0x1, %al
callq 0x3030
leal (%r12,%r13), %ecx
incl %ecx
movl %r13d, %eax
incl %eax
movl %eax, %r13d
incl %ebp
movl %ecx, %r12d
subl %r13d, %r14d
jne 0x18004
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop