// File: /workspace/github_c_makefile_star2_O3/chipkin[P]Linux-HighSpeedSerialMonitor/linuxMSTPFunctions.c
// Function: serialConnect(char const*, unsigned short)
bool serialConnect(const char* path, uint16_t baudRate)
{
    struct termios portSettings;

    serailFD = open(path, O_RDWR | O_NOCTTY | O_NDELAY);
    if (serailFD == -1) {
        std::cerr << "Error: Could not open port. path=" << path << ", Error: " << strerror(errno) << std::endl;
        return false;
    }

    if (!isatty(serailFD)) {
        std::cerr << "Error: File descripter is not pointing at a TTY device. path=" << path << std::endl;
        return false;
    }

    // Set the port options
    tcgetattr(serailFD, &portSettings); /* save current port settings */
    switch (baudRate) {
        case 38400:
            if (cfsetispeed(&portSettings, B38400) < 0 || cfsetospeed(&portSettings, B38400) < 0) {
                std::cerr << "Error: Could not set the Baud rate. path=" << path << ", baudRate: " << baudRate << std::endl;
                return false;
            }
            break;

        default:
            std::cerr << "Error: Unknown baud rate. path=" << path << ", baudRate: " << baudRate << std::endl;
            return false;
    }

    //
    // Input flags - Turn off input processing
    //
    // convert break to null byte, no CR to NL translation,
    // no NL to CR translation, don't mark parity errors or breaks
    // no input parity check, don't strip high bit off,
    // no XON/XOFF software flow control
    //
    portSettings.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | INLCR | PARMRK | INPCK | ISTRIP);
    // No software flow control
    portSettings.c_iflag &= ~(IXON | IXOFF | IXANY);

    //
    // Output flags - Turn off output processing
    //
    // no CR to NL translation, no NL to CR-NL translation,
    // no NL to CR translation, no column 0 CR suppression,
    // no Ctrl-D suppression, no fill characters, no case mapping,
    // no local output processing
    //
    // config.c_oflag &= ~(OCRNL | ONLCR | ONLRET |
    //                     ONOCR | ONOEOT| OFILL | OLCUC | OPOST);
    portSettings.c_oflag = 0;

    //
    // No line processing
    //
    // echo off, echo newline off, canonical mode off,
    // extended input processing off, signal chars off
    //
    portSettings.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);

    //
    // Turn off character processing
    //
    // clear current char size mask, no parity checking,
    // no output processing, force 8 bit input
    //
    portSettings.c_cflag &= ~(CSIZE | PARENB);
    portSettings.c_cflag |= CS8;

    //
    // One input byte is enough to return from read()
    // Inter-character timer off
    //
    portSettings.c_cc[VMIN] = 1;
    portSettings.c_cc[VTIME] = 0;

    // Enable reading
    // portSettings.c_cflag |= (CLOCAL | CREAD);

    if (tcsetattr(serailFD, TCSAFLUSH, &portSettings) < 0) {
        std::cerr << "Error: Could not set the port settings. path=" << path << ", baudRate: " << baudRate << std::endl;
        return false;
    }
    /*
    if (tcflush(serailFD, TCSAFLUSH, &portSettings) <= 0) {
        std::cerr << "Error: Could not inital flush the serial port. path=" << path << ", baudRate: " << baudRate << std::endl;
        return false;
    }
    */

    return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x48, %rsp
