// File: rpavlik[P]edid-decode/parse-vtb-ext-block.cpp
// Function: edid_state::parse_vtb_ext_block(unsigned char const*)
void edid_state::parse_vtb_ext_block(const unsigned char *x)
{
	printf("  Version: %u\n", x[1]);
	if (x[1] != 1)
		fail("Invalid version %u.\n", x[1]);

	unsigned num_dtd = x[2];
	unsigned num_cvt = x[3];
	unsigned num_st = x[4];

	x += 5;
	if (num_dtd) {
		printf("  Detailed Timing Descriptors:\n");
		for (unsigned i = 0; i < num_dtd; i++, x += 18)
			detailed_timings("    ", x, false);
	}
	if (num_cvt) {
		printf("  Coordinated Video Timings:\n");
		for (unsigned i = 0; i < num_cvt; i++, x += 3)
			detailed_cvt_descriptor("    ", x, false);
	}
	if (num_st) {
		// Note: the VTB-EXT standard has a mistake in the example EDID
		// that it provides: there the refresh rate (bits 5-0 of the
		// second byte) is set to 60 for 60 Hz, but this should be 0
		// since the actual refresh rate is the value + 60.
		//
		// The documentation itself is correct, though.
		printf("  Standard Timings:\n");
		for (unsigned i = 0; i < num_st; i++, x += 2)
			print_standard_timing("    ", x[0], x[1], true);
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movzbl 0x1(%rax), %esi
leaq 0xf72c(%rip), %rdi      # 0x3c5b3
movb $0x0, %al
callq 0x4050
movq -0x10(%rbp), %rax
movzbl 0x1(%rax), %eax
cmpl $0x1, %eax
je 0x2ceb3
movq -0x10(%rbp), %rax
movzbl 0x1(%rax), %edx
xorl %edi, %edi
leaq 0x15c71(%rip), %rsi     # 0x42b1d
movb $0x0, %al
callq 0x47d0
movq -0x10(%rbp), %rax
movzbl 0x2(%rax), %eax
movl %eax, -0x14(%rbp)
movq -0x10(%rbp), %rax
movzbl 0x3(%rax), %eax
movl %eax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movzbl 0x4(%rax), %eax
movl %eax, -0x1c(%rbp)
movq -0x10(%rbp), %rax
addq $0x5, %rax
movq %rax, -0x10(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0x2cf32
leaq 0x15c45(%rip), %rdi     # 0x42b32
movb $0x0, %al
callq 0x4050
movl $0x0, -0x20(%rbp)
movl -0x20(%rbp), %eax
cmpl -0x14(%rbp), %eax
jae 0x2cf30
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x78cd(%rip), %rsi      # 0x347df
xorl %ecx, %ecx
callq 0x10e10
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
movq -0x10(%rbp), %rax
addq $0x12, %rax
movq %rax, -0x10(%rbp)
jmp 0x2cefb
jmp 0x2cf32
cmpl $0x0, -0x18(%rbp)
je 0x2cf84
leaq 0x15c13(%rip), %rdi     # 0x42b52
movb $0x0, %al
callq 0x4050
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
cmpl -0x18(%rbp), %eax
jae 0x2cf82
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x787b(%rip), %rsi      # 0x347df
xorl %ecx, %ecx
callq 0xf0b0
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
movq -0x10(%rbp), %rax
addq $0x3, %rax
movq %rax, -0x10(%rbp)
jmp 0x2cf4d
jmp 0x2cf84
cmpl $0x0, -0x1c(%rbp)
je 0x2cfea
leaq 0x15bdf(%rip), %rdi     # 0x42b70
movb $0x0, %al
callq 0x4050
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jae 0x2cfe8
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rax
movb (%rax), %cl
movq -0x10(%rbp), %rax
leaq 0x7823(%rip), %rsi      # 0x347df
movl $0x1, %r8d
xorl %r9d, %r9d
movzbl %cl, %edx
movzbl 0x1(%rax), %ecx
callq 0xf6f0
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
movq -0x10(%rbp), %rax
addq $0x2, %rax
movq %rax, -0x10(%rbp)
jmp 0x2cf9f
jmp 0x2cfea
addq $0x30, %rsp
popq %rbp
retq