// File: /workspace/github_cpp_makefile_star2_O1/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, %r14
movq %rsi, %r15
movq %rdi, %rbx
movq %rsi, %rdi
callq 0x35f6
movq %rax, 0x30(%rsp)
movq %r14, %rdi
callq 0x35f6
movq %rax, 0x28(%rsp)
movq %r15, 0x8(%rsp)
movq %r15, %rdi
callq 0x35fe
movq %rax, 0x20(%rsp)
movq %r14, 0x10(%rsp)
movq %r14, %rdi
callq 0x35fe
movq %rax, %rcx
movq %rbx, 0x18(%rsp)
leaq 0x16c2(%rbx), %rdi
movb $0x1, %bl
xorl %r9d, %r9d
movabsq $0x4ec4ec4ec4ec4ec5, %r8 # imm = 0x4EC4EC4EC4EC4EC5
leaq (%r9,%r9), %r10
xorq $0x2, %r10
leaq (%rcx,%r10), %r11
movq 0x20(%rsp), %rax
leaq (%rax,%r10), %r14
movq 0x28(%rsp), %rax
leaq (%rax,%r10), %r15
addq 0x30(%rsp), %r10
xorl %r12d, %r12d
xorl %esi, %esi
movl %esi, %eax
andl $0x1, %eax
imulq $0x960, %rax, %r13      # imm = 0x960
movq %rsi, %rax
mulq %r8
movq %rdx, %rax
shrq $0x4, %rax
btl $0x4, %edx
sbbq $0x0, %r13
imulq $0x67e, %rax, %rax      # imm = 0x67E
subq %rax, %r13
leaq (%r11,%r13), %rax
leaq (%r14,%r13), %rdx
leaq (%r15,%r13), %rbp
addq %r10, %r13
testb $0x1, %sil
jne 0x59e9
movb (%r13,%r12,8), %r13b
movb %r13b, -0x16c2(%rdi,%r12)
movb (%rbp,%r12,8), %bpl
movb %bpl, -0x16c0(%rdi,%r12)
movb (%rdx,%r12,8), %dl
movb %dl, -0x2(%rdi,%r12)
movb (%rax,%r12,8), %al
jmp 0x5a10
movb (%rbp,%r12,8), %bpl
movb %bpl, -0x16c2(%rdi,%r12)
movb (%r13,%r12,8), %bpl
movb %bpl, -0x16c0(%rdi,%r12)
movb (%rax,%r12,8), %al
movb %al, -0x2(%rdi,%r12)
movb (%rdx,%r12,8), %al
movb %al, (%rdi,%r12)
testb $0x1, %bl
je 0x5a27
cmpb $0x1, -0x2(%rdi,%r12)
jne 0x5a27
movb (%rdi,%r12), %bl
jmp 0x5a29
xorl %ebx, %ebx
incq %rsi
addq $0x4, %r12
cmpq $0x16c0, %r12           # imm = 0x16C0
jne 0x5980
leaq 0x1(%r9), %rax
incq %rdi
testq %r9, %r9
movq %rax, %r9
je 0x5958
movq 0x8(%rsp), %r15
movq %r15, %rdi
callq 0x39bc
movq %rax, %r12
movq 0x10(%rsp), %r13
movq %r13, %rdi
callq 0x39bc
addq %r12, %rax
movq 0x18(%rsp), %r14
movq %rax, 0x2d80(%r14)
movq %r15, %rdi
callq 0x39c4
movq %rax, %r12
movq %r13, %rdi
callq 0x39c4
addq %r12, %rax
movq %rax, 0x2d88(%r14)
movq %r15, %rdi
callq 0x39cc
movq %rax, %r15
movq %r13, %rdi
callq 0x39cc
addq %r15, %rax
movq %rax, 0x2d90(%r14)
je 0x5ad6
testb %bl, %bl
je 0x5ad6
leaq 0x49ad(%rip), %rdi      # 0xa470
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
nop