// File: /workspace/github_cpp_makefile_star2_O3/eggnot[P]pixel_camera/matrix/lib/framebuffer.cc
// Function: rgb_matrix::internal::Framebuffer::DumpToMatrix(rgb_matrix::GPIO*)
void Framebuffer::DumpToMatrix(GPIO *io) {
  IoBits color_clk_mask;   // Mask of bits we need to set while clocking in.
  color_clk_mask.bits.p0_r1
    = color_clk_mask.bits.p0_g1
    = color_clk_mask.bits.p0_b1
    = color_clk_mask.bits.p0_r2
    = color_clk_mask.bits.p0_g2
    = color_clk_mask.bits.p0_b2 = 1;

#ifndef ONLY_SINGLE_CHAIN
  if (parallel_ >= 2) {
    color_clk_mask.bits.p1_r1
      = color_clk_mask.bits.p1_g1
      = color_clk_mask.bits.p1_b1
      = color_clk_mask.bits.p1_r2
      = color_clk_mask.bits.p1_g2
      = color_clk_mask.bits.p1_b2 = 1;
  }

  if (parallel_ >= 3) {
    color_clk_mask.bits.p2_r1
      = color_clk_mask.bits.p2_g1
      = color_clk_mask.bits.p2_b1
      = color_clk_mask.bits.p2_r2
      = color_clk_mask.bits.p2_g2
      = color_clk_mask.bits.p2_b2 = 1;
  }
#endif

#ifdef PI_REV1_RGB_PINOUT_
  color_clk_mask.bits.clock_rev1 = color_clk_mask.bits.clock_rev2 = 1;
#endif
  color_clk_mask.bits.clock = 1;

  IoBits row_mask;
  row_mask.bits.a = row_mask.bits.b = row_mask.bits.c = row_mask.bits.d = 1;

  IoBits clock, strobe, row_address;
#ifdef PI_REV1_RGB_PINOUT_
  clock.bits.clock_rev1 = clock.bits.clock_rev2 = 1;
#endif
  clock.bits.clock = 1;
  strobe.bits.strobe = 1;

  const int pwm_to_show = pwm_bits_;  // Local copy, might change in process.
  for (uint8_t d_row = 0; d_row < double_rows_; ++d_row) {
    row_address.bits.a = d_row;
    row_address.bits.b = d_row >> 1;
    row_address.bits.c = d_row >> 2;
    row_address.bits.d = d_row >> 3;

    io->WriteMaskedBits(row_address.raw, row_mask.raw);  // Set row address

    // Rows can't be switched very quickly without ghosting, so we do the
    // full PWM of one row before switching rows.
    for (int b = kBitPlanes - pwm_to_show; b < kBitPlanes; ++b) {
      IoBits *row_data = ValueAt(d_row, 0, b);
      // While the output enable is still on, we can already clock in the next
      // data.
      for (int col = 0; col < columns_; ++col) {
        const IoBits &out = *row_data++;
        io->WriteMaskedBits(out.raw, color_clk_mask.raw);  // col + reset clock
        io->SetBits(clock.raw);               // Rising edge: clock color in.
      }
      io->ClearBits(color_clk_mask.raw);    // clock back to normal.

      // OE of the previous row-data must be finished before strobe.
      sOutputEnablePulser->WaitPulseFinished();

      io->SetBits(strobe.raw);   // Strobe in the previously clocked in row.
      io->ClearBits(strobe.raw);

      // Now switch on for the sleep time necessary for that bit-plane.
      sOutputEnablePulser->SendPulse(b);
    }
    sOutputEnablePulser->WaitPulseFinished();
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl 0x4(%rdi), %eax
cmpl $0x3, %eax
movl $0xc3b7fec, %ecx        # imm = 0xC3B7FEC
movl $0x81a3fe0, %edx        # imm = 0x81A3FE0
cmovael %ecx, %edx
cmpl $0x2, %eax
movl $0x8020f80, %r15d       # imm = 0x8020F80
cmovgel %edx, %r15d
cmpl $0x0, 0x14(%rdi)
jle 0x4572
movq %rsi, %rbx
movq %rdi, %r14
movzbl 0x10(%rdi), %eax
movl $0xb, %ecx
movl %eax, 0x14(%rsp)
subl %eax, %ecx
movl %ecx, 0x10(%rsp)
xorl %eax, %eax
movl $0x10, %r12d
movq $0x0, 0x8(%rsp)
andl $0xf, %eax
shll $0x16, %eax
movl $0x3c00000, %ecx        # imm = 0x3C00000
cmpl %ecx, %eax
je 0x44a9
movl %eax, %ecx
xorl $0x3c00000, %ecx        # imm = 0x3C00000
movq 0x18(%rbx), %rdx
movl %ecx, (%rdx)
testl %eax, %eax
je 0x44af
movq 0x10(%rbx), %rcx
movl %eax, (%rcx)
cmpb $0x0, 0x14(%rsp)
je 0x454c
movzbl 0x8(%rsp), %eax
leal (%rax,%rax,4), %ecx
leal (%rax,%rcx,2), %r13d
movl 0x10(%rsp), %ebp
addl %ebp, %r13d
movl 0xc(%r14), %eax
testl %eax, %eax
jle 0x4511
imull %r13d, %eax
cltq
shlq $0x2, %rax
addq 0x20(%r14), %rax
xorl %ecx, %ecx
movl (%rax,%rcx,4), %edx
movl %edx, %esi
notl %esi
andl %r15d, %esi
je 0x44f7
movq 0x18(%rbx), %rdi
movl %esi, (%rdi)
movq 0x10(%rbx), %rsi
andl %r15d, %edx
je 0x4502
movl %edx, (%rsi)
movl $0x20000, (%rsi)        # imm = 0x20000
incq %rcx
cmpl 0xc(%r14), %ecx
jl 0x44e5
movq 0x18(%rbx), %rax
movl %r15d, (%rax)
movq 0x3ca1(%rip), %rdi      # 0x81c0
movq (%rdi), %rax
callq *0x18(%rax)
movq 0x10(%rbx), %rax
movl %r12d, (%rax)
movq 0x18(%rbx), %rax
movl %r12d, (%rax)
movq 0x3c86(%rip), %rdi      # 0x81c0
movq (%rdi), %rax
movl %ebp, %esi
callq *0x10(%rax)
incl %ebp
incl %r13d
cmpl $0xb, %ebp
jne 0x44cd
movq 0x3c6d(%rip), %rdi      # 0x81c0
movq (%rdi), %rax
callq *0x18(%rax)
movq 0x8(%rsp), %rax
incb %al
movq %rax, 0x8(%rsp)
movzbl %al, %eax
cmpl %eax, 0x14(%r14)
jg 0x4488
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq