// File: /workspace/github_c_makefile_star2_O0/DrYerzinia[P]C_DigiMode/src/io/uart/UART.c
// Function: UART_open
int UART_open(UART *self, char *device_name, unsigned int baud_rate){

	self->fd = open(device_name, O_RDWR | O_NOCTTY);
	if(self->fd < 0){
		perror("Unable to open UART");
		return -1;
	}

	tcgetattr(self->fd, &(self->tio));

	self->tio.c_cflag = CS8 | CLOCAL | CREAD;
	self->tio.c_iflag = IGNPAR;
	self->tio.c_oflag = 0;
	self->tio.c_lflag = 0;

	/* Set baud rate
	 */
	speed_t standard_baud_rate = B0;
	switch(baud_rate){
		case 50:
			standard_baud_rate = B50;
			break;
		case 75:
			standard_baud_rate = B75;
			break;
		case 110:
			standard_baud_rate = B110;
			break;
		case 134:
			standard_baud_rate = B134;
			break;
		case 150:
			standard_baud_rate = B150;
			break;
		case 200:
			standard_baud_rate = B200;
			break;
		case 300:
			standard_baud_rate = B300;
			break;
		case 600:
			standard_baud_rate = B600;
			break;
		case 1200:
			standard_baud_rate = B1200;
			break;
		case 1800:
			standard_baud_rate = B1800;
			break;
		case 2400:
			standard_baud_rate = B2400;
			break;
		case 4800:
			standard_baud_rate = B4800;
			break;
		case 9600:
			standard_baud_rate = B9600;
			break;
		case 19200:
			standard_baud_rate = B19200;
			break;
		case 38400:
			standard_baud_rate = B38400;
			break;
		case 57600:
			standard_baud_rate = B57600;
			break;
		case 115200:
			standard_baud_rate = B115200;
			break;
		case 230400:
			standard_baud_rate = B230400;
			break;
	}

	if(standard_baud_rate == B38400){

		// Ensure 38400 is actually 38400
		struct serial_struct ss;
		ioctl(self->fd, TIOCGSERIAL, &ss);
		ss.flags &= ~ASYNC_SPD_MASK;
		ioctl(self->fd, TIOCSSERIAL, &ss);

	} else if(standard_baud_rate == B0){

		standard_baud_rate = B38400;

		struct serial_struct ss;

		ioctl(self->fd, TIOCGSERIAL, &ss);

		ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;

		ss.custom_divisor = ((float)(ss.baud_base + (baud_rate / 2)) / baud_rate) + 0.5;

		unsigned int actual_rate = ss.baud_base / ss.custom_divisor;

		fprintf(stderr, "Actual baud rate set to %d\n", actual_rate);
		fprintf(stderr, "Error of %f%%\n", fabs((float)(baud_rate - actual_rate) / ((float)(baud_rate + actual_rate) / 2.0F)) * 100.0F);

		ioctl(self->fd, TIOCSSERIAL, &ss);

	}

	cfsetispeed(&(self->tio), standard_baud_rate);
	cfsetispeed(&(self->tio), standard_baud_rate);

	/* Wait until there is at least 1 byte and
	 * have an indefinite timeout
	 */
	self->tio.c_cc[VMIN] = 1;
	self->tio.c_cc[VTIME] = 0;

	tcflush(self->fd, TCIFLUSH);
	tcsetattr(self->fd, TCSANOW, &(self->tio));

	return 0;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq -0x18(%rbp), %rdi
movl $0x102, %esi            # imm = 0x102
movb $0x0, %al
callq 0x10e0
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
cmpl $0x0, (%rax)
jge 0x14df
leaq 0xc56(%rip), %rdi       # 0x2124
callq 0x1100
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18ed
movq -0x10(%rbp), %rsi
movl (%rsi), %edi
addq $0x4, %rsi
callq 0x10c0
movq -0x10(%rbp), %rax
movl $0x8b0, 0xc(%rax)       # imm = 0x8B0
movq -0x10(%rbp), %rax
movl $0x4, 0x4(%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x8(%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x10(%rax)
movl $0x0, -0x20(%rbp)
movl -0x1c(%rbp), %eax
movl %eax, -0xb8(%rbp)
subl $0x32, %eax
je 0x1677
jmp 0x1535
movl -0xb8(%rbp), %eax
subl $0x4b, %eax
je 0x1683
jmp 0x1546
movl -0xb8(%rbp), %eax
subl $0x6e, %eax
je 0x168f
jmp 0x1557
movl -0xb8(%rbp), %eax
subl $0x86, %eax
je 0x169b
jmp 0x156a
movl -0xb8(%rbp), %eax
subl $0x96, %eax
je 0x16a4
jmp 0x157d
movl -0xb8(%rbp), %eax
subl $0xc8, %eax
je 0x16ad
jmp 0x1590
movl -0xb8(%rbp), %eax
subl $0x12c, %eax            # imm = 0x12C
je 0x16b6
jmp 0x15a3
movl -0xb8(%rbp), %eax
subl $0x258, %eax            # imm = 0x258
je 0x16bf
jmp 0x15b6
movl -0xb8(%rbp), %eax
subl $0x4b0, %eax            # imm = 0x4B0
je 0x16c8
jmp 0x15c9
movl -0xb8(%rbp), %eax
subl $0x708, %eax            # imm = 0x708
je 0x16d1
jmp 0x15dc
movl -0xb8(%rbp), %eax
subl $0x960, %eax            # imm = 0x960
je 0x16da
jmp 0x15ef
movl -0xb8(%rbp), %eax
subl $0x12c0, %eax           # imm = 0x12C0
je 0x16e3
jmp 0x1602
movl -0xb8(%rbp), %eax
subl $0x2580, %eax           # imm = 0x2580
je 0x16ec
jmp 0x1615
movl -0xb8(%rbp), %eax
subl $0x4b00, %eax           # imm = 0x4B00
je 0x16f5
jmp 0x1628
movl -0xb8(%rbp), %eax
subl $0x9600, %eax           # imm = 0x9600
je 0x16fe
jmp 0x163b
movl -0xb8(%rbp), %eax
subl $0xe100, %eax           # imm = 0xE100
je 0x1707
jmp 0x164e
movl -0xb8(%rbp), %eax
subl $0x1c200, %eax          # imm = 0x1C200
je 0x1710
jmp 0x1661
movl -0xb8(%rbp), %eax
subl $0x38400, %eax          # imm = 0x38400
je 0x1719
jmp 0x1720
movl $0x1, -0x20(%rbp)
jmp 0x1720
movl $0x2, -0x20(%rbp)
jmp 0x1720
movl $0x3, -0x20(%rbp)
jmp 0x1720
movl $0x4, -0x20(%rbp)
jmp 0x1720
movl $0x5, -0x20(%rbp)
jmp 0x1720
movl $0x6, -0x20(%rbp)
jmp 0x1720
movl $0x7, -0x20(%rbp)
jmp 0x1720
movl $0x8, -0x20(%rbp)
jmp 0x1720
movl $0x9, -0x20(%rbp)
jmp 0x1720
movl $0xa, -0x20(%rbp)
jmp 0x1720
movl $0xb, -0x20(%rbp)
jmp 0x1720
movl $0xc, -0x20(%rbp)
jmp 0x1720
movl $0xd, -0x20(%rbp)
jmp 0x1720
movl $0xe, -0x20(%rbp)
jmp 0x1720
movl $0xf, -0x20(%rbp)
jmp 0x1720
movl $0x1001, -0x20(%rbp)    # imm = 0x1001
jmp 0x1720
movl $0x1002, -0x20(%rbp)    # imm = 0x1002
jmp 0x1720
movl $0x1003, -0x20(%rbp)    # imm = 0x1003
cmpl $0xf, -0x20(%rbp)
jne 0x1762
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x541e, %esi           # imm = 0x541E
leaq -0x68(%rbp), %rdx
movb $0x0, %al
callq 0x1050
movl -0x58(%rbp), %eax
andl $0xffffefcf, %eax       # imm = 0xFFFFEFCF
movl %eax, -0x58(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x541f, %esi           # imm = 0x541F
leaq -0x68(%rbp), %rdx
movb $0x0, %al
callq 0x1050
jmp 0x1894
cmpl $0x0, -0x20(%rbp)
jne 0x1892
movl $0xf, -0x20(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %edi
xorl %eax, %eax
movb %al, -0xc1(%rbp)
movl $0x541e, %esi           # imm = 0x541E
leaq -0xb0(%rbp), %rdx
callq 0x1050
movl -0xa0(%rbp), %eax
andl $0xffffefcf, %eax       # imm = 0xFFFFEFCF
orl $0x30, %eax
movl %eax, -0xa0(%rbp)
movl -0x94(%rbp), %ecx
movl -0x1c(%rbp), %eax
movl %eax, %edx
shrl %edx
addl %edx, %ecx
cvtsi2ss %rcx, %xmm0
cvtsi2ss %rax, %xmm1
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x939(%rip), %xmm1      # 0x2108
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x98(%rbp)
movl -0x98(%rbp), %ecx
movl -0x94(%rbp), %eax
cltd
idivl %ecx
movl %eax, %ecx
movb -0xc1(%rbp), %al
movl %ecx, -0xb4(%rbp)
movq 0x27f7(%rip), %rcx      # 0x3ff8
movq %rcx, -0xc0(%rbp)
movq (%rcx), %rdi
movl -0xb4(%rbp), %edx
leaq 0x920(%rip), %rsi       # 0x2138
callq 0x10a0
movq -0xc0(%rbp), %rax
movq (%rax), %rdi
movl -0x1c(%rbp), %eax
movl -0xb4(%rbp), %ecx
movl %eax, %edx
subl %ecx, %edx
cvtsi2ss %rdx, %xmm0
addl %ecx, %eax
cvtsi2ss %rax, %xmm1
movss 0x8d8(%rip), %xmm2      # 0x2120
divss %xmm2, %xmm1
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
movaps 0x8b5(%rip), %xmm1      # 0x2110
pand %xmm1, %xmm0
movsd 0x899(%rip), %xmm1      # 0x2100
mulsd %xmm1, %xmm0
leaq 0x8e2(%rip), %rsi       # 0x2154
movb $0x1, %al
callq 0x10a0
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl $0x541f, %esi           # imm = 0x541F
leaq -0xb0(%rbp), %rdx
movb $0x0, %al
callq 0x1050
jmp 0x1894
movq -0x10(%rbp), %rdi
addq $0x4, %rdi
movl -0x20(%rbp), %esi
callq 0x10f0
movq -0x10(%rbp), %rdi
addq $0x4, %rdi
movl -0x20(%rbp), %esi
callq 0x10f0
movq -0x10(%rbp), %rax
movb $0x1, 0x1b(%rax)
movq -0x10(%rbp), %rax
movb $0x0, 0x1a(%rax)
movq -0x10(%rbp), %rax
movl (%rax), %edi
xorl %esi, %esi
callq 0x1040
movq -0x10(%rbp), %rax
movl (%rax), %edi
movq -0x10(%rbp), %rdx
addq $0x4, %rdx
xorl %esi, %esi
callq 0x10d0
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xd0, %rsp
popq %rbp
retq
nopl (%rax)