// File: /workspace/github_cpp_makefile_star2_O1/probonopd[P]decodeir/DecodeIR.cpp
// Function: Signal::trySejin()
void Signal::trySejin()  // GD 2009  Added trySejin
// PID = 0161 (0161:3 for Sejin-1, 0161:5 for both Sejin-1 and Sejin-2 in one upgrade.)
//
// The Sejin protocols have two signal styles, Sejin-1 and Sejin-2, and two frequency 
// variants, 38 and 56.  The signal styles have the following common structure:
//
// Sejin-M-38	{38.8k,310,msb}<-1|1>(<8:4|4:4|2:4|1:4>(3,3:2,Dx:8,Fx:8,Fy:8,E:4,C:4,-L))+
// Sejin-M-56	{56.3k,310,msb}<-1|1>(<8:4|4:4|2:4|1:4>(3,3:2,Dx:8,Fx:8,Fy:8,E:4,C:4,-L))+
//
// where E is a checksum seed (0 in all known examples) and C is the checksum given by
// C = (Dx:4 + Dx:4:4 + Fx:4 + Fx:4:4 + Fy:4 + Fy:4:4 + E) & 15.
//
// Dx is a signed 8-bit integer, ie range -128 to +127. If Dx >= 0 the style is Sejin-1 and 
// the leadout time L is 77m.  This style is used for normal remote-control buttons.  If
// Dx < 0 the style is Sejin-2 and the leadout time L is the much shorter 3.6m.  This style is
// used for signals corresponding to a pointing device with up to 3 buttons.  The short
// leadout allows for much faster repeat action.  The signal parameters Dx, Fx, Fy have 
// different significance in the two styles.
//
// The data parameters in Sejin-1 are 7-bit device and subdevice codes D and S, an 8-bit
// function code F and a toggle bit T.  The signal repeats as long as the key is held, with
// T=0 for all frames except the last, T=1 for the last frame.  The corresponding signal
// parameters are:
//             Dx = D, Fx:1:7 = T, Fx:7 = S, Fy = F.
//
// Sejin-2 has a 5-bit device code D and no subdevice code.  It further divides into 
// two sub-styles, 2A corresponding to movement of the pointing device, and
// 2B corresponding to movement of its buttons.  In Sejin-2A the data parameters are the
// coordinates (X,Y) of the displacement of a cursor and the signal parameters are
//             Dx:6:2 = (-D):6,  Dx:2 = 0, Fx = X:8, Fy = Y:8.
// Note that X and Y can be negative, so Fx and Fy are signed 8-bit integers.  The signal
// repeats indefinitely.
//
// Sejin-2B corresponds to down and up movements of the buttons of the pointing device.
// A "down" signal is sent exactly once on button down (distinct for each button) and an
// "up" signal is sent exactly once on button up (same for each button).  There is one
// data parameter, B.  When B = 1,2 or 3 it denotes button B down, when B = 0 it denotes
// button up.  The signal parameters are
//             Dx:6:2 = (-D):6,  Dx:2 = B:2, Fx = 0, Fy = 0.
//
// The 0161:5 protocol can only generate signals in which one of Fx or Fy is zero.  It
// uses (-D)*4 as a device byte and has two function bytes.  The first is the nonzero
// one of Fx and Fy (or 0 if both are 0).  The second has B in bits 0 and 1 (0 for
// Sejin-2A), bit 4 is set for Sejin-2A and clear for Sejin-2B and bit 3 flags which of
// X or Y is nonzero in Sejin-2A (set for X, clear for Y).
//
// The Misc field includes a 13-byte integer RMOBC which is these two bytes in decimal
// form.  It can be entered in RemoteMaster into the RMOBC column of the function page
// for the Sejin-M-N protocol.

