// File: pelrun[P]aft/rs232.c
// Function: RS232_OpenComport
int RS232_OpenComport(const char* comport, int baudrate, const char *mode, HANDLE *handle)
{
  int baudr,
      status;

  struct termios new_port_settings;

  switch(baudrate)
  {
    case      50 : baudr = B50;
                   break;
    case      75 : baudr = B75;
                   break;
    case     110 : baudr = B110;
                   break;
    case     134 : baudr = B134;
                   break;
    case     150 : baudr = B150;
                   break;
    case     200 : baudr = B200;
                   break;
    case     300 : baudr = B300;
                   break;
    case     600 : baudr = B600;
                   break;
    case    1200 : baudr = B1200;
                   break;
    case    1800 : baudr = B1800;
                   break;
    case    2400 : baudr = B2400;
                   break;
    case    4800 : baudr = B4800;
                   break;
    case    9600 : baudr = B9600;
                   break;
    case   19200 : baudr = B19200;
                   break;
    case   38400 : baudr = B38400;
                   break;
    case   57600 : baudr = B57600;
                   break;
    case  115200 : baudr = B115200;
                   break;
    case  230400 : baudr = B230400;
                   break;
    case  460800 : baudr = B460800;
                   break;
    case  500000 : baudr = B500000;
                   break;
    case  576000 : baudr = B576000;
                   break;
    case  921600 : baudr = B921600;
                   break;
    case 1000000 : baudr = B1000000;
                   break;
    case 1152000 : baudr = B1152000;
                   break;
    case 1500000 : baudr = B1500000;
                   break;
    case 2000000 : baudr = B2000000;
                   break;
    case 2500000 : baudr = B2500000;
                   break;
    case 3000000 : baudr = B3000000;
                   break;
    case 3500000 : baudr = B3500000;
                   break;
    case 4000000 : baudr = B4000000;
                   break;
    default      : printf("invalid baudrate\n");
                   return -1;
                   break;
  }

  int cbits=CS8,
      cpar=0,
      ipar=IGNPAR,
      bstop=0;

  if(strlen(mode) != 3)
  {
    printf("invalid mode \"%s\"\n", mode);
    return -1;
  }

  switch(mode[0])
  {
    case '8': cbits = CS8;
              break;
    case '7': cbits = CS7;
              break;
    case '6': cbits = CS6;
              break;
    case '5': cbits = CS5;
              break;
    default : printf("invalid number of data-bits '%c'\n", mode[0]);
              return -1;
              break;
  }

  switch(mode[1])
  {
    case 'N':
    case 'n': cpar = 0;
              ipar = IGNPAR;
              break;
    case 'E':
    case 'e': cpar = PARENB;
              ipar = INPCK;
              break;
    case 'O':
    case 'o': cpar = (PARENB | PARODD);
              ipar = INPCK;
              break;
    default : printf("invalid parity '%c'\n", mode[1]);
              return -1;
              break;
  }

  switch(mode[2])
  {
    case '1': bstop = 0;
              break;
    case '2': bstop = CSTOPB;
              break;
    default : printf("invalid number of stop bits '%c'\n", mode[2]);
              return -1;
              break;
  }

/*
http://pubs.opengroup.org/onlinepubs/7908799/xsh/termios.h.html

http://man7.org/linux/man-pages/man3/termios.3.html
*/

  *handle = open(comport, O_RDWR | O_NOCTTY | O_NDELAY);
  if(*handle==-1)
  {
    perror("unable to open comport ");
    return -1;
  }

/*  error = tcgetattr(handle, old_port_settings + comport_number);
  if(error==-1)
  {
    close(handle);
    perror("unable to read portsettings ");
    return -1;
  }
  */
  memset(&new_port_settings, 0, sizeof(new_port_settings));  /* clear the new struct */

  new_port_settings.c_cflag = cbits | cpar | bstop | CLOCAL | CREAD;
  new_port_settings.c_iflag = ipar;
  new_port_settings.c_oflag = 0;
  new_port_settings.c_lflag = 0;
  new_port_settings.c_cc[VMIN] = 0;      /* block untill n bytes are received */
  new_port_settings.c_cc[VTIME] = 0;     /* block untill a timer expires (n * 100 mSec.) */

  cfsetispeed(&new_port_settings, baudr);
  cfsetospeed(&new_port_settings, baudr);

  error = tcsetattr(*handle, TCSANOW, &new_port_settings);
  if(error==-1)
  {
    close(*handle);
    perror("unable to adjust portsettings ");
    return -1;
  }

  if(ioctl(*handle, TIOCMGET, &status) == -1)
  {
    perror("unable to get portstatus");
    return -1;
  }

  status |= TIOCM_DTR;    /* turn on DTR */
  status |= TIOCM_RTS;    /* turn on RTS */

  if(ioctl(*handle, TIOCMSET, &status) == -1)
  {
    perror("unable to set portstatus");
    return -1;
  }

  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0x80(%rbp)
subl $0x32, %eax
je 0xe74a
jmp 0xe57b
movl -0x80(%rbp), %eax
subl $0x4b, %eax
je 0xe756
jmp 0xe589
movl -0x80(%rbp), %eax
subl $0x6e, %eax
je 0xe762
jmp 0xe597
movl -0x80(%rbp), %eax
subl $0x86, %eax
je 0xe76e
jmp 0xe5a7
movl -0x80(%rbp), %eax
subl $0x96, %eax
je 0xe77a
jmp 0xe5b7
movl -0x80(%rbp), %eax
subl $0xc8, %eax
je 0xe786
jmp 0xe5c7
movl -0x80(%rbp), %eax
subl $0x12c, %eax            # imm = 0x12C
je 0xe792
jmp 0xe5d7
movl -0x80(%rbp), %eax
subl $0x258, %eax            # imm = 0x258
je 0xe79e
jmp 0xe5e7
movl -0x80(%rbp), %eax
subl $0x4b0, %eax            # imm = 0x4B0
je 0xe7aa
jmp 0xe5f7
movl -0x80(%rbp), %eax
subl $0x708, %eax            # imm = 0x708
je 0xe7b6
jmp 0xe607
movl -0x80(%rbp), %eax
subl $0x960, %eax            # imm = 0x960
je 0xe7c2
jmp 0xe617
movl -0x80(%rbp), %eax
subl $0x12c0, %eax           # imm = 0x12C0
je 0xe7ce
jmp 0xe627
movl -0x80(%rbp), %eax
subl $0x2580, %eax           # imm = 0x2580
je 0xe7da
jmp 0xe637
movl -0x80(%rbp), %eax
subl $0x4b00, %eax           # imm = 0x4B00
je 0xe7e6
jmp 0xe647
movl -0x80(%rbp), %eax
subl $0x9600, %eax           # imm = 0x9600
je 0xe7f2
jmp 0xe657
movl -0x80(%rbp), %eax
subl $0xe100, %eax           # imm = 0xE100
je 0xe7fe
jmp 0xe667
movl -0x80(%rbp), %eax
subl $0x1c200, %eax          # imm = 0x1C200
je 0xe80a
jmp 0xe677
movl -0x80(%rbp), %eax
subl $0x38400, %eax          # imm = 0x38400
je 0xe816
jmp 0xe687
movl -0x80(%rbp), %eax
subl $0x70800, %eax          # imm = 0x70800
je 0xe822
jmp 0xe697
movl -0x80(%rbp), %eax
subl $0x7a120, %eax          # imm = 0x7A120
je 0xe82b
jmp 0xe6a7
movl -0x80(%rbp), %eax
subl $0x8ca00, %eax          # imm = 0x8CA00
je 0xe834
jmp 0xe6b7
movl -0x80(%rbp), %eax
subl $0xe1000, %eax          # imm = 0xE1000
je 0xe83d
jmp 0xe6c7
movl -0x80(%rbp), %eax
subl $0xf4240, %eax          # imm = 0xF4240
je 0xe846
jmp 0xe6d7
movl -0x80(%rbp), %eax
subl $0x119400, %eax         # imm = 0x119400
je 0xe84f
jmp 0xe6e7
movl -0x80(%rbp), %eax
subl $0x16e360, %eax         # imm = 0x16E360
je 0xe858
jmp 0xe6f7
movl -0x80(%rbp), %eax
subl $0x1e8480, %eax         # imm = 0x1E8480
je 0xe861
jmp 0xe707
movl -0x80(%rbp), %eax
subl $0x2625a0, %eax         # imm = 0x2625A0
je 0xe86a
jmp 0xe717
movl -0x80(%rbp), %eax
subl $0x2dc6c0, %eax         # imm = 0x2DC6C0
je 0xe873
jmp 0xe727
movl -0x80(%rbp), %eax
subl $0x3567e0, %eax         # imm = 0x3567E0
je 0xe87c
jmp 0xe737
movl -0x80(%rbp), %eax
subl $0x3d0900, %eax         # imm = 0x3D0900
je 0xe885
jmp 0xe88e
movl $0x1, -0x2c(%rbp)
jmp 0xe8a8
movl $0x2, -0x2c(%rbp)
jmp 0xe8a8
movl $0x3, -0x2c(%rbp)
jmp 0xe8a8
movl $0x4, -0x2c(%rbp)
jmp 0xe8a8
movl $0x5, -0x2c(%rbp)
jmp 0xe8a8
movl $0x6, -0x2c(%rbp)
jmp 0xe8a8
movl $0x7, -0x2c(%rbp)
jmp 0xe8a8
movl $0x8, -0x2c(%rbp)
jmp 0xe8a8
movl $0x9, -0x2c(%rbp)
jmp 0xe8a8
movl $0xa, -0x2c(%rbp)
jmp 0xe8a8
movl $0xb, -0x2c(%rbp)
jmp 0xe8a8
movl $0xc, -0x2c(%rbp)
jmp 0xe8a8
movl $0xd, -0x2c(%rbp)
jmp 0xe8a8
movl $0xe, -0x2c(%rbp)
jmp 0xe8a8
movl $0xf, -0x2c(%rbp)
jmp 0xe8a8
movl $0x1001, -0x2c(%rbp)    # imm = 0x1001
jmp 0xe8a8
movl $0x1002, -0x2c(%rbp)    # imm = 0x1002
jmp 0xe8a8
movl $0x1003, -0x2c(%rbp)    # imm = 0x1003
jmp 0xe8a8
movl $0x1004, -0x2c(%rbp)    # imm = 0x1004
jmp 0xe8a8
movl $0x1005, -0x2c(%rbp)    # imm = 0x1005
jmp 0xe8a8
movl $0x1006, -0x2c(%rbp)    # imm = 0x1006
jmp 0xe8a8
movl $0x1007, -0x2c(%rbp)    # imm = 0x1007
jmp 0xe8a8
movl $0x1008, -0x2c(%rbp)    # imm = 0x1008
jmp 0xe8a8
movl $0x1009, -0x2c(%rbp)    # imm = 0x1009
jmp 0xe8a8
movl $0x100a, -0x2c(%rbp)    # imm = 0x100A
jmp 0xe8a8
movl $0x100b, -0x2c(%rbp)    # imm = 0x100B
jmp 0xe8a8
movl $0x100c, -0x2c(%rbp)    # imm = 0x100C
jmp 0xe8a8
movl $0x100d, -0x2c(%rbp)    # imm = 0x100D
jmp 0xe8a8
movl $0x100e, -0x2c(%rbp)    # imm = 0x100E
jmp 0xe8a8
movl $0x100f, -0x2c(%rbp)    # imm = 0x100F
jmp 0xe8a8
leaq 0x72f3(%rip), %rdi      # 0x15b88
movb $0x0, %al
callq 0x4060
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xebaf
movl $0x30, -0x70(%rbp)
movl $0x0, -0x74(%rbp)
movl $0x4, -0x78(%rbp)
movl $0x0, -0x7c(%rbp)
movq -0x20(%rbp), %rdi
callq 0x4160
cmpq $0x3, %rax
je 0xe8f1
movq -0x20(%rbp), %rsi
leaq 0x72bc(%rip), %rdi      # 0x15b9a
movb $0x0, %al
callq 0x4060
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xebaf
movq -0x20(%rbp), %rax
movsbl (%rax), %eax
addl $-0x35, %eax
movl %eax, %ecx
movq %rcx, -0x88(%rbp)
subl $0x3, %eax
ja 0xe944
movq -0x88(%rbp), %rax
leaq 0x7261(%rip), %rcx      # 0x15b78
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x30, -0x70(%rbp)
jmp 0xe965
movl $0x20, -0x70(%rbp)
jmp 0xe965
movl $0x10, -0x70(%rbp)
jmp 0xe965
movl $0x0, -0x70(%rbp)
jmp 0xe965
movq -0x20(%rbp), %rax
movsbl (%rax), %esi
leaq 0x725b(%rip), %rdi      # 0x15bad
movb $0x0, %al
callq 0x4060
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xebaf
movq -0x20(%rbp), %rax
movsbl 0x1(%rax), %eax
movl %eax, -0x8c(%rbp)
subl $0x45, %eax
je 0xe9cb
jmp 0xe97a
movl -0x8c(%rbp), %eax
subl $0x4e, %eax
je 0xe9bb
jmp 0xe987
movl -0x8c(%rbp), %eax
subl $0x4f, %eax
je 0xe9db
jmp 0xe994
movl -0x8c(%rbp), %eax
subl $0x65, %eax
je 0xe9cb
jmp 0xe9a1
movl -0x8c(%rbp), %eax
subl $0x6e, %eax
je 0xe9bb
jmp 0xe9ae
movl -0x8c(%rbp), %eax
subl $0x6f, %eax
je 0xe9db
jmp 0xe9eb
movl $0x0, -0x74(%rbp)
movl $0x4, -0x78(%rbp)
jmp 0xea0d
movl $0x100, -0x74(%rbp)     # imm = 0x100
movl $0x10, -0x78(%rbp)
jmp 0xea0d
movl $0x300, -0x74(%rbp)     # imm = 0x300
movl $0x10, -0x78(%rbp)
jmp 0xea0d
movq -0x20(%rbp), %rax
movsbl 0x1(%rax), %esi
leaq 0x71d5(%rip), %rdi      # 0x15bcf
movb $0x0, %al
callq 0x4060
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xebaf
movq -0x20(%rbp), %rax
movsbl 0x2(%rax), %eax
movl %eax, -0x90(%rbp)
subl $0x31, %eax
je 0xea2f
jmp 0xea22
movl -0x90(%rbp), %eax
subl $0x32, %eax
je 0xea38
jmp 0xea41
movl $0x0, -0x7c(%rbp)
jmp 0xea63
movl $0x40, -0x7c(%rbp)
jmp 0xea63
movq -0x20(%rbp), %rax
movsbl 0x2(%rax), %esi
leaq 0x7194(%rip), %rdi      # 0x15be4
movb $0x0, %al
callq 0x4060
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xebaf
movq -0x10(%rbp), %rdi
movl $0x902, %esi            # imm = 0x902
movb $0x0, %al
callq 0x4220
movl %eax, %ecx
movq -0x28(%rbp), %rax
movl %ecx, (%rax)
movq -0x28(%rbp), %rax
cmpl $-0x1, (%rax)
jne 0xea9c
leaq 0x717b(%rip), %rdi      # 0x15c06
callq 0x4270
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xebaf
leaq -0x6c(%rbp), %rdi
xorl %esi, %esi
movl $0x3c, %edx
callq 0x41a0
movl -0x70(%rbp), %eax
orl -0x74(%rbp), %eax
orl -0x7c(%rbp), %eax
orl $0x800, %eax            # imm = 0x800
orl $0x80, %eax
movl %eax, -0x64(%rbp)
movl -0x78(%rbp), %eax
movl %eax, -0x6c(%rbp)
movl $0x0, -0x68(%rbp)
movl $0x0, -0x60(%rbp)
movb $0x0, -0x55(%rbp)
movb $0x0, -0x56(%rbp)
movl -0x2c(%rbp), %esi
leaq -0x6c(%rbp), %rdi
callq 0x41c0
movl -0x2c(%rbp), %esi
leaq -0x6c(%rbp), %rdi
callq 0x43c0
movq -0x28(%rbp), %rax
movl (%rax), %edi
xorl %esi, %esi
leaq -0x6c(%rbp), %rdx
callq 0x4470
movl %eax, 0xcf23(%rip)      # 0x1ba30
cmpl $-0x1, 0xcf1c(%rip)     # 0x1ba30
jne 0xeb36
movq -0x28(%rbp), %rax
movl (%rax), %edi
callq 0x4670
leaq 0x70f6(%rip), %rdi      # 0x15c1e
callq 0x4270
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xebaf
movq -0x28(%rbp), %rax
movl (%rax), %edi
movl $0x5415, %esi           # imm = 0x5415
leaq -0x30(%rbp), %rdx
movb $0x0, %al
callq 0x4520
cmpl $-0x1, %eax
jne 0xeb66
leaq 0x70e5(%rip), %rdi      # 0x15c3d
callq 0x4270
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xebaf
movl -0x30(%rbp), %eax
orl $0x2, %eax
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %eax
orl $0x4, %eax
movl %eax, -0x30(%rbp)
movq -0x28(%rbp), %rax
movl (%rax), %edi
movl $0x5418, %esi           # imm = 0x5418
leaq -0x30(%rbp), %rdx
movb $0x0, %al
callq 0x4520
cmpl $-0x1, %eax
jne 0xeba8
leaq 0x70bc(%rip), %rdi      # 0x15c56
callq 0x4270
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xebaf
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x90, %rsp
popq %rbp
retq
nopl (%rax,%rax)