// File: 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:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x8(%rbp)
cmpl $0x0, 0x12d52(%rip)     # 0x29658
je 0x1690d
jmp 0x16b6e
cmpq $0x0, 0x12d4b(%rip)     # 0x29660
jne 0x16928
movl $0x80, %edi
callq 0x4040
movq %rax, 0x12d38(%rip)     # 0x29660
cmpq $0x0, 0x12d38(%rip)     # 0x29668
jne 0x16943
movl $0x1000, %edi           # imm = 0x1000
callq 0x4040
movq %rax, 0x12d25(%rip)     # 0x29668
movl $0x0, -0x94(%rbp)
cmpl $0x20, -0x94(%rbp)
jge 0x16979
movslq -0x94(%rbp), %rax
movl $0xffffffff, -0x90(%rbp,%rax,4) # imm = 0xFFFFFFFF
movl -0x94(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x94(%rbp)
jmp 0x1694d
movl $0x0, -0x94(%rbp)
cmpl $0x20, -0x94(%rbp)
jge 0x169e9
movq -0x8(%rbp), %rax
movslq -0x94(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x98(%rbp)
movl -0x98(%rbp), %edx
movq 0x12cb3(%rip), %rax     # 0x29660
movslq -0x94(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
cmpl $0x0, -0x98(%rbp)
jne 0x169c2
jmp 0x169d8
movl -0x94(%rbp), %ecx
andl $0xf, %ecx
movl -0x98(%rbp), %eax
movl %ecx, -0x90(%rbp,%rax,4)
movl -0x94(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x94(%rbp)
jmp 0x16983
movl $0x0, -0x9c(%rbp)
cmpl $0x400, -0x9c(%rbp)     # imm = 0x400
jae 0x16b64
movq 0x12c5e(%rip), %rax     # 0x29668
movl -0x9c(%rbp), %ecx
movl $0x80000000, (%rax,%rcx,4) # imm = 0x80000000
movl -0x9c(%rbp), %eax
shrl $0x5, %eax
movl %eax, %eax
movl -0x90(%rbp,%rax,4), %eax
movl %eax, -0xa0(%rbp)
movl -0x9c(%rbp), %eax
andl $0x1f, %eax
movl %eax, %eax
movl -0x90(%rbp,%rax,4), %eax
movl %eax, -0xa4(%rbp)
cmpl $0x0, -0xa0(%rbp)
jl 0x16a59
cmpl $0x0, -0xa4(%rbp)
jge 0x16a5e
jmp 0x16b50
movl $0xffffffff, -0xa8(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0xac(%rbp)
movl $0x200, -0xb0(%rbp)     # imm = 0x200
cmpl $0x0, -0xb0(%rbp)
je 0x16b1a
movl -0x9c(%rbp), %edx
andl -0xb0(%rbp), %edx
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, -0xb4(%rbp)
movl -0xa8(%rbp), %eax
cmpl -0xb4(%rbp), %eax
je 0x16ace
movl -0xb4(%rbp), %eax
movl %eax, -0xa8(%rbp)
movl $0x1, -0xac(%rbp)
jmp 0x16b05
movl -0xac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xac(%rbp)
cmpl $0x0, -0xa8(%rbp)
jne 0x16aef
cmpl $0x3, -0xac(%rbp)
jge 0x16b01
cmpl $0x0, -0xa8(%rbp)
je 0x16b03
cmpl $0x5, -0xac(%rbp)
jl 0x16b03
jmp 0x16b1a
jmp 0x16b05
jmp 0x16b07
movl -0xb0(%rbp), %eax
shrl %eax
movl %eax, -0xb0(%rbp)
jmp 0x16a7c
cmpl $0x0, -0xb0(%rbp)
je 0x16b25
jmp 0x16b50
movl -0xa0(%rbp), %eax
shll $0x4, %eax
orl -0xa4(%rbp), %eax
movl %eax, -0xb8(%rbp)
movl -0xb8(%rbp), %edx
movq 0x12b21(%rip), %rax     # 0x29668
movl -0x9c(%rbp), %ecx
movl %edx, (%rax,%rcx,4)
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0x169f3
movl $0x1, 0x12aea(%rip)     # 0x29658
addq $0xc0, %rsp
popq %rbp
retq
nopw (%rax,%rax)