// File: rpavlik[P]edid-decode/parse-displayid-block.cpp
// Function: edid_state::parse_displayid_tiled_display_topology(unsigned char const*, bool)
void edid_state::parse_displayid_tiled_display_topology(const unsigned char *x, bool is_v2)
{
	check_displayid_datablock_revision(x[1]);

	if (!check_displayid_datablock_length(x, 22, 22))
		return;

	unsigned caps = x[3];
	unsigned num_v_tile = (x[4] & 0xf) | (x[6] & 0x30);
	unsigned num_h_tile = (x[4] >> 4) | ((x[6] >> 2) & 0x30);
	unsigned tile_v_location = (x[5] & 0xf) | ((x[6] & 0x3) << 4);
	unsigned tile_h_location = (x[5] >> 4) | (((x[6] >> 2) & 0x3) << 4);
	unsigned tile_width = x[7] | (x[8] << 8);
	unsigned tile_height = x[9] | (x[10] << 8);
	unsigned pix_mult = x[11];

	printf("    Capabilities:\n");
	printf("      Behavior if it is the only tile: ");
	switch (caps & 0x07) {
	case 0x00: printf("Undefined\n"); break;
	case 0x01: printf("Image is displayed at the Tile Location\n"); break;
	case 0x02: printf("Image is scaled to fit the entire tiled display\n"); break;
	case 0x03: printf("Image is cloned to all other tiles\n"); break;
	default: printf("Reserved\n"); break;
	}
	printf("      Behavior if more than one tile and fewer than total number of tiles: ");
	switch ((caps >> 3) & 0x03) {
	case 0x00: printf("Undefined\n"); break;
	case 0x01: printf("Image is displayed at the Tile Location\n"); break;
	default: printf("Reserved\n"); break;
	}
	if (caps & 0x80)
		printf("    Tiled display consists of a single physical display enclosure\n");
	else
		printf("    Tiled display consists of multiple physical display enclosures\n");
	printf("    Num horizontal tiles: %u Num vertical tiles: %u\n",
	       num_h_tile + 1, num_v_tile + 1);
	printf("    Tile location: %u, %u\n", tile_h_location, tile_v_location);
	printf("    Tile resolution: %ux%u\n", tile_width + 1, tile_height + 1);
	if (caps & 0x40) {
		if (pix_mult) {
			printf("    Top bevel size: %.1f pixels\n",
			       pix_mult * x[12] / 10.0);
			printf("    Bottom bevel size: %.1f pixels\n",
			       pix_mult * x[13] / 10.0);
			printf("    Right bevel size: %.1f pixels\n",
			       pix_mult * x[14] / 10.0);
			printf("    Left bevel size: %.1f pixels\n",
			       pix_mult * x[15] / 10.0);
		} else {
			fail("No bevel information, but the pixel multiplier is non-zero.\n");
		}
		printf("    Tile resolution: %ux%u\n", tile_width + 1, tile_height + 1);
	} else if (pix_mult) {
		fail("No bevel information, but the pixel multiplier is non-zero.\n");
	}
	if (is_v2)
		printf("    Tiled Display Manufacturer/Vendor ID: %02X-%02X-%02X\n",
		       x[0x10], x[0x11], x[0x12]);
	else
		printf("    Tiled Display Manufacturer/Vendor ID: %c%c%c\n",
		       x[0x10], x[0x11], x[0x12]);
	printf("    Tiled Display Product ID Code: %u\n",
	       x[0x13] | (x[0x14] << 8));
	if (hide_serial_numbers)
		printf("    Tiled Display Serial Number: ...\n");
	else
		printf("    Tiled Display Serial Number: %u\n",
		       x[0x15] | (x[0x16] << 8) | (x[0x17] << 16)| (x[0x18] << 24));
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movb %dl, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
andb $0x1, %al
movb %al, -0x11(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x40(%rbp)
movq -0x10(%rbp), %rax
xorl %ecx, %ecx
movzbl 0x1(%rax), %esi
movl %ecx, %edx
callq 0x21b00
movq -0x10(%rbp), %rdi
movl $0x16, %edx
xorl %ecx, %ecx
movl %edx, %esi
callq 0x21f90
testb $0x1, %al
jne 0x25acb
jmp 0x25e9f
movq -0x10(%rbp), %rax
movzbl 0x3(%rax), %eax
movl %eax, -0x18(%rbp)
movq -0x10(%rbp), %rcx
movzbl 0x4(%rcx), %eax
andl $0xf, %eax
movzbl 0x6(%rcx), %ecx
andl $0x30, %ecx
orl %ecx, %eax
movl %eax, -0x1c(%rbp)
movq -0x10(%rbp), %rcx
movzbl 0x4(%rcx), %eax
shrl $0x4, %eax
movzbl 0x6(%rcx), %ecx
shrl $0x2, %ecx
andl $0x30, %ecx
orl %ecx, %eax
movl %eax, -0x20(%rbp)
movq -0x10(%rbp), %rcx
movzbl 0x5(%rcx), %eax
andl $0xf, %eax
movzbl 0x6(%rcx), %ecx
andl $0x3, %ecx
shll $0x4, %ecx
orl %ecx, %eax
movl %eax, -0x24(%rbp)
movq -0x10(%rbp), %rax
movzbl 0x5(%rax), %edx
shrl $0x4, %edx
movzbl 0x6(%rax), %eax
andl $0xc, %eax
movl %eax, %ecx
movl %edx, %eax
leal (%rax,%rcx,4), %eax
movl %eax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movzwl 0x7(%rax), %eax
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movzwl 0x9(%rax), %eax
movl %eax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movzbl 0xb(%rax), %eax
movl %eax, -0x34(%rbp)
leaq 0x19b37(%rip), %rdi     # 0x3f69c
xorl %eax, %eax
movb %al, -0x49(%rbp)
callq 0x4050
movb -0x49(%rbp), %al
leaq 0x19b36(%rip), %rdi     # 0x3f6af
callq 0x4050
movl -0x18(%rbp), %eax
andl $0x7, %eax
movl %eax, %ecx
movq %rcx, -0x48(%rbp)
subl $0x3, %eax
ja 0x25be3
movq -0x48(%rbp), %rax
leaq 0x18202(%rip), %rcx     # 0x3dd9c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x16170(%rip), %rdi     # 0x3bd1a
movb $0x0, %al
callq 0x4050
jmp 0x25bf1
leaq 0x19b1d(%rip), %rdi     # 0x3f6d7
movb $0x0, %al
callq 0x4050
jmp 0x25bf1
leaq 0x19b36(%rip), %rdi     # 0x3f700
movb $0x0, %al
callq 0x4050
jmp 0x25bf1
leaq 0x19b57(%rip), %rdi     # 0x3f731
movb $0x0, %al
callq 0x4050
jmp 0x25bf1
leaq 0x19a3a(%rip), %rdi     # 0x3f624
movb $0x0, %al
callq 0x4050
leaq 0x19b5d(%rip), %rdi     # 0x3f755
xorl %eax, %eax
callq 0x4050
movl -0x18(%rbp), %eax
shrl $0x3, %eax
andl $0x3, %eax
movl %eax, -0x50(%rbp)
je 0x25c19
jmp 0x25c0f
movl -0x50(%rbp), %eax
subl $0x1, %eax
je 0x25c29
jmp 0x25c39
leaq 0x160fa(%rip), %rdi     # 0x3bd1a
movb $0x0, %al
callq 0x4050
jmp 0x25c47
leaq 0x19aa7(%rip), %rdi     # 0x3f6d7
movb $0x0, %al
callq 0x4050
jmp 0x25c47
leaq 0x199e4(%rip), %rdi     # 0x3f624
movb $0x0, %al
callq 0x4050
movl -0x18(%rbp), %eax
andl $0x80, %eax
cmpl $0x0, %eax
je 0x25c64
leaq 0x19b46(%rip), %rdi     # 0x3f7a1
movb $0x0, %al
callq 0x4050
jmp 0x25c72
leaq 0x19b79(%rip), %rdi     # 0x3f7e4
movb $0x0, %al
callq 0x4050
movl -0x20(%rbp), %esi
addl $0x1, %esi
movl -0x1c(%rbp), %edx
addl $0x1, %edx
leaq 0x19ba3(%rip), %rdi     # 0x3f828
movb $0x0, %al
callq 0x4050
movl -0x28(%rbp), %esi
movl -0x24(%rbp), %edx
leaq 0x19bc4(%rip), %rdi     # 0x3f85d
movb $0x0, %al
callq 0x4050
movl -0x2c(%rbp), %esi
addl $0x1, %esi
movl -0x30(%rbp), %edx
addl $0x1, %edx
leaq 0x19bc5(%rip), %rdi     # 0x3f878
movb $0x0, %al
callq 0x4050
movl -0x18(%rbp), %eax
andl $0x40, %eax
cmpl $0x0, %eax
je 0x25db9
cmpl $0x0, -0x34(%rbp)
je 0x25d8d
movl -0x34(%rbp), %eax
movq -0x10(%rbp), %rcx
movzbl 0xc(%rcx), %ecx
imull %ecx, %eax
cvtsi2sd %rax, %xmm0
movsd 0x17e6a(%rip), %xmm1    # 0x3db58
movsd %xmm1, -0x60(%rbp)
divsd %xmm1, %xmm0
leaq 0x19b96(%rip), %rdi     # 0x3f894
movb $0x1, %al
movb %al, -0x51(%rbp)
callq 0x4050
movsd -0x60(%rbp), %xmm1
movb -0x51(%rbp), %al
movl -0x34(%rbp), %ecx
movq -0x10(%rbp), %rdx
movzbl 0xd(%rdx), %edx
imull %edx, %ecx
cvtsi2sd %rcx, %xmm0
divsd %xmm1, %xmm0
leaq 0x19b87(%rip), %rdi     # 0x3f8b5
callq 0x4050
movsd -0x60(%rbp), %xmm1
movb -0x51(%rbp), %al
movl -0x34(%rbp), %ecx
movq -0x10(%rbp), %rdx
movzbl 0xe(%rdx), %edx
imull %edx, %ecx
cvtsi2sd %rcx, %xmm0
divsd %xmm1, %xmm0
leaq 0x19b80(%rip), %rdi     # 0x3f8d9
callq 0x4050
movl -0x34(%rbp), %eax
movq -0x10(%rbp), %rcx
movzbl 0xf(%rcx), %ecx
imull %ecx, %eax
cvtsi2sd %rax, %xmm0
movsd 0x17ddf(%rip), %xmm1    # 0x3db58
divsd %xmm1, %xmm0
leaq 0x19b78(%rip), %rdi     # 0x3f8fc
movb $0x1, %al
callq 0x4050
jmp 0x25d9d
xorl %edi, %edi
leaq 0x19b88(%rip), %rsi     # 0x3f91e
movb $0x0, %al
callq 0x47d0
movl -0x2c(%rbp), %esi
addl $0x1, %esi
movl -0x30(%rbp), %edx
addl $0x1, %edx
leaq 0x19ac8(%rip), %rdi     # 0x3f878
movb $0x0, %al
callq 0x4050
jmp 0x25dd1
cmpl $0x0, -0x34(%rbp)
je 0x25dcf
xorl %edi, %edi
leaq 0x19b56(%rip), %rsi     # 0x3f91e
movb $0x0, %al
callq 0x47d0
jmp 0x25dd1
testb $0x1, -0x11(%rbp)
je 0x25dff
movq -0x10(%rbp), %rax
movzbl 0x10(%rax), %esi
movq -0x10(%rbp), %rax
movzbl 0x11(%rax), %edx
movq -0x10(%rbp), %rax
movzbl 0x12(%rax), %ecx
leaq 0x19b65(%rip), %rdi     # 0x3f95b
movb $0x0, %al
callq 0x4050
jmp 0x25e25
movq -0x10(%rbp), %rax
movzbl 0x10(%rax), %esi
movq -0x10(%rbp), %rax
movzbl 0x11(%rax), %edx
movq -0x10(%rbp), %rax
movzbl 0x12(%rax), %ecx
leaq 0x19b77(%rip), %rdi     # 0x3f995
movb $0x0, %al
callq 0x4050
movq -0x10(%rbp), %rax
movzbl 0x13(%rax), %esi
movq -0x10(%rbp), %rax
movzbl 0x14(%rax), %eax
shll $0x8, %eax
orl %eax, %esi
leaq 0x19b86(%rip), %rdi     # 0x3f9c7
movb $0x0, %al
callq 0x4050
movq -0x40(%rbp), %rax
testb $0x1, 0x52(%rax)
je 0x25e62
leaq 0x19b95(%rip), %rdi     # 0x3f9ee
movb $0x0, %al
callq 0x4050
jmp 0x25e9f
movq -0x10(%rbp), %rax
movzbl 0x15(%rax), %esi
movq -0x10(%rbp), %rax
movzbl 0x16(%rax), %eax
shll $0x8, %eax
orl %eax, %esi
movq -0x10(%rbp), %rax
movzbl 0x17(%rax), %eax
shll $0x10, %eax
orl %eax, %esi
movq -0x10(%rbp), %rax
movzbl 0x18(%rax), %eax
shll $0x18, %eax
orl %eax, %esi
leaq 0x19b7c(%rip), %rdi     # 0x3fa14
movb $0x0, %al
callq 0x4050
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)