// File: eggnot[P]pixel_camera/matrix/lib/gpio.cc
// Function: rgb_matrix::(anonymous namespace)::HardwarePinPulser::HardwarePinPulser(unsigned int, std::vector<int, std::allocator<int>> const&)
HardwarePinPulser(uint32_t pins, const std::vector<int> &specs) {
    assert(CanHandle(pins));

    for (size_t i = 0; i < specs.size(); ++i) {
      sleep_hints_.push_back(specs[i] / 1000);
    }
    const int base = specs[0];
    // Get relevant registers
    const bool isPI2 = IsRaspberryPi2();
    volatile uint32_t *gpioReg = mmap_bcm_register(isPI2, GPIO_REGISTER_OFFSET);
    pwm_reg_  = mmap_bcm_register(isPI2, GPIO_PWM_BASE_OFFSET);
    clk_reg_  = mmap_bcm_register(isPI2, GPIO_CLK_BASE_OFFSET);
    fifo_ = pwm_reg_ + PWM_FIFO;
    assert((clk_reg_ != NULL) && (pwm_reg_ != NULL));  // init error.

    SetGPIOMode(gpioReg, 18, 2); // set GPIO 18 to PWM0 mode (Alternative 5)
    InitPWMDivider((base/2) / PWM_BASE_TIME_NS);
    for (size_t i = 0; i < specs.size(); ++i) {
      pwm_range_.push_back(2 * specs[i] / base);
    }
  }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x68(%rbp)
callq 0x3490
movq -0x68(%rbp), %rdi
leaq 0xaf72(%rip), %rax      # 0xdaf0
addq $0x10, %rax
movq %rax, (%rdi)
addq $0x8, %rdi
movq %rdi, -0x70(%rbp)
callq 0x34b0
movq -0x68(%rbp), %rdi
addq $0x20, %rdi
movq %rdi, -0x60(%rbp)
callq 0x34d0
movl -0xc(%rbp), %edi
callq 0x2b30
testb $0x1, %al
jne 0x2bb1
jmp 0x2bb3
jmp 0x2bd2
leaq 0x6557(%rip), %rdi      # 0x9111
leaq 0x6560(%rip), %rsi      # 0x9121
movl $0x11c, %edx            # imm = 0x11C
leaq 0x655c(%rip), %rcx      # 0x9129
callq 0x2110
movq $0x0, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x18(%rbp), %rdi
callq 0x34f0
movq %rax, %rcx
movq -0x78(%rbp), %rax
cmpq %rcx, %rax
jae 0x2c75
movq -0x68(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x80(%rbp)
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x3540
movq -0x80(%rbp), %rdi
movslq (%rax), %rax
imulq $0x10624dd3, %rax, %rax # imm = 0x10624DD3
movq %rax, %rcx
shrq $0x3f, %rcx
sarq $0x26, %rax
addl %ecx, %eax
movl %eax, -0x24(%rbp)
leaq -0x24(%rbp), %rsi
callq 0x3510
jmp 0x2c39
jmp 0x2c3b
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x2bda
movq -0x60(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
callq 0x3590
movq -0x70(%rbp), %rdi
callq 0x35f0
movq -0x68(%rbp), %rdi
callq 0x3650
jmp 0x2e28
movq -0x18(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x3540
movl (%rax), %eax
movl %eax, -0x38(%rbp)
callq 0x28d0
movb %al, -0x81(%rbp)
jmp 0x2c94
movb -0x81(%rbp), %al
andb $0x1, %al
movb %al, -0x39(%rbp)
movzbl -0x39(%rbp), %edi
andl $0x1, %edi
movl $0x200000, %esi         # imm = 0x200000
callq 0x27f0
movq %rax, -0x90(%rbp)
jmp 0x2cb9
movq -0x90(%rbp), %rax
movq %rax, -0x48(%rbp)
movzbl -0x39(%rbp), %edi
andl $0x1, %edi
movl $0x20c000, %esi         # imm = 0x20C000
callq 0x27f0
movq %rax, -0x98(%rbp)
jmp 0x2cde
movq -0x68(%rbp), %rax
movq -0x98(%rbp), %rcx
movq %rcx, 0x38(%rax)
movzbl -0x39(%rbp), %edi
andl $0x1, %edi
movl $0x101000, %esi         # imm = 0x101000
callq 0x27f0
movq %rax, -0xa0(%rbp)
jmp 0x2d07
movq -0x68(%rbp), %rcx
movq -0xa0(%rbp), %rax
movq %rax, 0x48(%rcx)
movq 0x38(%rcx), %rax
addq $0x18, %rax
movq %rax, 0x40(%rcx)
xorl %eax, %eax
cmpq $0x0, 0x48(%rcx)
movb %al, -0xa1(%rbp)
je 0x2d43
movq -0x68(%rbp), %rax
cmpq $0x0, 0x38(%rax)
setne %al
movb %al, -0xa1(%rbp)
movb -0xa1(%rbp), %al
testb $0x1, %al
jne 0x2d4f
jmp 0x2d51
jmp 0x2d70
leaq 0x643d(%rip), %rdi      # 0x9195
leaq 0x63c2(%rip), %rsi      # 0x9121
movl $0x128, %edx            # imm = 0x128
leaq 0x63be(%rip), %rcx      # 0x9129
callq 0x2110
movq -0x68(%rbp), %rdi
movq -0x48(%rbp), %rsi
movl $0x12, %edx
movl $0x2, %ecx
callq 0x2f40
jmp 0x2d89
movq -0x68(%rbp), %rdi
movl -0x38(%rbp), %eax
movl %eax, %ecx
shrl $0x1f, %ecx
addl %ecx, %eax
movl %eax, %esi
sarl %esi
shrl $0x1f, %eax
addl %eax, %esi
sarl %esi
callq 0x2fb0
jmp 0x2da9
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x18(%rbp), %rdi
callq 0x34f0
movq %rax, %rcx
movq -0xb0(%rbp), %rax
cmpq %rcx, %rax
jae 0x2e1f
movq -0x68(%rbp), %rax
addq $0x8, %rax
movq %rax, -0xb8(%rbp)
movq -0x18(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0x3540
movq -0xb8(%rbp), %rdi
movl (%rax), %eax
addl %eax, %eax
movl -0x38(%rbp), %ecx
cltd
idivl %ecx
movl %eax, -0x54(%rbp)
leaq -0x54(%rbp), %rsi
callq 0x3560
jmp 0x2e0f
jmp 0x2e11
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x2db1
addq $0xc0, %rsp
popq %rbp
retq
movq -0x30(%rbp), %rdi
callq 0x22b0
nopw %cs:(%rax,%rax)