// File: /workspace/github_cpp_makefile_star2_O2/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, 0xdb01(%rip)      # 0x19618
je 0xbb1a
retq
pushq %rbp
pushq %r14
pushq %rbx
subq $0x80, %rsp
movq %rdi, %rbx
movq 0xdaf1(%rip), %r14      # 0x19620
testq %r14, %r14
jne 0xbb48
movl $0x80, %edi
callq 0x3040
movq %rax, %r14
movq %rax, 0xdad8(%rip)      # 0x19620
movq 0xdad9(%rip), %rax      # 0x19628
testq %rax, %rax
jne 0xbb65
movl $0x1000, %edi           # imm = 0x1000
callq 0x3040
movq %rax, 0xdac3(%rip)      # 0x19628
xorl %ecx, %ecx
cmpq $0x20, %rcx
je 0xbb76
orl $-0x1, (%rsp,%rcx,4)
incq %rcx
jmp 0xbb67
xorl %ecx, %ecx
cmpq $0x20, %rcx
je 0xbb97
movl (%rbx,%rcx,4), %edx
movl %edx, (%r14,%rcx,4)
testq %rdx, %rdx
je 0xbb92
movl %ecx, %esi
andl $0xf, %esi
movl %esi, (%rsp,%rdx,4)
incq %rcx
jmp 0xbb78
xorl %ecx, %ecx
pushq $-0x1
popq %rdx
pushq $0x1
popq %rsi
cmpq $0x400, %rcx            # imm = 0x400
je 0xbc39
movl $0x80000000, (%rax,%rcx,4) # imm = 0x80000000
movl %ecx, %edi
shrl $0x5, %edi
movl (%rsp,%rdi,4), %edi
movl %ecx, %r8d
andl $0x1f, %r8d
movl (%rsp,%r8,4), %r8d
movl %edi, %r9d
orl %r8d, %r9d
js 0xbc31
movl $0x200, %r9d            # imm = 0x200
xorl %r10d, %r10d
movl %edx, %r11d
testl %r9d, %r9d
je 0xbc28
xorl %ebx, %ebx
testl %ecx, %r9d
setne %bl
movl %esi, %ebp
cmpl %ebx, %r11d
jne 0xbc1d
testl %r11d, %r11d
sete %bl
cmpl $0x2, %r10d
setge %bpl
testb %bpl, %bl
jne 0xbc31
testl %r11d, %r11d
setne %bl
cmpl $0x4, %r10d
setge %bpl
testb %bpl, %bl
jne 0xbc31
incl %r10d
movl %r11d, %ebx
movl %r10d, %ebp
shrl %r9d
movl %ebx, %r11d
movl %ebp, %r10d
jmp 0xbbda
shll $0x4, %edi
orl %r8d, %edi
movl %edi, (%rax,%rcx,4)
incq %rcx
jmp 0xbb9f
movl $0x1, 0xd9d5(%rip)      # 0x19618
addq $0x80, %rsp
popq %rbx
popq %r14
popq %rbp
retq
nop