// File: /workspace/github_cpp_makefile_star2_O2/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 0x5934
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %rbx
movss 0x98(%rdi), %xmm0
movss 0xc24c(%rip), %xmm1     # 0x11520
ucomiss %xmm0, %xmm1
ja 0x5926
ucomiss 0xc240(%rip), %xmm0     # 0x11524
ja 0x5926
movss 0x140(%rbx), %xmm0
ucomiss 0xc22f(%rip), %xmm0     # 0x11528
jb 0x5926
movss 0x188(%rbx), %xmm0
ucomiss 0xc21e(%rip), %xmm0     # 0x1152c
ja 0x5926
movss 0xc214(%rip), %xmm0     # 0x11530
ucomiss 0x180(%rbx), %xmm0
ja 0x5926
movq 0x38(%rbx), %r12
movss (%r12), %xmm1
movss 0xc1f9(%rip), %xmm0     # 0x11534
ucomiss %xmm1, %xmm0
ja 0x5926
ucomiss 0xc1ed(%rip), %xmm1     # 0x11538
ja 0x5926
movss 0x4(%r12), %xmm1
ucomiss %xmm1, %xmm0
ja 0x5926
ucomiss 0xc1d0(%rip), %xmm1     # 0x11538
ja 0x5926
xorps %xmm0, %xmm0
movups %xmm0, 0xa0(%rbx)
andq $0x0, 0xc0(%rbx)
addq $0x4, %r12
leaq 0xa0(%rbx), %rdi
movq %r12, 0xc8(%rbx)
xorl %eax, %eax
pushq $0x3
popq %r14
xorl %edx, %edx
movq 0x40(%rbx), %r13
cmpq %r13, %r12
jae 0x5417
movss (%r12), %xmm0
addss 0x4(%r12), %xmm0
divss 0xc188(%rip), %xmm0     # 0x11540
cvtss2sd %xmm0, %xmm0
addsd 0xbd0c(%rip), %xmm0     # 0x110d0
cvttsd2si %xmm0, %ecx
addl %ecx, %edx
addq $0x8, %r12
movq %r12, 0xc8(%rbx)
leal (%rax,%rax), %esi
cmpl %esi, %edx
jle 0x540e
notl %esi
addl %edx, %esi
cmpl $0x3, %esi
cmovgel %r14d, %esi
movl %eax, %ecx
notb %cl
andb $0x6, %cl
shll %cl, %esi
sarl $0x3, %eax
cltq
orb %sil, 0xa0(%rbx,%rax)
movl 0xc0(%rbx), %eax
addl $0x2, %eax
movl %eax, 0xc0(%rbx)
jmp 0x53d5
movq 0xc8(%rbx), %r12
jmp 0x539a
cmpl $0x22, %eax
jne 0x5926
movzbl (%rdi), %r15d
movl %r15d, %eax
notl %eax
testb $-0x40, %al
jne 0x5926
pushq $0x1e
popq %rsi
pushq $0x4
popq %rdx
movq %rdi, -0x30(%rbp)
movq %rbx, %rdi
callq 0xeb6a
movl %eax, -0x44(%rbp)
andl $0x3f, %r15d
movl %r15d, -0x48(%rbp)
shrl $0x2, %r15d
movl %r15d, -0x40(%rbp)
pushq $0x6
popq %rsi
movq %rbx, %rdi
pushq $0x4
popq %r15
movl %r15d, %edx
callq 0xeb6a
movl %eax, -0x3c(%rbp)
movzbl 0xa1(%rbx), %eax
shrl $0x2, %eax
movl %eax, -0x38(%rbp)
pushq $0xe
popq %rsi
movq %rbx, %rdi
movl %r15d, %edx
callq 0xeb6a
movl %eax, %r15d
movzbl 0xa2(%rbx), %eax
shrl $0x2, %eax
movl %eax, -0x34(%rbp)
pushq $0x16
popq %rsi
movq %rbx, %rdi
pushq $0x4
popq %rdx
callq 0xeb6a
movsd 0xbc24(%rip), %xmm3     # 0x110d0
movss 0xc08c(%rip), %xmm2     # 0x11540
movq -0x30(%rbp), %rdi
movzbl 0xa3(%rbx), %ecx
shrl $0x2, %ecx
addl -0x3c(%rbp), %r15d
addl -0x38(%rbp), %r15d
addl -0x40(%rbp), %r15d
addl -0x34(%rbp), %eax
addl %ecx, %eax
addl %r15d, %eax
movl -0x48(%rbp), %ecx
andl $0xf, %eax
cmpl %eax, -0x44(%rbp)
jne 0x5926
cmpl $0x1f, %ecx
ja 0x54ff
movss 0x140(%rbx), %xmm0
ucomiss 0xc043(%rip), %xmm0     # 0x1153c
jb 0x5926
movq 0x10(%rbx), %rax
addq $0x4, %r13
movss 0xc019(%rip), %xmm0     # 0x11528
movq %r13, %r15
cmpq %rax, %r13
jae 0x5525
movss (%r15), %xmm1
leaq 0x4(%r15), %r13
ucomiss %xmm0, %xmm1
jbe 0x550f
addq $0x8, %r12
movq %r12, 0xc8(%rbx)
pushq $0x44
popq %rax
pushq $0x22
popq %rdx
cmpq %r15, %r12
jae 0x55a8
movss (%r12), %xmm0
addss 0x4(%r12), %xmm0
divss %xmm2, %xmm0
cvtss2sd %xmm0, %xmm0
addsd %xmm3, %xmm0
cvttsd2si %xmm0, %ecx
addl %ecx, %eax
addq $0x8, %r12
movq %r12, 0xc8(%rbx)
leal (%rdx,%rdx), %esi
cmpl %esi, %eax
jle 0x559f
notl %esi
addl %eax, %esi
cmpl $0x3, %esi
cmovgel %r14d, %esi
movl %edx, %ecx
notb %cl
andb $0x6, %cl
shll %cl, %esi
sarl $0x3, %edx
movslq %edx, %rcx
orb %sil, 0xa0(%rbx,%rcx)
movl 0xc0(%rbx), %edx
addl $0x2, %edx
movl %edx, 0xc0(%rbx)
jmp 0x5565
movq 0xc8(%rbx), %r12
jmp 0x5536
cmpl $0x44, %edx
jne 0x55f5
pushq $0xa
popq %r14
movq %rbx, %rdi
xorl %esi, %esi
movl %r14d, %edx
callq 0xeb6a
movl %eax, %r12d
pushq $0x22
popq %rsi
movq %rbx, %rdi
movl %r14d, %edx
callq 0xeb6a
movb 0xa0(%rbx), %dl
cmpl %eax, %r12d
jne 0x55f7
movb 0xa1(%rbx), %r13b
testb $0x20, %dl
jne 0x582c
testb $0x20, %r13b
jne 0x55f7
jmp 0x5846
movb (%rdi), %dl
andb $0x3f, %dl
cmpb $0x1f, %dl
ja 0x56ba
pushq $0x2
popq %rsi
pushq $0x8
popq %r14
movq %rbx, %rdi
movl %r14d, %edx
callq 0xeb6a
movq 0x160(%rbx), %rcx
movl %eax, (%rcx)
pushq $0xb
popq %rsi
pushq $0x7
popq %rdx
movq %rbx, %rdi
callq 0xeb6a
movq 0x168(%rbx), %rcx
movl %eax, (%rcx)
pushq $0x12
popq %rsi
movq %rbx, %rdi
movl %r14d, %edx
callq 0xeb6a
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 0xc756(%rip), %rcx      # 0x11dc0
leaq 0xc75a(%rip), %rdx      # 0x11dcb
cmovlq %rcx, %rdx
movl 0x7(%rdx), %ecx
movl %ecx, 0x7(%rax)
movq (%rdx), %rcx
movq %rcx, (%rax)
testb $0x20, 0xa1(%rbx)
leaq 0xc747(%rip), %rax      # 0x11dd6
leaq 0xc618(%rip), %rsi      # 0x11cae
cmoveq %rax, %rsi
movq 0x150(%rbx), %rdi
movzbl 0xa3(%rbx), %edx
shrl $0x2, %edx
andl $0xf, %edx
xorl %eax, %eax
callq 0x2060
jmp 0x5913
movb %dl, -0x30(%rbp)
movzbl 0xa1(%rbx), %r13d
pushq $0xa
popq %rsi
pushq $0x8
popq %r14
movq %rbx, %rdi
movl %r14d, %edx
callq 0xeb6a
movl %eax, %r12d
movb 0xa2(%rbx), %r15b
pushq $0x12
popq %rsi
movq %rbx, %rdi
movl %r14d, %edx
callq 0xeb6a
movl $0xffffff00, %r14d      # imm = 0xFFFFFF00
leal (%rax,%r14), %ecx
testb $0x20, %r15b
movl %ecx, %r15d
cmovel %eax, %r15d
addl %r12d, %r14d
testb $0x20, %r13b
cmovel %r12d, %r14d
movq %rbx, %rdi
pushq $0xa
popq %rsi
pushq $0x8
popq %rdx
callq 0xeb6a
movl %eax, %r12d
testl %eax, %eax
jne 0x5735
pushq $0x12
popq %rsi
pushq $0x8
popq %rdx
movq %rbx, %rdi
callq 0xeb6a
movl %eax, %r12d
shrl $0x6, %r13d
movb $0x40, %al
subb -0x30(%rbp), %al
movzbl %al, %eax
movq 0x160(%rbx), %rcx
movl %eax, (%rcx)
movq 0x170(%rbx), %rax
movl %r13d, (%rax)
pushq $0xa
popq %rsi
pushq $0x8
popq %rdx
movq %rbx, %rdi
callq 0xeb6a
xorl %ecx, %ecx
testl %eax, %eax
setne %cl
xorl %eax, %eax
testl %r12d, %r12d
setne %al
shll $0x4, %eax
leal (%rax,%rcx,8), %r9d
orl %r13d, %r9d
movq 0x148(%rbx), %rax
cmpl $0xafc8, 0x2c(%rbx)     # imm = 0xAFC8
leaq 0xc659(%rip), %rcx      # 0x11de9
leaq 0xc65d(%rip), %rdx      # 0x11df4
cmovlq %rcx, %rdx
movl 0x7(%rdx), %ecx
movl %ecx, 0x7(%rax)
movq (%rdx), %rcx
movq %rcx, (%rax)
movzbl 0xa3(%rbx), %r8d
shrl $0x2, %r8d
andl $0xf, %r8d
movl %r15d, %eax
orl %r14d, %eax
movq 0x150(%rbx), %rdi
je 0x57e9
testl %r14d, %r14d
je 0x580c
testl %r15d, %r15d
je 0x580c
leaq 0xc686(%rip), %rsi      # 0x11e5d
movl %r14d, %edx
movl %r15d, %ecx
xorl %eax, %eax
callq 0x2060
jmp 0x5913
movq 0x170(%rbx), %rax
shll $0x8, %r9d
addl %r12d, %r9d
cmpl $0x0, (%rax)
je 0x58ff
leaq 0xc60f(%rip), %rsi      # 0x11e16
jmp 0x5906
shll $0x8, %r9d
addl %r12d, %r9d
leaq 0xc623(%rip), %rsi      # 0x11e3d
movl %r14d, %edx
movl %r15d, %ecx
xorl %eax, %eax
callq 0x2060
jmp 0x5913
movl %r13d, %eax
shrb $0x5, %al
movb 0xa5(%rbx), %cl
shrb $0x3, %cl
xorb %al, %cl
testb $0x1, %cl
jne 0x55f7
movb %dl, -0x30(%rbp)
pushq $0xb
popq %rsi
pushq $0x13
popq %r14
movq %rbx, %rdi
movl %r14d, %edx
callq 0xeb6a
movl %eax, %r12d
pushq $0x2d
popq %rsi
movq %rbx, %rdi
movl %r14d, %edx
callq 0xeb6a
cmpl %eax, %r12d
jne 0x58f7
pushq $0x1f
popq %rsi
pushq $0x3
popq %rdx
movq %rbx, %rdi
callq 0xeb6a
movzbl 0xa8(%rbx), %ecx
movl %ecx, %edx
shrl $0x4, %edx
andl $0x7, %edx
cmpl %edx, %eax
jne 0x58f7
movzbl 0xa3(%rbx), %eax
shrl %eax
andl $0x1, %eax
shrl $0x7, %ecx
xorl %eax, %ecx
shrb $0x5, %r13b
movb 0xa5(%rbx), %al
shrb $0x3, %al
xorb %r13b, %al
andb $0x1, %al
movzbl %al, %eax
cmpl %eax, %ecx
jne 0x58f7
testb $0x8, 0xa4(%rbx)
movb -0x30(%rbp), %dl
jne 0x58de
movss (%r15), %xmm0
ucomiss 0xbc64(%rip), %xmm0     # 0x1153c
jb 0x55f7
movl 0xfa33(%rip), %r14d     # 0x15318
testl %r14d, %r14d
jne 0x58f2
movq %rbx, %rdi
callq 0x266a
incl %r14d
jmp 0x591f
movb -0x30(%rbp), %dl
jmp 0x55f7
leaq 0xc4f9(%rip), %rsi      # 0x11dff
movl %r8d, %edx
movl %r9d, %ecx
xorl %eax, %eax
callq 0x2060
movl 0xf9ff(%rip), %eax      # 0x15318
movl %eax, 0x60(%rbx)
xorl %r14d, %r14d
movl %r14d, 0xf9f2(%rip)     # 0x15318
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop