// File: /workspace/github_c_makefile_star2_O0/j-hoppe[P]tu58fs/serial.c
// Function: serial_devinit
void serial_devinit(serial_device_t *serial, char *port, int32_t speed, int32_t databits,
		char parity, int32_t stopbits) {
	serial->rx_lasttime_ms = 0;
	serial->tx_lasttime_ms = 0;

	// init unix serial port mode
	struct termios line;
	char name[64];
	unsigned int n;

	serial->baudrate = speed;
	serial->bitcount = 1 + databits + stopbits; // total bit count

	// open serial port
	int32_t euid = geteuid();
	int32_t uid = getuid();
	setreuid(euid, -1);
	if (sscanf(port, "%u", &n) == 1)
		sprintf(name, "/dev/ttyS%u", n - 1);
	else
		strcpy(name, port);
	if ((serial->fd = open(name, O_RDWR | O_NDELAY | O_NOCTTY)) < 0)
		fatal("no serial line [%s]", name);
	setreuid(uid, euid);

	// get current line params, error if not a serial port
	if (tcgetattr(serial->fd, &serial->lineSave))
		fatal("not a serial device [%s]", name);

	// copy current parameters
	line = serial->lineSave;

	// input param
	line.c_iflag &= ~( IGNBRK | BRKINT | IMAXBEL | INPCK | ISTRIP |
	INLCR | IGNCR | ICRNL | IXON | IXOFF |
	IUCLC | IXANY | PARMRK | IGNPAR);
	line.c_iflag |= (0);

	// output param
	line.c_oflag &= ~( OPOST | OLCUC | OCRNL | ONLCR | ONOCR |
	ONLRET | OFILL | CRDLY | NLDLY | BSDLY |
	TABDLY | VTDLY | FFDLY | OFDEL);
	line.c_oflag |= (0);

	// control param
	line.c_cflag &= ~( CBAUD | CSIZE | CSTOPB | PARENB | PARODD |
	HUPCL | CRTSCTS | CLOCAL | CREAD);
	line.c_cflag |= ( CLOCAL | CREAD);

	// explicitly set size
	switch (databits) {
	case 5: // who needs this?
		line.c_cflag |= CS5;
		break;
	case 6: // who needs this?
		line.c_cflag |= CS6;
		break;
	case 7:
		line.c_cflag |= CS7;
		break;
	default:
		line.c_cflag |= CS8;
		break;
	}

	// explicitly set parity
	switch (toupper(parity)) {
	case 'E':
		line.c_cflag |= PARENB;
		line.c_cflag &= ~PARODD;
		serial->bitcount++; // one extra bit
		break;
	case 'O':
		line.c_cflag |= PARENB;
		line.c_cflag |= PARODD;
		serial->bitcount++; // one extra bit
		break;
	default: // no parity
		line.c_cflag &= ~PARENB;
		line.c_cflag &= ~PARODD;
	}

	// set two stop bits if requested, else default to one
	if (stopbits == 2)
		line.c_cflag |= CSTOPB;

	// local param
	line.c_lflag &= ~( ISIG | ICANON | ECHO | ECHOE | ECHOK |
	ECHONL | NOFLSH | TOSTOP | IEXTEN | FLUSHO |
	ECHOKE | ECHOCTL);
	line.c_lflag |= (0);

	// timing/read param
	line.c_cc[VMIN] = 1; // return a min of 1 chars
	line.c_cc[VTIME] = 0; // no timer

	// flush all existing input data
	tcflush(serial->fd, TCIFLUSH);

	// set baud rate, if it is legal
	if (devbaud(speed) == -1) {
		error("illegal serial speed %d., ignoring", speed);
	} else {
		cfsetispeed(&line, devbaud(speed));
		cfsetospeed(&line, devbaud(speed));
	}

	// set new device parameters
	tcsetattr(serial->fd, TCSANOW, &line);

	// and non-blocking also
	if (fcntl(serial->fd, F_SETFL, FNDELAY) == -1)
		error("failed to set non-blocking read");

	// zap current data, if any
	serial_devtxinit(serial);
	serial_devrxinit(serial);

	return;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movb %r8b, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movb %al, -0x19(%rbp)
movl %r9d, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x8(%rbp), %rax
movq $0x0, 0x18(%rax)
movl -0x14(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x4(%rax)
movl -0x18(%rbp), %ecx
addl $0x1, %ecx
addl -0x20(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x8(%rax)
callq 0x3230
movl %eax, -0xa8(%rbp)
callq 0x31a0
movl %eax, -0xac(%rbp)
movl -0xa8(%rbp), %edi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x3400
movq -0x10(%rbp), %rdi
leaq 0x13422(%rip), %rsi     # 0x1e018
leaq -0xa4(%rbp), %rdx
movb $0x0, %al
callq 0x33c0
cmpl $0x1, %eax
jne 0xac29
leaq -0xa0(%rbp), %rdi
movl -0xa4(%rbp), %edx
subl $0x1, %edx
leaq 0x11572(%rip), %rsi     # 0x1c192
movb $0x0, %al
callq 0x3520
jmp 0xac39
leaq -0xa0(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x30c0
leaq -0xa0(%rbp), %rdi
movl $0x902, %esi            # imm = 0x902
movb $0x0, %al
callq 0x3490
movq -0x8(%rbp), %rcx
movl %eax, (%rcx)
cmpl $0x0, %eax
jge 0xac6c
leaq -0xa0(%rbp), %rsi
leaq 0x11539(%rip), %rdi     # 0x1c19e
movb $0x0, %al
callq 0xd140
movl -0xac(%rbp), %edi
movl -0xa8(%rbp), %esi
callq 0x3400
movq -0x8(%rbp), %rax
movl (%rax), %edi
movq -0x8(%rbp), %rsi
addq $0x23c, %rsi            # imm = 0x23C
callq 0x3470
cmpl $0x0, %eax
je 0xacad
leaq -0xa0(%rbp), %rsi
leaq 0x1150c(%rip), %rdi     # 0x1c1b2
movb $0x0, %al
callq 0xd140
movq -0x8(%rbp), %rax
movups 0x23c(%rax), %xmm0
movups 0x24c(%rax), %xmm1
movups 0x25c(%rax), %xmm2
movups 0x268(%rax), %xmm3
movups %xmm3, -0x34(%rbp)
movaps %xmm2, -0x40(%rbp)
movaps %xmm1, -0x50(%rbp)
movaps %xmm0, -0x60(%rbp)
movl -0x60(%rbp), %eax
andl $0xffffc000, %eax       # imm = 0xFFFFC000
movl %eax, -0x60(%rbp)
movzwl -0x5a(%rbp), %eax
shll $0x10, %eax
movl %eax, -0x5c(%rbp)
movl -0x58(%rbp), %eax
andl $0x7fffe000, %eax       # imm = 0x7FFFE000
movl %eax, -0x58(%rbp)
movl -0x58(%rbp), %eax
orl $0x880, %eax            # imm = 0x880
movl %eax, -0x58(%rbp)
movl -0x18(%rbp), %eax
movl %eax, -0xb0(%rbp)
subl $0x5, %eax
je 0xad32
jmp 0xad18
movl -0xb0(%rbp), %eax
subl $0x6, %eax
je 0xad3d
jmp 0xad25
movl -0xb0(%rbp), %eax
subl $0x7, %eax
je 0xad48
jmp 0xad53
movl -0x58(%rbp), %eax
orl $0x0, %eax
movl %eax, -0x58(%rbp)
jmp 0xad5c
movl -0x58(%rbp), %eax
orl $0x10, %eax
movl %eax, -0x58(%rbp)
jmp 0xad5c
movl -0x58(%rbp), %eax
orl $0x20, %eax
movl %eax, -0x58(%rbp)
jmp 0xad5c
movl -0x58(%rbp), %eax
orl $0x30, %eax
movl %eax, -0x58(%rbp)
movsbl -0x19(%rbp), %edi
callq 0x30e0
movl %eax, %ecx
movl %ecx, -0xb4(%rbp)
subl $0x45, %eax
je 0xad81
jmp 0xad74
movl -0xb4(%rbp), %eax
subl $0x4f, %eax
je 0xada6
jmp 0xadcb
movl -0x58(%rbp), %eax
orl $0x100, %eax            # imm = 0x100
movl %eax, -0x58(%rbp)
movl -0x58(%rbp), %eax
andl $0xfffffdff, %eax       # imm = 0xFFFFFDFF
movl %eax, -0x58(%rbp)
movq -0x8(%rbp), %rax
movl 0x8(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x8(%rax)
jmp 0xade1
movl -0x58(%rbp), %eax
orl $0x100, %eax            # imm = 0x100
movl %eax, -0x58(%rbp)
movl -0x58(%rbp), %eax
orl $0x200, %eax            # imm = 0x200
movl %eax, -0x58(%rbp)
movq -0x8(%rbp), %rax
movl 0x8(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x8(%rax)
jmp 0xade1
movl -0x58(%rbp), %eax
andl $0xfffffeff, %eax       # imm = 0xFFFFFEFF
movl %eax, -0x58(%rbp)
movl -0x58(%rbp), %eax
andl $0xfffffdff, %eax       # imm = 0xFFFFFDFF
movl %eax, -0x58(%rbp)
cmpl $0x2, -0x20(%rbp)
jne 0xadf0
movl -0x58(%rbp), %eax
orl $0x40, %eax
movl %eax, -0x58(%rbp)
movl -0x54(%rbp), %eax
andl $0xffff6404, %eax       # imm = 0xFFFF6404
movl %eax, -0x54(%rbp)
movl -0x54(%rbp), %eax
orl $0x0, %eax
movl %eax, -0x54(%rbp)
movb $0x1, -0x49(%rbp)
movb $0x0, -0x4a(%rbp)
movq -0x8(%rbp), %rax
movl (%rax), %edi
xorl %esi, %esi
callq 0x31b0
movl -0x14(%rbp), %edi
callq 0xaec0
cmpl $-0x1, %eax
jne 0xae39
movl -0x14(%rbp), %esi
leaq 0x1139b(%rip), %rdi     # 0x1c1cb
movb $0x0, %al
callq 0xce70
jmp 0xae5f
movl -0x14(%rbp), %edi
callq 0xaec0
movl %eax, %esi
leaq -0x60(%rbp), %rdi
callq 0x34b0
movl -0x14(%rbp), %edi
callq 0xaec0
movl %eax, %esi
leaq -0x60(%rbp), %rdi
callq 0x3170
movq -0x8(%rbp), %rax
movl (%rax), %edi
xorl %esi, %esi
leaq -0x60(%rbp), %rdx
callq 0x3480
movq -0x8(%rbp), %rax
movl (%rax), %edi
movl $0x4, %esi
movl $0x800, %edx            # imm = 0x800
movb $0x0, %al
callq 0x3120
cmpl $-0x1, %eax
jne 0xae9a
leaq 0x1137b(%rip), %rdi     # 0x1c20e
movb $0x0, %al
callq 0xce70
movq -0x8(%rbp), %rdi
callq 0xa6f0
movq -0x8(%rbp), %rdi
callq 0xa740
addq $0xc0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)