// File: 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
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x60(%rbp)
movq 0x2b50(%rax), %rdi
movslq 0x2b70(%rax), %rdx
shlq $0x2, %rdx
xorl %esi, %esi
callq 0x20d0
movb $0x0, -0x25(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x16ea1
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
andl $0xf8000000, %eax       # imm = 0xF8000000
cmpl $0x18000000, %eax       # imm = 0x18000000
jne 0x16c5d
movl -0x24(%rbp), %eax
andl $0x7e00000, %eax        # imm = 0x7E00000
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %eax
sarl $0x15, %eax
movl %eax, -0x30(%rbp)
movl -0x24(%rbp), %eax
andl $0x1fffff, %eax         # imm = 0x1FFFFF
movl %eax, %eax
movq %rax, -0x38(%rbp)
cmpl $0x14, -0x30(%rbp)
jle 0x16b6d
jmp 0x16e93
cmpl $0x9, -0x30(%rbp)
jge 0x16b8a
movl $0x9, %ecx
subl -0x30(%rbp), %ecx
movq -0x38(%rbp), %rax
movl %ecx, %ecx
shrq %cl, %rax
movq %rax, -0x38(%rbp)
jmp 0x16b9d
movl -0x30(%rbp), %ecx
subl $0x9, %ecx
movq -0x38(%rbp), %rax
movl %ecx, %ecx
shlq %cl, %rax
movq %rax, -0x38(%rbp)
movl -0x30(%rbp), %eax
subl $0x9, %eax
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jge 0x16bb3
movl $0x0, -0x30(%rbp)
movq -0x60(%rbp), %rax
movq 0x2d8(%rax), %rax
movl -0x30(%rbp), %ecx
addl $0x15, %ecx
movl %ecx, %ecx
shrq %cl, %rax
movq %rax, -0x40(%rbp)
movl -0x30(%rbp), %ecx
addl $0x15, %ecx
movq -0x40(%rbp), %rax
movl %ecx, %ecx
shlq %cl, %rax
movq %rax, -0x40(%rbp)
cmpl $0x0, -0x30(%rbp)
je 0x16c04
movq -0x60(%rbp), %rax
movq 0x2d8(%rax), %rax
movl $0x40, %ecx
subl -0x30(%rbp), %ecx
movl %ecx, %ecx
shlq %cl, %rax
movq %rax, -0x68(%rbp)
jmp 0x16c0c
xorl %eax, %eax
movq %rax, -0x68(%rbp)
jmp 0x16c0c
movq -0x68(%rbp), %rax
movq %rax, -0x48(%rbp)
cmpl $0x0, -0x30(%rbp)
je 0x16c31
movq -0x48(%rbp), %rax
movl $0x40, %ecx
subl -0x30(%rbp), %ecx
movl %ecx, %ecx
shrq %cl, %rax
movq %rax, -0x70(%rbp)
jmp 0x16c39
xorl %eax, %eax
movq %rax, -0x70(%rbp)
jmp 0x16c39
movq -0x60(%rbp), %rax
movq -0x70(%rbp), %rcx
movq %rcx, -0x48(%rbp)
movq -0x40(%rbp), %rcx
orq -0x48(%rbp), %rcx
orq -0x38(%rbp), %rcx
movq %rcx, 0x2d8(%rax)
jmp 0x16e93
movl -0x24(%rbp), %eax
andl $0xc0000000, %eax       # imm = 0xC0000000
cmpl $0x40000000, %eax       # imm = 0x40000000
jbe 0x16dbc
movl -0x24(%rbp), %eax
andl $0xffffff, %eax         # imm = 0xFFFFFF
movl %eax, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
andl $0x800000, %eax         # imm = 0x800000
cmpl $0x0, %eax
je 0x16c93
movl -0x4c(%rbp), %eax
orl $0xff000000, %eax       # imm = 0xFF000000
movl %eax, -0x4c(%rbp)
movq -0x60(%rbp), %rax
testb $0x1, 0x14e0(%rax)
jne 0x16ca9
movl -0x4c(%rbp), %eax
shrl $0x2, %eax
movl %eax, -0x4c(%rbp)
movl -0x24(%rbp), %eax
andl $0x3f000000, %eax       # imm = 0x3F000000
shrl $0x18, %eax
movb %al, -0x26(%rbp)
movzbl -0x26(%rbp), %eax
cmpl $0x2a, %eax
jl 0x16cd5
movzbl -0x26(%rbp), %eax
cmpl $0x31, %eax
jg 0x16cd5
movzbl -0x26(%rbp), %eax
subl $0x19, %eax
movb %al, -0x26(%rbp)
jmp 0x16cf3
movzbl -0x26(%rbp), %eax
cmpl $0x15, %eax
jl 0x16cf1
movzbl -0x26(%rbp), %eax
cmpl $0x1c, %eax
jg 0x16cf1
movzbl -0x26(%rbp), %eax
subl $0xc, %eax
movb %al, -0x26(%rbp)
jmp 0x16cf3
movb $0x1, -0x4d(%rbp)
movl -0x24(%rbp), %eax
andl $0xc0000000, %eax       # imm = 0xC0000000
cmpl $0xc0000000, %eax       # imm = 0xC0000000
jne 0x16d0a
movb $0x0, -0x4d(%rbp)
testb $0x1, -0x4d(%rbp)
jne 0x16d23
movq -0x60(%rbp), %rax
movl 0x1550(%rax), %ecx
movzbl -0x26(%rbp), %eax
addl %ecx, %eax
movb %al, -0x26(%rbp)
movq -0x60(%rbp), %rcx
movzbl -0x26(%rbp), %eax
cmpl 0x2b70(%rcx), %eax
jge 0x16db7
movq -0x60(%rbp), %rcx
movq 0x2b50(%rcx), %rax
movzbl -0x26(%rbp), %edx
movl (%rax,%rdx,4), %esi
addl $0x1, %esi
movl %esi, (%rax,%rdx,4)
movq 0x2b50(%rcx), %rax
movzbl -0x26(%rbp), %edx
movl (%rax,%rdx,4), %eax
movl %eax, -0x54(%rbp)
movl -0x54(%rbp), %eax
cmpl 0x2b74(%rcx), %eax
jle 0x16d8e
movq -0x60(%rbp), %rax
movq 0x2b50(%rax), %rax
movzbl -0x26(%rbp), %ecx
movl (%rax,%rcx,4), %edx
addl $-0x1, %edx
movl %edx, (%rax,%rcx,4)
movl -0x54(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x16db3
movq -0x60(%rbp), %rsi
movl -0x4c(%rbp), %edx
movq 0x2b58(%rsi), %rax
movzbl -0x26(%rbp), %ecx
imull 0x2b74(%rsi), %ecx
addl -0x54(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movb $0x1, -0x25(%rbp)
jmp 0x16e91
movl -0x24(%rbp), %eax
andl $0xf0000000, %eax       # imm = 0xF0000000
cmpl $0x0, %eax
jne 0x16de1
movq -0x60(%rbp), %rax
movl -0x24(%rbp), %ecx
andl $0xffffff, %ecx         # imm = 0xFFFFFF
movl %ecx, 0x1540(%rax)
jmp 0x16e8f
movl -0x24(%rbp), %eax
andl $0x10000000, %eax       # imm = 0x10000000
cmpl $0x10000000, %eax       # imm = 0x10000000
jne 0x16e8d
movq -0x60(%rbp), %rcx
movl -0x24(%rbp), %eax
andl $0xffffff, %eax         # imm = 0xFFFFFF
movl %eax, -0x58(%rbp)
movl -0x58(%rbp), %eax
cmpl 0x1534(%rcx), %eax
jbe 0x16e2d
movq -0x60(%rbp), %rax
movl -0x58(%rbp), %ecx
subl 0x1534(%rax), %ecx
movl %ecx, %ecx
addq 0x1538(%rax), %rcx
movq %rcx, 0x1538(%rax)
jmp 0x16e80
movq -0x60(%rbp), %rcx
movl -0x58(%rbp), %eax
cmpl 0x1534(%rcx), %eax
jae 0x16e7e
movq -0x60(%rbp), %rax
movl -0x58(%rbp), %ecx
addq 0x1538(%rax), %rcx
movq %rcx, 0x1538(%rax)
movq 0x1538(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x1538(%rax)
movl $0xffffff, %ecx         # imm = 0xFFFFFF
subl 0x1534(%rax), %ecx
movl %ecx, %ecx
addq 0x1538(%rax), %rcx
movq %rcx, 0x1538(%rax)
jmp 0x16e80
movq -0x60(%rbp), %rax
movl -0x58(%rbp), %ecx
movl %ecx, 0x1534(%rax)
jmp 0x16e8f
jmp 0x16e91
jmp 0x16e93
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x16b13
testb $0x1, -0x25(%rbp)
je 0x16edd
movq -0x60(%rbp), %rax
movq 0x1538(%rax), %rdx
shlq $0x18, %rdx
movq -0x10(%rbp), %rcx
movq %rdx, (%rcx)
movl 0x1540(%rax), %ecx
movl %ecx, %edx
movq -0x10(%rbp), %rcx
addq (%rcx), %rdx
movq %rdx, (%rcx)
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
movq %rcx, 0x1548(%rax)
movb -0x25(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax,%rax)