// File: /workspace/github_cpp_makefile_star2_O3/ke6jjj[P]r-dat/DATFrame.cc
// Function: DATFrame::FillFromTrackPair(Track const&, Track const&)
void
DATFrame::FillFromTrackPair(const Track& A, const Track& B)
{
  bool everything_ok = true;

  //
  // Retrieve pointers to the data and meta-data in the A and B tracks passed
  // by the caller.
  //
  const Track::DataArray& a_bytes = A.Data();
  const Track::DataArray& b_bytes = B.Data();
  const Track::ValidityArray& a_valid = A.DataValid();
  const Track::ValidityArray& b_valid = B.DataValid();
  
  //
  // De-multiplex the bytes from the A and B tracks into their respective
  // positions in the frame.
  //
  // (Taken from DDS spec Section 9.3.4 G4 Sub-Group, there is likely the same
  // logic specified in the DAT Conference Standard as well).
  //
  for (size_t column = 0; column < 2; column++) {
    for (size_t word = 0; word < 1456; word++) {
      size_t source_block =
                                 (word %  52) + 
                            75 * (word %   2) +
                                 (word / 832);
      size_t u = (column + 1) % 2;
      size_t source_byte =
                            2  * (u + word /  52)     -
                                 (    word /  52) % 2 -
                            32 * (    word / 832);
      
      if ((word % 2) == 0) {
        mData[word][column]   = a_bytes[source_block][source_byte];
        mData[word][column+2] = b_bytes[source_block][source_byte];
        mDataIsValid[word][column]   = a_valid[source_block][source_byte];
        mDataIsValid[word][column+2] = b_valid[source_block][source_byte];
      } else {
        mData[word][column]   = b_bytes[source_block][source_byte];
        mData[word][column+2] = a_bytes[source_block][source_byte];
        mDataIsValid[word][column]   = b_valid[source_block][source_byte];
        mDataIsValid[word][column+2] = a_valid[source_block][source_byte];
      }
      everything_ok = everything_ok && mDataIsValid[word][column] &&
                      mDataIsValid[word][column+2];
    }
  }

  //
  // Gather up error statistics from the two constituent tracks.
  //
  mC1Errors = A.C1Errors() + B.C1Errors();
  mC1UncorrectableErrors = A.C1UncorrectableErrors() +
                           B.C1UncorrectableErrors();
  mC2UncorrectableErrors = A.C2UncorrectableErrors() +
                           B.C2UncorrectableErrors();

  if (mC2UncorrectableErrors && everything_ok) {
    //
    // This is supposed to be impossible.
    //
    printf("Inconsistency in C2 errors and erasures!!\n");
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdx, %r12
movq %rsi, %r14
movq %rdi, %rbx
movq %rsi, %rdi
callq 0x35d6
movq %rax, 0x10(%rsp)
movq %r12, %rdi
callq 0x35d6
movq %rax, %r15
movq %r14, 0x18(%rsp)
movq %r14, %rdi
callq 0x35de
movq %rax, %r14
movq %r12, 0x20(%rsp)
movq %r12, %rdi
callq 0x35de
movq %rax, %rcx
movq %rbx, 0x28(%rsp)
leaq 0x16c2(%rbx), %rax
movq %rax, 0x30(%rsp)
movb $0x1, %bl
xorl %r8d, %r8d
movb $0x1, %al
movl %eax, 0xc(%rsp)
movq 0x30(%rsp), %rax
leaq (%rax,%r8), %r11
xorq $0x1, %r8
xorl %esi, %esi
movl %esi, %r10d
andl $0x1, %r10d
movq %rsi, %rax
movabsq $0x4ec4ec4ec4ec4ec5, %rdx # imm = 0x4EC4EC4EC4EC4EC5
mulq %rdx
xorl %edi, %edi
cmpq $0x340, %rsi            # imm = 0x340
setae %r9b
movq 0x10(%rsp), %r12
movq %r15, %r13
movq %r14, %rbp
movq %rcx, %rax
testq %r10, %r10
je 0x59e5
movq %r15, %r12
movq 0x10(%rsp), %r13
movq %rcx, %rbp
movq %r14, %rax
imulq $0x4b, %r10, %r10
shrq $0x4, %rdx
imulq $0x34, %rdx, %rdx
subq %rdx, %r10
movb %r9b, %dil
addq %rsi, %r10
addq %rdi, %r10
movzwl %si, %edx
imull $0x4ec5, %edx, %r9d     # imm = 0x4EC5
shrl $0x14, %r9d
leaq (%r8,%r9), %rdx
addq %rdx, %rdx
andl $0x1, %r9d
shll $0x5, %edi
orq %r9, %rdi
subq %rdi, %rdx
shlq $0x5, %r10
addq %r10, %r12
movb (%rdx,%r12), %dil
movb %dil, -0x16c2(%r11,%rsi,4)
addq %r10, %r13
movb (%rdx,%r13), %dil
movb %dil, -0x16c0(%r11,%rsi,4)
addq %r10, %rbp
movb (%rdx,%rbp), %dil
movb %dil, -0x2(%r11,%rsi,4)
addq %rax, %r10
movzbl (%rdx,%r10), %eax
movb %al, (%r11,%rsi,4)
andb %dil, %bl
testb $0x1, %bl
jne 0x5a63
xorl %eax, %eax
movl %eax, %ebx
incq %rsi
cmpq $0x5b0, %rsi            # imm = 0x5B0
jne 0x59a0
movl $0x1, %r8d
testb $0x1, 0xc(%rsp)
movl $0x0, %eax
jne 0x598d
movq 0x18(%rsp), %r15
movq %r15, %rdi
callq 0x3994
movq %rax, %r12
movq 0x20(%rsp), %r13
movq %r13, %rdi
callq 0x3994
addq %r12, %rax
movq 0x28(%rsp), %r14
movq %rax, 0x2d80(%r14)
movq %r15, %rdi
callq 0x399c
movq %rax, %r12
movq %r13, %rdi
callq 0x399c
addq %r12, %rax
movq %rax, 0x2d88(%r14)
movq %r15, %rdi
callq 0x39a4
movq %rax, %r15
movq %r13, %rdi
callq 0x39a4
addq %r15, %rax
movq %rax, 0x2d90(%r14)
je 0x5b11
testb %bl, %bl
je 0x5b11
leaq 0x4982(%rip), %rdi      # 0xa480
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x21b0
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq