// File: /workspace/github_cpp_makefile_star2_O2/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
movq %rsi, %rbx
movq %rdi, %r14
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, %ebp        # imm = 0x8020F80
cmovgel %edx, %ebp
movzbl 0x10(%rdi), %eax
pushq $0xb
popq %rcx
subl %eax, %ecx
movl %ecx, 0x8(%rsp)
xorl %eax, %eax
movzbl %al, %esi
cmpl %esi, 0x14(%r14)
jle 0x40a4
movq %rax, 0x10(%rsp)
imull $0xb, %esi, %r12d
movl 0x8(%rsp), %r15d
addl %r15d, %r12d
andl $0xf, %esi
shll $0x16, %esi
movq %rbx, %rdi
movl $0x3c00000, %edx        # imm = 0x3C00000
callq 0x420e
cmpl $0xb, %r15d
je 0x408b
movl 0xc(%r14), %eax
movl %eax, %ecx
movl %r12d, 0xc(%rsp)
imull %r12d, %ecx
movslq %ecx, %r12
shlq $0x2, %r12
addq 0x20(%r14), %r12
xorl %r13d, %r13d
cmpl %eax, %r13d
jge 0x4049
movl (%r12,%r13,4), %esi
movq %rbx, %rdi
movl %ebp, %edx
callq 0x420e
movq 0x10(%rbx), %rax
movl $0x20000, (%rax)        # imm = 0x20000
movl 0xc(%r14), %eax
incq %r13
jmp 0x4023
movq 0x18(%rbx), %rax
movl %ebp, (%rax)
movq 0x416a(%rip), %rdi      # 0x81c0
movq (%rdi), %rax
callq *0x18(%rax)
movq 0x10(%rbx), %rax
pushq $0x10
popq %rcx
movl %ecx, (%rax)
movq 0x18(%rbx), %rax
movl %ecx, (%rax)
movq 0x414e(%rip), %rdi      # 0x81c0
movq (%rdi), %rax
movl %r15d, %esi
callq *0x10(%rax)
incl %r15d
movl 0xc(%rsp), %r12d
incl %r12d
jmp 0x3ffc
movq 0x412e(%rip), %rdi      # 0x81c0
movq (%rdi), %rax
callq *0x18(%rax)
movq 0x10(%rsp), %rax
incb %al
jmp 0x3fcb
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop