    {----------------------------------------------------------------------}
    {         Main Program Part of the Split-Screen Server (SSS)           }
    {----------------------------------------------------------------------}
    {                                                                      }
    {  Author:  Peter H. Heinrich (HB9CVV)                                 }
    {  Date:    July, 1986                                                 }
    {  Version: 1.1                                                        }
    {  Systems: For MS-DOS on IBM PCs and close compatibles only.          }
    {           Note:  I have checked this program on a PC/AT with EGA     }
    {                  and a PC/XT Clone with Hercules card, both          }
    {                  running PC-DOS V3.1.                                }
    {                                                                      }
    {----------------------------------------------------------------------}


    {-------------------- MAIN PROGRAM ------------------------------------------}

  VAR CRflag : Boolean;

  BEGIN
    ClrScr;                             {Clear the screen}
    WriteLn(logo);
    WriteLn;
    WriteLn('Use ALT/X to exit this program. To enter the TNC command-mode press ESC-key.');
    WriteLn;
    WriteLn('The Com-line will use 8 databits, 1 stopbit, no parity.');
    WriteLn;
    IF NOT(Send_ok) THEN BEGIN
      Write('File-send feature is disabled. ');
    END;
    READPARAMFILE(parfilnam);
    REPEAT
      CPort := 0;
      Write('Select Com-port 1 .. 6, default is ', DefPort, ': ');
      ReadLn(CPort); IF CPort = 0 THEN CPort := DefPort;
    UNTIL (CPort IN [1, 2, 3, 4, 5, 6]);
    REPEAT
      Cbaudrate := 0;
      Write('Select Baudrate (300..9600), default is ', Defbaud, ': ');
      ReadLn(Cbaudrate); IF CBaudrate = 0 THEN CBaudrate := DefBaud;
    UNTIL (Cbaudrate DIV 100 IN [3, 6, 12, 24, 48, 96]);
    InitHelpWindows;                    {Setup the text in the Help pop-ups}
    HelpWindow3;                        {and  show help}
    ClrScr;
    WriteLn;
    WriteLn('Initializing....');

    Async_Init;
    IF NOT Async_Open(CPort, CBaudrate, 'N', 8, 1) THEN BEGIN {Open the COMMport to the TNC}
      WriteLn('*** Com-port init failure ***');
      Halt;
    END;

    cha := space;                       {init variables}
    Outbuffer[NORM] := '';
    Outbuffer[DEV_CMD] := '';
    Outbuffer[PGM_CAP] := '';
    Outbuffer[PGM_SEN] := '';
    mode := NORM;
    pdate := '';
    minute := '00';
    CurWinNo := 0;
    Capture_enabled := False;
    Sendfile_enabled := False;
    Bells_enabled := True;
    Wordout_enabled := False;
    CRflag := False;
    Wtab[1, 5] := 1; Wtab[1, 6] := 1;
    Wtab[2, 5] := 1; Wtab[2, 6] := 1;

    InitDevice;                         {Load TNC with Init Values}
    ClrScr;                             {Clear the screen}
    Frame(Screendiv);                   {Draw the screen divider line}

    {=========================================================================}
    {=========================== THE BIG LOOP ================================}
    {=========================================================================}

    REPEAT BEGIN

      {-----------------------------------------------------------------------}
      { (1) Insert date and time at end of screen divider (if it has changed) }
      {-----------------------------------------------------------------------}

      IF minute = '00' THEN BEGIN
        IF pdate <> date THEN BEGIN
          Selectwindow(3);
          GoToXY(60, screendiv); Write(' ', date, ' ');
          pdate := date;
          SelectWindow(2);                {move cursor back to input window}
        END;
      END;
      IF ptime <> time THEN BEGIN
        Selectwindow(3);
        GoToXY(72, screendiv); Write(' ',time);
        ptime := time;
        SelectWindow(2);                {move cursor back to input window}
      END;

      {-----------------------------------------------------------------------}
      { (2) Read the characterstring from the TNC and display it on the upper }
      {     output window. We read all characters which are found in the      }
      {     receice buffer                                                    }
      {-----------------------------------------------------------------------}


      WHILE (Async_Receive(rcha)) DO BEGIN
        IF NOT Bells_enabled THEN IF rcha = ^G THEN rcha := '~';
        IF CRFlag AND (rcha <> lf) THEN
          Inbuffer := lf+rcha
        ELSE
          Inbuffer := rcha;
        UpdateWindow(1, Inbuffer);
        CRFlag := (rcha = cr);
      END;

      {-----------------------------------------------------------------------}
      { (3) Sending a file is done here. We use Slindex as control variable:  }
      {     If Slindex=0 (which is the start value also) then we read the     }
      {     next line and set Slindex=1. If 0<Slindex<Length(Sline) then we   }
      {     send the character at position Slindex. Please note that this is  }
      {     the programs main loop even if just one character is sent per     }
      {     pass, the sending speed is by far sufficient                      }
      {-----------------------------------------------------------------------}

      IF Sendfile_enabled THEN BEGIN
        IF Slindex = 0 THEN BEGIN       { we must read another line from file }
          IF EoF(Sendfile) THEN BEGIN   { its all over now }
            Sendfile_enabled := False;
            Close(Sendfile);
            Delay(500);
            Async_send(^Z);             { Append a ^Z, most BBS like it}
            Async_send(cr);
            TmpStr := '*** Finished: End Of File ***'+cr+lf;
            UpdateWindow(2, Tmpstr);    {Write it to lower window}
            Delay(2000);
            IF TNC_echo_on THEN Async_Send_STring(^C'ECHO ON'^M'CONV'^M);
          END ELSE BEGIN                { read the line }
            {$I-} ReadLn(Sendfile, Sline); IOR := IOResult; {$I+}
            IF IOR <> 0 THEN BEGIN
              Sendfile_enabled := False;
              Close(Sendfile);
              Async_send(^Z);           { Append a ^Z, most BBS like it}
              Async_send(cr);
              TmpStr := '*** Terminated: I/O Error reading File ***'+cr+lf;
              UpdateWindow(2, Tmpstr);  {Write it to lower window}
              Delay(2000);
              IF TNC_echo_on THEN Async_Send_STring(^C'ECHO ON'^M'CONV'^M);
            END ELSE BEGIN
              Slindex := 1;             { position the index on 1st char }
              Sline := Sline+cr;        { append a CR }
            END;
          END;
        END ELSE BEGIN                  { send ONE char }
          IF Async_CTS_On THEN BEGIN
            Tmpchr := Chr(Ord(Sline[Slindex]) AND $7F);
            IF ((Ord(Tmpchr) > $1F) OR (Tmpchr = cr)) THEN async_send(Tmpchr);
            Tmpstr := Tmpchr;
            UpdateWindow(2, Tmpstr);    { Write it to lower window }
            Slindex := Slindex+1;       { advance to next char }
            IF Slindex > Length(Sline) THEN BEGIN { Done this line }
              Slindex := 0;             { indicate it to read a new line next pass }
              Tmpstr := lf;             { scroll the text in window }
              UpdateWindow(2, Tmpstr);  { Write it to lower window }
            END;
          END;
        END;
      END;

      {-----------------------------------------------------------------------}
      { (4) Read character input from the Operator, process it and display it }
      {     on the lower input window. Watch out, if a file is sent it might  }
      {     be better to only permit the ABORT-file send here...              }
      {-----------------------------------------------------------------------}

      echa := Char(0);
      IF KeyPressed THEN BEGIN          {If OP pressed a key ....}
        ReadIchar(cha, echa);           {Get next keystroke}
        IF (cha = #00) THEN BEGIN       {it is a command char input}

          {----------------- Special character processing ----------------------}

          CASE Ord(echa) OF

            104..113:SWITCH_DEV_MODE;   {ALT/F1...ALT/F10}
            017     : PGMCMD_WORDOUT;       { ALT/W: Word output mode}
            038     : PGMCMD_LINEOUT;       { ALT/L: Line output mode}
            046     : PGMCMD_CAPTURE;       { ALT/C: Capture file }
            031     : PGMCMD_SENDFILE;      { ALT/S: Sendfile }
            048     : PGMCMD_BELLS;         { ALT/B: toggle bell recognition }
            021     : PGMCMD_CLR_L_SCREEN;  { ALT/Y: Clear lower screen and flush input line }
            030     : PGMCMD_ABORT_SEND;    { ALT/A: Abort sending a file }
            045     : BEGIN END;            { ALT/X: Terminate - dont show window}
            050     : SWITCH_DEV_MODE;      { ALT/M: Switch devive modes }

            { 1/End, 2/down, 3/PgDn, 0/Ins, ./Del  : Device special keys }
            079..083 : DEV_SPC_FUN(Ord(echa));

            059..64:                    { F-Key 1 to 6}
              BEGIN Transferstr(Fstr[Ord(echa)-59+1], NORM); END;
            067     :                       { F-Key 9 : Helpwindow for TNC/setups }
              HelpWindow1;
            068     :                       { F-Key10 : Helpwindow for QSO }
              BEGIN HelpWindow3; END;
          ELSE BEGIN Helpwindow2; END;  { All other Special Keys}
          END;

        END
        ELSE                            { it is a normal char input}

          {------------- Dialogue character processing -------------------------}

          BEGIN
            CASE cha OF
              del     : PROCCHAR_DEL;
              cr     : PROCCHAR_CR;
              esc     : PROCCHAR_ESC;
              space, '.', ',':
                IF wordout_enabled THEN PROCCHAR_SPACE ELSE PROCCHAR_REST;
            ELSE                        {ALL other 'normal' chars: no special treatment}
              PROCCHAR_REST;
            END;
          END;
      END;
      END;
    UNTIL (Ord(echa) = 45);             { ALT/X terminates }

    { Terminating this lovely little program - sigh - }

    Window(1, 1, 80, 25);
    ClrScr;
    WriteLn('Clean-up...');
    IF Capture_enabled THEN Close(Capturefile);
    IF Sendfile_enabled THEN Close(Sendfile);
    Shutdowndevice;
    Async_Close;
    ClrScr;

  END.

