use strict;
use warnings;
use Win32::SerialPort;
use Term::ReadKey;

my ($char, $run);

my $port = Win32::SerialPort->new('COM1')
    or die "Oops!\n";

$| = 1;

# Parameter setzen
$port->baudrate(9600)    || die "baudrate geht nicht\n";
$port->parity('none')	    || die "parity geht nicht\n";
$port->databits(8)        || die "databits geht nicht\n";
$port->stopbits(1)        || die "stopbits geht nicht\n";
$port->handshake("rts") 	|| die "handshake geht nicht\n";
# defined, weil "0" ein legaler Rueckgabewert ist
defined $port->parity_enable('T')	|| die "parity_enable geht nicht\n";

# Devicecontrolblock schreiben
$port->write_settings	    || die "write_setings geht nicht\n";

# Setup fuer dummes Terminal,
# kann je nach Anwendung variieren
$port->stty_icrnl(1);
$port->stty_ocrnl(0);  #
$port->stty_onlcr(0);  #
$port->stty_opost(1);

# Signalhandler fuer Stg-C
$SIG{INT}  = sub { $run = 0 };

print "Einfacher Terminal Emulator\n";
print "Ende mit Strg-C\n\n";

$run = 1;
while($run)
  {
  # Zeichen von der seriellen Schnittstelle lesen
  if ($char = $port->input())
    {
    # Behandlung von Carriage Return und Line Feed
	  $char =~ s/\r/\n/ogs if ($port->stty_icrnl);
	  # auf dem Bildschirm ausgeben
	  print $char;
    }
  # Zeichen von der Tastatur einlesen
  if (defined($char = ReadKey(-1)))
    {
    # Behandlung von Carriage Return und Line Feed
	  $char =~ s/\r/\n/ogs if ($port->stty_ocrnl);
	  $char =~ s/\n/\r\n/ogs if ($port->stty_opost && $port->stty_onlcr);
	  # Zeichen auf der seriellen Schnittstelle ausgeben
    $port->write($char);
    }
#  select undef, undef, undef, 0.2; # traditional 5/sec.
  }

$port -> close();
undef $port;  # closes port AND frees memory in perl
print "Bye\n";