// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/twiboot.c
// Function: twi_open
static int twi_open(struct multiboot *mboot)
{
    struct twi_privdata *twi = (struct twi_privdata *)mboot->privdata;

    if (twi->address == 0)
    {
        fprintf(stderr, "abort: no address given\n");
        return -1;
    }

    if (twi->device == NULL)
    {
        twi->device = strdup(TWI_DEFAULT_DEVICE);
        if (twi->device == NULL)
        {
            perror("strdup()");
            return -1;
        }
    }

    if (twi_open_device(twi) != 0)
    {
        return -1;
    }

    if (twi_switch_application(twi, BOOTTYPE_BOOTLOADER))
    {
        fprintf(stderr, "failed to switch to bootloader (invalid address?): %s\n",
                strerror(errno));

        twi_close(mboot);
        return -1;
    }

    /* wait for watchdog and startup time */
    usleep(100000);

    char version[16 +1];
    if (twi_read_version(twi, version, sizeof(version) -1))
    {
        fprintf(stderr, "failed to get bootloader version: %s\n",
                strerror(errno));

        twi_close(mboot);
        return -1;
    }

    version[16] = '\0';

    uint8_t chipinfo[8];
    if (twi_read_memory(twi, chipinfo, sizeof(chipinfo), MEMTYPE_CHIPINFO, 0x0000))
    {
        fprintf(stderr, "failed to get chipinfo: %s\n", strerror(errno));
        twi_close(mboot);
        return -1;
    }

    const char *chipname = chipinfo_get_avr_name(chipinfo);

    twi->pagesize   = chipinfo[3];
    twi->flashsize  = (chipinfo[4] << 8) + chipinfo[5];
    twi->eepromsize = (chipinfo[6] << 8) + chipinfo[7];

    printf("device         : %-16s (address: 0x%02X)\n",
           twi->device, twi->address);

    printf("version        : %-16s (sig: 0x%02x 0x%02x 0x%02x => %s)\n",
           version, chipinfo[0], chipinfo[1], chipinfo[2], chipname);

    printf("flash size     : 0x%04x / %5d   (0x%02x bytes/page)\n",
           twi->flashsize, twi->flashsize, twi->pagesize);

    printf("eeprom size    : 0x%04x / %5d\n",
           twi->eepromsize, twi->eepromsize);

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x28, %rsp
movq 0x8(%rdi), %rbx
cmpb $0x0, 0x8(%rbx)
je 0x6ab2
movq %rdi, %r14
movq (%rbx), %rdi
testq %rdi, %rdi
jne 0x690a
leaq 0x2e7a(%rip), %rdi      # 0x9770
callq 0x2290
movq %rax, %rdi
movq %rax, (%rbx)
testq %rax, %rax
je 0x6bce
pushq $0x2
popq %rsi
xorl %eax, %eax
callq 0x2210
movl %eax, 0xc(%rbx)
testl %eax, %eax
js 0x6ad3
leaq 0x10(%rsp), %rdx
movl $0x705, %esi            # imm = 0x705
movl %eax, %edi
xorl %eax, %eax
callq 0x2130
testl %eax, %eax
jne 0x6b08
testb $0x1, 0x10(%rsp)
je 0x6b16
movl 0xc(%rbx), %edi
movzbl 0x8(%rbx), %edx
movl $0x703, %esi            # imm = 0x703
xorl %eax, %eax
callq 0x2130
testl %eax, %eax
js 0x6b33
movl $0x1, 0x10(%rbx)
movq %rbx, %rdi
xorl %esi, %esi
callq 0x7088
testl %eax, %eax
jne 0x6b6d
movl $0x186a0, %edi          # imm = 0x186A0
callq 0x22c0
leaq 0x8(%rsp), %rsi
movb $0x1, (%rsi)
movl 0xc(%rbx), %edi
pushq $0x1
popq %rdx
callq 0x7110
cmpl $0x1, %eax
jne 0x6a90
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %rsi
movaps %xmm0, (%rsi)
movl 0xc(%rbx), %edi
pushq $0x10
popq %rdx
callq 0x2150
cmpq $0x10, %rax
jne 0x6a90
xorl %eax, %eax
cmpq $0x10, %rax
je 0x69d1
andb $0x7f, 0x10(%rsp,%rax)
incq %rax
jmp 0x69c1
movb $0x0, 0x20(%rsp)
leaq 0x8(%rsp), %rsi
pushq $0x8
popq %rdx
xorl %ebp, %ebp
movq %rbx, %rdi
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x70af
testl %eax, %eax
jne 0x6b8c
leaq 0x8(%rsp), %r14
movq %r14, %rdi
callq 0x2eb8
movb 0x3(%r14), %cl
movb %cl, 0x18(%rbx)
movzwl 0x4(%r14), %ecx
rolw $0x8, %cx
movw %cx, 0x1a(%rbx)
movzwl 0x6(%r14), %ecx
rolw $0x8, %cx
movq %rax, %r15
movw %cx, 0x1c(%rbx)
movq (%rbx), %rsi
movzbl 0x8(%rbx), %edx
leaq 0x288f(%rip), %rdi      # 0x92c3
xorl %eax, %eax
callq 0x20f0
movzbl (%r14), %edx
movzbl 0x1(%r14), %ecx
movzbl 0x2(%r14), %r8d
leaq 0x2381(%rip), %rdi      # 0x8dd1
leaq 0x10(%rsp), %rsi
movq %r15, %r9
xorl %eax, %eax
callq 0x20f0
movzwl 0x1a(%rbx), %edx
movzbl 0x18(%rbx), %ecx
leaq 0x239d(%rip), %rdi      # 0x8e0b
movl %edx, %esi
xorl %eax, %eax
callq 0x20f0
movzwl 0x1c(%rbx), %edx
leaq 0x197a(%rip), %rdi      # 0x83fc
movl %edx, %esi
xorl %eax, %eax
callq 0x20f0
jmp 0x6bc1
movq 0x6561(%rip), %rax      # 0xcff8
movq (%rax), %rbx
callq 0x2060
movl (%rax), %edi
callq 0x22a0
leaq 0x2d05(%rip), %rsi      # 0x97b2
jmp 0x6ba9
movq 0x653f(%rip), %rax      # 0xcff8
movq (%rax), %rcx
leaq 0x2212(%rip), %rdi      # 0x8cd5
pushq $0x18
popq %rsi
pushq $0x1
popq %rdx
callq 0x2280
jmp 0x6bbe
movq 0x651e(%rip), %rax      # 0xcff8
movq (%rax), %r14
movq (%rbx), %rbx
callq 0x2060
movl (%rax), %edi
callq 0x22a0
leaq 0x2d01(%rip), %rsi      # 0x97f4
movq %r14, %rdi
movq %rbx, %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x2180
jmp 0x6bbe
leaq 0x2cfe(%rip), %rdi      # 0x980d
callq 0x2240
jmp 0x6b63
movq 0x64db(%rip), %rax      # 0xcff8
movq (%rax), %rdi
movq (%rbx), %rdx
leaq 0x2cf4(%rip), %rsi      # 0x981e
xorl %eax, %eax
callq 0x2180
jmp 0x6b63
movq 0x64be(%rip), %rax      # 0xcff8
movq (%rax), %r14
movzbl 0x8(%rbx), %ebp
callq 0x2060
movl (%rax), %edi
callq 0x22a0
leaq 0x2cef(%rip), %rsi      # 0x9843
movq %r14, %rdi
movl %ebp, %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x2180
movl 0xc(%rbx), %edi
callq 0x2140
jmp 0x6bbe
movq 0x6484(%rip), %rax      # 0xcff8
movq (%rax), %rbx
callq 0x2060
movl (%rax), %edi
callq 0x22a0
leaq 0x2bf1(%rip), %rsi      # 0x977b
jmp 0x6ba9
movq 0x6465(%rip), %rax      # 0xcff8
movq (%rax), %rbx
callq 0x2060
movl (%rax), %edi
callq 0x22a0
leaq 0x2c2f(%rip), %rsi      # 0x97d8
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x2180
movq %r14, %rdi
callq 0x6bdc
pushq $-0x1
popq %rbp
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x14a5(%rip), %rdi      # 0x807a
callq 0x2240
jmp 0x6bbe