home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / communic / yasdemo.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-12-21  |  10.6 KB  |  301 lines

  1. Program YasDemo;
  2. {
  3.   YasDemo Version 1.1 - Quick and dirty, multiple async port demo for YASYNC.
  4.  
  5.   Run like this:
  6.  
  7.     yasdemo nedpshbbbbb [...]
  8.  
  9.   Where: n   = Serial port number, 1..4
  10.          e   = Echo option, E=Echo keyboard on screen (HDX), N=No Echo (FDX)
  11.          d   = Data bits, 5..8
  12.          p   = Parity, E,O,N,0 or 1
  13.          s   = Stop bits, 1 or 2
  14.          h   = Handshaking: N=None, D=Dtr/Dsr, C=Rts/Cts, X=Xon/Xoff
  15.          b.. = Data rate, bits per second
  16.  
  17.   Example:
  18.  
  19.     yasdemo 3N7E2X1200 1E8N1N9600 2E8N1N9600
  20.  
  21.   Translation - Establish three windows:
  22.  
  23.     1. COM3, No Echo, 7 bits, even parity, 2 stop bits, Xon/Xoff handshaking,
  24.        1200 Bps.
  25.  
  26.     2. COM1, Echo, 8 bits, no parity, 1 stop bit, no handshaking, 9600 Bps.
  27.  
  28.     3. COM2, Echo, 8 bits, no parity, 1 stop bit, no handshaking, 9600 Bps.
  29.  
  30.   Note.. Some hardware serial port configurations preclude concurrent
  31.   use of more than one serial port at a time.  In particular, two ports which
  32.   share an interrupt may "fight" over the irq line if not connected through
  33.   appropriate logic so either may trigger the interrupt independently.  This
  34.   sometimes results in one port appearing to function only when interrupts
  35.   occur regularly on the other port.  This is a sign of incorrect hardware
  36.   design or installation.
  37.  
  38.   The format of the control line was chosen for convenience of interprtation,
  39.   not ease of use.  If anyone feels the urge to correct this deficiency, please
  40.   don't hesitate.
  41.  
  42.   By: Edwin T. Floyd [76067,747]
  43.       Hughston Sports Medicine Foundation
  44.       P.O. Box 9517
  45.       Columbus, GA 31995
  46.       (404) 324-6074
  47.  
  48.   This demo program is contributed to the public domain.
  49.  
  50.   12-20-87 E. Floyd - Version 1.0
  51.   12-21-87 E. Floyd - V 1.1 Added Echo option, documented for C'Serv upload
  52. }
  53. Uses Crt, Dos, Yasync;
  54.  
  55. Const
  56.   BufferSize = 4096; { Transmit and receive buffers }
  57.  
  58. Type
  59.   ScreenWindowType = Record
  60.   { Control information for screen window }
  61.     WindowOk : Boolean;
  62.     Rate : LongInt;   { Data rate in bits per second }
  63.     ComPort : Word;   { Serial port number }
  64.     Bits : Word;      { Number of data bits }
  65.     Stop : Word;      { Number of stop bits }
  66.     ErrorCount : Word;   { Number of error interrupts }
  67.     OverrunCount : Word; { Number of overrun errors }
  68.     ParityCount : Word;  { Number of parity errors }
  69.     FrameCount : Word;   { Number of framing errors }
  70.     BreakCount : Word;   { Number of break signals received }
  71.     TimeoutCount : Word; { Number of timeouts }
  72.     Parity : Char;    { Parity (N,E,O,0,1) }
  73.     HandShake : Char; { Handshaking option (N,D,C,X) }
  74.     Echo : Char;      { Echo option (N,E) }
  75.     WinX1, WinY1, WinX2, WinY2, CursorX, CursorY : Byte;
  76.     Message : String[80];
  77.   End;
  78.  
  79. Var
  80.   ScreenWindow : Array[1..MaxPorts] Of ScreenWindowType;
  81.   W, InUse, KeyBoardScreen : Word;
  82.   Done : Boolean;
  83.   Ch : Char;
  84.  
  85. {$F+} Procedure ErrorProc(ComPort : Word); {$F-}
  86. { Error handler; Far call, don't use DOS - may be called from intrpt handler.
  87.   Note.. These are word-size counters and could easily overflow.  A practical
  88.   implementation would either use LongInts or check for impending overflow. }
  89. Begin { ErrorProc }
  90.   With AsyncPort[ComPort], ScreenWindow[UserData] Do Begin
  91.     Inc(ErrorCount);
  92.     If (LineStatus And LSROverrun) <> 0 Then Inc(OverrunCount);
  93.     If (LineStatus And LSRParity) <> 0 Then Inc(ParityCount);
  94.     If (LineStatus And LSRFrame) <> 0 Then Inc(FrameCount);
  95.     If (LineStatus And LSRBreak) <> 0 Then Inc(BreakCount);
  96.     If (LineStatus And LSRTimeout) <> 0 Then Inc(TimeoutCount);
  97.   End;
  98. End;  { ErrorProc }
  99.  
  100. Procedure InterpretParm(w : Word; s : String);
  101. { Interpret startup parameter passed on command line. }
  102. Var
  103.   i : Word;
  104.   bad : Boolean;
  105.   sm : String[5];
  106. Begin { InterpretParm }
  107.   bad := false;
  108.   With ScreenWindow[w] Do Begin
  109.     WindowOk := False;
  110.     ErrorCount := 0; { Clear error counters }
  111.     OverrunCount := 0;
  112.     ParityCount := 0;
  113.     FrameCount := 0;
  114.     BreakCount := 0;
  115.     TimeoutCount := 0;
  116.     Str(w, sm);
  117.     Val(Copy(s, 1, 1), ComPort, i);
  118.     If i <> 0 Then bad := True;
  119.     If (ComPort < 1) Or (ComPort > MaxPorts) Then bad := True;
  120.     Echo := UpCase(s[2]);
  121.     If Not (Echo In ['N','E']) Then bad := True;
  122.     Val(Copy(s, 3, 1), Bits, i);
  123.     If i <> 0 Then bad := True;
  124.     Parity := UpCase(s[4]);
  125.     Val(Copy(s, 5, 1), Stop, i);
  126.     If i <> 0 Then bad := True;
  127.     HandShake := UpCase(s[6]);
  128.     If Not (HandShake In ['N','D','C','X']) Then bad := True;
  129.     Val(Copy(s, 7, 5), Rate, i);
  130.     If i <> 0 Then bad := True;
  131.     If bad Then Begin
  132.       Message := 'Error in specification for window ' + sm
  133.         + ': "' + s + '" (nedpshbbbbb)';
  134.     End Else Begin
  135.       With AsyncPort[ComPort] Do Begin
  136.         If PortOpen Then Message := 'COM' + sm + ' Already open ' Else Begin
  137.           RtsHand := False;
  138.           TransmitSize := BufferSize;
  139.           ReceiveSize := BufferSize;
  140.           ErrorRoutine := @ErrorProc;
  141.           UserData := w;
  142.           Case HandShake Of
  143.             'N' : ;
  144.             'D' : Begin
  145.               WaitForDsr := True;
  146.               DtrHand := True;
  147.             End;
  148.             'C' : Begin
  149.               WaitForCts := True;
  150.               RtsHand := True;
  151.             End;
  152.             'X' : Begin
  153.               WaitForXon := True;
  154.               XoHand := True;
  155.               XoTransparent := False;
  156.             End;
  157.           End;
  158.           If OpenPort(ComPort, Rate, Bits, Stop, Parity) Then Begin
  159.             Str(ComPort, sm);
  160.             Message := 'COM' + sm + ' ';
  161.             Str(Rate, sm);
  162.             Message := Message + sm + ' Bps,  ';
  163.             Str(Bits, sm);
  164.             Message := Message + sm + ' Data bits, ';
  165.             Str(Stop, sm);
  166.             Message := Message + sm + ' Stop bits, ' + Parity + ' Parity, '
  167.              + Handshake + ' Handshake';
  168.             WindowOk := True;
  169.           End Else Begin
  170.             Case PortOpenError Of
  171.               1 : Message := 'Port number out of range (1..4)';
  172.               2 : Message := 'Baud rate out of range (50..115200)';
  173.               3 : Message := 'Word length out of range (5..8)';
  174.               4 : Message := 'Stop bits out of range (1..2)';
  175.               5 : Message := 'Invalid parity (N,E,O,1,0)';
  176.               6 : Message := 'Buffer size invalid (2..32767)';
  177.               7 : Message := 'Insufficient heap space for buffers';
  178.               8 : Message := 'UART not responding';
  179.               9 : Message := 'Program bug - should never happen';
  180.             End;
  181.             Message := '"' + s + '" (ndpshbbbbb), Error: ' + Message
  182.           End;
  183.         End;
  184.       End;
  185.     End;
  186.   End;
  187. End;  { InterpretParm }
  188.  
  189. Procedure SetKeyboardScreen(W : Word);
  190. { Set keyboard active screen }
  191. Begin { SetKeyboardScreen }
  192.   Window(1, 1, 80, 25);
  193.   TextColor(Black);
  194.   TextBackground(White);
  195.   GoToXY(66, Succ(ScreenWindow[KeyboardScreen].WinY2));
  196.   ClrEol;
  197.   GoToXY(66, Succ(ScreenWindow[W].WinY2));
  198.   Write('^^Keyboard^^');
  199.   TextColor(White);
  200.   TextBackground(Black);
  201.   KeyboardScreen := W;
  202. End;  { SetKeyboardScreen }
  203.  
  204. Begin { YasDemo }
  205.   InUse := 0;
  206.   While (InUse < ParamCount) And (InUse < MaxPorts) Do Begin
  207.     { Interpret parameter line }
  208.     Inc(InUse);
  209.     InterpretParm(InUse, ParamStr(InUse));
  210.   End;
  211.   If InUse > 0 Then Begin { We have some windows }
  212.     KeyboardScreen := 1;
  213.     TextBackground(White); { Write header and underlines in reverse video }
  214.     TextColor(Black);
  215.     ClrScr;
  216.     Write('    YasDemo Version 1.1, Press: F1 - change screens, F9 - break, F10 - exit ');
  217.     For W := 1 To InUse Do With ScreenWindow[W] Do Begin
  218.       { Set window location & size and write underline message }
  219.       WinX1 := 1;
  220.       WinY1 := Pred(W) * (24 Div InUse) + 2;
  221.       WinX2 := 80;
  222.       WinY2 := WinY1 + (24 Div InUse) - 2;
  223.       GoToXY(1, Succ(WinY2));
  224.       ClrEol;
  225.       Write(Message);
  226.       CursorX := 1;
  227.       CursorY := 24 Div InUse - 1;
  228.     End;
  229.     TextBackground(Black);
  230.     TextColor(White);
  231.     For W := 1 To InUse Do With ScreenWindow[W] Do Begin { Clear windows }
  232.       Window(WinX1, WinY1, WinX2, WinY2);
  233.       ClrScr;
  234.     End;
  235.     Done := False;
  236.     SetKeyboardScreen(KeyboardScreen);
  237.     W := 1;
  238.     Repeat { Main loop }
  239.       If KeyPressed Then Begin { We have a keystroke }
  240.         Ch := ReadKey;
  241.         If (Ch = #0) And KeyPressed Then Begin { Extended key code }
  242.           Ch := ReadKey;
  243.           Case Ch Of
  244.             #59 {F1} : SetKeyboardScreen(Succ(KeyboardScreen Mod InUse));
  245.             #67 {F9} : With ScreenWindow[KeyboardScreen] Do
  246.               If WindowOk Then SendBreak(ComPort);
  247.             #68 {F10}: Done := True;
  248.             Else Write(^G); { Beep }
  249.           End;
  250.         End
  251.         Else With ScreenWindow[KeyboardScreen] Do Begin { Send keystroke }
  252.           If Echo = 'E' Then Begin
  253.             Window(WinX1, WinY1, WinX2, WinY2);
  254.             GoToXY(CursorX, CursorY);
  255.             Write(Ch);
  256.             CursorX := WhereX;
  257.             CursorY := WhereY;
  258.           End;
  259.           If WindowOk Then If Not SendPort(ComPort, Ch) Then Write(^G);
  260.         End;
  261.       End;
  262.       With ScreenWindow[W] Do Begin { Check for received character }
  263.         If WindowOk Then Begin
  264.           If ReadPort(ComPort, Ch) Then Begin { We have received a character }
  265.             Window(WinX1, WinY1, WinX2, WinY2);
  266.             GoToXY(CursorX, CursorY);
  267.             Write(Ch);
  268.             CursorX := WhereX;
  269.             CursorY := WhereY;
  270.           End;
  271.         End;
  272.       End;
  273.       W := Succ(W Mod InUse);
  274.     Until Done;
  275.     { Finished, display error counts }
  276.     Window(1, 1, 80, 25);
  277.     ClrScr;
  278.     For W := 1 To InUse Do With ScreenWindow[W] Do Begin
  279.       If WindowOk Then ClosePort(ComPort);
  280.       WriteLn('Port COM', ComPort, ', ', ErrorCount, ' Error interrupts');
  281.       WriteLn('  ', OverrunCount, ' Overrun errors');
  282.       WriteLn('  ', ParityCount, ' Parity errors');
  283.       WriteLn('  ', FrameCount, ' Framing errors');
  284.       WriteLn('  ', BreakCount, ' Break signals received');
  285.       WriteLn('  ', TimeoutCount, ' Timeouts');
  286.     End;
  287.   End Else Begin { No windows, tell them how to run program }
  288.     WriteLn('Run like this:');
  289.     WriteLn;
  290.     WriteLn('  YASDEMO nedpshbbbbb [...]');
  291.     WriteLn;
  292.     WriteLn('Where: n   = Serial port number, 1..4');
  293.     WriteLn('       e   = Echo option, E=Echo keyboard on screen (HDX), N=No Echo (FDX)');
  294.     WriteLn('       d   = Data bits, 5..8');
  295.     WriteLn('       p   = Parity, E,O,N,0 or 1');
  296.     WriteLn('       s   = Stop bits, 1..2');
  297.     WriteLn('       h   = Handshaking: N=None, D=Dtr/Dsr, C=Rts/Cts, X=Xon/Xoff');
  298.     WriteLn('       b.. = Data rate, bits per second');
  299.   End;
  300. End.  { YasDemo }
  301.