{
	if ( nFrameL < 15 || nTotDur < 18000 || nTotDur > 26000) return;

	const float unit = 310.;
	static int FC = 0;					// count of bypassed frames

	if (	!framed(10 * unit)			// must allow for 3.6ms leadout for Sejin type 2
		||	sortOn.max2 > 2.4 * unit
		||	sortOn.min1 < 0.5 * unit )
	{
		return;
	}

	// Next condition added in v2.40 as a specific JVC{2} signal was giving spurious Sejin decode.
	if (	pFrame[0] < 700 || pFrame[0] > 1150		// nominal 930, allow 25% either way
		||	pFrame[1] < 700 || pFrame[1] > 1150 )	// nominal 930, allow 25% either way
	{
		return;
	}

	cleanup();
	pBit++;			// skip initial 3-unit ON
	int bcnt = 0;	// bit count (outer, <-1|1>, coding) to start of next OFF
	int dbit;		// double bit (inner coding)
	while (pBit < pFrameEnd)
	{
		bcnt += (int)( (pBit[0] + pBit[1]) / unit + 0.5 );	// advance to start of following OFF
		pBit += 2;
		while (bcnt > 2 * nBit)
		{
			dbit = min( bcnt - 2 * nBit - 1, 3 );		// make next double bit
			cBits[nBit>>3] |= dbit << (6 - (nBit & 6));	// add to cBits in msb form
			nBit += 2;
		}
	}
	if (	nBit != 34											// number of bits
		||	getMsb(0,2) != 3									// initial double bit
		||	getMsb(30,4) != ( getMsb(2,4) + getMsb(6,4) + getMsb(10,4) + 
				getMsb(14,4) + getMsb(18,4) + getMsb(22,4) + getMsb(26,4) ) % 16	// checksum
		||	!getMsb(2,1) && !framed(100*unit) )	// long leadout for Sejin type 1
	{
		return;
	}

	// look to see if there is a following frame
	float* pFrameEnd2 = pFrameEnd + 1;
	for ( ; pFrameEnd2 < pMainLimit; pFrameEnd2++ )
	{
		if ( *pFrameEnd2 > 10 * unit ) break;
	};
	pBit += 2;
	bcnt = 2 * nBit;
	while (pBit < pFrameEnd2)
	{
		bcnt += (int)( (pBit[0] + pBit[1]) / unit + 0.5 );	// advance to start of following OFF
		pBit += 2;
		while (bcnt > 2 * nBit)
		{
			dbit = min( bcnt - 2 * nBit - 1, 3 );		// make next double bit
			cBits[nBit>>3] |= dbit << (6 - (nBit & 6));	// add to cBits in msb form
			nBit += 2;
		}
	}

	if (	nBit == 68
		&&	getMsb(0,10) == getMsb(34,10)
		&&	(getMsb(2,1) || getMsb(10,1) == 0)		// if type 1 then T=0 except for last frame
		&&	(!getMsb(2,1) || getMsb(10,1) == getMsb(44,1)) // if type 2 then no toggle
		&&	getMsb(11,19) == getMsb(45,19)
		&&	getMsb(31,3) == getMsb(65,3)
		&&  ( getMsb(30,1)^getMsb(64,1) ) == ( getMsb(10,1)^getMsb(44,1) )  // chksum affected by toggle
		&&  (getMsb(36,1) || (*pFrameEnd2 >= 100 * unit) ) )  // either type 2 or long leadout
	{
		if ( FC == 0 ) setzContext();			// save the context value
		FC++;	// increment count of bypassed frames
		return;	// another frame follows, so wait for it to come round
	}

	if ( !getMsb(2,1) )		// type 1
	{
		*pDevice = getMsb(2,8);
		*pSubDevice = getMsb(11,7);
		*pOBC = getMsb(18,8);
		pHex[0] = *pOBC;
		strcpy(pProtocol, nFreq < 45000 ? "Sejin-1-38" : "Sejin-1-56");
		sprintf(pMisc, getMsb(10,1) ? "E=%d" : "E=%d, no end frame", getMsb(26,4));
	}
	else				// type 2
	{	
		// RMOBC is the decimal form of the 2-byte hex function code needed in RemoteMaster
		// with protocol 0161:5 to generate the signal concerned

		int X = getMsb(10,1) ? getMsb(10,8)-256 : getMsb(10,8); // X coord of delta
		int Y = getMsb(18,1) ? getMsb(18,8)-256 : getMsb(18,8); // Y coord of delta
		int Fn1 = getMsb(10,8) ? getMsb(10,8) : getMsb(18,8);	// 1st function byte
		int Fn2 = getMsb(8,2);									// 2nd function byte
		*pDevice = (64-getMsb(2,6));
		*pOBC = Fn2;
		Fn2 += getMsb(10,8) ? 0x08 : 0;		// flag set if X coord, clear if Y coord
		Fn2 += Fn1 ? 0x10 : 0;				// flag set if delta, clear if button down/up 
		strcpy(pProtocol, nFreq < 45000 ? "Sejin-2-38" : "Sejin-2-56");
		if ( X == 0 && Y == 0 && *pOBC == 0 )
		{
			sprintf(pMisc, "Btn up; E=%d, RMOBC=%d", getMsb(26,4), Fn1 + 0x100*Fn2);
		}
		else if ( X == 0 && Y == 0 )
		{
			sprintf(pMisc, "Btn down (OBC=Btn nbr); E=%d, RMOBC=%d", getMsb(26,4), Fn1 + 0x100*Fn2);
		}
		else if ( X == 0 || Y == 0 )
		{
			sprintf(pMisc, "delta = (%d,%d); E=%d, RMOBC=%d", X, Y, getMsb(26,4), Fn1 + 0x100*Fn2);
		}
		else
		{
			sprintf(pMisc, "delta = (%d,%d); E=%d, RMOBC unsupported", X, Y, getMsb(26,4) );
		}
	}
	nFrameCount = FC;
	FC = 0;		// reset static variable
}

