// File: /workspace/github_cpp_makefile_star2_O1/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, 0xdac9(%rip)      # 0x1b618
je 0xdb52
retq
pushq %rbx
subq $0x80, %rsp
movq %rdi, %rbx
cmpq $0x0, 0xdabb(%rip)      # 0x1b620
jne 0xdb78
movl $0x80, %edi
callq 0x4040
movq %rax, 0xdaa8(%rip)      # 0x1b620
cmpq $0x0, 0xdaa8(%rip)      # 0x1b628
jne 0xdb93
movl $0x1000, %edi           # imm = 0x1000
callq 0x4040
movq %rax, 0xda95(%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)
movq 0xda53(%rip), %rax      # 0x1b620
xorl %ecx, %ecx
movl (%rbx,%rcx,4), %edx
movl %edx, (%rax,%rcx,4)
testq %rdx, %rdx
je 0xdbe2
movl %ecx, %esi
andl $0xf, %esi
movl %esi, (%rsp,%rdx,4)
incq %rcx
cmpq $0x20, %rcx
jne 0xdbcf
movq 0xda36(%rip), %rax      # 0x1b628
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 0xdc86
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
xorl %r9d, %r9d
movl $0x200, %edi            # imm = 0x200
xorl %r11d, %r11d
testl %ecx, %edi
setne %r11b
cmpl %r11d, %r8d
jne 0xdc49
leal 0x1(%r9), %r11d
testl %r8d, %r8d
sete %r10b
cmpl $0x2, %r9d
setge %bl
testb %bl, %r10b
je 0xdc57
xorl %r10d, %r10d
jmp 0xdc68
movb $0x1, %r10b
movl $0x1, %r9d
movl %r11d, %r8d
jmp 0xdc6b
testl %r8d, %r8d
sete %bl
cmpl $0x4, %r9d
setl %r10b
orb %bl, %r10b
movl %r11d, %r9d
testb %r10b, %r10b
je 0xdc86
movl %edi, %r10d
shrl %r10d
cmpl $0x2, %edi
movl %r10d, %edi
jae 0xdc1f
shll $0x4, %edx
orl %esi, %edx
movl %edx, (%rax,%rcx,4)
incq %rcx
cmpq $0x400, %rcx            # imm = 0x400
jne 0xdbf4
movl $0x1, 0xd978(%rip)      # 0x1b618
addq $0x80, %rsp
popq %rbx
retq
nop