movl %esi, %ebp
movq %rdi, %rbx
movl $0x902, %esi            # imm = 0x902
xorl %eax, %eax
callq 0x2120
movl %eax, 0x2d17(%rip)      # 0x619c
cmpl $-0x1, %eax
je 0x354d
movl %eax, %edi
callq 0x22b0
testl %eax, %eax
je 0x3590
movl 0x2cf9(%rip), %edi      # 0x619c
leaq 0xc(%rsp), %rsi
callq 0x21c0
movzwl %bp, %r14d
cmpl $0x9600, %r14d          # imm = 0x9600
jne 0x35d3
leaq 0xc(%rsp), %rdi
movl $0xf, %esi
callq 0x20f0
testl %eax, %eax
js 0x3698
leaq 0xc(%rsp), %rdi
movl $0xf, %esi
callq 0x21b0
testl %eax, %eax
js 0x3698
leaq 0xc(%rsp), %rdx
andl $0xffffe284, (%rdx)     # imm = 0xFFFFE284
movl $0x0, 0x4(%rdx)
andl $0xffff7fb4, 0xc(%rdx)  # imm = 0xFFFF7FB4
movl $0xfffffecf, %eax       # imm = 0xFFFFFECF
andl 0x8(%rdx), %eax
orl $0x30, %eax
movl %eax, 0x8(%rdx)
movw $0x100, 0x16(%rdx)      # imm = 0x100
movl 0x2c7d(%rip), %edi      # 0x619c
movl $0x2, %esi
callq 0x21e0
movl %eax, %ecx
movb $0x1, %al
testl %ecx, %ecx
jns 0x37b9
movq 0x2ab4(%rip), %r14      # 0x5ff0
leaq 0xea9(%rip), %rsi       # 0x43ec
movl $0x2d, %edx
jmp 0x36ab
movq 0x2a9c(%rip), %r14      # 0x5ff0
leaq 0xdd0(%rip), %rsi       # 0x432b
movl $0x21, %edx
movq %r14, %rdi
callq 0x21d0
testq %rbx, %rbx
je 0x3616
movq %rbx, %rdi
callq 0x20b0
movq 0x2a70(%rip), %rdi      # 0x5ff0
movq %rbx, %rsi
movq %rax, %rdx
callq 0x21d0
jmp 0x362e
movq 0x2a59(%rip), %r14      # 0x5ff0
leaq 0xdb9(%rip), %rsi       # 0x4357
movl $0x3d, %edx
movq %r14, %rdi
callq 0x21d0
testq %rbx, %rbx
je 0x36db
movq %rbx, %rdi
callq 0x20b0
movq 0x2a2d(%rip), %rdi      # 0x5ff0
movq %rbx, %rsi
movq %rax, %rdx
callq 0x21d0
jmp 0x36f3
movq 0x2a16(%rip), %r15      # 0x5ff0
leaq 0xdeb(%rip), %rsi       # 0x43cc
movl $0x1f, %edx
movq %r15, %rdi
callq 0x21d0
testq %rbx, %rbx
je 0x3712
movq %rbx, %rdi
callq 0x20b0
movq 0x29ea(%rip), %rdi      # 0x5ff0
movq %rbx, %rsi
movq %rax, %rdx
callq 0x21d0
jmp 0x372a
movq (%r14), %rax
movq -0x18(%rax), %rax
leaq (%r14,%rax), %rdi
movl 0x20(%r14,%rax), %esi
orl $0x1, %esi
callq 0x2290
movq 0x29bb(%rip), %rbx      # 0x5ff0
leaq 0xd11(%rip), %rsi       # 0x434d
movl $0x9, %edx
movq %rbx, %rdi
callq 0x21d0
callq 0x2040
movl (%rax), %edi
callq 0x2080
testq %rax, %rax
je 0x3679
movq %rax, %r14
movq %rax, %rdi
callq 0x20b0
movq 0x2984(%rip), %rdi      # 0x5ff0
movq %r14, %rsi
movq %rax, %rdx
callq 0x21d0
jmp 0x3690
movq (%rbx), %rax
movq -0x18(%rax), %rax
leaq (%rbx,%rax), %rdi
movl 0x20(%rbx,%rax), %esi
orl $0x1, %esi
callq 0x2290
movq (%rbx), %rax
jmp 0x3793
movq 0x2951(%rip), %r14      # 0x5ff0
leaq 0xcef(%rip), %rsi       # 0x4395
movl $0x29, %edx
movq %r14, %rdi
callq 0x21d0
testq %rbx, %rbx
je 0x374d
movq %rbx, %rdi
callq 0x20b0
movq 0x2925(%rip), %rdi      # 0x5ff0
movq %rbx, %rsi
movq %rax, %rdx
callq 0x21d0
jmp 0x3765
movq (%r14), %rax
movq -0x18(%rax), %rax
leaq (%r14,%rax), %rdi
movl 0x20(%r14,%rax), %esi
orl $0x1, %esi
callq 0x2290
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %r14, %rdi
jmp 0x37aa
movq (%r15), %rax
movq -0x18(%rax), %rax
leaq (%r15,%rax), %rdi
movl 0x20(%r15,%rax), %esi
orl $0x1, %esi
callq 0x2290
movq 0x28bf(%rip), %rbx      # 0x5ff0
leaq 0xc87(%rip), %rsi       # 0x43bf
movl $0xc, %edx
movq %rbx, %rdi
callq 0x21d0
movq %rbx, %rdi
movq %r14, %rsi
jmp 0x3788
movq (%r14), %rax
movq -0x18(%rax), %rax
leaq (%r14,%rax), %rdi
movl 0x20(%r14,%rax), %esi
orl $0x1, %esi
callq 0x2290
movq 0x2884(%rip), %rbx      # 0x5ff0
leaq 0xc4c(%rip), %rsi       # 0x43bf
movl $0xc, %edx
movq %rbx, %rdi
callq 0x21d0
movl $0x9600, %esi           # imm = 0x9600
movq %rbx, %rdi
callq 0x2100
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2110
xorl %eax, %eax
addq $0x48, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq