home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / pascal / bbskt30a / term.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-11-10  |  18.4 KB  |  678 lines

  1. {
  2.   Term.Pas
  3.  
  4.   A sample terminal program for BBSkit.
  5.  
  6.   Version 1.2; updated for BBSkit 3.0.
  7.  
  8.   Written by Steve Madsen
  9.  
  10.   This program also includes a couple of "features" for debugging.  Compile
  11.   with the symbol DEBUG defined for the extras.  They are:
  12.  
  13.      Press Alt-D in terminal mode for a dump of the UART registers and some
  14.       other useful stuff.
  15.  
  16.      Press Alt-I to retrigger the interrupts.  This generally restarts a
  17.       stopped transmission if there is a problem with the interrupt handler.
  18.       May have to hit it a few times, though.
  19.  
  20.      Press F2 to output a >200 character string.
  21.  
  22.      -Dx command line switch lets you open two ports at once.  The second
  23.       port is COMx and runs at the same bps rate (to start with) as the
  24.       standard port.  You must Alt-X out of both ports to quit the program.
  25.       Switch between them with Left Alt-F1 and Left Alt-F2.
  26.  
  27.   NOTE: intended to be compiled using the registered version of BBSkit.  If
  28.   you wish to recompile with a demo copy, remove the space before the $ in
  29.   the following $DEFINE.
  30. }
  31.  
  32. { $DEFINE DEMO}
  33.  
  34. PROGRAM Term12;
  35.  
  36. {$X+}
  37. {$M 16384, 0, 131072}
  38.  
  39. {$DEFINE NOBSP}
  40.  
  41. Uses CRT, DOS, VC, Protocol, BBSkit, Comm, Util, MTask;
  42.  
  43. Const
  44.   MaxEmu     = 4;
  45.   Emulations : Array[1..MaxEmu] of String = ('TTY', 'ANSI', 'VT100', 'VT52');
  46.  
  47. Type
  48.   TTerm = object(TBBS)
  49.     Baud      : Longint;
  50.     Capture   : Boolean;
  51.     Comport   : Byte;
  52.     TermFlags : TTermMode;
  53.     ExitCh    : Char;
  54.     Printer   : Boolean;
  55.     Template  : Byte;
  56.  
  57.     CONSTRUCTOR Init(IComport : Byte; IBaud : Longint);
  58.     PROCEDURE Run; VIRTUAL;
  59.     DESTRUCTOR Done; VIRTUAL;
  60.  
  61.     PROCEDURE Baudrate;
  62.     PROCEDURE DebugInfo;
  63.     PROCEDURE DOSShell;
  64.     PROCEDURE Download;
  65.     PROCEDURE Emulation;
  66.     PROCEDURE EnterAnswerMode;
  67.     PROCEDURE EnterOriginateMode;
  68.     PROCEDURE Help(var Cmd : Char);
  69.     PROCEDURE ReInitModem;
  70.     PROCEDURE Status(Msg : String);
  71.     PROCEDURE ToggleBackspace;
  72.     PROCEDURE ToggleCapture;
  73.     PROCEDURE ToggleDuplex;
  74.     PROCEDURE TogglePrinter;
  75.     PROCEDURE ToggleShowControls;
  76.     PROCEDURE Upload;
  77.   end;
  78.  
  79. Var
  80.   TaskID     : Word;
  81.   TaskResult : Word;
  82.   Term       : TTerm;
  83.   Param      : Word;
  84.  
  85. {$IFDEF DEBUG}
  86.   DebugTerm : TTerm;
  87. {$ENDIF}
  88.  
  89. {********************************************************************}
  90.  
  91. PROCEDURE Usage;
  92.  begin
  93.    WriteLn('Term usage:');
  94.    WriteLn;
  95.    WriteLn(ProgramName, ' <comport> <baudrate> [-o]');
  96.    WriteLn;
  97.    WriteLn(' <comport> can be 1, 2, 3 or 4.');
  98.    WriteLn(' <baudrate> can be 300, 600, 1200, 2400, 4800, 9600, 19200,');
  99.    WriteLn('                   38400, 57600, or 115200.');
  100.    WriteLn;
  101.    WriteLn(' -o   starts Term without sending the init string');
  102. {$IFDEF DEBUG}
  103.    WriteLn;
  104.    WriteLn(' -dx  opens debug port COMx at same speed.  Must be last parameter!');
  105. {$ENDIF}
  106.    WriteLn;
  107.    WriteLn('example: ', ProgramName, ' 2 2400    { com2, at 2400 bps }');
  108.    WriteLn('         ', ProgramName, ' 1 9600    { com1, at 9600 bps }');
  109.  end;
  110.  
  111. {--------------------------------------------------------------------}
  112.  
  113. PROCEDURE StartATerm(var AtPort); FAR;
  114.  begin
  115.    if (Word(AtPort) = 0) then
  116.     begin
  117.       Term.Init(StrToInt(ParamStr(1)), StrToInt(ParamStr(2)));
  118.       Term.Run;
  119.       Term.Done;
  120. {$IFDEF DEBUG}
  121.     end
  122.    else
  123.     begin
  124.       DebugTerm.Init(StrToInt(Copy(ParamStr(ParamCount), 3, 1)), StrToInt(ParamStr(2)));
  125.       DebugTerm.Run;
  126.       DebugTerm.Done;
  127. {$ENDIF}
  128.     end;
  129.  end;
  130.  
  131. {--------------------------------------------------------------------}
  132.  
  133. CONSTRUCTOR TTerm.Init(IComport : Byte; IBaud : Longint);
  134.  begin
  135.    TBBS.Init;
  136. {$IFDEF DEBUG}
  137.    AllowVCSwitching(True);
  138. {$ELSE}
  139.    AllowVCSwitching(False);
  140. {$ENDIF}
  141.    Comport := IComport;
  142.    Baud := IBaud;
  143.    if (not OpenPort(Comport)) then
  144.     begin
  145.       vcWriteLn('Can''t open comport.');
  146.       Halt(1);
  147.     end;
  148.    SetBpsRate(Comport, Baud);
  149.    SetFlowControl(PortIdx, False, False);
  150.    SetParity(PortIdx, NoParity);
  151.    SetWordLength(PortIdx, 8);
  152.    SetStopBits(PortIdx, 1);
  153.    TermFlags.Duplex := Full;
  154.    TermFlags.ShowControls := False;
  155.    TermFlags.Backspace := #8;
  156.    Capture := False;
  157.    Printer := False;
  158.    SetInput(True, False);
  159.    ClrScr;
  160.    Template := 1;
  161.    Status('');
  162.    if (ParamCount < 3) or (Lower(ParamStr(3)) <> '-o') then
  163.       EnterOriginateMode;
  164.  end;
  165.  
  166. {--------------------------------------------------------------------}
  167.  
  168. PROCEDURE TTerm.Run;
  169.  Const
  170.    BigString = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'+
  171.                'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'+
  172.                'cccccccccccccccccccccccccccccccccccccccccccccccccccccccc'+
  173.                'dddddddddddddddddddddddddddddddddddddddddddddddddddddddd';
  174.  
  175.  begin
  176.    Repeat
  177.      ExitCh := TerminalMode(TermFlags);
  178.      if (ExitCh = #59) then
  179.         Help(ExitCh);  { F1 = help }
  180.      case ExitCh of
  181. {$IFDEF DEBUG}
  182.        #60 : begin
  183.                SendString(PortIdx, BigString);
  184.                Status(IntToStr(PortArray[PortIdx].OutUsed));
  185.              end;
  186.        #32 : DebugInfo;
  187.        #23 : ReInitModem;
  188. {$ENDIF}
  189.        #48 : Baudrate;
  190.        #36 : DOSShell;
  191.        #81 : Download;
  192.        #50 : Emulation;
  193.        #30 : EnterAnswerMode;
  194.        #24 : EnterOriginateMode;
  195.        #35 : begin
  196.                Hangup;
  197.                Status('');
  198.              end;
  199.        #20 : ToggleBackspace;
  200.        #46 : ToggleCapture;
  201.        #18 : ToggleDuplex;
  202.        #25 : TogglePrinter;
  203.        #31 : ToggleShowControls;
  204.        #73 : Upload;
  205.      end;
  206.    Until (ExitCh = #45);  { Alt-X = quit }
  207.  end;
  208.  
  209. {--------------------------------------------------------------------}
  210.  
  211. DESTRUCTOR TTerm.Done;
  212.  Var
  213.    Online : Boolean;
  214.  
  215.  begin
  216.    Online := Carrier(PortIdx);
  217.    ClosePort(not Online);
  218.    Window(1, 1, 80, TextScreenMaxY);
  219.    TextColor(LightGray);
  220.    TextBackground(Black);
  221.    ClrScr;
  222.    TBBS.Done;
  223.    if (Online) and (InCommandLine('-D') = 0) then
  224.       WriteLn('Warning: DTR not lowered since you are still online.');
  225.  end;
  226.  
  227. {--------------------------------------------------------------------}
  228.  
  229.   {
  230.   *  We can just double the rate for any step up, *except* for the step
  231.   *  from 38400 to 57600.
  232.   }
  233.  
  234. PROCEDURE TTerm.Baudrate;
  235.  begin
  236.    if (Baud <> 38400) then
  237.     begin
  238.       Baud := Baud SHL 1;
  239.       if (Baud > 115200) then
  240.          Baud := 300;
  241.     end
  242.    else
  243.       Baud := 57600;
  244.    SetBpsRate(Comport, Baud);
  245.    Status('');
  246.  end;
  247.  
  248. {--------------------------------------------------------------------}
  249.  
  250. PROCEDURE TTerm.DebugInfo;
  251.  
  252.  FUNCTION BinaryByte(Value : Byte) : String;
  253.   Var
  254.     Strn : String;
  255.     Idx  : Word;
  256.  
  257.   begin
  258.     Strn := '';
  259.     Idx := $1;
  260.     Repeat
  261.       if (Value AND Idx = Idx) then
  262.          Strn := '1' + Strn
  263.       else
  264.          Strn := '0' + Strn;
  265.       Idx := Idx SHL 1;
  266.     Until (Idx = $100);
  267.     BinaryByte := Strn;
  268.   end;
  269.  
  270.  begin
  271.    vcWriteLn('');
  272.    vcWrite  ('   Port: COM' + IntToStr(PortIdx));
  273.    vcWrite  ('      Status flags: ' + BinaryByte(PortArray[Comport].StatusFlg));
  274.    vcWriteLn('   Error flags: ' + BinaryByte(PortArray[Comport].ErrorFlg));
  275.    vcWrite  ('    IER: ' + BinaryByte(Port[PortArray[Comport].PortAddr + IER]));
  276.    vcWrite  ('           IIR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + IIR]));
  277.    vcWriteLn('           LCR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + LCR]));
  278.    vcWrite  ('    MCR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + MCR]));
  279.    vcWrite  ('           LSR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + LSR]));
  280.    vcWriteLn('           MSR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + MSR]));
  281.    vcWrite  ('    SCR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + SCR]));
  282.    vcWrite  ('          OCW1: ' + BinaryByte(Port[OCW1]));
  283.    vcWriteLn('          OCW2: ' + BinaryByte(Port[OCW2]));
  284.    vcWrite  ('OutUsed: ' + Left(IntToStr(PortArray[Comport].OutUsed), 4));
  285.    vcWriteLn('            InUsed: ' + IntToStr(PortArray[Comport].InUsed));
  286.    vcWriteLn('');
  287.  end;
  288.  
  289. {--------------------------------------------------------------------}
  290.  
  291. PROCEDURE TTerm.DOSShell;
  292.  begin
  293.    SaveScreen;
  294.    if (GetEnv('COMSPEC') = '') then
  295.       Exec('\COMMAND.COM', '')
  296.    else
  297.       Exec(GetEnv('COMSPEC'), '');
  298.    RestoreScreen;
  299.  end;
  300.  
  301. {--------------------------------------------------------------------}
  302.  
  303. PROCEDURE TTerm.Download;
  304.  Var
  305.    Ch    : Char;
  306.    Fname : String;
  307.    Err   : TError;
  308.  
  309.  begin
  310.    OpenWindow(3, 3, 50, 15, White, Blue, SingleLine, 'Download');
  311.    vcWriteLn('Receive mode: [X]modem, Xmodem-[C]RC,');
  312. {$IFNDEF DEMO}
  313.    vcWriteLn('              Xmodem-[1]K, [Y]modem,');
  314.    vcWrite('              Ymodem-[G]? ');
  315. {$ELSE}
  316.    vcWrite('              Xmodem-[1]K? ');
  317. {$ENDIF}
  318.    Ch := UpCase(ReadKey);
  319.    vcWriteLn(Ch);
  320. {$IFNDEF DEMO}
  321.    if (Pos(Ch, 'XC1YG') > 0) then
  322. {$ELSE}
  323.    if (Pos(Ch, 'XC1') > 0) then
  324. {$ENDIF}
  325.     begin
  326.       case Ch of
  327.         'X',
  328.         'C',
  329.         '1' : begin
  330.                 vcWriteLn('');
  331.                 vcWrite('Receive file: ');
  332.                 ReadLn(Fname);
  333.                 if (Fname = '') then
  334.                  begin
  335.                    CloseWindow;
  336.                    Exit;
  337.                  end;
  338.                 case Ch of
  339.                   'X' : Err := ReceiveXmodem(Checksum, Fname);
  340.                   'C' : Err := ReceiveXmodem(CRC, Fname);
  341.                   '1' : Err := ReceiveXmodem(OneK, Fname);
  342.                 end;
  343.               end;
  344. {$IFNDEF DEMO}
  345.         'Y',
  346.         'G' : begin
  347.                 vcWriteLn('');
  348.                 vcWrite('Batch receive to path: ');
  349.                 vcReadLn(Fname);
  350.                 if (Fname = '') then
  351.                  begin
  352.                    CloseWindow;
  353.                    Exit;
  354.                  end;
  355.                 case Ch of
  356.                   'Y' : Err := ReceiveYmodem(Normal, Fname);
  357.                   'G' : Err := ReceiveYmodem(Streaming, Fname);
  358.                 end;
  359.               end;
  360. {$ENDIF}
  361.       end;
  362.       case Err of
  363.         NoError       : Status('Last Transfer GOOD');
  364.         TimeOut       : Status('Transfer Timeout');
  365.         TooManyErrors : Status('Too Many Errors');
  366.         Aborted       : Status('Aborted by User');
  367.         DiskError     : Status('Disk Error');
  368.         NoCarrier     : Status('Carrier Lost');
  369.         FileExists    : Status('File Already Exists');
  370.       end;
  371.     end;
  372.    CloseWindow;
  373.  end;
  374.  
  375. {--------------------------------------------------------------------}
  376.  
  377. PROCEDURE TTerm.Emulation;
  378.  begin
  379.    if (Exist('STD.EML')) then
  380.     begin
  381.       Inc(Template);
  382.       if (Template > MaxEmu) then
  383.          Template := 1;
  384.       LoadEmulationLib(Emulations[Template], 'STD.EML');
  385.       Status('');
  386.     end
  387.    else
  388.       Status('No STD.EML');
  389.  end;
  390.  
  391. {--------------------------------------------------------------------}
  392.  
  393. PROCEDURE TTerm.EnterAnswerMode;
  394.  begin
  395.    Status('');
  396.    OpenWindow(20, 3, 40, 3, White, Blue, SingleLine, '');
  397.    vcWrite('        Switching To Answer Mode');
  398.    if (not SendAT('ATS0=1')) then
  399.       Status('Modem Not Responding');
  400.    CloseWindow;
  401.  end;
  402.  
  403. {--------------------------------------------------------------------}
  404.  
  405. PROCEDURE TTerm.EnterOriginateMode;
  406.  begin
  407.    Status('');
  408.    OpenWindow(20, 3, 40, 3, White, Blue, SingleLine, '');
  409.    vcWrite('      Switching To Originate Mode');
  410.    if (not SendAT('ATS0=0M1L1E1')) then
  411.       Status('Modem Not Responding');
  412.    CloseWindow;
  413.  end;
  414.  
  415. {--------------------------------------------------------------------}
  416.  
  417. PROCEDURE TTerm.Help(var Cmd : Char);
  418.  Var
  419.    Ch : Char;
  420.  
  421.  begin
  422.    OpenWindow(5, 3, 72, 12, White, Blue, SingleLine, 'Help');
  423.    SetWindowTitle('Term Help');
  424.    GotoXY(1, 2);
  425.    vcWriteLn('  Alt-A  Auto-answer mode              Alt-B  Toggle baudrate');
  426.    vcWriteLn('  Alt-C  Toggle capture buffer         Alt-E  Toggle duplex');
  427.    vcWriteLn('  Alt-H  Hangup                        Alt-J  Jump to DOS');
  428.    vcWriteLn('  Alt-M  Emulation                     Alt-O  Originate mode');
  429.    vcWriteLn('  Alt-P  Toggle printer                Alt-S  Toggle "show controls"');
  430.    vcWriteLn('  Alt-T  Toggle backspace key          Alt-X  Exit');
  431.    vcWriteLn('');
  432.    vcWriteLn('  PgUp   Upload file(s)                PgDn   Download file(s)');
  433.    Ch := ReadKey;
  434.    if (Ch = #0) then
  435.       Cmd := ReadKey;
  436.    CloseWindow;
  437.  end;
  438.  
  439. {--------------------------------------------------------------------}
  440.  
  441. PROCEDURE TTerm.ReInitModem;
  442.  Var
  443.    Save : Byte;
  444.  
  445.  begin
  446.    Save := Port[PortArray[PortIdx].PortAddr + IER];
  447.    Port[PortArray[PortIdx].PortAddr + IER] := $00;
  448.    Port[PortArray[PortIdx].PortAddr + IER] := Save;
  449.  end;
  450.  
  451. {--------------------------------------------------------------------}
  452.  
  453. PROCEDURE TTerm.Status(Msg : String);
  454.  Var
  455.    Fore, Back : Byte;
  456.    SX, SY     : Byte;
  457.    ScrEnd     : Byte;
  458.  
  459.  begin
  460.    Fore := GetTextColor;
  461.    Back := GetTextBackground;
  462.    SX := WhereX;
  463.    SY := WhereY;
  464.    ScrEnd := Hi(WindMax);
  465.    Window(1, 1, 80, 1);
  466.    TextBackground(Blue);
  467.    ClrScr;
  468.    TextColor(Yellow);
  469.    vcWrite(' Term  ');
  470.    TextColor(White);
  471.    case TermFlags.Duplex of
  472.      Full : vcWrite('Full Duplex  ');
  473.      Half : vcWrite('Half Duplex  ');
  474.      Chat : vcWrite('Chat Duplex  ');
  475.    end;
  476.    vcWrite(Right(IntToStr(Baud), 6) + 'bps  ');
  477.    vcWrite('COM' + IntToStr(Comport) + '  ');
  478.    if (Carrier(Comport)) then
  479.       vcWrite('Carrier ')
  480.    else
  481.       vcWrite('        ');
  482.    if (Capture) then
  483.       vcWrite('Cap ')
  484.    else
  485.       vcWrite('    ');
  486.    if (Printer) then
  487.       vcWrite('Prn ')
  488.    else
  489.       vcWrite('    ');
  490.    vcWrite(Left(Emu.Key, 8));
  491.    if (Msg = '') then
  492.       Msg := 'F1 = Help';
  493.    GotoXY(80 - Length(Msg), 1);
  494.    vcWrite(Msg);
  495.    Window(1, 2, 80, TextScreenMaxY);
  496.    TextColor(Fore);
  497.    TextBackground(Back);
  498.    GotoXY(SX, SY);
  499.  end;
  500.  
  501. {--------------------------------------------------------------------}
  502.  
  503. PROCEDURE TTerm.ToggleBackspace;
  504.  begin
  505.    if (TermFlags.Backspace = #8) then
  506.     begin
  507.       TermFlags.Backspace := #127;
  508.       Status('Backspace is RUB');
  509.     end
  510.    else
  511.     begin
  512.       TermFlags.Backspace := #8;
  513.       Status('Backspace is ^H');
  514.     end;
  515.  end;
  516.  
  517. {--------------------------------------------------------------------}
  518.  
  519. PROCEDURE TTerm.ToggleCapture;
  520.  Var
  521.    Cap : String;
  522.  
  523.  begin
  524.    Capture := not Capture;
  525.    if (Capture) then
  526.     begin
  527.       OpenWindow(5, 3, 45, 5, White, Blue, SingleLine, 'Capture to File');
  528.       GotoXY(1, 2);
  529.       vcWrite(' Filename: ');
  530.       ReadLn(Cap);
  531.       if (Cap = '') then
  532.          Cap := 'SESSION.TXT';
  533.       SetCaptureFile(Cap);
  534.       CloseWindow;
  535.     end;
  536.    SetCaptureStatus(Capture);
  537.    Status('');
  538.  end;
  539.  
  540. {--------------------------------------------------------------------}
  541.  
  542. PROCEDURE TTerm.ToggleDuplex;
  543.  begin
  544.    case TermFlags.Duplex of
  545.      Full : TermFlags.Duplex := Half;
  546.      Half : TermFlags.Duplex := Chat;
  547.      Chat : TermFlags.Duplex := Full;
  548.    end;
  549.    Status('');
  550.  end;
  551.  
  552. {--------------------------------------------------------------------}
  553.  
  554. PROCEDURE TTerm.TogglePrinter;
  555.  begin
  556.    Printer := not Printer;
  557.    SetPrinter(Printer);
  558.    Status('');
  559.  end;
  560.  
  561. {--------------------------------------------------------------------}
  562.  
  563. PROCEDURE TTerm.ToggleShowControls;
  564.  begin
  565.    TermFlags.ShowControls := not TermFlags.ShowControls;
  566.    if (TermFlags.ShowControls) then
  567.       Status('Show Controls ON')
  568.    else
  569.       Status('Show Controls OFF');
  570.  end;
  571.  
  572. {--------------------------------------------------------------------}
  573.  
  574. PROCEDURE TTerm.Upload;
  575.  Var
  576.    Ch    : Char;
  577.    Fname : String;
  578.    FInfo : SearchRec;
  579.    Err   : TError;
  580.  
  581.  begin
  582.    OpenWindow(3, 3, 50, 15, White, Blue, SingleLine, 'Upload');
  583.    vcWriteLn('Send mode: [X]modem, Xmodem-[C]RC,');
  584. {$IFNDEF DEMO}
  585.    vcWriteLn('           Xmodem-[1]K, [Y]modem,');
  586.    vcWrite('           Ymodem-[G]? ');
  587. {$ELSE}
  588.    vcWrite('           Xmodem-[1]K? ');
  589. {$ENDIF}
  590.    Ch := UpCase(ReadKey);
  591.    vcWriteLn(Ch);
  592. {$IFNDEF DEMO}
  593.    if (Pos(Ch, 'XC1YG') > 0) then
  594. {$ELSE}
  595.    if (Pos(Ch, 'XC1') > 0) then
  596. {$ENDIF}
  597.     begin
  598.       case Ch of
  599.         'X',
  600.         'C',
  601.         '1' : begin
  602.                 vcWriteLn('');
  603.                 vcWrite('File to send: ');
  604.                 ReadLn(Fname);
  605.                 if (Fname = '') then
  606.                  begin
  607.                    CloseWindow;
  608.                    Exit;
  609.                  end;
  610.                 vcWriteLn('');
  611.                 case Ch of
  612.                   'X' : Err := SendXmodem(Checksum, Fname);
  613.                   'C' : Err := SendXmodem(CRC, Fname);
  614.                   '1' : Err := SendXmodem(OneK, Fname);
  615.                 end;
  616.               end;
  617. {$IFNDEF DEMO}
  618.         'Y',
  619.         'G' : begin
  620.                 vcWriteLn('');
  621.                 vcWriteLn('Batch send: enter a blank line when done.');
  622.                 vcWriteLn('');
  623.                 ClearBatch;
  624.                 Repeat
  625.                   vcWrite('Send file: ');
  626.                   vcReadLn(Fname);
  627.                   if (Fname <> '') then
  628.                      AddBatch(Fname);
  629.                 Until (Fname = '');
  630.                 if (FilesInBatch > 0) then
  631.                  begin
  632.                    case Ch of
  633.                      'Y' : Err := SendYmodem(Normal);
  634.                      'G' : Err := SendYmodem(Streaming);
  635.                    end;
  636.                  end
  637.                 else
  638.                  begin
  639.                    CloseWindow;
  640.                    Exit;
  641.                  end;
  642.               end;
  643. {$ENDIF}
  644.       end;
  645.       case Err of
  646.         NoError       : Status('Last Transfer GOOD');
  647.         Timeout       : Status('Transfer Timeout');
  648.         TooManyErrors : Status('Too Many Errors');
  649.         Aborted       : Status('Aborted by User');
  650.         DiskError     : Status('Disk Error');
  651.         NoCarrier     : Status('Carrier Lost');
  652.         FileExists    : Status('File Already Exists');
  653.       end;
  654.     end;
  655.    CloseWindow;
  656.  end;
  657.  
  658. {********************************************************************}
  659.  
  660. BEGIN
  661.   CheckBreak := False;
  662.   if (ParamCount = 0) or (Pos('?', ParamStr(1)) <> 0) then
  663.      Usage
  664.   else
  665.    begin
  666.      Param := 0;
  667.      Create_Task(StartATerm, Param, 8192, TaskID, TaskResult);
  668.      Switch_Task;
  669.      if (InCommandLine('-D') <> 0) then
  670.       begin
  671.         Param := 1;
  672.         Create_Task(StartATerm, Param, 8192, TaskID, TaskResult);
  673.       end;
  674.      while (Number_Of_Tasks > 2) do  { loop until all terms shutdown }
  675.         Switch_Task;
  676.    end;
  677. END.
  678.