// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/Codec/DiskEncoding.cpp
// Function: CDiskEncoding::InitGCRVorpal2(unsigned int*)
void CDiskEncoding::InitGCRVorpal2(uint32_t *gcrtable)
{
	// stop if correct tables are available
	if (gcrvorpal2init)
		return;

	// create tables
	if (!gcrvorpal2code)
		gcrvorpal2code=new uint32_t[32];

	if (!gcrvorpal2decode)
		gcrvorpal2decode=new uint32_t[1024];

	// decoded 5 bit gcr value
	int gdtab[32];
	int i;

	// mark all values as illegal
	for (i=0; i < 32; i++)
		gdtab[i]=-1;

	// add valid gcr and decoded values
	for (i=0; i < 32; i++) {
		uint32_t code=gcrtable[i];
		gcrvorpal2code[i]=code;

		// skip illegal codes
		if (!code)
			continue;

		// 4 bit decoded value
		gdtab[code]=i & 0x0f;
	}

	// process all possible 10 bit combinations (5 bit hi nybble, 5 bit lo nybble)
	for (uint32_t sval=0; sval < 1024; sval++) {
		// set value as illegal by default
		gcrvorpal2decode[sval]=DF_31;

		// decode the 5 bit gcr values
		int dechi=gdtab[sval >> 5];
		int declo=gdtab[sval & 0x1f];

		// the 10 bit encoded value is illegal if any of its nybbles decoded is an illegal code
		if (dechi < 0 || declo < 0)
			continue;

		int lbv=-1;
		int bc=0;

		// check the 10 bit encoded value as a stream for illegal encoding
		uint32_t bm;
		for (bm=1 << 9; bm; bm >>= 1) {
			// current bit value
			int bitval=(sval & bm) ? 1 : 0;
			if (lbv != bitval) {
				// if different from previous bit, restart counting
				lbv=bitval;
				bc=1;
			} else {
				// same as previous bit, count it in
				bc++;

				// the stream is illegal if it contains 5 consecutive 1 bits or 3 consecutive 0 bits
				if ((!lbv && bc >= 3) || (lbv && bc >= 5))
					break;
			}
		}

		// skip illegal value; the loop ended early
		if (bm)
			continue;

		// set 8 bit decoded value
		uint32_t code=dechi << 4 | declo;
		gcrvorpal2decode[sval]=code;
	}

	gcrvorpal2init=1;
}

// Assembly:
cmpl $0x0, 0xda01(%rip)      # 0x1b618
je 0xdc1a
retq
pushq %r14
pushq %rbx
subq $0x88, %rsp
movq %rdi, %rbx
movq 0xd9f2(%rip), %r14      # 0x1b620
testq %r14, %r14
jne 0xdc47
movl $0x80, %edi
callq 0x4040
movq %rax, %r14
movq %rax, 0xd9d9(%rip)      # 0x1b620
movq 0xd9da(%rip), %rax      # 0x1b628
testq %rax, %rax
jne 0xdc64
movl $0x1000, %edi           # imm = 0x1000
callq 0x4040
movq %rax, 0xd9c4(%rip)      # 0x1b628
pcmpeqd %xmm0, %xmm0
movdqa %xmm0, 0x70(%rsp)
movdqa %xmm0, 0x60(%rsp)
movdqa %xmm0, 0x50(%rsp)
movdqa %xmm0, 0x40(%rsp)
movdqa %xmm0, 0x30(%rsp)
movdqa %xmm0, 0x20(%rsp)
movdqa %xmm0, 0x10(%rsp)
movdqa %xmm0, (%rsp)
xorl %ecx, %ecx
movl (%rbx,%rcx,4), %edx
movl %edx, (%r14,%rcx,4)
testq %rdx, %rdx
je 0xdcad
movl %ecx, %esi
andl $0xf, %esi
movl %esi, (%rsp,%rdx,4)
incq %rcx
cmpq $0x20, %rcx
jne 0xdc99
xorl %ecx, %ecx
movl $0x80000000, (%rax,%rcx,4) # imm = 0x80000000
movl %ecx, %edx
shrl $0x5, %edx
movl (%rsp,%rdx,4), %edx
movl %ecx, %esi
andl $0x1f, %esi
movl (%rsp,%rsi,4), %esi
movl %edx, %edi
orl %esi, %edi
js 0xdd41
movl $0xffffffff, %r9d       # imm = 0xFFFFFFFF
xorl %r8d, %r8d
movl $0x200, %edi            # imm = 0x200
xorl %r10d, %r10d
testl %ecx, %edi
setne %r10b
movl $0x1, %r11d
cmpl %r10d, %r9d
jne 0xdd28
testl %r9d, %r9d
sete %r10b
cmpl $0x2, %r8d
setge %r11b
testb %r11b, %r10b
jne 0xdd41
testl %r9d, %r9d
setne %r10b
cmpl $0x4, %r8d
setge %r11b
testb %r11b, %r10b
jne 0xdd41
incl %r8d
movl %r9d, %r10d
movl %r8d, %r11d
movl %edi, %ebx
shrl %ebx
movl %r11d, %r8d
movl %r10d, %r9d
cmpl $0x1, %edi
movl %ebx, %edi
ja 0xdce3
shll $0x4, %edx
orl %esi, %edx
movl %edx, (%rax,%rcx,4)
incq %rcx
cmpq $0x400, %rcx            # imm = 0x400
jne 0xdcb8
movl $0x1, 0xd8bd(%rip)      # 0x1b618
addq $0x88, %rsp
popq %rbx
popq %r14
retq