// File: /workspace/github_cpp_makefile_star2_O3/NichtJens[P]lmf2txt/LMF_IO.cpp
// Function: LMF_IO::PCIGetTDC_TDC8HP_25psGroupMode(unsigned long long&, int, unsigned int*)
__int32 LMF_IO::PCIGetTDC_TDC8HP_25psGroupMode(unsigned __int64 &ref_ui64TDC8HPAbsoluteTimeStamp, __int32 count, unsigned __int32 * Buffer)
///////////////////////////////////////////////////////////////////////////////////
{
	memset(number_of_hits,0,num_channels*sizeof(__int32));		// clear the hit-counts values in _TDC array

	unsigned __int32 ui32DataWord;
	bool bOKFlag = false;
	unsigned __int8 ucTDCChannel;

	for(__int32 i = 0; i < count ; ++i)
	{
		ui32DataWord = Buffer[i];
		if ((ui32DataWord & 0xf8000000) == 0x18000000) // handle output level info
		{
			__int32 n = ui32DataWord & 0x7e00000;
			n >>= 21;
			unsigned __int64 ui64_temp_LevelInfo = ui32DataWord & 0x1fffff;
			if (n > 20) continue;
			if (n < 9) ui64_temp_LevelInfo >>= (9-n); else ui64_temp_LevelInfo <<= (n-9);
			
			n-=9;
			if (n<0) n = 0;

			unsigned __int64 ui64_tempL_LevelInfo = ui64LevelInfo >> (n+21);
			ui64_tempL_LevelInfo <<= (n+21);
			unsigned __int64 ui64_tempR_LevelInfo = n!=0 ? ui64LevelInfo << (64-n) : 0;
			ui64_tempR_LevelInfo = n!=0 ? ui64_tempR_LevelInfo >> (64-n) : 0;

//			unsigned __int64 old = ui64LevelInfo;
			ui64LevelInfo = ui64_tempL_LevelInfo | ui64_tempR_LevelInfo | ui64_temp_LevelInfo;

			continue;
		}
		if( (ui32DataWord&0xC0000000)>0x40000000)		// valid data only if rising or falling trigger indicated
		{
			unsigned __int32 lTDCData = (ui32DataWord&0x00FFFFFF);
			if(lTDCData & 0x00800000)				// detect 24 bit signed flag
				lTDCData |= 0xff000000;				// if detected extend negative value to 32 bit
			if(!this->TDC8HP.VHR_25ps)				// correct for 100ps if necessary
				lTDCData >>= 2;

			ucTDCChannel = (unsigned __int8)((ui32DataWord&0x3F000000)>>24);		// extract channel information
			// calculate TDC channel to _TDC channel
			if((ucTDCChannel >= 42) && (ucTDCChannel <= 49))
				ucTDCChannel -= 25;
			else if((ucTDCChannel >= 21) && (ucTDCChannel <= 28))
				ucTDCChannel -= 12;
			
			bool bIsFalling = true;
			if ((ui32DataWord&0xC0000000) == 0xC0000000) bIsFalling = false;

			if (!bIsFalling) {
				ucTDCChannel += TDC8HP.channel_offset_for_rising_transitions;
			}

			if(ucTDCChannel < num_channels)	// if detected channel fits into TDC array then sort
			{
				++number_of_hits[ucTDCChannel];
				__int32 cnt = number_of_hits[ucTDCChannel];
				// increase Hit Counter;
				
				// test for oversized Hits
				if(cnt > num_ions) {
					--number_of_hits[ucTDCChannel];
					--cnt;
				}
				else			
					// if Hit # ok then store it
					i32TDC[ucTDCChannel*num_ions+cnt-1] = lTDCData;

				bOKFlag = true;
			}
		} 
		else
		{
			if ((ui32DataWord & 0xf0000000) == 0x00000000) {			// GroupWord detected
				this->TDC8HP.ui32AbsoluteTimeStamp = ui32DataWord & 0x00ffffff;
		}
			else if ((ui32DataWord & 0x10000000) == 0x10000000) {			// RollOverWord detected ?
				unsigned __int32 ui32newRollOver = (ui32DataWord & 0x00ffffff);
				if (ui32newRollOver > this->TDC8HP.ui32oldRollOver) {
					this->TDC8HP.ui64RollOvers += ui32newRollOver - this->TDC8HP.ui32oldRollOver;
				} else if (ui32newRollOver < this->TDC8HP.ui32oldRollOver) {
					this->TDC8HP.ui64RollOvers += ui32newRollOver;
					this->TDC8HP.ui64RollOvers += 1;
					this->TDC8HP.ui64RollOvers += (unsigned __int32)(0x00ffffff) - this->TDC8HP.ui32oldRollOver;
				}
				this->TDC8HP.ui32oldRollOver = ui32newRollOver;
			}
			//	only for debugging:
#ifdef _DEBUG
			else if (((ui32DataWord & 0xc0000000)>>30) == 0x00000001)			// ErrorWord detected ?
			{
				__int32 channel = (ui32DataWord & 0x3f000000)>>24;
				__int32 error = (ui32DataWord   & 0x00ff0000)>>16;
				__int32 count = ui32DataWord    & 0x0000ffff;
			}
#endif

		}
	}

	if (bOKFlag)
	{
		ref_ui64TDC8HPAbsoluteTimeStamp  = this->TDC8HP.ui64RollOvers * (unsigned __int64)(0x0000000001000000);
		ref_ui64TDC8HPAbsoluteTimeStamp += (unsigned __int64)(this->TDC8HP.ui32AbsoluteTimeStamp);
		this->TDC8HP.ui64TDC8HP_AbsoluteTimeStamp = ref_ui64TDC8HPAbsoluteTimeStamp;
	}
	
	return bOKFlag;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rcx, %r15
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %rbx
movq 0x2b50(%rdi), %rdi
movslq 0x2b70(%rbx), %rdx
shlq $0x2, %rdx
xorl %r12d, %r12d
xorl %esi, %esi
callq 0x20b0
testl %ebp, %ebp
jle 0xfff1
movq %r14, 0x8(%rsp)
movb 0x14e0(%rbx), %al
movb %al, 0x7(%rsp)
movq 0x2b50(%rbx), %rdi
movq 0x2b58(%rbx), %rax
movq %rax, 0x10(%rsp)
movq 0x1538(%rbx), %rsi
movq 0x2d8(%rbx), %r10
movl %ebp, %r11d
xorl %r13d, %r13d
xorl %r12d, %r12d
movl (%r15,%r13,4), %r14d
movl %r14d, %eax
andl $0xf8000000, %eax       # imm = 0xF8000000
cmpl $0x18000000, %eax       # imm = 0x18000000
jne 0xfea3
movl %r14d, %ebp
shrl $0x15, %ebp
andl $0x3f, %ebp
cmpl $0x14, %ebp
ja 0xffbc
cmpl $0xa, %ebp
movl $0x9, %eax
cmovael %ebp, %eax
movb $0x49, %cl
subb %al, %cl
movq %r10, %rdx
shlq %cl, %rdx
shrq %cl, %rdx
cmpl $0xa, %ebp
movl $0x0, %r8d
cmovaeq %rdx, %r8
andl $0x1fffff, %r14d        # imm = 0x1FFFFF
leal -0x9(%rbp), %edx
movb $0x9, %cl
subb %bpl, %cl
movq %r14, %r9
shrq %cl, %r9
movl %edx, %ecx
shlq %cl, %r14
cmpl $0x9, %ebp
cmovbq %r9, %r14
addb $0xc, %al
movl %eax, %ecx
shrq %cl, %r10
shlq %cl, %r10
orq %r14, %r10
orq %r8, %r10
movq %r10, 0x2d8(%rbx)
jmp 0xffbc
movl %r14d, %eax
andl $0xc0000000, %eax       # imm = 0xC0000000
cmpl $0x40000001, %eax       # imm = 0x40000001
jb 0xfef2
movl %r14d, %eax
andl $0xffffff, %eax         # imm = 0xFFFFFF
movl %r14d, %ecx
shll $0x8, %ecx
sarl $0x1f, %ecx
andl $0xff000000, %ecx       # imm = 0xFF000000
orl %eax, %ecx
movl %ecx, %eax
shrl $0x2, %eax
testb $0x1, 0x7(%rsp)
cmovnel %ecx, %eax
movl %r14d, %edx
shrl $0x18, %edx
movl %edx, %ecx
andl $0x3f, %ecx
leal -0x2a(%rcx), %r8d
cmpl $0x7, %r8d
ja 0xff0e
addb $-0x19, %cl
jmp 0xff46
cmpl $0xfffffff, %r14d       # imm = 0xFFFFFFF
ja 0xff1d
andl $0xffffff, %r14d        # imm = 0xFFFFFF
movl %r14d, 0x1540(%rbx)
jmp 0xffbc
leal -0x15(%rcx), %r8d
cmpl $0x7, %r8d
ja 0xff41
addb $-0xc, %cl
jmp 0xff46
btl $0x1c, %r14d
jae 0xffbc
andl $0xffffff, %r14d        # imm = 0xFFFFFF
movl 0x1534(%rbx), %eax
movl %r14d, %ecx
subl %eax, %ecx
jbe 0xff99
addq %rcx, %rsi
jmp 0xffae
andb $0x3f, %dl
movl %edx, %ecx
xorl %edx, %edx
cmpl $0xc0000000, %r14d      # imm = 0xC0000000
jb 0xff57
movl 0x1550(%rbx), %edx
addb %cl, %dl
movzbl %dl, %ecx
cmpl %ecx, 0x2b70(%rbx)
jle 0xffbc
movl %ecx, %r8d
movl (%rdi,%r8,4), %edx
leal 0x1(%rdx), %r9d
movl %r9d, (%rdi,%r8,4)
movl 0x2b74(%rbx), %ebp
cmpl %ebp, %r9d
jle 0xff84
movl %edx, (%rdi,%r8,4)
jmp 0xff94
imull %ecx, %ebp
addl %edx, %ebp
movslq %ebp, %rcx
movq 0x10(%rsp), %rdx
movl %eax, (%rdx,%rcx,4)
movb $0x1, %r12b
jmp 0xffbc
jae 0xffb5
movl $0xffffff, %ecx         # imm = 0xFFFFFF
subl %eax, %ecx
movq %r14, %rax
addq %rcx, %rax
addq %rax, %rsi
incq %rsi
movq %rsi, 0x1538(%rbx)
movl %r14d, 0x1534(%rbx)
incq %r13
cmpq %r13, %r11
jne 0xfe1c
testb $0x1, %r12b
je 0xfff1
movq 0x1538(%rbx), %rax
shlq $0x18, %rax
movl 0x1540(%rbx), %ecx
addq %rax, %rcx
movq 0x8(%rsp), %rax
movq %rcx, (%rax)
movq %rcx, 0x1548(%rbx)
andb $0x1, %r12b
movzbl %r12b, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq