// File: geoherna[P]lib605/./src/lib605.cpp
// Function: lib605::MSR::SetBPI(int, lib605::Track::TRACK_BPI)
bool MSR::SetBPI(int track, Track::TRACK_BPI TrackBPI) {
		if(!this->MSRConected) {
#if defined(DEBUG)
			std::cout << "[*] Unable to set BPI, not connect to device" << std::endl;
#endif
			return false;
		}
		char resp[2];
		switch(track) {
			case 1: {
				switch(TrackBPI){
					case Track::BPI_210: {
						this->WriteAutoSize(MSR_SB_TRACK1_210);
						break;
					} case Track::BPI_75: {
						this->WriteAutoSize(MSR_SB_TRACK1_75);
						break;
					} default: break;
				}
				break;
			} case 2: {
				switch(TrackBPI){
					case Track::BPI_210: {
						this->WriteAutoSize(MSR_SB_TRACK2_210);
						break;
					} case Track::BPI_75: {
						this->WriteAutoSize(MSR_SB_TRACK2_75);
						break;
					} default: break;
				}
				break;
			} case 3: {
				switch(TrackBPI){
					case Track::BPI_210: {
						this->WriteAutoSize(MSR_SB_TRACK3_210);
						break;
					} case Track::BPI_75: {
						this->WriteAutoSize(MSR_SB_TRACK3_75);
						break;
					} default: break;
				}
				break;
			} default: break;
		}
		// Check Response
		if(this->ReadBytes((char*)&resp, 2) != 2) {
#if defined(DEBUG)
			std::cout << "[*] Set BPI failed, expected back 2 bytes" << std::endl;
#endif
			return false;
		}
		if(memcmp(resp, MSR_OK, 2) == 0) {
			return true;
		}else if (memcmp(resp, MSR_FAIL, 2) == 0) {
#if defined(DEBUG)
			std::cout << "[*] Set BPI failed, got MSR_FAIL" << std::endl;
#endif
			return false;
		} else {
#if defined(DEBUG)
			std::cout << "[*] Set BPI failed, expected MSR_OK or MSR_FAIL, got other" << std::endl;
#endif
			return false;
		}
		return false;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x28(%rbp)
testb $0x1, 0x4(%rax)
jne 0x6e99
movb $0x0, -0x1(%rbp)
jmp 0x6fd6
movl -0x14(%rbp), %eax
movl %eax, -0x2c(%rbp)
subl $0x1, %eax
je 0x6ec1
jmp 0x6ea6
movl -0x2c(%rbp), %eax
subl $0x2, %eax
je 0x6eff
jmp 0x6eb0
movl -0x2c(%rbp), %eax
subl $0x3, %eax
je 0x6f3d
jmp 0x6f7b
movl -0x18(%rbp), %eax
movl %eax, -0x30(%rbp)
testl %eax, %eax
je 0x6ed7
jmp 0x6ecd
movl -0x30(%rbp), %eax
subl $0x1, %eax
je 0x6ee9
jmp 0x6efb
movq -0x28(%rbp), %rdi
leaq 0x2243(%rip), %rsi      # 0x9125
callq 0x5240
jmp 0x6efd
movq -0x28(%rbp), %rdi
leaq 0x2235(%rip), %rsi      # 0x9129
callq 0x5240
jmp 0x6efd
jmp 0x6efd
jmp 0x6f7d
movl -0x18(%rbp), %eax
movl %eax, -0x34(%rbp)
testl %eax, %eax
je 0x6f15
jmp 0x6f0b
movl -0x34(%rbp), %eax
subl $0x1, %eax
je 0x6f27
jmp 0x6f39
movq -0x28(%rbp), %rdi
leaq 0x220d(%rip), %rsi      # 0x912d
callq 0x5240
jmp 0x6f3b
movq -0x28(%rbp), %rdi
leaq 0x21ff(%rip), %rsi      # 0x9131
callq 0x5240
jmp 0x6f3b
jmp 0x6f3b
jmp 0x6f7d
movl -0x18(%rbp), %eax
movl %eax, -0x38(%rbp)
testl %eax, %eax
je 0x6f53
jmp 0x6f49
movl -0x38(%rbp), %eax
subl $0x1, %eax
je 0x6f65
jmp 0x6f77
movq -0x28(%rbp), %rdi
leaq 0x21d7(%rip), %rsi      # 0x9135
callq 0x5240
jmp 0x6f79
movq -0x28(%rbp), %rdi
leaq 0x21c9(%rip), %rsi      # 0x9139
callq 0x5240
jmp 0x6f79
jmp 0x6f79
jmp 0x6f7d
jmp 0x6f7d
movq -0x28(%rbp), %rdi
leaq -0x1a(%rbp), %rsi
movl $0x2, %edx
callq 0x5160
cmpl $0x2, %eax
je 0x6f9a
movb $0x0, -0x1(%rbp)
jmp 0x6fd6
leaq -0x1a(%rbp), %rax
movw (%rax), %ax
subw $0x301b, %ax            # imm = 0x301B
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x6fb6
movb $0x1, -0x1(%rbp)
jmp 0x6fd6
leaq -0x1a(%rbp), %rax
movw (%rax), %ax
subw $0x411b, %ax            # imm = 0x411B
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x6fd2
movb $0x0, -0x1(%rbp)
jmp 0x6fd6
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)