// File: /workspace/github_cpp_makefile_star2_O2/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 %rbx
pushq %rax
movq %rdi, %rbx
movzwl 0x1014(%rdi), %eax
movzbl 0x2(%rdi,%rax), %edx
movl %edx, %r8d
shll $0x8, %r8d
movb 0x3(%rdi,%rax), %dil
movzbl %dil, %esi
leal (%r8,%rsi), %ecx
movw %cx, (%rbx)
shrl $0xc, %r8d
leaq 0x1983(%rip), %r9       # 0x4004
movslq (%r9,%r8,4), %r8
addq %r9, %r8
jmpq *%r8
cmpl $0xee, %esi
je 0x29b4
cmpl $0xe0, %esi
jne 0x2c96
xorl %ecx, %ecx
cmpq $0x800, %rcx            # imm = 0x800
je 0x299e
andl $0x0, 0x1018(%rbx,%rcx,4)
incq %rcx
jmp 0x26a5
movl %ecx, %edx
andl $0xf, %edx
cmpl $0x1, %edx
je 0x297a
cmpl $0xe, %edx
jne 0x2c96
shrl $0x8, %ecx
andl $0xf, %ecx
movzbl 0x1002(%rbx,%rcx), %ecx
cmpb $0x0, 0x303c(%rbx,%rcx)
jne 0x2996
jmp 0x2c8c
andl $0xfff, %ecx            # imm = 0xFFF
movzbl 0x1002(%rbx), %eax
addl %ecx, %eax
jmp 0x2c8f
shrl $0x8, %ecx
andl $0xf, %ecx
cmpb %dil, 0x1002(%rbx,%rcx)
jne 0x2996
jmp 0x2c8c
callq 0x20b0
movl $0xff, %ecx
cltd
idivl %ecx
movzwl (%rbx), %eax
andl %eax, %edx
andl $0xf, %eax
movb %dl, 0x1002(%rbx,%rax)
addw $0x2, 0x1014(%rbx)
jmp 0x2c96
movl %ecx, %edx
andl $0xf, %edx
movb 0x1002(%rbx,%rdx), %dl
shrl $0x4, %ecx
andl $0xf, %ecx
cmpb 0x1002(%rbx,%rcx), %dl
jne 0x2996
jmp 0x2c8c
movzwl 0x303a(%rbx), %edx
movw %ax, 0x301a(%rbx,%rdx,2)
incw 0x303a(%rbx)
andl $0xfff, %ecx            # imm = 0xFFF
movw %cx, 0x1014(%rbx)
jmp 0x2c96
cmpl $0x7, %esi
je 0x2a6a
cmpl $0xa, %esi
je 0x2c00
cmpl $0x15, %esi
je 0x2b59
cmpl $0x18, %esi
je 0x29d7
cmpl $0x1e, %esi
je 0x2a34
cmpl $0x29, %esi
je 0x2b3c
cmpl $0x33, %esi
je 0x2a7b
cmpl $0x55, %esi
je 0x29ef
cmpl $0x65, %esi
jne 0x2c96
andl $0xf, %edx
leaq 0x1002(%rbx), %rax
movq %rdx, %rcx
incq %rcx
subq $0x1, %rcx
jb 0x2a1c
movzwl 0x1012(%rbx), %esi
movb -0x1000(%rax,%rsi), %sil
movb %sil, (%rax)
incq %rax
jmp 0x27fa
shrl $0x8, %ecx
andl $0xf, %ecx
cmpb %dil, 0x1002(%rbx,%rcx)
je 0x2996
jmp 0x2c8c
shrl $0x8, %ecx
andl $0xf, %ecx
addb %dil, 0x1002(%rbx,%rcx)
jmp 0x2c8c
movl %ecx, %edx
shrl $0x8, %edx
andl $0xf, %edx
movb 0x1002(%rbx,%rdx), %dl
shrl $0x4, %ecx
andl $0xf, %ecx
cmpb 0x1002(%rbx,%rcx), %dl
je 0x2996
jmp 0x2c8c
shrl $0x8, %ecx
andl $0xf, %ecx
movzbl 0x1002(%rbx,%rcx), %ecx
movw %cx, 0x399d(%rip)       # 0x6220
movl %esi, %edx
shrl $0x4, %edx
movzbl 0x1002(%rbx,%rdx), %edi
movw %di, 0x398b(%rip)       # 0x6222
andl $0xf, %esi
movl %esi, 0x3984(%rip)      # 0x6224
movb $0x0, 0x1011(%rbx)
movzwl 0x1012(%rbx), %edx
shll $0x8, %edi
leaq (%rdi,%rcx,4), %rcx
leaq (%rbx,%rcx), %rdi
addq $0x1018, %rdi           # imm = 0x1018
xorl %r8d, %r8d
cmpq %rsi, %r8
je 0x2917
leaq (%r8,%rdx), %rcx
movzbl 0x2(%rbx,%rcx), %r9d
movw %r9w, 0x3944(%rip)      # 0x621e
xorl %ecx, %ecx
cmpq $0x8, %rcx
je 0x290b
movl %r9d, %r10d
shll %cl, %r10d
testb %r10b, %r10b
jns 0x2906
movl (%rdi,%rcx,4), %r10d
cmpl $0x1, %r10d
jne 0x28fe
movb $0x1, 0x1011(%rbx)
xorl $0x1, %r10d
movl %r10d, (%rdi,%rcx,4)
incq %rcx
jmp 0x28dc
incq %r8
addq $0x100, %rdi            # imm = 0x100
jmp 0x28c3
movb $0x1, 0x304c(%rbx)
jmp 0x2c8c
shrl $0x8, %ecx
andl $0xf, %ecx
movb %dil, 0x1002(%rbx,%rcx)
jmp 0x2c8c
andl $0xfff, %ecx            # imm = 0xFFF
movw %cx, 0x1012(%rbx)
jmp 0x2c8c
movl %ecx, %esi
andl $0xf, %esi
cmpl $0xe, %esi
ja 0x2c96
leaq 0x16e7(%rip), %rdi      # 0x4044
movslq (%rdi,%rsi,4), %rsi
addq %rdi, %rsi
jmpq *%rsi
movl %ecx, %edx
shrl $0x4, %edx
andl $0xf, %edx
movb 0x1002(%rbx,%rdx), %dl
jmp 0x2a70
shrl $0x8, %ecx
andl $0xf, %ecx
movzbl 0x1002(%rbx,%rcx), %ecx
cmpb $0x0, 0x303c(%rbx,%rcx)
jne 0x2c8c
addl $0x4, %eax
jmp 0x2c8f
addl $0x2, %eax
movw %ax, 0x1014(%rbx)
movb $0x1, 0x304c(%rbx)
jmp 0x2c96
movzwl 0x303a(%rbx), %eax
decl %eax
movw %ax, 0x303a(%rbx)
movzwl %ax, %eax
movzwl 0x301a(%rbx,%rax,2), %eax
addl $0x2, %eax
jmp 0x2c8f
shrl $0x8, %ecx
andl $0xf, %ecx
movb 0x1002(%rbx,%rcx), %cl
movb %cl, 0x3019(%rbx)
jmp 0x2c8c
andl $0xf, %edx
leaq 0x1002(%rbx), %rax
movq %rdx, %rcx
incq %rcx
subq $0x1, %rcx
jb 0x2a1c
movb (%rax), %sil
movzwl 0x1012(%rbx), %edi
movb %sil, -0x1000(%rax,%rdi)
incq %rax
jmp 0x29ff
movzwl 0x1012(%rbx), %eax
addw %dx, %ax
incl %eax
movw %ax, 0x1012(%rbx)
jmp 0x2740
movzwl 0x1012(%rbx), %esi
shrl $0x8, %ecx
andl $0xf, %ecx
movzbl 0x1002(%rbx,%rcx), %ecx
addl %esi, %ecx
cmpl $0x10000, %ecx          # imm = 0x10000
setae 0x1011(%rbx)
andl $0xf, %edx
movzbl 0x1002(%rbx,%rdx), %ecx
addl %esi, %ecx
jmp 0x2b4d
movb 0x3018(%rbx), %dl
shrl $0x8, %ecx
andl $0xf, %ecx
jmp 0x2bf4
shrl $0x8, %ecx
andl $0xf, %ecx
movzbl 0x1002(%rbx,%rcx), %eax
movb $0x64, %cl
divb %cl
movzwl 0x1012(%rbx), %esi
movb %al, 0x2(%rbx,%rsi)
andl $0xf, %edx
movzbl 0x1002(%rbx,%rdx), %eax
movb $0xa, %sil
divb %sil
movzbl %al, %eax
divb %sil
movzbl %ah, %eax
movzwl 0x1012(%rbx), %edi
movb %al, 0x3(%rbx,%rdi)
movzbl 0x1002(%rbx,%rdx), %eax
divb %cl
movzbl %ah, %eax
movzbl %al, %eax
divb %sil
movzbl %ah, %eax
movzwl 0x1012(%rbx), %ecx
movb %al, 0x4(%rbx,%rcx)
jmp 0x2740
movl %ecx, %edx
shrl $0x4, %edx
andl $0xf, %edx
movb 0x1002(%rbx,%rdx), %dl
shrl $0x8, %ecx
andl $0xf, %ecx
andb %dl, 0x1002(%rbx,%rcx)
jmp 0x2c8c
movl %ecx, %edx
shrl $0x8, %edx
andl $0xf, %edx
movb 0x1002(%rbx,%rdx), %sil
shrl $0x4, %ecx
andl $0xf, %ecx
cmpb 0x1002(%rbx,%rcx), %sil
seta 0x1011(%rbx)
movb 0x1002(%rbx,%rcx), %cl
subb %cl, 0x1002(%rbx,%rdx)
jmp 0x2c8c
shrl $0x8, %ecx
andl $0xf, %ecx
movzbl 0x1002(%rbx,%rcx), %ecx
leal (%rcx,%rcx,4), %ecx
movw %cx, 0x1012(%rbx)
jmp 0x2c8c
shrl $0x8, %ecx
andl $0xf, %ecx
movb 0x1002(%rbx,%rcx), %cl
movb %cl, 0x3018(%rbx)
jmp 0x2c8c
movl %ecx, %edx
shrl $0x4, %edx
andl $0xf, %edx
movb 0x1002(%rbx,%rdx), %dl
shrl $0x8, %ecx
andl $0xf, %ecx
orb %dl, 0x1002(%rbx,%rcx)
jmp 0x2c8c
shrl $0x8, %ecx
andl $0xf, %ecx
movb 0x1002(%rbx,%rcx), %cl
andb $0x1, %cl
movb %cl, 0x1011(%rbx)
addl $0x2, %eax
movw %ax, 0x1014(%rbx)
andl $0xf, %edx
shrb 0x1002(%rbx,%rdx)
jmp 0x2c96
movl %ecx, %edx
shrl $0x4, %edx
andl $0xf, %edx
movb 0x1002(%rbx,%rdx), %sil
shrl $0x8, %ecx
andl $0xf, %ecx
cmpb 0x1002(%rbx,%rcx), %sil
seta 0x1011(%rbx)
movb 0x1002(%rbx,%rdx), %dl
subb 0x1002(%rbx,%rcx), %dl
movb %dl, 0x1002(%rbx,%rcx)
jmp 0x2c8c
movb $0x0, 0x3616(%rip)      # 0x621d
andl $0xf, %edx
xorl %ecx, %ecx
testb $0x1, %cl
jne 0x2c8c
xorl %esi, %esi
cmpq $0x10, %rsi
je 0x2c0c
cmpb $0x0, 0x303c(%rbx,%rsi)
jne 0x2c28
incq %rsi
jmp 0x2c13
movb %sil, 0x1002(%rbx,%rdx)
movb $0x1, 0x35e6(%rip)      # 0x621d
movb $0x1, %cl
jmp 0x2c0c
movl %ecx, %edx
shrl $0x4, %edx
andl $0xf, %edx
movb 0x1002(%rbx,%rdx), %dl
shrl $0x8, %ecx
andl $0xf, %ecx
xorb %dl, 0x1002(%rbx,%rcx)
jmp 0x2c8c
movl %ecx, %edx
shrl $0x4, %edx
andl $0xf, %edx
shrl $0x8, %ecx
andl $0xf, %ecx
movb 0x1002(%rbx,%rcx), %sil
addb 0x1002(%rbx,%rdx), %sil
setb 0x1011(%rbx)
movb 0x1002(%rbx,%rdx), %dl
addb %dl, 0x1002(%rbx,%rcx)
addl $0x2, %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)
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
shrl $0x8, %ecx
andl $0xf, %ecx
movb 0x1002(%rbx,%rcx), %cl
shrb $0x7, %cl
movb %cl, 0x1011(%rbx)
addl $0x2, %eax
movw %ax, 0x1014(%rbx)
andl $0xf, %edx
shlb 0x1002(%rbx,%rdx)
jmp 0x2c96