// File: ke6jjj[P]r-dat/DDSGroup3.cc
// Function: DDSGroup3::HandleDataAreaFrame(DDSSubcodePack3 const&, Track const&, Track const&)
DDSGroup3::DecodeError
DDSGroup3::HandleDataAreaFrame(const DDSSubcodePack3& sub3, const Track& A,
                               const Track& B)
{
  //
  // Data area frames also have the following, which come from sub-code
  // pack 3.
  //
  mLogicalFrameID = sub3.mLogicalFrameID;
  mIsLastLogicalFrame = sub3.mIsLastLogicalFrame;
  mIsECC3Frame = sub3.mIsECC3Frame;
  
  //
  // Retrieve sub-code pack 1 to get the group number and separator 1
  // counts.
  //
  const uint8_t *subcode;

  if (!GetSubcodePack(1, A, B, &subcode))
    return MISSING_SUBCODE_1;
  
  DDSSubcodePack1 sub1;
  sub1.Decode(subcode);
  mBasicGroupID = sub1.mGroup;
  mSeparator1Count = sub1.mSeparator1Count;
  
  //
  // Retrieve sub-code pack 2 to get the separator 2 count and record
  // counts.
  //
  DDSSubcodePack2 sub2;
  
  if (!GetSubcodePack(2, A, B, &subcode))
    return MISSING_SUBCODE_2;
  
  sub2.Decode(subcode);
  mSeparator2Count = sub2.mSeparator2Count;
  mRecordCount = sub2.mRecordCount;
  
  //
  // Recreate the "LFID" byte from the LogicalFrameID, the
  // IsECC3 and the IsLastFrame flags.
  //
  uint8_t original_lfid = 
    mLogicalFrameID |
    (mIsECC3Frame ? 0x40 : 0) |
    (mIsLastLogicalFrame ? 0x80 : 0);
  
  //
  // Also fetch sub-code 4 for extra error-checking.
  //
  
  if (!GetSubcodePack(4, A, B, &subcode))
      return MISSING_SUBCODE_4;
  
  //
  // Decode the pack 4 subcode.
  //
  DDSSubcodePack4 sub4;
  sub4.Decode(subcode);

  //
  // Fill in the frame data by demultiplexing the data from both tracks.
  //
  mFrame.FillFromTrackPair(A, B);
  
  //
  // Make certain everything was received ok.
  //
  if (!mFrame.OK())
    return C2_ERRORS_PRESENT;

  //
  // Perform some other basic checks on the frame. First, let's check
  // that the head bytes on the group look good.
  //
  // The logical frame id should be repeated bytes 1 and 3 of the first
  // row of data.
  //
  const DATFrame::DataArray& data = mFrame.Data();
  
  if (data[0][1] != original_lfid ||
      data[0][3] != original_lfid ||
      //
      // Check that the format id is also zero.
      //
      data[0][0] != 0 ||
      data[0][2] != 0) {
    return INVALID_HEADER;  
  }

  //
  // Pick up the half column checksums from packs 3 and 4.
  //
  uint8_t c1 = sub3.mChecksum1;
  uint8_t c2 = sub3.mChecksum2;
  uint8_t c3 = sub4.mChecksum3;
  uint8_t c4 = sub4.mChecksum4;
  
  //
  // Prepare to perform half-column checksuming of the received data.
  //
  uint8_t r_c1 = 0;
  uint8_t r_c2 = 0;
  uint8_t r_c3 = 0;
  uint8_t r_c4 = 0;
  
  //
  // C1 and C3 start with the recreated LFID byte.
  //
  r_c1 = r_c3 = original_lfid;
  
  //
  // The rest of the error checking is convoluted.
  //
  for (size_t i = 0; i < 719; i++) {
    //
    // 9.4.3.3.1.1 Byte No. 5; i = [0,718]
    //
    r_c1 ^= Di(data, (8*i)+3) ^
            Di(data, (8*i)+5) ^
            Di(data, 5755); // This is dumb to repeat

    //
    // 9.4.3.3.1.2 Byte No. 6; i = [0,718]
    //
    r_c2 ^= Di(data, (8*i)+2) ^
            Di(data, (8*i)+4) ^
            Di(data, 5754); // This is dumb to repeat

    //
    // 9.4.4.3.1.1 Byte No. 5; i = [1,719]
    //
    r_c3 ^= Di(data, 1) ^   // This is dumb to repeat
            Di(data, 8*(i+1)-1) ^
            Di(data, 8*(i+1)+1);

    //
    // 9.4.4.3.1.2 Byte No. 6 [1-719]
    //
    r_c4 ^= Di(data, 0) ^  // This is dumb to repeat
            Di(data, 8*(i+1)-2) ^
            Di(data, 8*(i+1));
  }
  
  //
  // Check that the half-column weird checksums match the data.
  //
#if 0
  if ((r_c1 != c1) ||
      (r_c2 != c2) ||
      (r_c3 != c3) ||
      (r_c4 != c4))
    return ECC4_ERROR;
#endif
  
  return DECODE_OK;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x18(%rbp), %rcx
movb 0xa(%rcx), %cl
movb %cl, 0x10(%rax)
movq -0x18(%rbp), %rcx
movb 0xb(%rcx), %cl
andb $0x1, %cl
movb %cl, 0x11(%rax)
movq -0x18(%rbp), %rcx
movb 0xc(%rcx), %cl
andb $0x1, %cl
movb %cl, 0x12(%rax)
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movl $0x1, %edi
leaq -0x30(%rbp), %rcx
callq 0x7fa0
testb $0x1, %al
jne 0x79a0
movl $0x3, -0x4(%rbp)
jmp 0x7e8e
leaq -0x38(%rbp), %rdi
movq %rdi, -0x90(%rbp)
callq 0x8080
movq -0x90(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0xa520
jmp 0x79c2
movq -0x88(%rbp), %rax
movzwl -0x36(%rbp), %ecx
movl %ecx, 0xc(%rax)
movl -0x34(%rbp), %ecx
movl %ecx, 0x14(%rax)
leaq -0x4c(%rbp), %rdi
callq 0x80a0
jmp 0x79e1
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movl $0x2, %edi
leaq -0x30(%rbp), %rcx
callq 0x7fa0
movb %al, -0x91(%rbp)
jmp 0x79ff
movb -0x91(%rbp), %al
testb $0x1, %al
jne 0x7a40
jmp 0x7a0b
movl $0x4, -0x4(%rbp)
movl $0x1, -0x50(%rbp)
jmp 0x7e66
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x7e83
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x7e7a
movq -0x30(%rbp), %rsi
leaq -0x4c(%rbp), %rdi
callq 0xa5f0
jmp 0x7a4f
movq -0x88(%rbp), %rcx
movzwl -0x4a(%rbp), %eax
movl %eax, 0x18(%rcx)
movl -0x48(%rbp), %eax
movl %eax, 0x1c(%rcx)
movl 0x10(%rcx), %eax
movzbl 0x12(%rcx), %edx
andl $0x1, %edx
shll $0x6, %edx
orl %edx, %eax
movzbl 0x11(%rcx), %ecx
shll $0x7, %ecx
orl %ecx, %eax
movb %al, -0x51(%rbp)
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movl $0x4, %edi
leaq -0x30(%rbp), %rcx
callq 0x7fa0
movb %al, -0x92(%rbp)
jmp 0x7a9c
movb -0x92(%rbp), %al
testb $0x1, %al
jne 0x7abb
jmp 0x7aa8
movl $0x5, -0x4(%rbp)
movl $0x1, -0x50(%rbp)
jmp 0x7e66
leaq -0x64(%rbp), %rdi
callq 0x80c0
jmp 0x7ac6
movq -0x30(%rbp), %rsi
leaq -0x64(%rbp), %rdi
callq 0xa760
jmp 0x7ad5
movq -0x88(%rbp), %rdi
addq $0x20, %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x8d40
jmp 0x7aef
movq -0x88(%rbp), %rdi
addq $0x20, %rdi
callq 0x91d0
movb %al, -0x93(%rbp)
jmp 0x7b07
movb -0x93(%rbp), %al
testb $0x1, %al
jne 0x7b40
jmp 0x7b13
movl $0x9, -0x4(%rbp)
movl $0x1, -0x50(%rbp)
jmp 0x7e5d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x64(%rbp), %rdi
callq 0x80e0
jmp 0x7e7a
movq -0x88(%rbp), %rdi
addq $0x20, %rdi
callq 0x9170
movq %rax, -0xa0(%rbp)
jmp 0x7b59
movq -0xa0(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movzbl 0x1(%rax), %eax
movzbl -0x51(%rbp), %ecx
cmpl %ecx, %eax
jne 0x7b9d
movq -0x70(%rbp), %rax
movzbl 0x3(%rax), %eax
movzbl -0x51(%rbp), %ecx
cmpl %ecx, %eax
jne 0x7b9d
movq -0x70(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
jne 0x7b9d
movq -0x70(%rbp), %rax
movzbl 0x2(%rax), %eax
cmpl $0x0, %eax
je 0x7bb0
movl $0xa, -0x4(%rbp)
movl $0x1, -0x50(%rbp)
jmp 0x7e5d
movq -0x18(%rbp), %rax
movb 0x8(%rax), %al
movb %al, -0x71(%rbp)
movq -0x18(%rbp), %rax
movb 0x9(%rax), %al
movb %al, -0x72(%rbp)
movb -0x5c(%rbp), %al
movb %al, -0x73(%rbp)
movb -0x5b(%rbp), %al
movb %al, -0x74(%rbp)
movb $0x0, -0x75(%rbp)
movb $0x0, -0x76(%rbp)
movb $0x0, -0x77(%rbp)
movb $0x0, -0x78(%rbp)
movb -0x51(%rbp), %al
movb %al, -0x77(%rbp)
movb %al, -0x75(%rbp)
movq $0x0, -0x80(%rbp)
cmpq $0x2cf, -0x80(%rbp)     # imm = 0x2CF
jae 0x7e4f
movq -0x70(%rbp), %rdi
movq -0x80(%rbp), %rax
leaq 0x3(,%rax,8), %rsi
callq 0x8000
movb %al, -0xa1(%rbp)
jmp 0x7c1c
movb -0xa1(%rbp), %al
movzbl %al, %eax
movl %eax, -0xa8(%rbp)
movq -0x70(%rbp), %rdi
movq -0x80(%rbp), %rax
leaq 0x5(,%rax,8), %rsi
callq 0x8000
movb %al, -0xa2(%rbp)
jmp 0x7c48
movl -0xa8(%rbp), %eax
movb -0xa2(%rbp), %cl
movzbl %cl, %ecx
xorl %ecx, %eax
movl %eax, -0xb0(%rbp)
movq -0x70(%rbp), %rdi
movl $0x167b, %esi           # imm = 0x167B
callq 0x8000
movb %al, -0xa9(%rbp)
jmp 0x7c75
movl -0xb0(%rbp), %ecx
movb -0xa9(%rbp), %al
movzbl %al, %eax
xorl %eax, %ecx
movzbl -0x75(%rbp), %eax
xorl %ecx, %eax
movb %al, -0x75(%rbp)
movq -0x70(%rbp), %rdi
movq -0x80(%rbp), %rax
leaq 0x2(,%rax,8), %rsi
callq 0x8000
movb %al, -0xb1(%rbp)
jmp 0x7cac
movb -0xb1(%rbp), %al
movzbl %al, %eax
movl %eax, -0xb8(%rbp)
movq -0x70(%rbp), %rdi
movq -0x80(%rbp), %rax
leaq 0x4(,%rax,8), %rsi
callq 0x8000
movb %al, -0xb2(%rbp)
jmp 0x7cd8
movl -0xb8(%rbp), %eax
movb -0xb2(%rbp), %cl
movzbl %cl, %ecx
xorl %ecx, %eax
movl %eax, -0xc0(%rbp)
movq -0x70(%rbp), %rdi
movl $0x167a, %esi           # imm = 0x167A
callq 0x8000
movb %al, -0xb9(%rbp)
jmp 0x7d05
movl -0xc0(%rbp), %ecx
movb -0xb9(%rbp), %al
movzbl %al, %eax
xorl %eax, %ecx
movzbl -0x76(%rbp), %eax
xorl %ecx, %eax
movb %al, -0x76(%rbp)
movq -0x70(%rbp), %rdi
movl $0x1, %esi
callq 0x8000
movb %al, -0xc1(%rbp)
jmp 0x7d35
movb -0xc1(%rbp), %al
movzbl %al, %eax
movl %eax, -0xc8(%rbp)
movq -0x70(%rbp), %rdi
movq -0x80(%rbp), %rax
leaq 0x7(,%rax,8), %rsi
callq 0x8000
movb %al, -0xc2(%rbp)
jmp 0x7d61
movl -0xc8(%rbp), %eax
movb -0xc2(%rbp), %cl
movzbl %cl, %ecx
xorl %ecx, %eax
movl %eax, -0xd0(%rbp)
movq -0x70(%rbp), %rdi
movq -0x80(%rbp), %rax
leaq 0x9(,%rax,8), %rsi
callq 0x8000
movb %al, -0xc9(%rbp)
jmp 0x7d95
movl -0xd0(%rbp), %ecx
movb -0xc9(%rbp), %al
movzbl %al, %eax
xorl %eax, %ecx
movzbl -0x77(%rbp), %eax
xorl %ecx, %eax
movb %al, -0x77(%rbp)
movq -0x70(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x8000
movb %al, -0xd1(%rbp)
jmp 0x7dc4
movb -0xd1(%rbp), %al
movzbl %al, %eax
movl %eax, -0xd8(%rbp)
movq -0x70(%rbp), %rdi
movq -0x80(%rbp), %rax
leaq 0x6(,%rax,8), %rsi
callq 0x8000
movb %al, -0xd2(%rbp)
jmp 0x7df0
movl -0xd8(%rbp), %eax
movb -0xd2(%rbp), %cl
movzbl %cl, %ecx
xorl %ecx, %eax
movl %eax, -0xe0(%rbp)
movq -0x70(%rbp), %rdi
movq -0x80(%rbp), %rax
leaq 0x8(,%rax,8), %rsi
callq 0x8000
movb %al, -0xd9(%rbp)
jmp 0x7e24
movl -0xe0(%rbp), %ecx
movb -0xd9(%rbp), %al
movzbl %al, %eax
xorl %eax, %ecx
movzbl -0x78(%rbp), %eax
xorl %ecx, %eax
movb %al, -0x78(%rbp)
movq -0x80(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x80(%rbp)
jmp 0x7bf1
movl $0x0, -0x4(%rbp)
movl $0x1, -0x50(%rbp)
leaq -0x64(%rbp), %rdi
callq 0x80e0
leaq -0x4c(%rbp), %rdi
callq 0x8100
leaq -0x38(%rbp), %rdi
callq 0x8120
jmp 0x7e8e
leaq -0x4c(%rbp), %rdi
callq 0x8100
leaq -0x38(%rbp), %rdi
callq 0x8120
jmp 0x7e9a
movl -0x4(%rbp), %eax
addq $0xe0, %rsp
popq %rbp
retq
movq -0x40(%rbp), %rdi
callq 0x21d0
nopw %cs:(%rax,%rax)