// Assembly:
cmpl $0xf, 0x48(%rdi)
jl 0x5d3d
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rdi, %rbx
movss 0x98(%rdi), %xmm0
movss 0xce8a(%rip), %xmm1     # 0x12520
ucomiss %xmm0, %xmm1
ja 0x5d35
ucomiss 0xce7e(%rip), %xmm0     # 0x12524
ja 0x5d35
movss 0x140(%rbx), %xmm0
ucomiss 0xce6d(%rip), %xmm0     # 0x12528
jb 0x5d35
movss 0x188(%rbx), %xmm0
ucomiss 0xce5c(%rip), %xmm0     # 0x1252c
ja 0x5d35
movss 0xce52(%rip), %xmm0     # 0x12530
ucomiss 0x180(%rbx), %xmm0
ja 0x5d35
movq 0x38(%rbx), %rcx
movss (%rcx), %xmm1
movss 0xce39(%rip), %xmm0     # 0x12534
ucomiss %xmm1, %xmm0
ja 0x5d35
ucomiss 0xce2d(%rip), %xmm1     # 0x12538
ja 0x5d35
movss 0x4(%rcx), %xmm1
ucomiss %xmm1, %xmm0
ja 0x5d35
ucomiss 0xce12(%rip), %xmm1     # 0x12538
ja 0x5d35
addq $0x4, %rcx
xorps %xmm0, %xmm0
movups %xmm0, 0xa0(%rbx)
movq $0x0, 0xc0(%rbx)
movq %rcx, 0xc8(%rbx)
movq 0x40(%rbx), %rsi
cmpq %rsi, %rcx
jae 0x57ee
xorl %edx, %edx
movss 0xcdd9(%rip), %xmm0     # 0x1253c
movsd 0xc965(%rip), %xmm1     # 0x120d0
movl $0x3, %eax
movss (%rcx), %xmm2
addss 0x4(%rcx), %xmm2
movl %edx, %esi
divss %xmm0, %xmm2
cvtss2sd %xmm2, %xmm2
addsd %xmm1, %xmm2
cvttsd2si %xmm2, %edx
addl %esi, %edx
addq $0x8, %rcx
movq %rcx, 0xc8(%rbx)
movl 0xc0(%rbx), %esi
leal (%rsi,%rsi), %edi
cmpl %edi, %edx
jle 0x57de
notl %edi
addl %edx, %edi
cmpl $0x3, %edi
cmovgel %eax, %edi
movl %esi, %ecx
notb %cl
andb $0x6, %cl
shll %cl, %edi
sarl $0x3, %esi
movslq %esi, %rcx
orb %dil, 0xa0(%rbx,%rcx)
movl 0xc0(%rbx), %ecx
leal 0x2(%rcx), %esi
movl %esi, 0xc0(%rbx)
leal 0x4(,%rcx,2), %edi
jmp 0x57a1
movq 0x40(%rbx), %rsi
movq 0xc8(%rbx), %rcx
cmpq %rsi, %rcx
jb 0x5770
cmpl $0x22, 0xc0(%rbx)
jne 0x5d35
leaq 0xa0(%rbx), %rax
movzbl (%rax), %r8d
movl %r8d, %edx
notl %edx
testb $-0x40, %dl
jne 0x5d35
movzbl 0xa3(%rbx), %r9d
movl %r9d, %edx
andl $0x3, %edx
movzbl 0xa4(%rbx), %edi
shrl $0x6, %edi
leal (%rdi,%rdx,4), %edi
movl %r8d, %edx
andl $0x3f, %edx
movl %edx, %r14d
shrl $0x2, %r14d
andl $0x3, %r8d
movzbl 0xa1(%rbx), %r10d
movl %r10d, %r15d
shrl $0x6, %r15d
movzbl 0xa2(%rbx), %r11d
movl %r9d, %r12d
shrl $0x6, %r12d
shrl $0x2, %r9d
addl %r12d, %r9d
addl %r15d, %r9d
leal (%r14,%r8,4), %r8d
addl %r9d, %r8d
leal (%r8,%r11,4), %r8d
leal (%r8,%r10,4), %r8d
movl %r10d, %r9d
shrl $0x2, %r9d
movl %r11d, %r10d
shrl $0x6, %r11d
addl %r9d, %r11d
shrl $0x2, %r10d
addl %r11d, %r10d
addl %r10d, %r8d
andl $0xf, %r8d
cmpl %r8d, %edi
jne 0x5d35
cmpl $0x1f, %edx
ja 0x58b9
movss 0x140(%rbx), %xmm0
ucomiss 0xcc8d(%rip), %xmm0     # 0x12540
jb 0x5d35
movq 0x10(%rbx), %rdi
addq $0x4, %rsi
movss 0xcc5f(%rip), %xmm0     # 0x12528
movq %rsi, %rdx
cmpq %rdi, %rsi
jae 0x58de
movss (%rdx), %xmm1
leaq 0x4(%rdx), %rsi
ucomiss %xmm0, %xmm1
jbe 0x58c9
addq $0x8, %rcx
movq %rcx, 0xc8(%rbx)
cmpq %rdx, %rcx
jae 0x5999
movl $0x44, %edi
movss 0xcc3d(%rip), %xmm0     # 0x1253c
movsd 0xc7c9(%rip), %xmm1     # 0x120d0
movl $0x3, %esi
movss (%rcx), %xmm2
addss 0x4(%rcx), %xmm2
movl %edi, %r8d
divss %xmm0, %xmm2
cvtss2sd %xmm2, %xmm2
addsd %xmm1, %xmm2
cvttsd2si %xmm2, %edi
addl %r8d, %edi
addq $0x8, %rcx
movq %rcx, 0xc8(%rbx)
movl 0xc0(%rbx), %r8d
leal (%r8,%r8), %r9d
cmpl %r9d, %edi
jle 0x5989
notl %r9d
addl %edi, %r9d
cmpl $0x3, %r9d
cmovgel %esi, %r9d
movl %r8d, %ecx
notb %cl
andb $0x6, %cl
shll %cl, %r9d
sarl $0x3, %r8d
movslq %r8d, %rcx
orb %r9b, 0xa0(%rbx,%rcx)
movl 0xc0(%rbx), %ecx
leal 0x2(%rcx), %r8d
movl %r8d, 0xc0(%rbx)
leal 0x4(,%rcx,2), %r9d
jmp 0x5941
movq 0xc8(%rbx), %rcx
cmpq %rdx, %rcx
jb 0x590c
cmpl $0x44, 0xc0(%rbx)
jne 0x5adb
movzbl 0xa0(%rbx), %r8d
movzbl 0xa1(%rbx), %esi
movl %esi, %ecx
shrl $0x6, %ecx
leal (%rcx,%r8,4), %r9d
movzbl 0xa4(%rbx), %ecx
movl %ecx, %r10d
andl $0x3f, %r10d
shll $0x4, %r10d
movzbl 0xa5(%rbx), %edi
movl %edi, %r11d
shrl $0x4, %r11d
orl %r10d, %r11d
cmpl %r11d, %r9d
jne 0x5adb
testb $0x20, %r8b
jne 0x5a00
testb $0x20, %sil
jne 0x5adb
testb $0x20, %r8b
je 0x5a1b
movl %esi, %r8d
shrl $0x5, %r8d
movl %edi, %r9d
shrl $0x3, %r9d
xorl %r8d, %r9d
testb $0x1, %r9b
jne 0x5adb
movl %esi, %r9d
andl $0x1f, %r9d
shll $0x8, %r9d
movzbl 0xa2(%rbx), %r8d
orl %r9d, %r8d
movzbl 0xa3(%rbx), %r9d
shrl $0x2, %r9d
movl %edi, %r10d
andl $0x7, %r10d
movl $0xa6, %r11d
movl %r10d, %r14d
shll $0x8, %r14d
movzbl (%rbx,%r11), %r10d
orl %r14d, %r10d
incq %r11
cmpq $0xa8, %r11
jne 0x5a4a
shll $0x6, %r8d
orl %r9d, %r8d
cmpl %r10d, %r8d
jne 0x5adb
movzbl 0xa3(%rbx), %r9d
movl %r9d, %r8d
andl $0x1, %r8d
movl %ecx, %r10d
shrl $0x6, %r10d
leal (%r10,%r8,4), %r10d
movzbl 0xa8(%rbx), %r8d
movl %r8d, %r11d
shrl $0x4, %r11d
andl $0x7, %r11d
cmpl %r11d, %r10d
jne 0x5adb
shrl %r9d
andl $0x1, %r9d
shrl $0x7, %r8d
xorl %r9d, %r8d
shrl $0x5, %esi
shrl $0x3, %edi
xorl %esi, %edi
andl $0x1, %edi
cmpl %edi, %r8d
jne 0x5adb
testb $0x8, %cl
jne 0x5d3e
movss (%rdx), %xmm0
ucomiss 0xca6b(%rip), %xmm0     # 0x12540
jae 0x5d3e
movzbl (%rax), %esi
andl $0x3f, %esi
cmpb $0x1f, %sil
ja 0x5baf
movzbl 0xa1(%rbx), %eax
shrl $0x6, %eax
leal (%rax,%rsi,4), %eax
movq 0x160(%rbx), %rcx
movl %eax, (%rcx)
movzbl 0xa1(%rbx), %eax
andl $0x1f, %eax
movzbl 0xa2(%rbx), %ecx
shrl $0x6, %ecx
leal (%rcx,%rax,4), %eax
movq 0x168(%rbx), %rcx
movl %eax, (%rcx)
movb 0xa2(%rbx), %al
movb 0xa3(%rbx), %cl
shrb $0x6, %cl
shlb $0x2, %al
orb %cl, %al
movzbl %al, %eax
movq 0x170(%rbx), %rcx
movl %eax, (%rcx)
movq 0x178(%rbx), %rcx
movl %eax, (%rcx)
movq 0x148(%rbx), %rax
cmpl $0xafc8, 0x2c(%rbx)     # imm = 0xAFC8
leaq 0xd26a(%rip), %rcx      # 0x12dc9
leaq 0xd26e(%rip), %rdx      # 0x12dd4
cmovlq %rcx, %rdx
movl 0x7(%rdx), %ecx
movl %ecx, 0x7(%rax)
movq (%rdx), %rcx
movq %rcx, (%rax)
testb $0x20, 0xa1(%rbx)
leaq 0xd25b(%rip), %rax      # 0x12ddf
leaq 0xd12c(%rip), %rsi      # 0x12cb7
cmoveq %rax, %rsi
movq 0x150(%rbx), %rdi
movzbl 0xa3(%rbx), %edx
shrl $0x2, %edx
andl $0xf, %edx
xorl %eax, %eax
callq 0x2060
jmp 0x5d22
movzbl 0xa1(%rbx), %eax
movl %eax, %edi
andl $0x3f, %edi
movzbl 0xa2(%rbx), %ecx
shrl $0x6, %ecx
cmpl $0x20, %edi
jae 0x5bcf
leal (%rcx,%rdi,4), %edx
jmp 0x5bd8
leal (%rcx,%rax,4), %edx
orl $0xffffff00, %edx       # imm = 0xFFFFFF00
movzbl 0xa2(%rbx), %r9d
movl %r9d, %r8d
andl $0x3f, %r8d
movzbl 0xa3(%rbx), %ecx
shrl $0x6, %ecx
cmpl $0x20, %r8d
jae 0x5bfd
leal (%rcx,%r8,4), %ecx
jmp 0x5c07
leal (%rcx,%r9,4), %ecx
orl $0xffffff00, %ecx       # imm = 0xFFFFFF00
shrl $0x6, %r9d
leal (%r9,%rdi,4), %edi
movzbl 0xa3(%rbx), %r9d
shrl $0x6, %r9d
testl %edi, %edi
leal (%r9,%r8,4), %r10d
cmovnel %edi, %r10d
xorl %edi, %edi
testl %r10d, %r10d
setne %dil
shrl $0x6, %eax
movl $0x40, %r8d
subl %esi, %r8d
movq 0x160(%rbx), %rsi
movl %r8d, (%rsi)
movq 0x170(%rbx), %rsi
movl %eax, (%rsi)
movb 0xa1(%rbx), %sil
movb 0xa2(%rbx), %r8b
shrb $0x6, %r8b
shlb $0x2, %sil
orb %r8b, %sil
xorl %r8d, %r8d
testb %sil, %sil
setne %r8b
shll $0x4, %edi
leal (%rdi,%r8,8), %r9d
orl %eax, %r9d
movq 0x148(%rbx), %rax
cmpl $0xafc8, 0x2c(%rbx)     # imm = 0xAFC8
leaq 0xd163(%rip), %rsi      # 0x12df2
leaq 0xd167(%rip), %rdi      # 0x12dfd
cmovlq %rsi, %rdi
movl 0x7(%rdi), %esi
movl %esi, 0x7(%rax)
movq (%rdi), %rsi
movq %rsi, (%rax)
movzbl 0xa3(%rbx), %r8d
shrl $0x2, %r8d
andl $0xf, %r8d
movl %ecx, %eax
orl %edx, %eax
movq 0x150(%rbx), %rdi
je 0x5cdb
testl %edx, %edx
je 0x5cf7
testl %ecx, %ecx
je 0x5cf7
leaq 0xd194(%rip), %rsi      # 0x12e66
xorl %eax, %eax
callq 0x2060
jmp 0x5d22
movq 0x170(%rbx), %rax
shll $0x8, %r9d
orl %r10d, %r9d
cmpl $0x0, (%rax)
je 0x5d0e
leaq 0xd12a(%rip), %rsi      # 0x12e1f
jmp 0x5d15
shll $0x8, %r9d
orl %r10d, %r9d
leaq 0xd141(%rip), %rsi      # 0x12e46
xorl %eax, %eax
callq 0x2060
jmp 0x5d22
leaq 0xd0f3(%rip), %rsi      # 0x12e08
movl %r8d, %edx
movl %r9d, %ecx
xorl %eax, %eax
callq 0x2060
movl 0x105e0(%rip), %eax     # 0x16308
movl %eax, 0x60(%rbx)
xorl %r14d, %r14d
movl %r14d, 0x105d3(%rip)    # 0x16308
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movl 0x105c3(%rip), %r14d    # 0x16308
testl %r14d, %r14d
jne 0x5d52
movq %rbx, %rdi
callq 0x26ec
incl %r14d
jmp 0x5d2e
nop