// File: /workspace/github_cpp_makefile_star2_O1/TNanukem[P]chip8-emulator/chip8.cpp
// Function: chip8::nextCycle()
void chip8::nextCycle(){

	// Fetching the instruction
	opcode = memory[pc] << 8 | memory[pc+1];

	// Decoding the instruction
	switch(opcode & GET_4BITS){					// Decode the instruction based on the first 4 bits

		// Decodification of the 0x0 opcodes
		case 0x0000:
			switch(opcode & GET_8BIT_CONSTANT){

				// Clears the screen.
				case 0x00E0:
					for(int i = 0; i < 32*64; i++){
						display[i] = 0;
					}
					pc += 2;
					drawFlag = 1;
                    //printf("CLS\n");
					break;

				// Returns from a subroutine.
				case 0x00EE:
					sp--;
					pc = stack[sp];
                    pc += 2;
                    //printf("RET\n");
					break;
			}
			break;

		// Jumps to the address NNN
		case 0x1000:
			pc = (opcode & GET_ADDRESS);
            //printf("JMP %d\n", opcode & GET_ADDRESS);
			break;

        // Calls subroutine at NNN.
		case 0x2000:
			stack[sp] = pc;
			sp++;
			pc = opcode & GET_ADDRESS;
            //printf("CALL %d\n", opcode & GET_ADDRESS);
			break;

		// Skips the next instruction if v[X] is equal to NN
		case 0x3000:
			if(v[(opcode & GET_X) >> 8] == (opcode & GET_8BIT_CONSTANT))
					pc += 4;
			else
                pc += 2;
            //printf("SE V%d,%d\n", (opcode & GET_X) >> 8, opcode & GET_8BIT_CONSTANT);
			break;

		// Skips the next instruction if v[X] is not equal to NN
		case 0x4000:
			if(v[(opcode & GET_X) >> 8] != (opcode & GET_8BIT_CONSTANT))
				pc += 4;
			else
                pc += 2;
            //printf("SNE V%d,%d\n", (opcode & GET_X) >> 8, opcode & GET_8BIT_CONSTANT);
			break;

		// Skips the next instruction if v[X] is equal to v[Y]
		case 0x5000:
			if(v[(opcode & GET_X) >> 8] == v[(opcode & GET_Y) >> 4]){
				pc += 4;
			}
			else
				pc += 2;

            //printf("SE V%d,V%d\n", (opcode & GET_X) >> 8, (opcode & GET_Y) >> 4);
			break;

		// Sets v[X] to NN
		case 0x6000:
			v[(opcode & GET_X) >> 8] = (opcode & GET_8BIT_CONSTANT);
			pc += 2;
            //printf("LD V%d,%d\n", (opcode & GET_X) >> 8, opcode & GET_8BIT_CONSTANT);
			break;

		// Adds NN to v[X]
		case 0x7000:
			v[(opcode & GET_X) >> 8]  += (opcode & GET_8BIT_CONSTANT);
			pc += 2;
            //printf("ADD V%d,%d\n", (opcode & GET_X) >> 8, opcode & GET_8BIT_CONSTANT);
			break;

		// Skips the next instruction if v[X] is not equal to v[Y]
		case 0x9000:
			if(v[opcode & GET_X >> 8] != v[(opcode & GET_Y) >> 4]){
				pc += 4;
			}
			else pc += 2;
            //printf("SNE V%d,V%d\n", (opcode & GET_X) >> 8, (opcode & GET_Y) >> 4);
			break;

		case 0x8000:
			switch(opcode & GET_4BIT_CONSTANT){

				// Sets v[X] to v[Y]
				case 0x0000:
					v[(opcode & GET_X) >> 8] = v[(opcode & GET_Y) >> 4];
					pc += 2;
                    //printf("LD V%d,V%d\n", (opcode & GET_X) >> 8, (opcode & GET_Y) >> 4);
					break;

				// Sets v[X] to v[X] OR v[Y]
				case 0x0001:
					v[(opcode & GET_X) >> 8] |= v[(opcode & GET_Y) >> 4];
					pc += 2;
                    //printf("OR V%d,V%d\n", (opcode & GET_X) >> 8, (opcode & GET_Y) >> 4);
					break;

				// Sets v[X] to v[X] AND v[Y]
				case 0x0002:
					v[(opcode & GET_X) >> 8] &= v[(opcode & GET_Y) >> 4];
					pc += 2;
                    //printf("AND V%d,V%d\n", (opcode & GET_X) >> 8, (opcode & GET_Y) >> 4);
					break;

				// Sets v[X] to v[X] XOR v[Y]
				case 0x0003:
					v[(opcode & GET_X) >> 8] ^= v[(opcode & GET_Y) >> 4];
					pc += 2;
                    //printf("XOR V%d,V%d\n", (opcode & GET_X) >> 8, (opcode & GET_Y) >> 4);
					break;

				// Adds VY to VX. VF is set to 1 when there's a carry, and to 0 when there isn't.
				case 0x0004:
					if(v[(opcode & GET_Y) >> 4] > (0xFF - v[(opcode & GET_X) >> 8]))
						v[0xF] = 1;
					else
						v[0xF] = 0;
					v[(opcode & GET_X) >> 8] += v[(opcode & GET_Y) >> 4];
					pc += 2;
                    //printf("ADD V%d,V%d\n", (opcode & GET_X) >> 8, (opcode & GET_Y) >> 4);
					break;

				// VY is subtracted from VX. VF is set to 0 when there's a borrow, and 1 when there isn't.
				case 0x0005:
					if(v[(opcode & GET_X) >> 8] > v[(opcode & GET_Y) >> 4])
						v[0xF] = 1;
					else
						v[0xF] = 0;
					v[(opcode & GET_X) >> 8] -= v[(opcode & GET_Y) >> 4];
					pc += 2;
                    //printf("SUB V%d,V%d\n", (opcode & GET_X) >> 8, (opcode & GET_Y) >> 4);
					break;

				// Stores the least significant bit of VX in VF and then shifts VX to the right by 1.
				case 0x0006:
					if((v[(opcode & GET_X) >> 8] & 0x01) == 0x01)
                        v[0xF] = 1;
                    else
                        v[0xF] = 0;
                    pc += 2;
                    v[(opcode & GET_X) >> 8] = v[(opcode & GET_X) >> 8]/2;
                    //printf("SHR V%d,V%d\n", (opcode & GET_X) >> 8, (opcode & GET_Y) >> 4);
					break;

				// Sets VX to VY minus VX. VF is set to 0 when there's a borrow, and 1 when there isn't.
				case 0x0007:
					if(v[(opcode & GET_Y) >> 4] > v[(opcode & GET_X) >> 8])
						v[0xF] = 1;
					else
						v[0xF] = 0;
					v[(opcode & GET_X) >> 8] = v[(opcode & GET_Y) >> 4] - v[(opcode & GET_X) >> 8];
					pc += 2;
                    //printf("SUBN V%d,V%d\n", (opcode & GET_X) >> 8, (opcode & GET_Y) >> 4);
					break;

				// Stores the most significant bit of VX in VF and then shifts VX to the left by 1.
				case 0x000E:
                    if((v[(opcode & GET_X) >> 8] & 0x80) == 0x80)
                        v[0xF] = 1;
                    else
                        v[0xF] = 0;
					pc += 2;
                    v[(opcode & GET_X) >> 8] = v[(opcode & GET_X) >> 8]*2;
                    //printf("SHL V%d,V%d\n", (opcode & GET_X) >> 8, (opcode & GET_Y) >> 4);
					break;
			}
			break;

		// Sets the I address to NNN
		case 0xA000:
			I = opcode & GET_ADDRESS;
			pc += 2;
            //printf("LD I, %d\n", opcode & GET_ADDRESS);
			break;

		// Jumps to the address V0 + NNN
		case 0xB000:
			pc = (opcode & GET_ADDRESS) + v[0];
            //printf("JP V0,%d\n", opcode & GET_ADDRESS);
			break;

		// Sets VX to the result of a bitwise and operation on a random number (Typically: 0 to 255) and NN.
		case 0xC000:
			v[opcode & GET_X >> 8] = (rand() % 255) & (opcode & GET_8BIT_CONSTANT);
			pc += 2;
            //printf("RND V%d,%d\n", (opcode & GET_X) >> 8, opcode & GET_8BIT_CONSTANT);
			break;

		// Draws a sprite at (vx,vy) with size height of N pixels
		case 0xD000:
            xaux = v[(opcode & GET_X) >> 8];
            yaux = v[(opcode & GET_Y) >> 4];
            height = opcode & GET_4BIT_CONSTANT;

            v[0xF] = 0;         // Resets the VF

            for(int y = 0; y < height; y++){              // Passes through all lines of the sprite
                pixel = memory[I + y];      // Fetches the pixel value on the memory
                for(int x = 0; x < 8; x++){             // Passes through all 8 columns of the sprite, in each line
                    if((pixel & (0x80 >> x)) != 0){
                        if(display[(xaux + x + ((yaux + y)*64))] == 1)
                            v[0xF] = 1;                 // Registers the collision
                        display[(xaux + x + ((yaux + y)*64))] ^= 1;
                    }
                }
            }

            drawFlag = true;
			pc += 2;
            //printf("DRW V%d,V%d,%d\n", (opcode & GET_X) >> 8, (opcode & GET_Y) >> 4, opcode & GET_4BIT_CONSTANT);
			break;

		case 0xE000:
			switch(opcode & GET_4BIT_CONSTANT){

				// Skips the next instruction if the key stored in VX is pressed.
				case 0x000E:
                    //printf("SKP V%d\n", (opcode & GET_X) >> 8);
					if(keyboard[v[(opcode & GET_X) >> 8]] != 0)
						pc += 4;
					else
						pc += 2;
					break;

				// Skips the next instruction if the key stored in VX isn't pressed.
				case 0x0001:
                    //printf("SKNP V%d\n", (opcode & GET_X) >> 8);
					if(keyboard[v[(opcode & GET_X) >> 8]] == 0)
						pc += 4;
					else
						pc += 2;
					break;
			}

			break;

		case 0xF000:
            switch(opcode & GET_8BIT_CONSTANT){
				// Sets VX to the value of the delay timer.
				case 0x0007:
					v[(opcode & GET_X) >> 8] = delayTimer;
					pc += 2;
                    //printf("LD V%d, DT\n", (opcode & GET_X) >> 8);
					break;

                // A key press is awaited, and then stored in VX
				case 0x000A:
                    //printf("KEYWAIT V%d, K\n", (opcode & GET_X) >> 8);
					pressedKey = false;
                    while(!pressedKey){
    					for(int i = 0; i < 16; i++){
    						if(keyboard[i] != 0){
    							v[(opcode & GET_X) >> 8] = i;
    							pressedKey = true;
                                break;
    						}
                        }
                    }
						pc += 2;
                        break;

				// Sets the delay timer to the value of v[X]
				case 0x0015:
                    //printf("LD DT, V%d\n", (opcode & GET_X) >> 8);
					delayTimer = v[(opcode & GET_X) >> 8];
					pc += 2;
					break;

				// Sets the sound timer to the value of v[X]
				case 0x0018:
                    //printf("LD ST, V%d\n", (opcode & GET_X) >> 8);
					soundTimer = v[(opcode & GET_X) >> 8];
					pc += 2;
					break;

				// Adds v[X] to I
				case 0x001E:
                    //printf("ADD I, V%d\n", (opcode & GET_X) >> 8);
                    if((I + v[(opcode & GET_X) >> 8]) > 0xFFFF)
                        v[0xF] = 1;
                    else
                        v[0xF] = 0;

                    I += v[(opcode & GET_X) >> 8];
					pc += 2;
					break;

				// Sets I to the location of the sprite for the character in VX.
				case 0x0029:
                    //printf("LD F, V%d\n", (opcode & GET_X) >> 8);
					I = v[(opcode & GET_X) >> 8] * 0x5;
					pc += 2;
					break;

				// Stores the Binary-coded decimal representation of VX at the addresses I, I plus 1, and I plus 2
				// Implementation by TJA
				case 0x0033:
                    //printf("LD B, V%d\n", (opcode & GET_X) >> 8);
					memory[I]     = v[(opcode & 0x0F00) >> 8] / 100;
					memory[I + 1] = (v[(opcode & 0x0F00) >> 8] / 10) % 10;
					memory[I + 2] = (v[(opcode & 0x0F00) >> 8] % 100) % 10;
					pc += 2;
					break;

				//Stores V0 to VX (including VX) in memory starting at address I.
				case 0x0055:
                    //printf("LD [I], V%d\n", (opcode & GET_X) >> 8);
					for(int i = 0; i <= ((opcode & GET_X) >> 8); i++){
						memory[I+i] = v[i];
					}
                    I += ((opcode & GET_X) >> 8) + 1;
					pc += 2;
					break;

				// Fills V0 to VX (including VX) with values from memory starting at address I.
				case 0x0065:
                    //printf("I = %d\n", I);
                    //printf("LD V%d, [I]\n", (opcode & GET_X) >> 8);
					for(int i = 0; i <= ((opcode & GET_X) >> 8) ; i++){
                        v[i] = memory[I+i];
					}
                    I += ((opcode & GET_X) >> 8) + 1;
					pc += 2;
					break;
			}
        break;

        default:
            //printf("ERROR! Opcode not known!\n");
            break;
	}

	// Decrement the timers if they are greater than zero
	if(delayTimer > 0)
		delayTimer--;

	if(soundTimer > 0)
        if(soundTimer == 1){
            playSound = true;
            //printf("BEEP\n");
        }
		soundTimer--;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
movq %rdi, %rbx
movzwl 0x1014(%rdi), %r14d
movzbl 0x2(%rdi,%r14), %ecx
movl %ecx, %edi
shll $0x8, %edi
movb 0x3(%rbx,%r14), %sil
movzbl %sil, %edx
leal (%rdi,%rdx), %eax
movw %ax, (%rbx)
shrl $0xc, %edi
leaq 0x19be(%rip), %r8       # 0x4004
movslq (%r8,%rdi,4), %rdi
addq %r8, %rdi
jmpq *%rdi
cmpl $0xee, %edx
je 0x29b5
cmpl $0xe0, %edx
jne 0x2c96
leaq 0x1018(%rbx), %rdi
movl $0x2000, %edx           # imm = 0x2000
xorl %esi, %esi
callq 0x2110
leal 0x2(%r14), %eax
movw %ax, 0x1014(%rbx)
movb $0x1, 0x304c(%rbx)
jmp 0x2c96
movl %eax, %ecx
andl $0xf, %ecx
cmpl $0x1, %ecx
je 0x2990
cmpl $0xe, %ecx
jne 0x2c96
shrl $0x8, %eax
andl $0xf, %eax
movzbl 0x1002(%rbx,%rax), %eax
cmpb $0x0, 0x303c(%rbx,%rax)
jne 0x29ac
jmp 0x2c8b
andl $0xfff, %eax            # imm = 0xFFF
movzbl 0x1002(%rbx), %ecx
addl %eax, %ecx
movw %cx, 0x1014(%rbx)
jmp 0x2c96
shrl $0x8, %eax
andl $0xf, %eax
cmpb %sil, 0x1002(%rbx,%rax)
jne 0x29ac
jmp 0x2c8b
callq 0x20b0
cltq
imulq $-0x7f7f7f7f, %rax, %rcx # imm = 0x80808081
shrq $0x20, %rcx
addl %eax, %ecx
movl %ecx, %edx
shrl $0x1f, %edx
shrl $0x7, %ecx
addl %edx, %ecx
addl %eax, %ecx
movzwl (%rbx), %eax
andl %eax, %ecx
andl $0xf, %eax
movb %cl, 0x1002(%rbx,%rax)
addw $0x2, 0x1014(%rbx)
jmp 0x2c96
movl %eax, %ecx
andl $0xf, %ecx
movb 0x1002(%rbx,%rcx), %cl
shrl $0x4, %eax
andl $0xf, %eax
cmpb 0x1002(%rbx,%rax), %cl
jne 0x29ac
jmp 0x2c8b
movzwl 0x303a(%rbx), %ecx
movw %r14w, 0x301a(%rbx,%rcx,2)
incw 0x303a(%rbx)
andl $0xfff, %eax            # imm = 0xFFF
movw %ax, 0x1014(%rbx)
jmp 0x2c96
cmpl $0x1d, %edx
jle 0x2939
cmpl $0x32, %edx
jle 0x29fe
cmpl $0x33, %edx
je 0x2aa6
cmpl $0x55, %edx
je 0x2bfa
cmpl $0x65, %edx
jne 0x2c96
andl $0xf, %ecx
leaq 0x1002(%rbx), %rax
movq %rcx, %rdx
incq %rdx
movzwl 0x1012(%rbx), %esi
movb -0x1000(%rax,%rsi), %sil
movb %sil, (%rax)
incq %rax
decq %rdx
jne 0x27c1
jmp 0x2c24
shrl $0x8, %eax
andl $0xf, %eax
cmpb %sil, 0x1002(%rbx,%rax)
je 0x29ac
jmp 0x2c8b
shrl $0x8, %eax
andl $0xf, %eax
addb %sil, 0x1002(%rbx,%rax)
jmp 0x2c8b
movl %eax, %ecx
shrl $0x8, %ecx
andl $0xf, %ecx
movb 0x1002(%rbx,%rcx), %cl
shrl $0x4, %eax
andl $0xf, %eax
cmpb 0x1002(%rbx,%rax), %cl
je 0x29ac
jmp 0x2c8b
shrl $0x8, %eax
andl $0xf, %eax
movzbl 0x1002(%rbx,%rax), %eax
movw %ax, 0x39c8(%rip)       # 0x6210
movl %edx, %ecx
shrl $0x4, %ecx
movzbl 0x1002(%rbx,%rcx), %ecx
movw %cx, 0x39b6(%rip)       # 0x6212
andl $0xf, %edx
movl %edx, 0x39af(%rip)      # 0x6214
movb $0x0, 0x1011(%rbx)
je 0x28d7
movzwl %ax, %esi
movzwl %cx, %ecx
movzwl 0x1012(%rbx), %eax
shll $0x8, %ecx
leaq (%rcx,%rsi,4), %rcx
leaq (%rbx,%rcx), %rsi
addq $0x1018, %rsi           # imm = 0x1018
xorl %edi, %edi
leaq (%rdi,%rax), %rcx
movzbl 0x2(%rbx,%rcx), %r8d
xorl %ecx, %ecx
movl %r8d, %r9d
shll %cl, %r9d
testb %r9b, %r9b
jns 0x28b7
cmpl $0x1, (%rsi,%rcx,4)
jne 0x28b3
movb $0x1, 0x1011(%rbx)
xorb $0x1, (%rsi,%rcx,4)
incq %rcx
cmpq $0x8, %rcx
jne 0x289b
incq %rdi
addq $0x100, %rsi            # imm = 0x100
cmpq %rdx, %rdi
jne 0x288f
movw %r8w, 0x3937(%rip)      # 0x620e
movb $0x1, 0x304c(%rbx)
jmp 0x2c8b
shrl $0x8, %eax
andl $0xf, %eax
movb %sil, 0x1002(%rbx,%rax)
jmp 0x2c8b
andl $0xfff, %eax            # imm = 0xFFF
movw %ax, 0x1012(%rbx)
jmp 0x2c8b
movl %eax, %edx
andl $0xf, %edx
cmpl $0xe, %edx
ja 0x2c96
leaq 0x1728(%rip), %rsi      # 0x4044
movslq (%rsi,%rdx,4), %rdx
addq %rsi, %rdx
jmpq *%rdx
movl %eax, %ecx
shrl $0x4, %ecx
andl $0xf, %ecx
movb 0x1002(%rbx,%rcx), %cl
jmp 0x2a4d
cmpl $0x14, %edx
jg 0x29d8
cmpl $0x7, %edx
je 0x2a47
cmpl $0xa, %edx
jne 0x2c96
movb $0x0, 0x38b2(%rip)      # 0x620d
andl $0xf, %ecx
xorl %eax, %eax
xorl %edx, %edx
cmpb $0x0, 0x303c(%rbx,%rdx)
jne 0x2977
incq %rdx
cmpq $0x10, %rdx
jne 0x2962
jmp 0x2987
movb %dl, 0x1002(%rbx,%rcx)
movb $0x1, 0x3888(%rip)      # 0x620d
movb $0x1, %al
testb $0x1, %al
je 0x2960
jmp 0x2c8b
shrl $0x8, %eax
andl $0xf, %eax
movzbl 0x1002(%rbx,%rax), %eax
cmpb $0x0, 0x303c(%rbx,%rax)
jne 0x2c8b
leal 0x4(%r14), %eax
jmp 0x2c8f
movzwl 0x303a(%rbx), %eax
decl %eax
movw %ax, 0x303a(%rbx)
movzwl %ax, %eax
movzwl 0x301a(%rbx,%rax,2), %eax
addl $0x2, %eax
jmp 0x2c8f
cmpl $0x15, %edx
je 0x2a58
cmpl $0x18, %edx
jne 0x2c96
shrl $0x8, %eax
andl $0xf, %eax
movb 0x1002(%rbx,%rax), %al
movb %al, 0x3019(%rbx)
jmp 0x2c8b
cmpl $0x1e, %edx
je 0x2b31
cmpl $0x29, %edx
jne 0x2c96
shrl $0x8, %eax
andl $0xf, %eax
movzbl 0x1002(%rbx,%rax), %eax
leal (%rax,%rax,4), %eax
jmp 0x2b61
movl %eax, %ecx
shrl $0x4, %ecx
andl $0xf, %ecx
movb 0x1002(%rbx,%rcx), %cl
shrl $0x8, %eax
andl $0xf, %eax
andb %cl, 0x1002(%rbx,%rax)
jmp 0x2c8b
movb 0x3018(%rbx), %cl
shrl $0x8, %eax
andl $0xf, %eax
jmp 0x2bee
shrl $0x8, %eax
andl $0xf, %eax
movb 0x1002(%rbx,%rax), %al
movb %al, 0x3018(%rbx)
jmp 0x2c8b
movl %eax, %ecx
shrl $0x8, %ecx
andl $0xf, %ecx
movb 0x1002(%rbx,%rcx), %dl
shrl $0x4, %eax
andl $0xf, %eax
cmpb 0x1002(%rbx,%rax), %dl
seta 0x1011(%rbx)
movb 0x1002(%rbx,%rax), %al
subb %al, 0x1002(%rbx,%rcx)
jmp 0x2c8b
shrl $0x8, %eax
andl $0xf, %eax
movzbl 0x1002(%rbx,%rax), %eax
leal (%rax,%rax,4), %edx
leal (%rax,%rdx,8), %eax
shrl $0xc, %eax
movzwl 0x1012(%rbx), %edx
movb %al, 0x2(%rbx,%rdx)
andl $0xf, %ecx
movzbl 0x1002(%rbx,%rcx), %eax
imull $0xcd, %eax, %eax
shrl $0xb, %eax
leal (%rax,%rax,4), %edx
leal (%rdx,%rdx,4), %edx
addl %eax, %edx
shrl $0x7, %edx
andl $0x6, %edx
leal (%rdx,%rdx,4), %edx
subb %dl, %al
movzwl 0x1012(%rbx), %edx
movb %al, 0x3(%rbx,%rdx)
movzbl 0x1002(%rbx,%rcx), %eax
leal (%rax,%rax,4), %ecx
leal (%rax,%rcx,8), %ecx
shrl $0xc, %ecx
imull $0x64, %ecx, %ecx
subb %cl, %al
movzbl %al, %eax
imull $0x67, %eax, %ecx
shrl $0x9, %ecx
andl $-0x2, %ecx
leal (%rcx,%rcx,4), %ecx
subb %cl, %al
movzwl 0x1012(%rbx), %ecx
movb %al, 0x4(%rbx,%rcx)
jmp 0x272b
movzwl 0x1012(%rbx), %edx
shrl $0x8, %eax
andl $0xf, %eax
movzbl 0x1002(%rbx,%rax), %eax
addl %edx, %eax
cmpl $0x10000, %eax          # imm = 0x10000
setae 0x1011(%rbx)
andl $0xf, %ecx
movzbl 0x1002(%rbx,%rcx), %eax
addl %edx, %eax
movw %ax, 0x1012(%rbx)
jmp 0x2c8b
movl %eax, %ecx
shrl $0x4, %ecx
andl $0xf, %ecx
movb 0x1002(%rbx,%rcx), %cl
shrl $0x8, %eax
andl $0xf, %eax
orb %cl, 0x1002(%rbx,%rax)
jmp 0x2c8b
shrl $0x8, %eax
andl $0xf, %eax
movb 0x1002(%rbx,%rax), %al
andb $0x1, %al
movb %al, 0x1011(%rbx)
leal 0x2(%r14), %eax
movw %ax, 0x1014(%rbx)
andl $0xf, %ecx
shrb 0x1002(%rbx,%rcx)
jmp 0x2c96
movl %eax, %ecx
shrl $0x4, %ecx
andl $0xf, %ecx
movb 0x1002(%rbx,%rcx), %dl
shrl $0x8, %eax
andl $0xf, %eax
cmpb 0x1002(%rbx,%rax), %dl
seta 0x1011(%rbx)
movb 0x1002(%rbx,%rcx), %cl
subb 0x1002(%rbx,%rax), %cl
movb %cl, 0x1002(%rbx,%rax)
jmp 0x2c8b
andl $0xf, %ecx
leaq 0x1002(%rbx), %rax
movq %rcx, %rdx
incq %rdx
movb (%rax), %sil
movzwl 0x1012(%rbx), %edi
movb %sil, -0x1000(%rax,%rdi)
incq %rax
decq %rdx
jne 0x2c0a
movzwl 0x1012(%rbx), %eax
addw %cx, %ax
incl %eax
movw %ax, 0x1012(%rbx)
jmp 0x272b
movl %eax, %ecx
shrl $0x4, %ecx
andl $0xf, %ecx
movb 0x1002(%rbx,%rcx), %cl
shrl $0x8, %eax
andl $0xf, %eax
xorb %cl, 0x1002(%rbx,%rax)
jmp 0x2c8b
movl %eax, %ecx
shrl $0x4, %ecx
andl $0xf, %ecx
shrl $0x8, %eax
andl $0xf, %eax
movb 0x1002(%rbx,%rax), %dl
addb 0x1002(%rbx,%rcx), %dl
setb 0x1011(%rbx)
movb 0x1002(%rbx,%rcx), %cl
addb %cl, 0x1002(%rbx,%rax)
leal 0x2(%r14), %eax
movw %ax, 0x1014(%rbx)
movb 0x3018(%rbx), %al
testb %al, %al
je 0x2ca8
decb %al
movb %al, 0x3018(%rbx)
movb 0x3019(%rbx), %al
cmpb $0x1, %al
jne 0x2cb9
movb $0x1, 0x304d(%rbx)
decb %al
movb %al, 0x3019(%rbx)
popq %rbx
popq %r14
popq %rbp
retq
shrl $0x8, %eax
andl $0xf, %eax
movb 0x1002(%rbx,%rax), %al
shrb $0x7, %al
movb %al, 0x1011(%rbx)
leal 0x2(%r14), %eax
movw %ax, 0x1014(%rbx)
andl $0xf, %ecx
shlb 0x1002(%rbx,%rcx)
jmp 0x2c96
nop