home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_GEN / BBSKIT31.ZIP / TERM.PAS < prev    next >
Pascal/Delphi Source File  |  1994-01-06  |  19KB  |  679 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.    SetPortRoutines(Comport, FOSSIL);
  144.    if (not OpenPort(Comport)) then
  145.     begin
  146.       vcWriteLn('Can''t open comport.');
  147.       Halt(1);
  148.     end;
  149.    SetBpsRate(Comport, Baud);
  150.    SetFlowControl(PortIdx, False, False);
  151.    SetParity(PortIdx, NoParity);
  152.    SetWordLength(PortIdx, 8);
  153.    SetStopBits(PortIdx, 1);
  154.    TermFlags.Duplex := Full;
  155.    TermFlags.ShowControls := False;
  156.    TermFlags.Backspace := #8;
  157.    Capture := False;
  158.    Printer := False;
  159.    SetInput(True, False);
  160.    ClrScr;
  161.    Template := 1;
  162.    Status('');
  163.    if (ParamCount < 3) or (Lower(ParamStr(3)) <> '-o') then
  164.       EnterOriginateMode;
  165.  end;
  166.  
  167. {--------------------------------------------------------------------}
  168.  
  169. PROCEDURE TTerm.Run;
  170.  Const
  171.    BigString = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'+
  172.                'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'+
  173.                'cccccccccccccccccccccccccccccccccccccccccccccccccccccccc'+
  174.                'dddddddddddddddddddddddddddddddddddddddddddddddddddddddd';
  175.  
  176.  begin
  177.    Repeat
  178.      ExitCh := TerminalMode(TermFlags);
  179.      if (ExitCh = #59) then
  180.         Help(ExitCh);  { F1 = help }
  181.      case ExitCh of
  182. {$IFDEF DEBUG}
  183.        #60 : begin
  184.                SendString(PortIdx, BigString);
  185.                Status(IntToStr(PortArray[PortIdx].OutUsed));
  186.              end;
  187.        #32 : DebugInfo;
  188.        #23 : ReInitModem;
  189. {$ENDIF}
  190.        #48 : Baudrate;
  191.        #36 : DOSShell;
  192.        #81 : Download;
  193.        #50 : Emulation;
  194.        #30 : EnterAnswerMode;
  195.        #24 : EnterOriginateMode;
  196.        #35 : begin
  197.                Hangup;
  198.                Status('');
  199.              end;
  200.        #20 : ToggleBackspace;
  201.        #46 : ToggleCapture;
  202.        #18 : ToggleDuplex;
  203.        #25 : TogglePrinter;
  204.        #31 : ToggleShowControls;
  205.        #73 : Upload;
  206.      end;
  207.    Until (ExitCh = #45);  { Alt-X = quit }
  208.  end;
  209.  
  210. {--------------------------------------------------------------------}
  211.  
  212. DESTRUCTOR TTerm.Done;
  213.  Var
  214.    Online : Boolean;
  215.  
  216.  begin
  217.    Online := Carrier(PortIdx);
  218.    ClosePort(not Online);
  219.    Window(1, 1, 80, TextScreenMaxY);
  220.    TextColor(LightGray);
  221.    TextBackground(Black);
  222.    ClrScr;
  223.    TBBS.Done;
  224.    if (Online) and (InCommandLine('-D') = 0) then
  225.       WriteLn('Warning: DTR not lowered since you are still online.');
  226.  end;
  227.  
  228. {--------------------------------------------------------------------}
  229.  
  230.   {
  231.   *  We can just double the rate for any step up, *except* for the step
  232.   *  from 38400 to 57600.
  233.   }
  234.  
  235. PROCEDURE TTerm.Baudrate;
  236.  begin
  237.    if (Baud <> 38400) then
  238.     begin
  239.       Baud := Baud SHL 1;
  240.       if (Baud > 115200) then
  241.          Baud := 300;
  242.     end
  243.    else
  244.       Baud := 57600;
  245.    SetBpsRate(Comport, Baud);
  246.    Status('');
  247.  end;
  248.  
  249. {--------------------------------------------------------------------}
  250.  
  251. PROCEDURE TTerm.DebugInfo;
  252.  
  253.  FUNCTION BinaryByte(Value : Byte) : String;
  254.   Var
  255.     Strn : String;
  256.     Idx  : Word;
  257.  
  258.   begin
  259.     Strn := '';
  260.     Idx := $1;
  261.     Repeat
  262.       if (Value AND Idx = Idx) then
  263.          Strn := '1' + Strn
  264.       else
  265.          Strn := '0' + Strn;
  266.       Idx := Idx SHL 1;
  267.     Until (Idx = $100);
  268.     BinaryByte := Strn;
  269.   end;
  270.  
  271.  begin
  272.    vcWriteLn('');
  273.    vcWrite  ('   Port: COM' + IntToStr(PortIdx));
  274.    vcWrite  ('      Status flags: ' + BinaryByte(PortArray[Comport].StatusFlg));
  275.    vcWriteLn('   Error flags: ' + BinaryByte(PortArray[Comport].ErrorFlg));
  276.    vcWrite  ('    IER: ' + BinaryByte(Port[PortArray[Comport].PortAddr + IER]));
  277.    vcWrite  ('           IIR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + IIR]));
  278.    vcWriteLn('           LCR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + LCR]));
  279.    vcWrite  ('    MCR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + MCR]));
  280.    vcWrite  ('           LSR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + LSR]));
  281.    vcWriteLn('           MSR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + MSR]));
  282.    vcWrite  ('    SCR: ' + BinaryByte(Port[PortArray[Comport].PortAddr + SCR]));
  283.    vcWrite  ('          OCW1: ' + BinaryByte(Port[OCW1]));
  284.    vcWriteLn('          OCW2: ' + BinaryByte(Port[OCW2]));
  285.    vcWrite  ('OutUsed: ' + Left(IntToStr(PortArray[Comport].OutUsed), 4));
  286.    vcWriteLn('            InUsed: ' + IntToStr(PortArray[Comport].InUsed));
  287.    vcWriteLn('');
  288.  end;
  289.  
  290. {--------------------------------------------------------------------}
  291.  
  292. PROCEDURE TTerm.DOSShell;
  293.  begin
  294.    SaveScreen;
  295.    if (GetEnv('COMSPEC') = '') then
  296.       Exec('\COMMAND.COM', '')
  297.    else
  298.       Exec(GetEnv('COMSPEC'), '');
  299.    RestoreScreen;
  300.  end;
  301.  
  302. {--------------------------------------------------------------------}
  303.  
  304. PROCEDURE TTerm.Download;
  305.  Var
  306.    Ch    : Char;
  307.    Fname : String;
  308.    Err   : TError;
  309.  
  310.  begin
  311.    OpenWindow(3, 3, 50, 15, White, Blue, SingleLine, 'Download');
  312.    vcWriteLn('Receive mode: [X]modem, Xmodem-[C]RC,');
  313. {$IFNDEF DEMO}
  314.    vcWriteLn('              Xmodem-[1]K, [Y]modem,');
  315.    vcWrite('              Ymodem-[G]? ');
  316. {$ELSE}
  317.    vcWrite('              Xmodem-[1]K? ');
  318. {$ENDIF}
  319.    Ch := UpCase(ReadKey);
  320.    vcWriteLn(Ch);
  321. {$IFNDEF DEMO}
  322.    if (Pos(Ch, 'XC1YG') > 0) then
  323. {$ELSE}
  324.    if (Pos(Ch, 'XC1') > 0) then
  325. {$ENDIF}
  326.     begin
  327.       case Ch of
  328.         'X',
  329.         'C',
  330.         '1' : begin
  331.                 vcWriteLn('');
  332.                 vcWrite('Receive file: ');
  333.                 ReadLn(Fname);
  334.                 if (Fname = '') then
  335.                  begin
  336.                    CloseWindow;
  337.                    Exit;
  338.                  end;
  339.                 case Ch of
  340.                   'X' : Err := ReceiveXmodem(Checksum, Fname);
  341.                   'C' : Err := ReceiveXmodem(CRC, Fname);
  342.                   '1' : Err := ReceiveXmodem(OneK, Fname);
  343.                 end;
  344.               end;
  345. {$IFNDEF DEMO}
  346.         'Y',
  347.         'G' : begin
  348.                 vcWriteLn('');
  349.                 vcWrite('Batch receive to path: ');
  350.                 vcReadLn(Fname);
  351.                 if (Fname = '') then
  352.                  begin
  353.                    CloseWindow;
  354.                    Exit;
  355.                  end;
  356.                 case Ch of
  357.                   'Y' : Err := ReceiveYmodem(Normal, Fname);
  358.                   'G' : Err := ReceiveYmodem(Streaming, Fname);
  359.                 end;
  360.               end;
  361. {$ENDIF}
  362.       end;
  363.       case Err of
  364.         NoError       : Status('Last Transfer GOOD');
  365.         TimeOut       : Status('Transfer Timeout');
  366.         TooManyErrors : Status('Too Many Errors');
  367.         Aborted       : Status('Aborted by User');
  368.         DiskError     : Status('Disk Error');
  369.         NoCarrier     : Status('Carrier Lost');
  370.         FileExists    : Status('File Already Exists');
  371.       end;
  372.     end;
  373.    CloseWindow;
  374.  end;
  375.  
  376. {--------------------------------------------------------------------}
  377.  
  378. PROCEDURE TTerm.Emulation;
  379.  begin
  380.    if (Exist('STD.EML')) then
  381.     begin
  382.       Inc(Template);
  383.       if (Template > MaxEmu) then
  384.          Template := 1;
  385.       LoadEmulationLib(Emulations[Template], 'STD.EML');
  386.       Status('');
  387.     end
  388.    else
  389.       Status('No STD.EML');
  390.  end;
  391.  
  392. {--------------------------------------------------------------------}
  393.  
  394. PROCEDURE TTerm.EnterAnswerMode;
  395.  begin
  396.    Status('');
  397.    OpenWindow(20, 3, 40, 3, White, Blue, SingleLine, '');
  398.    vcWrite('        Switching To Answer Mode');
  399.    if (not SendAT('ATS0=1')) then
  400.       Status('Modem Not Responding');
  401.    CloseWindow;
  402.  end;
  403.  
  404. {--------------------------------------------------------------------}
  405.  
  406. PROCEDURE TTerm.EnterOriginateMode;
  407.  begin
  408.    Status('');
  409.    OpenWindow(20, 3, 40, 3, White, Blue, SingleLine, '');
  410.    vcWrite('      Switching To Originate Mode');
  411.    if (not SendAT('ATS0=0M1L1E1')) then
  412.       Status('Modem Not Responding');
  413.    CloseWindow;
  414.  end;
  415.  
  416. {--------------------------------------------------------------------}
  417.  
  418. PROCEDURE TTerm.Help(var Cmd : Char);
  419.  Var
  420.    Ch : Char;
  421.  
  422.  begin
  423.    OpenWindow(5, 3, 72, 12, White, Blue, SingleLine, 'Help');
  424.    SetWindowTitle('Term Help');
  425.    GotoXY(1, 2);
  426.    vcWriteLn('  Alt-A  Auto-answer mode              Alt-B  Toggle baudrate');
  427.    vcWriteLn('  Alt-C  Toggle capture buffer         Alt-E  Toggle duplex');
  428.    vcWriteLn('  Alt-H  Hangup                        Alt-J  Jump to DOS');
  429.    vcWriteLn('  Alt-M  Emulation                     Alt-O  Originate mode');
  430.    vcWriteLn('  Alt-P  Toggle printer                Alt-S  Toggle "show controls"');
  431.    vcWriteLn('  Alt-T  Toggle backspace key          Alt-X  Exit');
  432.    vcWriteLn('');
  433.    vcWriteLn('  PgUp   Upload file(s)                PgDn   Download file(s)');
  434.    Ch := ReadKey;
  435.    if (Ch = #0) then
  436.       Cmd := ReadKey;
  437.    CloseWindow;
  438.  end;
  439.  
  440. {--------------------------------------------------------------------}
  441.  
  442. PROCEDURE TTerm.ReInitModem;
  443.  Var
  444.    Save : Byte;
  445.  
  446.  begin
  447.    Save := Port[PortArray[PortIdx].PortAddr + IER];
  448.    Port[PortArray[PortIdx].PortAddr + IER] := $00;
  449.    Port[PortArray[PortIdx].PortAddr + IER] := Save;
  450.  end;
  451.  
  452. {--------------------------------------------------------------------}
  453.  
  454. PROCEDURE TTerm.Status(Msg : String);
  455.  Var
  456.    Fore, Back : Byte;
  457.    SX, SY     : Byte;
  458.    ScrEnd     : Byte;
  459.  
  460.  begin
  461.    Fore := GetTextColor;
  462.    Back := GetTextBackground;
  463.    SX := WhereX;
  464.    SY := WhereY;
  465.    ScrEnd := Hi(WindMax);
  466.    Window(1, 1, 80, 1);
  467.    TextBackground(Blue);
  468.    ClrScr;
  469.    TextColor(Yellow);
  470.    vcWrite(' Term  ');
  471.    TextColor(White);
  472.    case TermFlags.Duplex of
  473.      Full : vcWrite('Full Duplex  ');
  474.      Half : vcWrite('Half Duplex  ');
  475.      Chat : vcWrite('Chat Duplex  ');
  476.    end;
  477.    vcWrite(Right(IntToStr(Baud), 6) + 'bps  ');
  478.    vcWrite('COM' + IntToStr(Comport) + '  ');
  479.    if (Carrier(Comport)) then
  480.       vcWrite('Carrier ')
  481.    else
  482.       vcWrite('        ');
  483.    if (Capture) then
  484.       vcWrite('Cap ')
  485.    else
  486.       vcWrite('    ');
  487.    if (Printer) then
  488.       vcWrite('Prn ')
  489.    else
  490.       vcWrite('    ');
  491.    vcWrite(Left(Emu.Key, 8));
  492.    if (Msg = '') then
  493.       Msg := 'F1 = Help';
  494.    GotoXY(80 - Length(Msg), 1);
  495.    vcWrite(Msg);
  496.    Window(1, 2, 80, TextScreenMaxY);
  497.    TextColor(Fore);
  498.    TextBackground(Back);
  499.    GotoXY(SX, SY);
  500.  end;
  501.  
  502. {--------------------------------------------------------------------}
  503.  
  504. PROCEDURE TTerm.ToggleBackspace;
  505.  begin
  506.    if (TermFlags.Backspace = #8) then
  507.     begin
  508.       TermFlags.Backspace := #127;
  509.       Status('Backspace is RUB');
  510.     end
  511.    else
  512.     begin
  513.       TermFlags.Backspace := #8;
  514.       Status('Backspace is ^H');
  515.     end;
  516.  end;
  517.  
  518. {--------------------------------------------------------------------}
  519.  
  520. PROCEDURE TTerm.ToggleCapture;
  521.  Var
  522.    Cap : String;
  523.  
  524.  begin
  525.    Capture := not Capture;
  526.    if (Capture) then
  527.     begin
  528.       OpenWindow(5, 3, 45, 5, White, Blue, SingleLine, 'Capture to File');
  529.       GotoXY(1, 2);
  530.       vcWrite(' Filename: ');
  531.       ReadLn(Cap);
  532.       if (Cap = '') then
  533.          Cap := 'SESSION.TXT';
  534.       SetCaptureFile(Cap);
  535.       CloseWindow;
  536.     end;
  537.    SetCaptureStatus(Capture);
  538.    Status('');
  539.  end;
  540.  
  541. {--------------------------------------------------------------------}
  542.  
  543. PROCEDURE TTerm.ToggleDuplex;
  544.  begin
  545.    case TermFlags.Duplex of
  546.      Full : TermFlags.Duplex := Half;
  547.      Half : TermFlags.Duplex := Chat;
  548.      Chat : TermFlags.Duplex := Full;
  549.    end;
  550.    Status('');
  551.  end;
  552.  
  553. {--------------------------------------------------------------------}
  554.  
  555. PROCEDURE TTerm.TogglePrinter;
  556.  begin
  557.    Printer := not Printer;
  558.    SetPrinter(Printer);
  559.    Status('');
  560.  end;
  561.  
  562. {--------------------------------------------------------------------}
  563.  
  564. PROCEDURE TTerm.ToggleShowControls;
  565.  begin
  566.    TermFlags.ShowControls := not TermFlags.ShowControls;
  567.    if (TermFlags.ShowControls) then
  568.       Status('Show Controls ON')
  569.    else
  570.       Status('Show Controls OFF');
  571.  end;
  572.  
  573. {--------------------------------------------------------------------}
  574.  
  575. PROCEDURE TTerm.Upload;
  576.  Var
  577.    Ch    : Char;
  578.    Fname : String;
  579.    FInfo : SearchRec;
  580.    Err   : TError;
  581.  
  582.  begin
  583.    OpenWindow(3, 3, 50, 15, White, Blue, SingleLine, 'Upload');
  584.    vcWriteLn('Send mode: [X]modem, Xmodem-[C]RC,');
  585. {$IFNDEF DEMO}
  586.    vcWriteLn('           Xmodem-[1]K, [Y]modem,');
  587.    vcWrite('           Ymodem-[G]? ');
  588. {$ELSE}
  589.    vcWrite('           Xmodem-[1]K? ');
  590. {$ENDIF}
  591.    Ch := UpCase(ReadKey);
  592.    vcWriteLn(Ch);
  593. {$IFNDEF DEMO}
  594.    if (Pos(Ch, 'XC1YG') > 0) then
  595. {$ELSE}
  596.    if (Pos(Ch, 'XC1') > 0) then
  597. {$ENDIF}
  598.     begin
  599.       case Ch of
  600.         'X',
  601.         'C',
  602.         '1' : begin
  603.                 vcWriteLn('');
  604.                 vcWrite('File to send: ');
  605.                 ReadLn(Fname);
  606.                 if (Fname = '') then
  607.                  begin
  608.                    CloseWindow;
  609.                    Exit;
  610.                  end;
  611.                 vcWriteLn('');
  612.                 case Ch of
  613.                   'X' : Err := SendXmodem(Checksum, Fname);
  614.                   'C' : Err := SendXmodem(CRC, Fname);
  615.                   '1' : Err := SendXmodem(OneK, Fname);
  616.                 end;
  617.               end;
  618. {$IFNDEF DEMO}
  619.         'Y',
  620.         'G' : begin
  621.                 vcWriteLn('');
  622.                 vcWriteLn('Batch send: enter a blank line when done.');
  623.                 vcWriteLn('');
  624.                 ClearBatch;
  625.                 Repeat
  626.                   vcWrite('Send file: ');
  627.                   vcReadLn(Fname);
  628.                   if (Fname <> '') then
  629.                      AddBatch(Fname);
  630.                 Until (Fname = '');
  631.                 if (FilesInBatch > 0) then
  632.                  begin
  633.                    case Ch of
  634.                      'Y' : Err := SendYmodem(Normal);
  635.                      'G' : Err := SendYmodem(Streaming);
  636.                    end;
  637.                  end
  638.                 else
  639.                  begin
  640.                    CloseWindow;
  641.                    Exit;
  642.                  end;
  643.               end;
  644. {$ENDIF}
  645.       end;
  646.       case Err of
  647.         NoError       : Status('Last Transfer GOOD');
  648.         Timeout       : Status('Transfer Timeout');
  649.         TooManyErrors : Status('Too Many Errors');
  650.         Aborted       : Status('Aborted by User');
  651.         DiskError     : Status('Disk Error');
  652.         NoCarrier     : Status('Carrier Lost');
  653.         FileExists    : Status('File Already Exists');
  654.       end;
  655.     end;
  656.    CloseWindow;
  657.  end;
  658.  
  659. {********************************************************************}
  660.  
  661. BEGIN
  662.   CheckBreak := False;
  663.   if (ParamCount = 0) or (Pos('?', ParamStr(1)) <> 0) then
  664.      Usage
  665.   else
  666.    begin
  667.      Param := 0;
  668.      Create_Task(StartATerm, Param, 8192, TaskID, TaskResult);
  669.      Switch_Task;
  670.      if (InCommandLine('-D') <> 0) then
  671.       begin
  672.         Param := 1;
  673.         Create_Task(StartATerm, Param, 8192, TaskID, TaskResult);
  674.       end;
  675.      while (Number_Of_Tasks > 2) do  { loop until all terms shutdown }
  676.         Switch_Task;
  677.    end;
  678. END.
  679.