// File: 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
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x70(%rbp)
movb $0x1, -0x19(%rbp)
movq -0x10(%rbp), %rdi
callq 0x46a0
movq %rax, -0x28(%rbp)
movq -0x18(%rbp), %rdi
callq 0x46a0
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rdi
callq 0x46c0
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rdi
callq 0x46c0
movq %rax, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
cmpq $0x2, -0x48(%rbp)
jae 0x90b1
movq $0x0, -0x50(%rbp)
cmpq $0x5b0, -0x50(%rbp)     # imm = 0x5B0
jae 0x909e
movq -0x50(%rbp), %rax
movl $0x34, %ecx
xorl %edx, %edx
divq %rcx
movq -0x50(%rbp), %rax
andq $0x1, %rax
imulq $0x4b, %rax, %rax
addq %rax, %rdx
movq %rdx, -0x90(%rbp)
movq -0x50(%rbp), %rax
movl $0x340, %ecx            # imm = 0x340
xorl %edx, %edx
divq %rcx
movq %rax, %rcx
movq -0x90(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x58(%rbp)
movq -0x48(%rbp), %rax
addq $0x1, %rax
andq $0x1, %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x50(%rbp), %rax
movl $0x34, %ecx
xorl %edx, %edx
divq %rcx
movq %rax, %rcx
movq -0x88(%rbp), %rax
addq %rcx, %rax
shlq %rax
movq %rax, -0x80(%rbp)
movq -0x50(%rbp), %rax
movl $0x34, %ecx
xorl %edx, %edx
divq %rcx
movq %rax, %rcx
movq -0x80(%rbp), %rax
andq $0x1, %rcx
subq %rcx, %rax
movq %rax, -0x78(%rbp)
movq -0x50(%rbp), %rax
movl $0x340, %ecx            # imm = 0x340
xorl %edx, %edx
divq %rcx
movq %rax, %rcx
movq -0x78(%rbp), %rax
shlq $0x5, %rcx
subq %rcx, %rax
movq %rax, -0x68(%rbp)
movq -0x50(%rbp), %rax
andq $0x1, %rax
cmpq $0x0, %rax
jne 0x8f60
movq -0x70(%rbp), %rax
movq -0x28(%rbp), %rcx
movq -0x58(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rcx
movq -0x68(%rbp), %rdx
movb (%rcx,%rdx), %sil
movq -0x50(%rbp), %rdx
shlq $0x2, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq -0x48(%rbp), %rdx
movb %sil, (%rcx,%rdx)
movq -0x30(%rbp), %rcx
movq -0x58(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rcx
movq -0x68(%rbp), %rdx
movb (%rcx,%rdx), %sil
movq -0x50(%rbp), %rdx
shlq $0x2, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq -0x48(%rbp), %rdx
movb %sil, 0x2(%rcx,%rdx)
movq -0x38(%rbp), %rcx
movq -0x58(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rcx
movq -0x68(%rbp), %rdx
movb (%rcx,%rdx), %sil
movq %rax, %rcx
addq $0x16c0, %rcx           # imm = 0x16C0
movq -0x50(%rbp), %rdx
shlq $0x2, %rdx
addq %rdx, %rcx
movq -0x48(%rbp), %rdx
andb $0x1, %sil
movb %sil, (%rcx,%rdx)
movq -0x40(%rbp), %rcx
movq -0x58(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rcx
movq -0x68(%rbp), %rdx
movb (%rcx,%rdx), %dl
addq $0x16c0, %rax           # imm = 0x16C0
movq -0x50(%rbp), %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq -0x48(%rbp), %rcx
andb $0x1, %dl
movb %dl, 0x2(%rax,%rcx)
jmp 0x9029
movq -0x70(%rbp), %rax
movq -0x30(%rbp), %rcx
movq -0x58(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rcx
movq -0x68(%rbp), %rdx
movb (%rcx,%rdx), %sil
movq -0x50(%rbp), %rdx
shlq $0x2, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq -0x48(%rbp), %rdx
movb %sil, (%rcx,%rdx)
movq -0x28(%rbp), %rcx
movq -0x58(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rcx
movq -0x68(%rbp), %rdx
movb (%rcx,%rdx), %sil
movq -0x50(%rbp), %rdx
shlq $0x2, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq -0x48(%rbp), %rdx
movb %sil, 0x2(%rcx,%rdx)
movq -0x40(%rbp), %rcx
movq -0x58(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rcx
movq -0x68(%rbp), %rdx
movb (%rcx,%rdx), %sil
movq %rax, %rcx
addq $0x16c0, %rcx           # imm = 0x16C0
movq -0x50(%rbp), %rdx
shlq $0x2, %rdx
addq %rdx, %rcx
movq -0x48(%rbp), %rdx
andb $0x1, %sil
movb %sil, (%rcx,%rdx)
movq -0x38(%rbp), %rcx
movq -0x58(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rcx
movq -0x68(%rbp), %rdx
movb (%rcx,%rdx), %dl
addq $0x16c0, %rax           # imm = 0x16C0
movq -0x50(%rbp), %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq -0x48(%rbp), %rcx
andb $0x1, %dl
movb %dl, 0x2(%rax,%rcx)
xorl %eax, %eax
testb $0x1, -0x19(%rbp)
movb %al, -0x91(%rbp)
je 0x9082
movq -0x70(%rbp), %rcx
addq $0x16c0, %rcx           # imm = 0x16C0
movq -0x50(%rbp), %rax
shlq $0x2, %rax
addq %rax, %rcx
movq -0x48(%rbp), %rdx
xorl %eax, %eax
testb $0x1, (%rcx,%rdx)
movb %al, -0x91(%rbp)
je 0x9082
movq -0x70(%rbp), %rax
addq $0x16c0, %rax           # imm = 0x16C0
movq -0x50(%rbp), %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq -0x48(%rbp), %rcx
movb 0x2(%rax,%rcx), %al
movb %al, -0x91(%rbp)
movb -0x91(%rbp), %al
andb $0x1, %al
movb %al, -0x19(%rbp)
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x8db2
jmp 0x90a0
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x8d9f
movq -0x10(%rbp), %rdi
callq 0x4f60
movq %rax, -0xb0(%rbp)
movq -0x18(%rbp), %rdi
callq 0x4f60
movq -0xb0(%rbp), %rcx
movq %rax, %rdx
movq -0x70(%rbp), %rax
addq %rdx, %rcx
movq %rcx, 0x2d80(%rax)
movq -0x10(%rbp), %rdi
callq 0x4f80
movq %rax, -0xa8(%rbp)
movq -0x18(%rbp), %rdi
callq 0x4f80
movq -0xa8(%rbp), %rcx
movq %rax, %rdx
movq -0x70(%rbp), %rax
addq %rdx, %rcx
movq %rcx, 0x2d88(%rax)
movq -0x10(%rbp), %rdi
callq 0x4fa0
movq %rax, -0xa0(%rbp)
movq -0x18(%rbp), %rdi
callq 0x4fa0
movq -0xa0(%rbp), %rcx
movq %rax, %rdx
movq -0x70(%rbp), %rax
addq %rdx, %rcx
movq %rcx, 0x2d90(%rax)
cmpq $0x0, 0x2d90(%rax)
je 0x9162
testb $0x1, -0x19(%rbp)
je 0x9162
leaq 0x6365(%rip), %rdi      # 0xf4c0
movb $0x0, %al
callq 0x2040
addq $0xb0, %rsp
popq %rbp
retq
nopl (%rax,%rax)