// File: /workspace/github_cpp_makefile_star2_O3/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 0x5e14
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movss 0x98(%rdi), %xmm0
movss 0xcda3(%rip), %xmm1     # 0x12520
ucomiss %xmm0, %xmm1
ja 0x5e06
ucomiss 0xcd97(%rip), %xmm0     # 0x12524
ja 0x5e06
movss 0x140(%rbx), %xmm0
ucomiss 0xcd86(%rip), %xmm0     # 0x12528
jb 0x5e06
movss 0x188(%rbx), %xmm0
ucomiss 0xcd75(%rip), %xmm0     # 0x1252c
ja 0x5e06
movss 0xcd6b(%rip), %xmm0     # 0x12530
ucomiss 0x180(%rbx), %xmm0
ja 0x5e06
movq 0x38(%rbx), %rdx
movss (%rdx), %xmm1
movss 0xcd52(%rip), %xmm0     # 0x12534
ucomiss %xmm1, %xmm0
ja 0x5e06
ucomiss 0xcd46(%rip), %xmm1     # 0x12538
ja 0x5e06
movss 0x4(%rdx), %xmm1
ucomiss %xmm1, %xmm0
ja 0x5e06
ucomiss 0xcd2b(%rip), %xmm1     # 0x12538
ja 0x5e06
addq $0x4, %rdx
xorps %xmm0, %xmm0
movups %xmm0, 0xa0(%rbx)
movq $0x0, 0xc0(%rbx)
movq %rdx, 0xc8(%rbx)
movq 0x40(%rbx), %rdi
cmpq %rdi, %rdx
jae 0x5e06
leaq 0xa0(%rbx), %rax
xorl %r8d, %r8d
movss 0xccea(%rip), %xmm0     # 0x1253c
movsd 0xc876(%rip), %xmm1     # 0x120d0
movl $0x3, %esi
xorl %r9d, %r9d
movl %r9d, %ecx
movss (%rdx), %xmm2
addss 0x4(%rdx), %xmm2
divss %xmm0, %xmm2
cvtss2sd %xmm2, %xmm2
addsd %xmm1, %xmm2
cvttsd2si %xmm2, %r9d
addl %ecx, %r9d
addq $0x8, %rdx
movq %rdx, 0xc8(%rbx)
leal (%r8,%r8), %r10d
cmpl %r10d, %r9d
jle 0x58e7
notl %r10d
addl %r9d, %r10d
cmpl $0x3, %r10d
cmovgel %esi, %r10d
movl %r8d, %ecx
notb %cl
andb $0x6, %cl
shll %cl, %r10d
sarl $0x3, %r8d
movslq %r8d, %rcx
orb %r10b, 0xa0(%rbx,%rcx)
movl 0xc0(%rbx), %ecx
leal 0x2(%rcx), %r8d
movl %r8d, 0xc0(%rbx)
leal 0x4(,%rcx,2), %r10d
cmpl %r10d, %r9d
jg 0x5896
movq 0x40(%rbx), %rdi
movq 0xc8(%rbx), %rdx
cmpq %rdi, %rdx
jb 0x5862
cmpl $0x22, %r8d
jne 0x5e06
movb (%rax), %cl
movzbl %cl, %r9d
movl %r9d, %esi
notl %esi
testb $-0x40, %sil
jne 0x5e06
movzbl 0xa3(%rbx), %r10d
movl %r10d, %esi
andl $0x3, %esi
movzbl 0xa4(%rbx), %r8d
shrl $0x6, %r8d
leal (%r8,%rsi,4), %r8d
movl %r9d, %esi
andl $0x3f, %esi
movl %esi, %r15d
shrl $0x2, %r15d
andl $0x3, %r9d
movzbl 0xa1(%rbx), %r11d
movl %r11d, %r12d
shrl $0x6, %r12d
movzbl 0xa2(%rbx), %r14d
movl %r10d, %r13d
shrl $0x6, %r13d
shrl $0x2, %r10d
addl %r13d, %r10d
addl %r12d, %r10d
leal (%r15,%r9,4), %r9d
addl %r10d, %r9d
leal (%r9,%r14,4), %r9d
leal (%r9,%r11,4), %r9d
movl %r11d, %r10d
shrl $0x2, %r10d
movl %r14d, %r11d
shrl $0x6, %r14d
addl %r10d, %r14d
shrl $0x2, %r11d
addl %r14d, %r11d
addl %r11d, %r9d
andl $0xf, %r9d
cmpl %r9d, %r8d
jne 0x5e06
cmpl $0x1f, %esi
ja 0x59b7
movss 0x140(%rbx), %xmm2
ucomiss 0xcb8f(%rip), %xmm2     # 0x12540
jb 0x5e06
movq 0x10(%rbx), %r8
addq $0x4, %rdi
movss 0xcb61(%rip), %xmm2     # 0x12528
movq %rdi, %rsi
cmpq %r8, %rdi
jae 0x59dc
movss (%rsi), %xmm3
leaq 0x4(%rsi), %rdi
ucomiss %xmm2, %xmm3
jbe 0x59c7
addq $0x8, %rdx
movq %rdx, 0xc8(%rbx)
cmpq %rsi, %rdx
jae 0x5bb7
movl $0x44, %r9d
movl $0x22, %r8d
movl $0x3, %edi
movl %r9d, %ecx
movss (%rdx), %xmm2
addss 0x4(%rdx), %xmm2
divss %xmm0, %xmm2
cvtss2sd %xmm2, %xmm2
addsd %xmm1, %xmm2
cvttsd2si %xmm2, %r9d
addl %ecx, %r9d
addq $0x8, %rdx
movq %rdx, 0xc8(%rbx)
leal (%r8,%r8), %r10d
cmpl %r10d, %r9d
jle 0x5a82
notl %r10d
addl %r9d, %r10d
cmpl $0x3, %r10d
cmovgel %edi, %r10d
movl %r8d, %ecx
notb %cl
andb $0x6, %cl
shll %cl, %r10d
sarl $0x3, %r8d
movslq %r8d, %rcx
orb %r10b, 0xa0(%rbx,%rcx)
movl 0xc0(%rbx), %ecx
leal 0x2(%rcx), %r8d
movl %r8d, 0xc0(%rbx)
leal 0x4(,%rcx,2), %r10d
cmpl %r10d, %r9d
jg 0x5a35
movq 0xc8(%rbx), %rdx
cmpq %rsi, %rdx
jb 0x5a01
movb (%rax), %cl
cmpl $0x44, %r8d
jne 0x5bb7
movzbl %cl, %eax
movzbl 0xa1(%rbx), %edx
movl %edx, %edi
shrl $0x6, %edi
leal (%rdi,%rax,4), %r8d
movzbl 0xa4(%rbx), %eax
movl %eax, %r9d
andl $0x3f, %r9d
shll $0x4, %r9d
movzbl 0xa5(%rbx), %edi
movl %edi, %r10d
shrl $0x4, %r10d
orl %r9d, %r10d
cmpl %r10d, %r8d
jne 0x5bb7
testb $0x20, %cl
jne 0x5ae5
testb $0x20, %dl
je 0x5b00
jmp 0x5bb7
movl %edx, %r8d
shrl $0x5, %r8d
movl %edi, %r9d
shrl $0x3, %r9d
xorl %r8d, %r9d
testb $0x1, %r9b
jne 0x5bb7
movl %edx, %r8d
andl $0x1f, %r8d
shll $0x8, %r8d
movzbl 0xa2(%rbx), %r9d
orl %r8d, %r9d
movzbl 0xa3(%rbx), %r8d
movl %r8d, %r10d
shrl $0x2, %r10d
movl %edi, %r11d
andl $0x7, %r11d
shll $0x8, %r11d
movzbl 0xa6(%rbx), %r14d
orl %r11d, %r14d
shll $0x8, %r14d
movzbl 0xa7(%rbx), %r11d
orl %r14d, %r11d
shll $0x6, %r9d
orl %r10d, %r9d
cmpl %r11d, %r9d
jne 0x5bb7
movl %r8d, %r9d
andl $0x1, %r9d
movl %eax, %r10d
shrl $0x6, %r10d
leal (%r10,%r9,4), %r10d
movzbl 0xa8(%rbx), %r9d
movl %r9d, %r11d
shrl $0x4, %r11d
andl $0x7, %r11d
cmpl %r11d, %r10d
jne 0x5bb7
shrl %r8d
andl $0x1, %r8d
shrl $0x7, %r9d
xorl %r8d, %r9d
shrl $0x5, %edx
shrl $0x3, %edi
xorl %edx, %edi
andl $0x1, %edi
cmpl %edi, %r9d
jne 0x5bb7
testb $0x8, %al
jne 0x5e15
movss (%rsi), %xmm0
ucomiss 0xc98f(%rip), %xmm0     # 0x12540
jae 0x5e15
andb $0x3f, %cl
movzbl %cl, %edi
cmpb $0x1f, %dil
ja 0x5c8b
movzbl 0xa1(%rbx), %eax
shrl $0x6, %eax
leal (%rax,%rdi,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 0xd185(%rip), %rcx      # 0x12dc0
leaq 0xd189(%rip), %rdx      # 0x12dcb
cmovlq %rcx, %rdx
movl 0x7(%rdx), %ecx
movl %ecx, 0x7(%rax)
movq (%rdx), %rcx
movq %rcx, (%rax)
testb $0x20, 0xa1(%rbx)
leaq 0xd176(%rip), %rax      # 0x12dd6
leaq 0xd047(%rip), %rsi      # 0x12cae
cmoveq %rax, %rsi
movq 0x150(%rbx), %rdi
movzbl 0xa3(%rbx), %edx
shrl $0x2, %edx
andl $0xf, %edx
xorl %eax, %eax
callq 0x2060
jmp 0x5df3
movzbl 0xa1(%rbx), %eax
movl %eax, %r8d
andl $0x3f, %r8d
movzbl 0xa2(%rbx), %ecx
movl %ecx, %r9d
shrl $0x6, %r9d
cmpl $0x20, %r8d
jae 0x5cb3
leal (%r9,%r8,4), %edx
jmp 0x5cbd
leal (%r9,%rax,4), %edx
orl $0xffffff00, %edx       # imm = 0xFFFFFF00
movl %ecx, %esi
andl $0x3f, %esi
movzbl 0xa3(%rbx), %r10d
shrl $0x6, %r10d
cmpl $0x20, %esi
jae 0x5cdb
leal (%r10,%rsi,4), %esi
movl %esi, %ecx
jmp 0x5ce9
leal (%r10,%rcx,4), %ecx
orl $0xffffff00, %ecx       # imm = 0xFFFFFF00
leal (%r10,%rsi,4), %esi
leal (%r9,%r8,4), %r8d
testl %r8d, %r8d
cmovnel %r8d, %esi
xorl %r8d, %r8d
testl %esi, %esi
setne %r8b
shrl $0x6, %eax
movl $0x40, %r9d
subl %edi, %r9d
movq 0x160(%rbx), %rdi
movl %r9d, (%rdi)
movq 0x170(%rbx), %rdi
movl %eax, (%rdi)
movb 0xa1(%rbx), %dil
movb 0xa2(%rbx), %r9b
shrb $0x6, %r9b
shlb $0x2, %dil
orb %r9b, %dil
xorl %r9d, %r9d
testb %dil, %dil
setne %r9b
shll $0x4, %r8d
leal (%r8,%r9,8), %r9d
orl %eax, %r9d
movq 0x148(%rbx), %rax
cmpl $0xafc8, 0x2c(%rbx)     # imm = 0xAFC8
leaq 0xd08a(%rip), %rdi      # 0x12de9
leaq 0xd08e(%rip), %r8       # 0x12df4
cmovlq %rdi, %r8
movl 0x7(%r8), %edi
movl %edi, 0x7(%rax)
movq (%r8), %rdi
movq %rdi, (%rax)
movzbl 0xa3(%rbx), %r8d
shrl $0x2, %r8d
andl $0xf, %r8d
movl %ecx, %eax
orl %edx, %eax
movq 0x150(%rbx), %rdi
je 0x5dac
testl %edx, %edx
je 0x5dc8
testl %ecx, %ecx
je 0x5dc8
leaq 0xd0ba(%rip), %rsi      # 0x12e5d
xorl %eax, %eax
callq 0x2060
jmp 0x5df3
movq 0x170(%rbx), %rax
shll $0x8, %r9d
orl %esi, %r9d
cmpl $0x0, (%rax)
je 0x5ddf
leaq 0xd050(%rip), %rsi      # 0x12e16
jmp 0x5de6
shll $0x8, %r9d
orl %esi, %r9d
leaq 0xd067(%rip), %rsi      # 0x12e3d
xorl %eax, %eax
callq 0x2060
jmp 0x5df3
leaq 0xd019(%rip), %rsi      # 0x12dff
movl %r8d, %edx
movl %r9d, %ecx
xorl %eax, %eax
callq 0x2060
movl 0x1050f(%rip), %eax     # 0x16308
movl %eax, 0x60(%rbx)
xorl %r14d, %r14d
movl %r14d, 0x10502(%rip)    # 0x16308
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl 0x104ec(%rip), %r14d    # 0x16308
testl %r14d, %r14d
jne 0x5e29
movq %rbx, %rdi
callq 0x26e8
incl %r14d
jmp 0x5dff