// File: ke6jjj[P]r-dat/DDSGroup3.cc
// Function: DDSGroup3::DecodeFrame(Track const&, Track const&)
DDSGroup3::DecodeError
DDSGroup3::DecodeFrame(const Track& A, const Track& B)
{
  //
  // Retrieve the items from subcode id #3 from both tracks.
  // 
  const uint8_t *a_subcode, *b_subcode;
  
  if (!A.GetSubcode(3, &a_subcode))
    return A_MISSING_SUBCODE_3;
  if (!B.GetSubcode(3, &b_subcode))
    return B_MISSING_SUBCODE_3;
  
  //
  // Every track should have a valid subcode pack 3. Let's fetch it from
  // both tracks and make certain they match. (This may be redundant as
  // the frame pairing protocol is supposed to have checked this earlier).
  //
  DDSSubcodePack3 a3, b3;
  a3.Decode(a_subcode);
  b3.Decode(b_subcode);
    
  //
  // Assert that both tracks contain the same absolute frame number.
  //
  if (a3.mAbsoluteFrameID != b3.mAbsoluteFrameID)
    return ABSOLUTE_FRAME_MISMATCH;
    
  //
  // Record frame numbers and such.
  //
  mPartitionID = PartitionID(a3.mPartitionID);
  mAreaID   = AreaID(a3.mAreaID);
  mAbsoluteFrameID = a3.mAbsoluteFrameID;

  //
  // Fetch additional items, depending on the Area of the tape
  // we're supposedly in.
  //
  switch (mAreaID) {
  case DEVICE_AREA:
  case REFERENCE_AREA:
  case SYSTEM_AREA:
  case EOD_AREA:
    //
    // Not handling these areas yet.
    //
    return DECODE_OK;
  case DATA_AREA:
    //
    // Data area frames also have data, which we should check and store.
    //
    // Assert that both tracks of this famre also agree on their logical
    // frame number (this frame's position within the larger Basic Group).
    //
    if (a3.mLogicalFrameID != b3.mLogicalFrameID)
      return LOGICAL_FRAME_MISMATCH;
    
    return HandleDataAreaFrame(a3, A, B);
    break;
  default:
    return UNKNOWN_AREA_ID;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x18(%rbp), %rdi
movl $0x3, %esi
leaq -0x28(%rbp), %rdx
callq 0x4640
testb $0x1, %al
jne 0x77be
movl $0x1, -0x4(%rbp)
jmp 0x7911
movq -0x20(%rbp), %rdi
movl $0x3, %esi
leaq -0x30(%rbp), %rdx
callq 0x4640
testb $0x1, %al
jne 0x77e0
movl $0x2, -0x4(%rbp)
jmp 0x7911
leaq -0x40(%rbp), %rdi
callq 0x8040
leaq -0x50(%rbp), %rdi
callq 0x8040
jmp 0x77f4
movq -0x28(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0xa660
jmp 0x7803
movq -0x30(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0xa660
jmp 0x7812
movl -0x3c(%rbp), %eax
cmpl -0x4c(%rbp), %eax
je 0x7858
movl $0x6, -0x4(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x78f2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x7906
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x8060
jmp 0x7906
movq -0x68(%rbp), %rax
movzbl -0x3f(%rbp), %ecx
movl %ecx, 0x4(%rax)
movzbl -0x3e(%rbp), %ecx
movl %ecx, (%rax)
movl -0x3c(%rbp), %ecx
movl %ecx, 0x8(%rax)
movl (%rax), %eax
movl %eax, -0x6c(%rbp)
subl $0x3, %eax
jb 0x788f
jmp 0x787b
movl -0x6c(%rbp), %eax
subl $0x4, %eax
je 0x789f
jmp 0x7885
movl -0x6c(%rbp), %eax
subl $0x5, %eax
jne 0x78e4
jmp 0x788f
movl $0x0, -0x4(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x78f2
movzbl -0x36(%rbp), %eax
movzbl -0x46(%rbp), %ecx
cmpl %ecx, %eax
je 0x78bb
movl $0x7, -0x4(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x78f2
movq -0x68(%rbp), %rdi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
leaq -0x40(%rbp), %rsi
callq 0x7930
movl %eax, -0x70(%rbp)
jmp 0x78d5
movl -0x70(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x78f2
movl $0x8, -0x4(%rbp)
movl $0x1, -0x60(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x8060
leaq -0x40(%rbp), %rdi
callq 0x8060
jmp 0x7911
leaq -0x40(%rbp), %rdi
callq 0x8060
jmp 0x791a
movl -0x4(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
movq -0x58(%rbp), %rdi
callq 0x21d0
nopw %cs:(%rax,%rax)